agent-insight 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
- package/.next/standalone/.next/build-manifest.json +2 -2
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/routes-manifest.json +6 -0
- package/.next/standalone/.next/server/app/_global-error.html +2 -2
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig/channels/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig/channels.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/channels.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig/health/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig/health.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/health.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.html +2 -2
- package/.next/standalone/.next/server/app/accessconfig/install.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig/install/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig/install.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/install.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig/webhooks/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig/webhooks.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig/webhooks.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.html +1 -1
- package/.next/standalone/.next/server/app/accessconfig.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p/accessconfig/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p/accessconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/accessconfig.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.html +1 -1
- package/.next/standalone/.next/server/app/agents.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/agent/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/stream/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-datasets/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent-datasets/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/apikey/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/organization/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/dashboard/stats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/batch-tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/batch-tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/execute/[jobId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/execute/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/grayscale-tasks/[taskId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/grayscale-tasks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/history/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/debug/history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/backfill-routing/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/create/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/reparse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/config/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/evaluation/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/rejudge/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/settings/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/terminate-all/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/results/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/results/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/eval/trajectory/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/evaluation/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/evaluation/cancel/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fault/diagnosis/session/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fault/diagnosis/stream/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fleet/breakdowns/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/fleet/trends/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/guide/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/opencode/session-complete/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/logs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/metrics/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/otel/v1/traces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/end/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/proxy/[taskId]/start/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/app-paths-manifest.json +3 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/build-manifest.json +11 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route/server-reference-manifest.json +4 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js +7 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js.map +5 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route.js.nft.json +1 -0
- package/.next/standalone/.next/server/app/api/ingest/setup/opencode-offline-fix/route_client-reference-manifest.js +2 -0
- package/.next/standalone/.next/server/app/api/ingest/sync/manifest/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/sync/opencode/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/ingest/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/data/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/agent-debug/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/agent-debug/skills-analysis/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/analyze-match/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/executions/[executionId]/infra/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/poll/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/derive/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/overview/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/infra/sources/test/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/session/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/observe/task-stats/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/public/otel/v1/traces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/agents/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/backfill/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/executions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/quality/report/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/draft/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/run/[runId]/cancel/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-eval/trigger/[skillName]/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/attachments/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/chat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/download/[sessionId]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/files/list/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/sessions/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-generator/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/chat/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/plan/items/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/plan/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/iterations/[draftNumber]/apply/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/iterations/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skill-opt/sessions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/activate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/benchmark-generate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/runs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/toggle/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/evaluate/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/evaluation-summary/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/parse-flow/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/[version]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/[id]/versions/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/automation/import/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/automation/push/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/analysis-diagnosis/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/optimization-points/resolve/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/[name]/optimization-points/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/by-name/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/logs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/publish/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/sync-enterprise/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/skills/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/user-evaluators/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/dashboard.html +1 -1
- package/.next/standalone/.next/server/app/dashboard.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p/dashboard/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p/dashboard.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.html +1 -1
- package/.next/standalone/.next/server/app/dataset.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p/dataset/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p/dataset.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/dataset.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.html +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval/trajectory/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval/trajectory.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p/eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval/trajectory.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.html +1 -1
- package/.next/standalone/.next/server/app/eval.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p/eval/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p/eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/eval.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.html +1 -1
- package/.next/standalone/.next/server/app/fault.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p/fault/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p/fault.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/fault.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.html +1 -1
- package/.next/standalone/.next/server/app/infra/sources.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra/sources/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra/sources.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p/infra.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra/sources.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.html +1 -1
- package/.next/standalone/.next/server/app/infra.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p/infra/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p/infra.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/infra.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.html +1 -1
- package/.next/standalone/.next/server/app/login.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.html +1 -1
- package/.next/standalone/.next/server/app/memory.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p/memory/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p/memory.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.html +1 -1
- package/.next/standalone/.next/server/app/metrics.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p/metrics/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p/metrics.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/metrics.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig/registry/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig/registry.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/registry.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig/web-search/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig/web-search.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig/web-search.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.html +1 -1
- package/.next/standalone/.next/server/app/modelconfig.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p/modelconfig/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p/modelconfig.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/modelconfig.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.html +1 -1
- package/.next/standalone/.next/server/app/optapi.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p/optapi/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p/optapi.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/optapi.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.html +1 -1
- package/.next/standalone/.next/server/app/quality.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p/quality/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p/quality.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/quality.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.html +1 -1
- package/.next/standalone/.next/server/app/security.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p/security/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p/security.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/security.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.html +1 -1
- package/.next/standalone/.next/server/app/skill-detail.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/skill-detail/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-detail.segments/skill-detail.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.html +2 -2
- package/.next/standalone/.next/server/app/skill-eval/grayscale.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval/grayscale/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval/grayscale.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p/skill-eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval/grayscale.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.html +1 -1
- package/.next/standalone/.next/server/app/skill-eval.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p/skill-eval/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p/skill-eval.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-eval.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.html +1 -1
- package/.next/standalone/.next/server/app/skill-generator.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p/skill-generator/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p/skill-generator.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-generator.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.html +1 -1
- package/.next/standalone/.next/server/app/skill-history.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p/skill-history/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p/skill-history.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-history.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.html +1 -1
- package/.next/standalone/.next/server/app/skill-opt.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p/skill-opt/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p/skill-opt.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-opt.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.html +1 -1
- package/.next/standalone/.next/server/app/skill-release.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p/skill-release/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p/skill-release.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skill-release.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.html +1 -1
- package/.next/standalone/.next/server/app/skills.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p/skills/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p/skills.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/skills.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.html +1 -1
- package/.next/standalone/.next/server/app/trace.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p/trace/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p/trace.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/trace.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__edc6a75f._.js +3 -0
- package/.next/standalone/.next/server/chunks/ce889_server_app_api_ingest_setup_opencode-offline-fix_route_actions_13b9e7e1.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_c4a195e5.js +1 -1
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +2 -2
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_2.md +1312 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_3.md +712 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna_4.md +1228 -0
- package/.next/standalone/docker-compose.amd64.yml +1 -1
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/scripts/opencode-offline-fix.ps1 +93 -0
- package/.next/standalone/scripts/opencode_tui_plugin.tsx +23 -1
- package/package.json +1 -1
- package/scripts/opencode-offline-fix.ps1 +93 -0
- package/scripts/opencode_tui_plugin.tsx +23 -1
- package/.next/standalone/scripts/activate_telemetry.sh +0 -202
- package/.next/standalone/scripts/insight-paths.js +0 -33
- package/.next/standalone/scripts/opencode_otel_schema.ts +0 -73
- package/.next/standalone/scripts/opencode_plugin.ts +0 -1063
- package/scripts/activate_telemetry.sh +0 -202
- package/scripts/insight-paths.js +0 -33
- package/scripts/opencode_otel_schema.ts +0 -73
- package/scripts/opencode_plugin.ts +0 -1063
- /package/.next/standalone/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/standalone/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
- /package/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{xzZesDmllz08gJIxUNkXr → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,1312 @@
|
|
|
1
|
+
# Agent 评估器调研问答 2
|
|
2
|
+
|
|
3
|
+
调研日期:2026-07-06
|
|
4
|
+
|
|
5
|
+
这份文档用于继续记录 `agent_evaluator_industry_research.md` 里的细节问题。上一份问答见 `agent_evaluator_research_qna.md`。
|
|
6
|
+
|
|
7
|
+
## Q5:DeepEval PlanAdherenceMetric 的意义是什么?如果 plan 和 execution steps 都来自 trace,这种“自我评价”奇怪吗?
|
|
8
|
+
|
|
9
|
+
### 简短回答
|
|
10
|
+
|
|
11
|
+
确实容易觉得奇怪,但它不是让 agent “自己评价自己”。更准确地说,DeepEval [`PlanAdherenceMetric`](https://deepeval.com/docs/metrics-plan-adherence) 是用一个外部 LLM judge,从同一条 trace 中抽取两类对象:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
1. agent 曾经表达或暗示过的计划 plan
|
|
15
|
+
2. agent 后续实际执行的步骤 execution steps
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
然后评估:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
实际执行步骤是否遵守了前面那个计划?
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
所以它评估的不是“计划好不好”,也不是“最终结果好不好”,而是:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
agent 是否能把自己定下的路线稳定执行下去?
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 为什么这不是纯粹的自我评价?
|
|
31
|
+
|
|
32
|
+
它看起来像自我评价,是因为 plan 和 execution steps 都来自同一条 trace。但真正的评价者不是原 agent,而是外部 evaluator。
|
|
33
|
+
|
|
34
|
+
可以类比成人类项目复盘:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
会议纪要里写了计划:
|
|
38
|
+
1. 先确认需求
|
|
39
|
+
2. 再修改代码
|
|
40
|
+
3. 最后运行测试
|
|
41
|
+
|
|
42
|
+
实际工作记录里显示:
|
|
43
|
+
1. 直接修改代码
|
|
44
|
+
2. 没有确认需求
|
|
45
|
+
3. 没有运行测试
|
|
46
|
+
|
|
47
|
+
复盘者判断:
|
|
48
|
+
没有遵守计划
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
计划和执行记录都来自同一个项目过程,但复盘判断不是项目执行者自己做的,而是外部观察者做的。
|
|
52
|
+
|
|
53
|
+
### 这个指标的意义在哪?
|
|
54
|
+
|
|
55
|
+
Plan Adherence 的意义是把 agent 的失败拆成更细的责任阶段。
|
|
56
|
+
|
|
57
|
+
很多时候 agent 会先说出一个看起来合理的计划:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
我会先读取相关文件,然后定位问题,再修改代码,最后运行测试。
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
但实际 trace 里可能是:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
读取了一个文件
|
|
67
|
+
直接修改
|
|
68
|
+
没有运行测试
|
|
69
|
+
直接回复完成
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
这时如果只看 Plan Quality,计划可能是好的;如果只看 Task Completion,可能只知道结果成败;Plan Adherence 则能指出:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
计划本身没问题,但执行没有跟上。
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
它尤其能发现这些问题:
|
|
79
|
+
|
|
80
|
+
- 计划里说要验证,但最后没验证。
|
|
81
|
+
- 计划里说要先收集信息,但直接行动。
|
|
82
|
+
- 计划里说要分阶段处理,但执行时跳步。
|
|
83
|
+
- 计划里说要调用某类工具,但实际用了无关工具。
|
|
84
|
+
- 计划里说要交给某个子 agent,但实际没有派发或派错。
|
|
85
|
+
- 中途遇到错误后,偏离计划但没有解释或重规划。
|
|
86
|
+
|
|
87
|
+
### 它和 Plan Quality 的区别
|
|
88
|
+
|
|
89
|
+
| 指标 | 比较对象 | 回答的问题 |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| Plan Quality | Task vs Plan | 这个计划本身能不能完成任务? |
|
|
92
|
+
| Plan Adherence | Plan vs Execution Steps | agent 后续有没有按计划执行? |
|
|
93
|
+
|
|
94
|
+
典型情况:
|
|
95
|
+
|
|
96
|
+
| Plan Quality | Plan Adherence | 说明 |
|
|
97
|
+
| --- | --- | --- |
|
|
98
|
+
| 高 | 高 | 计划合理,执行也遵守,理想状态 |
|
|
99
|
+
| 高 | 低 | 计划合理,但执行偏离,问题在执行控制 |
|
|
100
|
+
| 低 | 高 | agent 忠实执行了坏计划,问题在规划能力 |
|
|
101
|
+
| 低 | 低 | 规划和执行都不稳定 |
|
|
102
|
+
|
|
103
|
+
### `agent's execution steps` 是什么意思?
|
|
104
|
+
|
|
105
|
+
`agent's execution steps` 指的是 agent 在 trace 中实际发生过的一系列可观察动作。它不是隐藏推理,也不是模型脑子里的 chain-of-thought,而是运行记录里能看到的步骤。
|
|
106
|
+
|
|
107
|
+
常见 execution steps 包括:
|
|
108
|
+
|
|
109
|
+
- 用户请求。
|
|
110
|
+
- agent 的可见计划或行动说明。
|
|
111
|
+
- LLM 生成的一次响应。
|
|
112
|
+
- 工具调用,例如 `read_file`、`web_search`、`bash`、`database_query`。
|
|
113
|
+
- 工具返回结果。
|
|
114
|
+
- skill 调用。
|
|
115
|
+
- 子 agent / handoff 调用。
|
|
116
|
+
- 错误、重试、参数修正。
|
|
117
|
+
- 最终回复。
|
|
118
|
+
|
|
119
|
+
一个简化 trace 可以表示成:
|
|
120
|
+
|
|
121
|
+
```text
|
|
122
|
+
[#0] user: 修复登录失败问题
|
|
123
|
+
[#1] assistant: 我会先查看日志,再定位代码,再修改并运行测试
|
|
124
|
+
[#2] tool: read_file("auth.log")
|
|
125
|
+
[#3] tool_result: database timeout
|
|
126
|
+
[#4] tool: read_file("src/auth.ts")
|
|
127
|
+
[#5] tool: edit_file("src/auth.ts")
|
|
128
|
+
[#6] assistant: 已修复
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
这里:
|
|
132
|
+
|
|
133
|
+
- plan 是 `[#1]` 里的“先查看日志、再定位代码、再修改并运行测试”。
|
|
134
|
+
- execution steps 是 `[#2]` 到 `[#6]` 的实际动作序列。
|
|
135
|
+
- Plan Adherence 会发现:计划里有“运行测试”,execution steps 里没有测试步骤。
|
|
136
|
+
|
|
137
|
+
### execution steps 怎么提取?
|
|
138
|
+
|
|
139
|
+
通常从 trace 的 span / event 序列中提取。不同框架字段不同,但核心思路类似。
|
|
140
|
+
|
|
141
|
+
#### 1. 先把 trace 按时间排序
|
|
142
|
+
|
|
143
|
+
原始 trace 里可能有很多 span:
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
llm.call
|
|
147
|
+
tool.call
|
|
148
|
+
tool.result
|
|
149
|
+
agent.message
|
|
150
|
+
subagent.start
|
|
151
|
+
subagent.end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
先按时间线排成一条或一棵执行链。
|
|
155
|
+
|
|
156
|
+
#### 2. 过滤成 agent 行为相关事件
|
|
157
|
+
|
|
158
|
+
不是所有 telemetry 都是 execution step。通常保留:
|
|
159
|
+
|
|
160
|
+
- LLM 输出。
|
|
161
|
+
- tool call。
|
|
162
|
+
- tool result。
|
|
163
|
+
- skill call。
|
|
164
|
+
- subagent / handoff。
|
|
165
|
+
- 错误和 retry。
|
|
166
|
+
- 最终输出。
|
|
167
|
+
|
|
168
|
+
可以忽略:
|
|
169
|
+
|
|
170
|
+
- 纯内部网络 span。
|
|
171
|
+
- 日志写入 span。
|
|
172
|
+
- UI 事件。
|
|
173
|
+
- 与任务无关的 telemetry。
|
|
174
|
+
|
|
175
|
+
#### 3. 归一化为步骤结构
|
|
176
|
+
|
|
177
|
+
例如统一成:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"step_index": 4,
|
|
182
|
+
"kind": "tool",
|
|
183
|
+
"name": "read_file",
|
|
184
|
+
"args_summary": "{\"path\":\"src/auth.ts\"}",
|
|
185
|
+
"output_summary": "function login(...) ...",
|
|
186
|
+
"timestamp": "...",
|
|
187
|
+
"agent": "root"
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
这一步的目标是让 evaluator 不必理解每个框架的原始日志格式。
|
|
192
|
+
|
|
193
|
+
#### 4. 抽取 plan
|
|
194
|
+
|
|
195
|
+
plan 可以来自:
|
|
196
|
+
|
|
197
|
+
- agent 明确输出的计划。
|
|
198
|
+
- TODO list。
|
|
199
|
+
- “I will first..., then...” 这类行动说明。
|
|
200
|
+
- 子 agent 派发前的任务拆解。
|
|
201
|
+
- 对用户可见的工作步骤承诺。
|
|
202
|
+
|
|
203
|
+
不建议从隐藏推理里抽 plan,也不应该为了评估要求模型泄露 chain-of-thought。
|
|
204
|
+
|
|
205
|
+
#### 5. 比较 plan 和 execution steps
|
|
206
|
+
|
|
207
|
+
外部 judge 会判断:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
计划中的每个步骤是否执行了?
|
|
211
|
+
执行顺序是否大体一致?
|
|
212
|
+
是否跳过关键步骤?
|
|
213
|
+
是否做了计划外但合理的重规划?
|
|
214
|
+
是否偏离计划且没有解释?
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
输出通常可以是:
|
|
218
|
+
|
|
219
|
+
```text
|
|
220
|
+
score: 0-1
|
|
221
|
+
reason: 为什么遵守/没遵守
|
|
222
|
+
missed_plan_items: [...]
|
|
223
|
+
deviated_steps: [...]
|
|
224
|
+
evidence_steps: [...]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### 什么时候这个指标有意义?
|
|
228
|
+
|
|
229
|
+
Plan Adherence 有意义的前提是:trace 里真的有可见计划。
|
|
230
|
+
|
|
231
|
+
适合场景:
|
|
232
|
+
|
|
233
|
+
- agent 会先输出任务计划。
|
|
234
|
+
- coding agent 有 todo list。
|
|
235
|
+
- 多 agent 系统有任务拆解和 handoff 计划。
|
|
236
|
+
- 高风险任务要求先说明步骤再执行。
|
|
237
|
+
- skill 明确要求 agent 按流程执行。
|
|
238
|
+
|
|
239
|
+
例如:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
先分析日志 -> 再定位根因 -> 再修改配置 -> 最后验证
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
如果 trace 里能看到这个计划,那么评估实际是否遵守就很有价值。
|
|
246
|
+
|
|
247
|
+
### 什么时候它会变得很弱,甚至误导?
|
|
248
|
+
|
|
249
|
+
#### 1. trace 里没有可见计划
|
|
250
|
+
|
|
251
|
+
如果 agent 没有输出计划,或者框架不记录 planning 信息,Plan Adherence 就缺少比较对象。
|
|
252
|
+
|
|
253
|
+
这时不应该强行给高分或低分,更合理的是:
|
|
254
|
+
|
|
255
|
+
```text
|
|
256
|
+
N/A: no visible plan
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
#### 2. plan 是评估器事后从执行步骤“反推”的
|
|
260
|
+
|
|
261
|
+
这是最危险的情况。
|
|
262
|
+
|
|
263
|
+
如果 evaluator 不是从 agent 执行前的可见计划抽 plan,而是看完整 trace 后总结出一个“计划”,再拿这个计划和同一条 trace 比较,那么就会产生循环:
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
根据实际执行反推出计划
|
|
267
|
+
再评估实际执行是否符合这个计划
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
这当然会虚高,也就失去意义。
|
|
271
|
+
|
|
272
|
+
所以 Plan Adherence 的关键约束是:
|
|
273
|
+
|
|
274
|
+
```text
|
|
275
|
+
plan 必须来自执行前或执行中的可见计划表达,
|
|
276
|
+
不能由 evaluator 看完整执行后倒推出。
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
#### 3. agent 合理重规划
|
|
280
|
+
|
|
281
|
+
如果执行过程中出现新证据,agent 偏离原计划不一定是坏事。
|
|
282
|
+
|
|
283
|
+
例如:
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
原计划:读取 A 文件后修改 A
|
|
287
|
+
实际:读取 A 后发现问题在 B,于是改 B 并说明原因
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
这应该算合理重规划,而不是简单扣分。
|
|
291
|
+
|
|
292
|
+
所以评估时要区分:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
合理偏离:有新证据、有解释、目标仍一致
|
|
296
|
+
不合理偏离:无理由跳过关键步骤、忘记验证、做无关动作
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 这个指标对 agent 评估改进有什么用?
|
|
300
|
+
|
|
301
|
+
它主要帮助改 **执行控制能力**,不是直接改最终答案。
|
|
302
|
+
|
|
303
|
+
如果 Plan Quality 高但 Plan Adherence 低,优化方向通常是:
|
|
304
|
+
|
|
305
|
+
- 增加 checklist / todo 状态跟踪。
|
|
306
|
+
- 在回复前检查计划项是否完成。
|
|
307
|
+
- 给关键步骤加 hard constraint,例如“修改后必须验证”。
|
|
308
|
+
- 增加中途偏离计划时的重规划说明。
|
|
309
|
+
- 给多 agent handoff 增加父 agent 汇总和验收步骤。
|
|
310
|
+
|
|
311
|
+
它能避免一种常见问题:
|
|
312
|
+
|
|
313
|
+
```text
|
|
314
|
+
agent 很会说计划,但执行时不按计划做。
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
这类 agent 看起来很聪明,但可靠性差。Plan Adherence 正是用来抓这种“计划-执行脱节”的。
|
|
318
|
+
|
|
319
|
+
### 总结
|
|
320
|
+
|
|
321
|
+
Plan Adherence 的核心不是“自我评价”,而是:
|
|
322
|
+
|
|
323
|
+
```text
|
|
324
|
+
外部 evaluator 检查 agent 的可见计划和实际执行是否一致。
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
`agent's execution steps` 就是 trace 中可观察到的行动序列,包括 LLM 消息、工具调用、工具返回、skill 调用、子 agent 调用、错误重试和最终回复。
|
|
328
|
+
|
|
329
|
+
这个指标有意义的前提是:
|
|
330
|
+
|
|
331
|
+
```text
|
|
332
|
+
plan 必须是执行前/执行中可见的真实计划,
|
|
333
|
+
不能是根据完整 trace 事后反推出来的计划。
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
如果没有可见计划,最好标记为 N/A;如果有可见计划,它就能很好地区分“计划错了”与“执行没跟上”。
|
|
337
|
+
|
|
338
|
+
### 参考链接
|
|
339
|
+
|
|
340
|
+
- DeepEval Plan Adherence: https://deepeval.com/docs/metrics-plan-adherence
|
|
341
|
+
|
|
342
|
+
## Q6:Ragas Context Precision / Context Recall 和 Phoenix Document Relevance 有什么区别?Ragas Context Precision / Recall 的输入、输出和评估过程是什么?
|
|
343
|
+
|
|
344
|
+
### 简短结论
|
|
345
|
+
|
|
346
|
+
这三个指标都和 RAG / 检索质量有关,但粒度和回答的问题不一样。
|
|
347
|
+
|
|
348
|
+
| 指标 | 主要回答的问题 | 评估粒度 | 是否看排序 | 是否需要 reference | 输出 |
|
|
349
|
+
| --- | --- | --- | --- | --- | --- |
|
|
350
|
+
| Ragas [`Context Precision`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/) | 检索回来的上下文里,相关内容是否排在前面? | 一次 query 的整组 retrieved contexts | 看排序 | 可用 reference、response、reference_contexts 或 context IDs,取决于变体 | 0-1 连续分 |
|
|
351
|
+
| Ragas [`Context Recall`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_recall/) | reference 里需要的信息,有多少被检索回来了? | 一次 query 的整组 retrieved contexts | 不重点看排序 | 需要 reference / reference_contexts / reference IDs | 0-1 连续分 |
|
|
352
|
+
| Phoenix [`Document Relevance`](https://arize.com/docs/phoenix/evaluation/pre-built-metrics/document-relevance) | 单个文档 chunk 对当前 query 是否相关? | 单个 document / span | 不看排序 | 不需要 reference,只需要 query + document | `relevant` / `unrelated`,1 或 0 |
|
|
353
|
+
|
|
354
|
+
可以这样记:
|
|
355
|
+
|
|
356
|
+
```text
|
|
357
|
+
Phoenix Document Relevance:
|
|
358
|
+
这个单独文档有没有用?
|
|
359
|
+
|
|
360
|
+
Ragas Context Precision:
|
|
361
|
+
检索回来的一组文档里,有用的是否排在前面?
|
|
362
|
+
|
|
363
|
+
Ragas Context Recall:
|
|
364
|
+
该找回的重要信息有没有找全?
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Phoenix Document Relevance 是什么
|
|
368
|
+
|
|
369
|
+
Phoenix Document Relevance 是一个 **单文档相关性分类器**。它的输入很简单:
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
input: 用户问题
|
|
373
|
+
document_text: 一个被检索出来的文档/chunk
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
输出是:
|
|
377
|
+
|
|
378
|
+
```text
|
|
379
|
+
label: relevant | unrelated
|
|
380
|
+
score: 1.0 | 0.0
|
|
381
|
+
explanation: LLM 判断理由
|
|
382
|
+
```
|
|
383
|
+
|
|
384
|
+
它适合用在 retriever span 上,对每个检索结果单独打标:
|
|
385
|
+
|
|
386
|
+
```text
|
|
387
|
+
query: COVID-19 有什么症状?
|
|
388
|
+
|
|
389
|
+
doc1: COVID-19 symptoms include fever, cough...
|
|
390
|
+
=> relevant, 1
|
|
391
|
+
|
|
392
|
+
doc2: The history of coronaviruses dates back...
|
|
393
|
+
=> unrelated, 0
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
它不天然回答:
|
|
397
|
+
|
|
398
|
+
- 相关文档是否排在前面。
|
|
399
|
+
- 所有必要信息是否都找全。
|
|
400
|
+
- 多个文档合起来是否覆盖 reference。
|
|
401
|
+
|
|
402
|
+
如果要得到类似 precision 的聚合,需要你自己对多个文档结果做统计;如果要 recall,则必须有 reference 或标准相关文档集合,否则没法知道“漏了什么”。
|
|
403
|
+
|
|
404
|
+
### Ragas Context Precision 的输入是什么?
|
|
405
|
+
|
|
406
|
+
Ragas Context Precision 有多个变体,输入略有不同。
|
|
407
|
+
|
|
408
|
+
#### 1. LLM Context Precision with reference
|
|
409
|
+
|
|
410
|
+
适合有标准答案时。
|
|
411
|
+
|
|
412
|
+
```text
|
|
413
|
+
user_input: 用户问题
|
|
414
|
+
reference: 标准答案 / 期望答案
|
|
415
|
+
retrieved_contexts: 按检索排序返回的一组 context chunks
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
例子:
|
|
419
|
+
|
|
420
|
+
```text
|
|
421
|
+
user_input:
|
|
422
|
+
Where is the Eiffel Tower located?
|
|
423
|
+
|
|
424
|
+
reference:
|
|
425
|
+
The Eiffel Tower is located in Paris.
|
|
426
|
+
|
|
427
|
+
retrieved_contexts:
|
|
428
|
+
1. The Eiffel Tower is located in Paris.
|
|
429
|
+
2. The Brandenburg Gate is located in Berlin.
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### 2. LLM Context Precision without reference / Context Utilization
|
|
433
|
+
|
|
434
|
+
适合没有标准答案,但已有模型生成回答时。
|
|
435
|
+
|
|
436
|
+
```text
|
|
437
|
+
user_input: 用户问题
|
|
438
|
+
response: 模型生成的回答
|
|
439
|
+
retrieved_contexts: 按检索排序返回的一组 context chunks
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
它会用 response 作为判断依据,看每个 retrieved context 是否对生成回答有用。
|
|
443
|
+
|
|
444
|
+
#### 3. Non-LLM Context Precision with reference contexts
|
|
445
|
+
|
|
446
|
+
适合有标准相关文档集合时。
|
|
447
|
+
|
|
448
|
+
```text
|
|
449
|
+
retrieved_contexts: 实际检索返回的 contexts
|
|
450
|
+
reference_contexts: 标准相关 contexts
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
它不用 LLM,而是用字符串相似度等方法判断 retrieved context 是否命中 reference context。
|
|
454
|
+
|
|
455
|
+
#### 4. ID-based Context Precision
|
|
456
|
+
|
|
457
|
+
适合文档有稳定 ID 时。
|
|
458
|
+
|
|
459
|
+
```text
|
|
460
|
+
retrieved_context_ids: 实际检索返回的文档 ID
|
|
461
|
+
reference_context_ids: 标准相关文档 ID
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
直接按 ID 计算命中。
|
|
465
|
+
|
|
466
|
+
### Ragas Context Precision 的中间评估过程
|
|
467
|
+
|
|
468
|
+
Context Precision 重点看的是:**相关 context 是否排在检索结果前面**。
|
|
469
|
+
|
|
470
|
+
它的核心过程可以拆成:
|
|
471
|
+
|
|
472
|
+
#### 1. 对每个 retrieved context 判断是否相关
|
|
473
|
+
|
|
474
|
+
对检索结果列表里的每个 chunk,得到一个相关性标记:
|
|
475
|
+
|
|
476
|
+
```text
|
|
477
|
+
v_k = 1 表示第 k 个 chunk relevant
|
|
478
|
+
v_k = 0 表示第 k 个 chunk irrelevant
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
这个判断可以由 LLM 完成,也可以由字符串相似度或 ID 匹配完成。
|
|
482
|
+
|
|
483
|
+
LLM with reference 时:
|
|
484
|
+
|
|
485
|
+
```text
|
|
486
|
+
判断 retrieved_context[k] 是否有助于回答 reference
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
LLM without reference / utilization 时:
|
|
490
|
+
|
|
491
|
+
```text
|
|
492
|
+
判断 retrieved_context[k] 是否有助于支撑 response
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
ID-based 时:
|
|
496
|
+
|
|
497
|
+
```text
|
|
498
|
+
判断 retrieved_context_id[k] 是否在 reference_context_ids 中
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
#### 2. 计算每个 relevant chunk 位置上的 precision@k
|
|
502
|
+
|
|
503
|
+
例如检索回来 4 个 chunk:
|
|
504
|
+
|
|
505
|
+
```text
|
|
506
|
+
rank 1: relevant
|
|
507
|
+
rank 2: irrelevant
|
|
508
|
+
rank 3: relevant
|
|
509
|
+
rank 4: irrelevant
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
那么:
|
|
513
|
+
|
|
514
|
+
```text
|
|
515
|
+
precision@1 = 1/1 = 1.0
|
|
516
|
+
precision@3 = 2/3 = 0.67
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
#### 3. 对 relevant chunk 的 precision@k 求平均
|
|
520
|
+
|
|
521
|
+
Context Precision 类似 average precision:
|
|
522
|
+
|
|
523
|
+
```text
|
|
524
|
+
Context Precision =
|
|
525
|
+
sum(precision@k * v_k) / number_of_relevant_chunks_in_retrieved_contexts
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
所以它会奖励:
|
|
529
|
+
|
|
530
|
+
```text
|
|
531
|
+
相关 chunk 排在前面
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
惩罚:
|
|
535
|
+
|
|
536
|
+
```text
|
|
537
|
+
无关 chunk 排在前面,把相关 chunk 挤到后面
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
#### 4. 为什么它关注排序
|
|
541
|
+
|
|
542
|
+
两个检索结果包含相同文档,但顺序不同:
|
|
543
|
+
|
|
544
|
+
```text
|
|
545
|
+
结果 A:
|
|
546
|
+
1. Eiffel Tower is located in Paris
|
|
547
|
+
2. Brandenburg Gate is in Berlin
|
|
548
|
+
|
|
549
|
+
结果 B:
|
|
550
|
+
1. Brandenburg Gate is in Berlin
|
|
551
|
+
2. Eiffel Tower is located in Paris
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
两个结果都找到了正确 context,但结果 A 的 Context Precision 更高,因为正确 context 排在前面。对 RAG 很重要,因为 LLM 通常更容易使用前面的、靠前的上下文;排序差会导致生成阶段更容易被噪声干扰。
|
|
555
|
+
|
|
556
|
+
### Ragas Context Precision 的输出是什么?
|
|
557
|
+
|
|
558
|
+
Ragas 示例里返回的是:
|
|
559
|
+
|
|
560
|
+
```text
|
|
561
|
+
result.value
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
取值范围:
|
|
565
|
+
|
|
566
|
+
```text
|
|
567
|
+
0.0 到 1.0
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
含义:
|
|
571
|
+
|
|
572
|
+
```text
|
|
573
|
+
越接近 1,说明相关 context 越靠前,检索排序越好。
|
|
574
|
+
越接近 0,说明相关 context 少或排得很靠后。
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
如果使用 LLM 版本,内部通常还会有 per-context 的判断理由或中间判断,但标准示例主要展示最终分数。
|
|
578
|
+
|
|
579
|
+
### Ragas Context Recall 的输入是什么?
|
|
580
|
+
|
|
581
|
+
Context Recall 衡量的是“有没有漏掉重要信息”。它不像 precision 那样主要看排序,而是看 reference 中需要的信息是否被 retrieved contexts 覆盖。
|
|
582
|
+
|
|
583
|
+
Ragas 文档明确说:Context Recall 需要 reference 来比较。
|
|
584
|
+
|
|
585
|
+
#### 1. LLM Context Recall
|
|
586
|
+
|
|
587
|
+
输入:
|
|
588
|
+
|
|
589
|
+
```text
|
|
590
|
+
user_input: 用户问题
|
|
591
|
+
reference: 标准答案 / 期望答案
|
|
592
|
+
retrieved_contexts: 检索返回的一组 context chunks
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
例子:
|
|
596
|
+
|
|
597
|
+
```text
|
|
598
|
+
user_input:
|
|
599
|
+
Where is the Eiffel Tower located?
|
|
600
|
+
|
|
601
|
+
reference:
|
|
602
|
+
The Eiffel Tower is located in Paris.
|
|
603
|
+
|
|
604
|
+
retrieved_contexts:
|
|
605
|
+
Paris is the capital of France.
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
#### 2. Non-LLM Context Recall
|
|
609
|
+
|
|
610
|
+
输入:
|
|
611
|
+
|
|
612
|
+
```text
|
|
613
|
+
retrieved_contexts: 实际检索返回的 contexts
|
|
614
|
+
reference_contexts: 标准相关 contexts
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
#### 3. ID-based Context Recall
|
|
618
|
+
|
|
619
|
+
输入:
|
|
620
|
+
|
|
621
|
+
```text
|
|
622
|
+
retrieved_context_ids: 实际检索返回的文档 ID
|
|
623
|
+
reference_context_ids: 标准相关文档 ID
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Ragas Context Recall 的中间评估过程
|
|
627
|
+
|
|
628
|
+
Context Recall 的核心是:
|
|
629
|
+
|
|
630
|
+
```text
|
|
631
|
+
reference 里有多少信息能从 retrieved_contexts 中找到证据?
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
LLM 版本通常这样做。
|
|
635
|
+
|
|
636
|
+
#### 1. 把 reference 拆成 claims
|
|
637
|
+
|
|
638
|
+
例如:
|
|
639
|
+
|
|
640
|
+
```text
|
|
641
|
+
reference:
|
|
642
|
+
The Eiffel Tower is located in Paris and was completed in 1889.
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
拆成:
|
|
646
|
+
|
|
647
|
+
```text
|
|
648
|
+
claim 1: The Eiffel Tower is located in Paris.
|
|
649
|
+
claim 2: The Eiffel Tower was completed in 1889.
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
#### 2. 对每个 claim 判断是否被 retrieved contexts 支持
|
|
653
|
+
|
|
654
|
+
假设:
|
|
655
|
+
|
|
656
|
+
```text
|
|
657
|
+
retrieved_contexts:
|
|
658
|
+
1. Paris is the capital of France.
|
|
659
|
+
2. The Eiffel Tower is located in Paris.
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
判断:
|
|
663
|
+
|
|
664
|
+
```text
|
|
665
|
+
claim 1 supported: yes
|
|
666
|
+
claim 2 supported: no
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
#### 3. 计算支持比例
|
|
670
|
+
|
|
671
|
+
公式:
|
|
672
|
+
|
|
673
|
+
```text
|
|
674
|
+
Context Recall =
|
|
675
|
+
number_of_reference_claims_supported_by_retrieved_contexts
|
|
676
|
+
/ total_number_of_reference_claims
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
上面的例子:
|
|
680
|
+
|
|
681
|
+
```text
|
|
682
|
+
Context Recall = 1 / 2 = 0.5
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
#### 4. Non-LLM / ID-based recall
|
|
686
|
+
|
|
687
|
+
如果有 `reference_contexts` 或 `reference_context_ids`,可以不拆 claims:
|
|
688
|
+
|
|
689
|
+
```text
|
|
690
|
+
Context Recall =
|
|
691
|
+
retrieved 中命中的 reference contexts 数量
|
|
692
|
+
/ reference contexts 总数
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
ID-based 例子:
|
|
696
|
+
|
|
697
|
+
```text
|
|
698
|
+
retrieved_context_ids:
|
|
699
|
+
doc_1, doc_2, doc_3
|
|
700
|
+
|
|
701
|
+
reference_context_ids:
|
|
702
|
+
doc_1, doc_4, doc_5, doc_6
|
|
703
|
+
|
|
704
|
+
Context Recall = 1 / 4 = 0.25
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Ragas Context Recall 的输出是什么?
|
|
708
|
+
|
|
709
|
+
输出同样是 0-1 分数:
|
|
710
|
+
|
|
711
|
+
```text
|
|
712
|
+
result.value
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
含义:
|
|
716
|
+
|
|
717
|
+
```text
|
|
718
|
+
越接近 1,说明 reference 需要的信息基本都被检索回来了。
|
|
719
|
+
越接近 0,说明检索漏掉了大量关键证据。
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### 三者最关键的区别
|
|
723
|
+
|
|
724
|
+
#### 1. Phoenix Document Relevance 是单文档判断
|
|
725
|
+
|
|
726
|
+
它判断:
|
|
727
|
+
|
|
728
|
+
```text
|
|
729
|
+
这个 doc 对 query 有没有用?
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
不关心:
|
|
733
|
+
|
|
734
|
+
```text
|
|
735
|
+
这个 doc 排第几?
|
|
736
|
+
是否漏了其他关键 doc?
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
#### 2. Ragas Context Precision 是排序质量
|
|
740
|
+
|
|
741
|
+
它判断:
|
|
742
|
+
|
|
743
|
+
```text
|
|
744
|
+
检索结果里相关 context 是否排得足够靠前?
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
所以它适合比较:
|
|
748
|
+
|
|
749
|
+
- embedding 模型。
|
|
750
|
+
- chunking 策略。
|
|
751
|
+
- reranker。
|
|
752
|
+
- hybrid search。
|
|
753
|
+
- top-k 设置。
|
|
754
|
+
|
|
755
|
+
#### 3. Ragas Context Recall 是覆盖质量
|
|
756
|
+
|
|
757
|
+
它判断:
|
|
758
|
+
|
|
759
|
+
```text
|
|
760
|
+
reference 里需要的信息有没有被找回来?
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
所以它适合发现:
|
|
764
|
+
|
|
765
|
+
- top-k 太小。
|
|
766
|
+
- query rewrite 不够好。
|
|
767
|
+
- 索引缺文档。
|
|
768
|
+
- chunk 太碎导致关键信息分散。
|
|
769
|
+
- retriever 找到了相关但不完整的上下文。
|
|
770
|
+
|
|
771
|
+
### 在 agent 评估里的意义
|
|
772
|
+
|
|
773
|
+
对于 agent,尤其是会搜索、读文档、查知识库的 agent,这三个指标对应检索链路的三个问题:
|
|
774
|
+
|
|
775
|
+
```text
|
|
776
|
+
Document Relevance:
|
|
777
|
+
每个检索结果是不是有用?
|
|
778
|
+
|
|
779
|
+
Context Precision:
|
|
780
|
+
有用结果是不是排在前面,噪声有没有挡路?
|
|
781
|
+
|
|
782
|
+
Context Recall:
|
|
783
|
+
任务需要的关键信息有没有找全?
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
如果答案错了:
|
|
787
|
+
|
|
788
|
+
- Document Relevance 低:检索结果本身大量无关。
|
|
789
|
+
- Context Precision 低:相关信息有,但排得靠后,被噪声干扰。
|
|
790
|
+
- Context Recall 低:关键证据根本没被找回来。
|
|
791
|
+
- 这三项都高但答案仍错:问题更可能在生成、证据忠实度或工具结果处理。
|
|
792
|
+
|
|
793
|
+
### 附加问题:这三个指标是不是专门用来衡量 RAG 检索质量的?
|
|
794
|
+
|
|
795
|
+
是的,严格来说它们主要是 **RAG / retrieval 质量指标**,不是通用 agent 指标。
|
|
796
|
+
|
|
797
|
+
它们评估的是 agent 链路里的“取证/检索阶段”:
|
|
798
|
+
|
|
799
|
+
```text
|
|
800
|
+
用户问题
|
|
801
|
+
=> 检索器 / 搜索 / 文档读取
|
|
802
|
+
=> retrieved contexts / documents
|
|
803
|
+
=> 后续生成或行动
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
三者关注的都是 retrieved contexts / documents 的质量:
|
|
807
|
+
|
|
808
|
+
- `Document Relevance`:单个检索结果是否相关。
|
|
809
|
+
- `Context Precision`:相关检索结果是否排得靠前。
|
|
810
|
+
- `Context Recall`:任务需要的信息是否被检索回来。
|
|
811
|
+
|
|
812
|
+
所以它们适用于这些 agent:
|
|
813
|
+
|
|
814
|
+
- RAG 问答 agent。
|
|
815
|
+
- 文档分析 agent。
|
|
816
|
+
- 知识库客服 agent。
|
|
817
|
+
- 需要 web search / file search / database search 的 agent。
|
|
818
|
+
- 需要先读材料再回答或行动的工具型 agent。
|
|
819
|
+
|
|
820
|
+
但它们不适合直接评价所有 agent。例如:
|
|
821
|
+
|
|
822
|
+
- 纯代码修改 agent,如果没有检索/读文档阶段,这三个指标可能 N/A。
|
|
823
|
+
- 纯计算或格式转换任务,不需要 context retrieval。
|
|
824
|
+
- 工具调用型业务 agent,如果工具返回的是结构化业务状态,更适合用 Tool Invocation / Tool Response Handling,而不是 Context Precision / Recall。
|
|
825
|
+
|
|
826
|
+
更准确的定位是:
|
|
827
|
+
|
|
828
|
+
```text
|
|
829
|
+
它们不是评价 agent 整体好坏,
|
|
830
|
+
而是评价 agent 在 RAG / 检索 / 取证环节做得好不好。
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
如果把 agent 看成一条链路:
|
|
834
|
+
|
|
835
|
+
```text
|
|
836
|
+
计划 -> 检索/取证 -> 工具调用 -> 结果处理 -> 最终回答
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
那么这三个指标主要覆盖:
|
|
840
|
+
|
|
841
|
+
```text
|
|
842
|
+
检索/取证
|
|
843
|
+
```
|
|
844
|
+
|
|
845
|
+
如果这三项都很好,最终答案仍然差,说明问题多半不在检索,而在后续的 groundedness、工具结果处理、推理或任务完成度。
|
|
846
|
+
|
|
847
|
+
### 参考链接
|
|
848
|
+
|
|
849
|
+
- Ragas Context Precision: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_precision/
|
|
850
|
+
- Ragas Context Recall: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/context_recall/
|
|
851
|
+
- Phoenix Document Relevance: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/document-relevance
|
|
852
|
+
|
|
853
|
+
## Q7:稳定性 / 可重复性,业界各方法的逻辑是什么?
|
|
854
|
+
|
|
855
|
+
### 简短结论
|
|
856
|
+
|
|
857
|
+
稳定性 / 可重复性评估关注的不是:
|
|
858
|
+
|
|
859
|
+
```text
|
|
860
|
+
这次 agent 有没有成功?
|
|
861
|
+
```
|
|
862
|
+
|
|
863
|
+
而是:
|
|
864
|
+
|
|
865
|
+
```text
|
|
866
|
+
同一个任务、同一类任务、或轻微扰动后的任务,agent 能不能稳定成功?
|
|
867
|
+
```
|
|
868
|
+
|
|
869
|
+
这类指标要解决一个 agent 评估里的核心问题:
|
|
870
|
+
|
|
871
|
+
```text
|
|
872
|
+
单次成功不代表可上线。
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
一个 agent 可能某次完成任务,但换一次随机种子、换一种用户说法、工具慢一点、API 报一次错,就失败。稳定性指标就是用来量化这种不可靠性。
|
|
876
|
+
|
|
877
|
+
### 方法 1:重复运行成功率 success rate@N
|
|
878
|
+
|
|
879
|
+
这是最直观的方法。
|
|
880
|
+
|
|
881
|
+
对同一个 case 重复运行 N 次:
|
|
882
|
+
|
|
883
|
+
```text
|
|
884
|
+
case_1 run_1: pass
|
|
885
|
+
case_1 run_2: fail
|
|
886
|
+
case_1 run_3: pass
|
|
887
|
+
case_1 run_4: pass
|
|
888
|
+
case_1 run_5: fail
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
计算:
|
|
892
|
+
|
|
893
|
+
```text
|
|
894
|
+
success_rate@5 = 成功次数 / 总次数 = 3 / 5 = 0.6
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
然后对所有 case 求平均:
|
|
898
|
+
|
|
899
|
+
```text
|
|
900
|
+
mean_success_rate@N =
|
|
901
|
+
average(success_count(case_i) / N)
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
#### 它说明什么
|
|
905
|
+
|
|
906
|
+
它衡量 agent 在相同任务上的平均成功概率。
|
|
907
|
+
|
|
908
|
+
如果单次 pass rate 是 80%,但 success_rate@5 的分布很散,说明 agent 行为不稳定,有时能成、有时不能成。
|
|
909
|
+
|
|
910
|
+
#### 优点
|
|
911
|
+
|
|
912
|
+
- 简单直观。
|
|
913
|
+
- 适合 A/B、版本回归、灰度评测。
|
|
914
|
+
- 容易和任务完成度评估器结合。
|
|
915
|
+
|
|
916
|
+
#### 缺点
|
|
917
|
+
|
|
918
|
+
- 只看平均值,可能掩盖“某些 case 非常不稳定”。
|
|
919
|
+
- 如果 N 太小,估计不稳。
|
|
920
|
+
- 不能区分失败原因。
|
|
921
|
+
|
|
922
|
+
### 方法 2:tau-bench 的 `pass^k`
|
|
923
|
+
|
|
924
|
+
[`tau-bench`](https://arxiv.org/abs/2406.12045) 提出了一个很适合 agent 的稳定性指标:`pass^k`。
|
|
925
|
+
|
|
926
|
+
它的直觉是:
|
|
927
|
+
|
|
928
|
+
```text
|
|
929
|
+
一个 agent 只有连续 k 次都完成同一个任务,才算这个任务稳定通过。
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
所以它比普通 success rate 更严格。
|
|
933
|
+
|
|
934
|
+
#### 计算逻辑
|
|
935
|
+
|
|
936
|
+
对每个任务重复运行 k 次。
|
|
937
|
+
|
|
938
|
+
```text
|
|
939
|
+
case A:
|
|
940
|
+
run 1: pass
|
|
941
|
+
run 2: pass
|
|
942
|
+
run 3: pass
|
|
943
|
+
=> pass^3 = 1
|
|
944
|
+
|
|
945
|
+
case B:
|
|
946
|
+
run 1: pass
|
|
947
|
+
run 2: fail
|
|
948
|
+
run 3: pass
|
|
949
|
+
=> pass^3 = 0
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
然后对所有 case 求平均:
|
|
953
|
+
|
|
954
|
+
```text
|
|
955
|
+
pass^k =
|
|
956
|
+
number_of_cases_that_pass_all_k_trials / total_cases
|
|
957
|
+
```
|
|
958
|
+
|
|
959
|
+
#### 它和 pass@k 不一样
|
|
960
|
+
|
|
961
|
+
常见 benchmark 里有 `pass@k`:
|
|
962
|
+
|
|
963
|
+
```text
|
|
964
|
+
k 次里只要有一次成功,就算通过
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
这适合代码生成或采样多个答案的场景。
|
|
968
|
+
|
|
969
|
+
但 tau-bench 的 `pass^k` 更严格:
|
|
970
|
+
|
|
971
|
+
```text
|
|
972
|
+
k 次必须全部成功,才算通过
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
这更适合 agent 上线质量,因为真实用户通常不会接受“多试几次总有一次能成”。
|
|
976
|
+
|
|
977
|
+
#### 它说明什么
|
|
978
|
+
|
|
979
|
+
`pass^k` 衡量的是:
|
|
980
|
+
|
|
981
|
+
```text
|
|
982
|
+
agent 行为是否可重复、可靠、稳定。
|
|
983
|
+
```
|
|
984
|
+
|
|
985
|
+
如果:
|
|
986
|
+
|
|
987
|
+
```text
|
|
988
|
+
pass^1 = 0.70
|
|
989
|
+
pass^8 = 0.25
|
|
990
|
+
```
|
|
991
|
+
|
|
992
|
+
说明 agent 单次看起来还行,但连续稳定完成任务的能力很差。tau-bench 论文里就观察到:一些函数调用 agent 单次成功率尚可,但多次重复后 `pass^8` 大幅下降。
|
|
993
|
+
|
|
994
|
+
#### 适用场景
|
|
995
|
+
|
|
996
|
+
- 业务流程 agent,例如客服、订票、订单修改。
|
|
997
|
+
- 多轮工具调用 agent。
|
|
998
|
+
- 有明确最终状态的任务。
|
|
999
|
+
- 版本发布前的可靠性门槛。
|
|
1000
|
+
|
|
1001
|
+
### 方法 3:方差 / 分数波动
|
|
1002
|
+
|
|
1003
|
+
如果每次运行不只是 pass/fail,而是有 0-1 分数,可以看方差。
|
|
1004
|
+
|
|
1005
|
+
例如同一个 case 跑 5 次任务完成度:
|
|
1006
|
+
|
|
1007
|
+
```text
|
|
1008
|
+
0.9, 0.8, 0.2, 0.95, 0.3
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
平均分可能还不低,但波动很大。
|
|
1012
|
+
|
|
1013
|
+
常用统计包括:
|
|
1014
|
+
|
|
1015
|
+
```text
|
|
1016
|
+
mean_score
|
|
1017
|
+
stddev_score
|
|
1018
|
+
min_score
|
|
1019
|
+
max_score
|
|
1020
|
+
coefficient_of_variation = stddev / mean
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
#### 它说明什么
|
|
1024
|
+
|
|
1025
|
+
它衡量 agent 的输出质量是否稳定。
|
|
1026
|
+
|
|
1027
|
+
两个 agent 平均分一样:
|
|
1028
|
+
|
|
1029
|
+
```text
|
|
1030
|
+
Agent A: 0.8, 0.8, 0.8, 0.8
|
|
1031
|
+
Agent B: 1.0, 0.6, 1.0, 0.6
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
Agent A 更稳定,Agent B 更随机。
|
|
1035
|
+
|
|
1036
|
+
#### 适用场景
|
|
1037
|
+
|
|
1038
|
+
- LLM judge 给连续分的任务。
|
|
1039
|
+
- 结果质量评估。
|
|
1040
|
+
- RAG 回答质量。
|
|
1041
|
+
- 多指标综合评分。
|
|
1042
|
+
|
|
1043
|
+
### 方法 4:一致性 / 输出等价性
|
|
1044
|
+
|
|
1045
|
+
有些任务不是简单 pass/fail,而是多种答案都可以接受。这时可以评估多次运行之间是否语义一致、最终状态等价。
|
|
1046
|
+
|
|
1047
|
+
逻辑是:
|
|
1048
|
+
|
|
1049
|
+
```text
|
|
1050
|
+
同一个任务运行多次
|
|
1051
|
+
=> 比较最终输出 / 最终状态 / 工具动作序列
|
|
1052
|
+
=> 判断是否等价
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
例如:
|
|
1056
|
+
|
|
1057
|
+
```text
|
|
1058
|
+
run 1: 把订单地址改成 A,成功
|
|
1059
|
+
run 2: 把订单地址改成 A,成功
|
|
1060
|
+
run 3: 把订单地址改成 B,成功
|
|
1061
|
+
```
|
|
1062
|
+
|
|
1063
|
+
如果用户目标是地址 A,那么 run 3 即使自称成功,也不是等价成功。
|
|
1064
|
+
|
|
1065
|
+
#### 常见等价对象
|
|
1066
|
+
|
|
1067
|
+
- 最终数据库状态。
|
|
1068
|
+
- 文件 diff。
|
|
1069
|
+
- API side effect。
|
|
1070
|
+
- 关键事实集合。
|
|
1071
|
+
- 用户可见最终答案。
|
|
1072
|
+
- 工具调用序列是否满足同一目标。
|
|
1073
|
+
|
|
1074
|
+
#### 适用场景
|
|
1075
|
+
|
|
1076
|
+
- 有多个合理文本表达的任务。
|
|
1077
|
+
- 最终状态比最终文本更重要的业务 agent。
|
|
1078
|
+
- 工具型 agent。
|
|
1079
|
+
|
|
1080
|
+
tau-bench 就是用最终数据库状态与标注 goal state 比较,避免只看文本回复。
|
|
1081
|
+
|
|
1082
|
+
### 方法 5:语义扰动鲁棒性
|
|
1083
|
+
|
|
1084
|
+
这是更接近生产环境的方法:不是只重复同一句输入,而是生成语义等价或近似等价的变体。
|
|
1085
|
+
|
|
1086
|
+
例如:
|
|
1087
|
+
|
|
1088
|
+
```text
|
|
1089
|
+
原始任务:
|
|
1090
|
+
帮我把 8 点的航班改签到明早最早一班。
|
|
1091
|
+
|
|
1092
|
+
扰动 1:
|
|
1093
|
+
我想把今晚 8 点那趟飞机改成明天早上最早的。
|
|
1094
|
+
|
|
1095
|
+
扰动 2:
|
|
1096
|
+
能不能帮我改签?目标是明早越早越好,原票是晚上 8 点。
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
评估:
|
|
1100
|
+
|
|
1101
|
+
```text
|
|
1102
|
+
agent 是否在这些语义等价输入上都达成同一目标?
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1105
|
+
#### 它说明什么
|
|
1106
|
+
|
|
1107
|
+
它衡量 agent 是否只记住了某种表述,还是理解了用户意图。
|
|
1108
|
+
|
|
1109
|
+
#### 适用场景
|
|
1110
|
+
|
|
1111
|
+
- 用户自然语言高度多样的客服/业务 agent。
|
|
1112
|
+
- 需要抗 prompt wording 变化的生产 agent。
|
|
1113
|
+
- 数据集样本太模板化时的补充评估。
|
|
1114
|
+
|
|
1115
|
+
[`ReliabilityBench`](https://arxiv.org/abs/2601.06112) 把这种思想系统化,提出在语义扰动强度 `ε` 下评估 agent robustness。
|
|
1116
|
+
|
|
1117
|
+
### 方法 6:故障注入 / 压力条件下的可靠性
|
|
1118
|
+
|
|
1119
|
+
生产环境里,工具/API 不会总是完美工作。稳定性评估还要看 agent 在工具失败时能否恢复。
|
|
1120
|
+
|
|
1121
|
+
常见故障注入:
|
|
1122
|
+
|
|
1123
|
+
- timeout。
|
|
1124
|
+
- rate limit。
|
|
1125
|
+
- partial response。
|
|
1126
|
+
- schema drift。
|
|
1127
|
+
- 空结果。
|
|
1128
|
+
- 权限错误。
|
|
1129
|
+
- 临时网络错误。
|
|
1130
|
+
|
|
1131
|
+
评估:
|
|
1132
|
+
|
|
1133
|
+
```text
|
|
1134
|
+
正常条件下是否成功?
|
|
1135
|
+
工具故障条件下是否仍能成功或合理失败?
|
|
1136
|
+
是否会重复相同错误调用?
|
|
1137
|
+
是否能修正参数或换路径?
|
|
1138
|
+
```
|
|
1139
|
+
|
|
1140
|
+
[`ReliabilityBench`](https://arxiv.org/abs/2601.06112) 把可靠性建模成一个面:
|
|
1141
|
+
|
|
1142
|
+
```text
|
|
1143
|
+
R(k, ε, λ)
|
|
1144
|
+
```
|
|
1145
|
+
|
|
1146
|
+
其中:
|
|
1147
|
+
|
|
1148
|
+
- `k`:重复执行次数。
|
|
1149
|
+
- `ε`:语义扰动强度。
|
|
1150
|
+
- `λ`:工具/API 故障强度。
|
|
1151
|
+
|
|
1152
|
+
这个框架的意思是:
|
|
1153
|
+
|
|
1154
|
+
```text
|
|
1155
|
+
真正的可靠性 = 重复执行 + 输入扰动 + 工具故障 三者共同压力下的表现。
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
### 方法 7:CLEAR 的 Reliability 维度
|
|
1159
|
+
|
|
1160
|
+
[`CLEAR`](https://arxiv.org/abs/2511.14136) 是面向企业 agent 的多维评估框架:
|
|
1161
|
+
|
|
1162
|
+
```text
|
|
1163
|
+
C = Cost
|
|
1164
|
+
L = Latency
|
|
1165
|
+
E = Efficacy
|
|
1166
|
+
A = Assurance
|
|
1167
|
+
R = Reliability
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
其中 Reliability 关注:
|
|
1171
|
+
|
|
1172
|
+
```text
|
|
1173
|
+
agent 在多次运行、不同条件下是否稳定可靠。
|
|
1174
|
+
```
|
|
1175
|
+
|
|
1176
|
+
CLEAR 的重要观点是:
|
|
1177
|
+
|
|
1178
|
+
```text
|
|
1179
|
+
accuracy-only 不够。
|
|
1180
|
+
```
|
|
1181
|
+
|
|
1182
|
+
一个 agent 可能单次准确率高,但:
|
|
1183
|
+
|
|
1184
|
+
- 成本极高。
|
|
1185
|
+
- 延迟不可接受。
|
|
1186
|
+
- 多次运行不稳定。
|
|
1187
|
+
- 合规性不好。
|
|
1188
|
+
- 遇到边界条件就失败。
|
|
1189
|
+
|
|
1190
|
+
CLEAR 把 reliability 和 cost、latency、assurance 放在一起,是为了判断 agent 是否真的适合生产环境。
|
|
1191
|
+
|
|
1192
|
+
#### 它说明什么
|
|
1193
|
+
|
|
1194
|
+
CLEAR 的稳定性逻辑不是只算一个成功率,而是把稳定性放入上线决策:
|
|
1195
|
+
|
|
1196
|
+
```text
|
|
1197
|
+
能不能稳定完成?
|
|
1198
|
+
完成成本是否稳定?
|
|
1199
|
+
延迟是否稳定?
|
|
1200
|
+
风险是否可控?
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
它特别适合企业 agent,因为企业更关心:
|
|
1204
|
+
|
|
1205
|
+
```text
|
|
1206
|
+
可预测性 > 偶然高分
|
|
1207
|
+
```
|
|
1208
|
+
|
|
1209
|
+
### 方法 8:平台化 eval runs,例如 LangSmith / OpenAI
|
|
1210
|
+
|
|
1211
|
+
LangSmith、OpenAI Evals 这类平台通常不只定义某一个“稳定性指标”,而是提供可重复的评测运行机制:
|
|
1212
|
+
|
|
1213
|
+
```text
|
|
1214
|
+
固定 dataset
|
|
1215
|
+
固定 evaluator / grader
|
|
1216
|
+
固定模型和配置
|
|
1217
|
+
重复运行
|
|
1218
|
+
比较不同版本
|
|
1219
|
+
记录每次 run 的分数、失败样例和趋势
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
稳定性来自实验设计:
|
|
1223
|
+
|
|
1224
|
+
- 同一数据集重复跑。
|
|
1225
|
+
- 同一 case 多次采样。
|
|
1226
|
+
- 比较 run-to-run score。
|
|
1227
|
+
- 记录分布,而不是只看单次平均值。
|
|
1228
|
+
- 用 regression report 看新版本是否退化。
|
|
1229
|
+
|
|
1230
|
+
#### 它说明什么
|
|
1231
|
+
|
|
1232
|
+
这类平台方法关注:
|
|
1233
|
+
|
|
1234
|
+
```text
|
|
1235
|
+
评估是否可重复、可比较、可回归。
|
|
1236
|
+
```
|
|
1237
|
+
|
|
1238
|
+
它不一定内置 `pass^k`,但提供了实现 `success_rate@N`、方差、回归检测、版本对比的基础设施。
|
|
1239
|
+
|
|
1240
|
+
### 各方法对比
|
|
1241
|
+
|
|
1242
|
+
| 方法 | 核心逻辑 | 最适合回答的问题 |
|
|
1243
|
+
| --- | --- | --- |
|
|
1244
|
+
| success_rate@N | 同一 case 跑 N 次,统计成功比例 | 平均有多大概率成功? |
|
|
1245
|
+
| pass^k | 同一 case 连续 k 次全成功才算过 | 是否稳定到可以依赖? |
|
|
1246
|
+
| 分数方差 | 多次运行的连续分是否波动 | 输出质量是否稳定? |
|
|
1247
|
+
| 输出/状态等价性 | 多次运行最终状态是否等价 | 是否每次都达成同一个目标? |
|
|
1248
|
+
| 语义扰动鲁棒性 | 换说法后是否仍成功 | 是否理解意图,而非记模板? |
|
|
1249
|
+
| 故障注入 | 工具/API 异常时是否恢复 | 是否具备生产容错能力? |
|
|
1250
|
+
| CLEAR Reliability | 把可靠性与成本、延迟、风险一起看 | 是否适合企业上线? |
|
|
1251
|
+
| Eval runs 平台化 | 固定数据集和 evaluator 做重复实验 | 版本是否可比较、可回归? |
|
|
1252
|
+
|
|
1253
|
+
### 对 agent 评估的价值
|
|
1254
|
+
|
|
1255
|
+
稳定性 / 可重复性指标能发现单次评测看不出来的问题:
|
|
1256
|
+
|
|
1257
|
+
```text
|
|
1258
|
+
偶然成功
|
|
1259
|
+
随机失败
|
|
1260
|
+
对措辞敏感
|
|
1261
|
+
对工具错误脆弱
|
|
1262
|
+
成本和延迟波动大
|
|
1263
|
+
同一任务多次产生不同副作用
|
|
1264
|
+
```
|
|
1265
|
+
|
|
1266
|
+
它也能帮助做发布决策:
|
|
1267
|
+
|
|
1268
|
+
```text
|
|
1269
|
+
单次任务完成度高,但 pass^k 低
|
|
1270
|
+
=> 不适合上线,只能说明偶尔能成
|
|
1271
|
+
|
|
1272
|
+
平均分高,但方差大
|
|
1273
|
+
=> 需要增加 guardrail 或降低随机性
|
|
1274
|
+
|
|
1275
|
+
正常条件好,故障注入差
|
|
1276
|
+
=> 需要优化错误恢复和 fallback
|
|
1277
|
+
|
|
1278
|
+
旧版本 pass^5 高,新版本 pass^5 低
|
|
1279
|
+
=> 新版本有可靠性回归
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### 一个推荐的稳定性指标组合
|
|
1283
|
+
|
|
1284
|
+
如果要系统评估 agent 稳定性,可以组合这些指标:
|
|
1285
|
+
|
|
1286
|
+
```text
|
|
1287
|
+
1. success_rate@N
|
|
1288
|
+
2. pass^k
|
|
1289
|
+
3. score_mean / score_stddev
|
|
1290
|
+
4. semantic_perturbation_success_rate
|
|
1291
|
+
5. fault_injection_success_rate
|
|
1292
|
+
6. final_state_consistency
|
|
1293
|
+
7. cost / latency variance
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
其中:
|
|
1297
|
+
|
|
1298
|
+
- `success_rate@N` 看平均成功概率。
|
|
1299
|
+
- `pass^k` 看连续可靠性。
|
|
1300
|
+
- `stddev` 看质量波动。
|
|
1301
|
+
- `semantic perturbation` 看表达鲁棒性。
|
|
1302
|
+
- `fault injection` 看生产容错。
|
|
1303
|
+
- `final state consistency` 看副作用是否一致。
|
|
1304
|
+
- `cost / latency variance` 看运行是否可预测。
|
|
1305
|
+
|
|
1306
|
+
### 参考链接
|
|
1307
|
+
|
|
1308
|
+
- tau-bench: https://arxiv.org/abs/2406.12045
|
|
1309
|
+
- CLEAR: https://arxiv.org/abs/2511.14136
|
|
1310
|
+
- ReliabilityBench: https://arxiv.org/abs/2601.06112
|
|
1311
|
+
- LangSmith evaluation concepts: https://docs.langchain.com/langsmith/evaluation-concepts
|
|
1312
|
+
- OpenAI agent evals: https://developers.openai.com/api/docs/guides/agent-evals
|