agent-insight 0.5.0 → 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/(main)/dashboard/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/eval/trajectory/[taskId]/trace/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/infra/source/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/quality/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/skill-history/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/skills/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/(main)/trace/page_client-reference-manifest.js +1 -1
- 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 +2 -2
- package/.next/standalone/.next/server/app/dashboard.segments/!KG1haW4p/dashboard/__PAGE__.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/quality.segments/!KG1haW4p/quality/__PAGE__.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/skill-history.segments/!KG1haW4p/skill-history/__PAGE__.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/skills.segments/!KG1haW4p/skills/__PAGE__.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/.next/server/app/trace.segments/!KG1haW4p/trace/__PAGE__.segment.rsc +2 -2
- 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 +2 -2
- 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/chunks/ssr/_a3d5f9bc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_0ec17dda._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_2906b362._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_3ad6a908._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_6e2c1036._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_a443e166._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_c49ac16a._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_cf1f3d2c._.js +2 -2
- 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/.next/static/chunks/1ee0fbf466669cb8.js +1 -0
- package/.next/standalone/.next/static/chunks/3a0f454536f3ebc8.js +1 -0
- package/.next/standalone/.next/static/chunks/4dcd21eef469e66b.js +1 -0
- package/.next/{static/chunks/7e6eb6ade82c4979.js → standalone/.next/static/chunks/b40cbbf52dfd5473.js} +1 -1
- package/.next/standalone/.next/static/chunks/ec50621fcfea9f71.js +287 -0
- package/.next/standalone/Dockerfile +10 -2
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_industry_research.md +260 -0
- package/.next/standalone/Evaluation_and_Research/agent_evaluator_research_qna.md +1379 -0
- 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 +10 -0
- 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/.next/static/chunks/1ee0fbf466669cb8.js +1 -0
- package/.next/static/chunks/3a0f454536f3ebc8.js +1 -0
- package/.next/static/chunks/4dcd21eef469e66b.js +1 -0
- package/.next/{standalone/.next/static/chunks/7e6eb6ade82c4979.js → static/chunks/b40cbbf52dfd5473.js} +1 -1
- package/.next/static/chunks/ec50621fcfea9f71.js +287 -0
- package/README.md +76 -60
- package/package.json +1 -1
- package/scripts/opencode-offline-fix.ps1 +93 -0
- package/scripts/opencode_tui_plugin.tsx +23 -1
- package/.next/standalone/.next/static/chunks/13ea6fabf1d0af65.js +0 -287
- package/.next/standalone/.next/static/chunks/74a2b1d10a1772b4.js +0 -1
- package/.next/standalone/.next/static/chunks/94042ce1cf94ccfd.js +0 -1
- package/.next/standalone/.next/static/chunks/965c5a1f38c3d7db.js +0 -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/.next/static/chunks/13ea6fabf1d0af65.js +0 -287
- package/.next/static/chunks/74a2b1d10a1772b4.js +0 -1
- package/.next/static/chunks/94042ce1cf94ccfd.js +0 -1
- package/.next/static/chunks/965c5a1f38c3d7db.js +0 -1
- 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/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/standalone/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_buildManifest.js +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_clientMiddlewareManifest.json +0 -0
- /package/.next/static/{uwRBb8F1kIm0K4LV3Jkwa → iE8084jR9Kgb7Bhs3Xokh}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,1379 @@
|
|
|
1
|
+
# Agent 评估器调研问答
|
|
2
|
+
|
|
3
|
+
调研日期:2026-07-06
|
|
4
|
+
|
|
5
|
+
这份文档用于承接 `agent_evaluator_industry_research.md` 里的细节问题。每个问题独立回答,后续可以继续追加。
|
|
6
|
+
|
|
7
|
+
## Q1:DeepEval 和 Ragas 的“任务完成度”逻辑是怎么样?
|
|
8
|
+
|
|
9
|
+
### 简短结论
|
|
10
|
+
|
|
11
|
+
DeepEval 和 Ragas 都把“任务完成度”理解成:**Agent 最终有没有达成用户目标**,而不是中间有没有严格按照某条路径执行。
|
|
12
|
+
|
|
13
|
+
但两者的评估形态不一样:
|
|
14
|
+
|
|
15
|
+
| 项目 | 指标名 | 主要输入 | 是否需要参考答案 | 输出形态 | 核心逻辑 |
|
|
16
|
+
| --- | --- | --- | --- | --- | --- |
|
|
17
|
+
| DeepEval | [`TaskCompletionMetric`](https://deepeval.com/docs/metrics-task-completion) | 完整 agent trace,可选显式 `task` | 默认不需要 | 0-1 分数,可带 reason | 从 trace 中抽取 task 和 outcome,再用 LLM judge 评估 outcome 与 task 的对齐程度 |
|
|
18
|
+
| Ragas | [`AgentGoalAccuracyWithReference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#with-reference) | 多轮消息/工具调用 + reference | 需要 | 0/1 | 判断工作流最终状态/结果是否符合给定 reference outcome |
|
|
19
|
+
| Ragas | [`AgentGoalAccuracyWithoutReference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#without-reference) | 多轮消息/工具调用 | 不需要 | 0/1 | 从对话中推断用户目标和实际达成结果,再判断是否达成 |
|
|
20
|
+
|
|
21
|
+
### DeepEval:TaskCompletionMetric 的逻辑
|
|
22
|
+
|
|
23
|
+
DeepEval 的任务完成度是一个 **LLM-as-a-judge、trace-level、referenceless** 指标。它不是拿最终回答和标准答案做字符串比较,而是读取 agent 的完整执行 trace,判断这次运行最终是否完成了任务。
|
|
24
|
+
|
|
25
|
+
官方给出的计算口径可以概括为:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
Task Completion Score = AlignmentScore(Task, Outcome)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
其中:
|
|
32
|
+
|
|
33
|
+
- `Task`:从 trace 中抽取出来的用户任务;也可以由调用方通过 `task` 参数显式传入。
|
|
34
|
+
- `Outcome`:从 trace 中抽取出来的最终结果/实际完成状态。
|
|
35
|
+
- `AlignmentScore`:由 LLM judge 判断 `Outcome` 与 `Task` 的对齐程度。
|
|
36
|
+
|
|
37
|
+
DeepEval 的几个关键点:
|
|
38
|
+
|
|
39
|
+
1. **默认无参考答案**
|
|
40
|
+
它默认不需要 expected output / reference。`task` 参数也默认是 `None`,由评估器从 trace 里推断。如果你想固定评估目标,可以显式传入 `task`。
|
|
41
|
+
|
|
42
|
+
2. **依赖 trace,而不是只看 final answer**
|
|
43
|
+
DeepEval 文档明确说该指标会分析 agent 的 full trace 来判断任务成功,因此需要先设置 tracing,并把 `TaskCompletionMetric()` 绑定到被观测的 agent run。
|
|
44
|
+
|
|
45
|
+
3. **分数是连续分**
|
|
46
|
+
默认输出 0-1 的分数,并用 `threshold` 判断是否通过。默认 threshold 是 0.5。也可以开 `strict_mode`,这时变成严格二值:完美完成给 1,否则给 0。
|
|
47
|
+
|
|
48
|
+
4. **可以输出 reason**
|
|
49
|
+
`include_reason` 默认开启,所以它不只是给分,还会解释为什么这么判。这一点适合 Agent Insight 后续做 `SkillIssue` / failure attribution。
|
|
50
|
+
|
|
51
|
+
5. **它评估 outcome,不评估是否按计划执行**
|
|
52
|
+
DeepEval 自己也把 `TaskCompletionMetric` 和 `PlanAdherenceMetric` 区分开:前者回答“是否完成任务”,后者回答“是否遵守计划”。所以一个 agent 可以没按原计划走,但最终完成任务;也可以严格按计划走,但任务失败。
|
|
53
|
+
|
|
54
|
+
#### DeepEval 的例子怎么理解
|
|
55
|
+
|
|
56
|
+
官方示例是一个 trip planner agent:它根据目的地和天数生成 itinerary,并找餐厅。评估器会读取 trace 中的函数/工具调用和最终返回结果,抽取:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
Task: 用户希望完成一次旅行规划
|
|
60
|
+
Outcome: agent 返回了景点行程和餐厅列表
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
然后由 LLM judge 判断 outcome 是否足够满足 task。它不要求你提前写一个标准答案,比如“必须包含 Eiffel Tower”;而是判断最终结果是否和任务目标对齐。
|
|
64
|
+
|
|
65
|
+
#### DeepEval 适合 Agent Insight 怎么借鉴
|
|
66
|
+
|
|
67
|
+
DeepEval 的逻辑很适合作为 Agent Insight 里的“无参考任务完成度”版本:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
输入:
|
|
71
|
+
- 用户原始任务
|
|
72
|
+
- 完整 trace summary
|
|
73
|
+
- 最终输出
|
|
74
|
+
- 可选:显式目标 task / rubric
|
|
75
|
+
|
|
76
|
+
评估:
|
|
77
|
+
- 从 trace 中抽取用户目标
|
|
78
|
+
- 从 trace 和最终输出中抽取实际达成结果
|
|
79
|
+
- 判断达成程度,输出 score + reason + evidence
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
但如果要落地到 Agent Insight,我建议比 DeepEval 多做两点:
|
|
83
|
+
|
|
84
|
+
1. **要求 evidence span**
|
|
85
|
+
给分理由必须引用具体 message/tool/span,否则很难用于后续优化。
|
|
86
|
+
|
|
87
|
+
2. **把“任务完成度”和“失败类型”分开**
|
|
88
|
+
任务完成度给总分;失败类型单独标注,例如 `missing_key_requirement`、`wrong_final_answer`、`tool_result_ignored`、`asked_user_when_should_act`。
|
|
89
|
+
|
|
90
|
+
### Ragas:AgentGoalAccuracy 的逻辑
|
|
91
|
+
|
|
92
|
+
Ragas 把 agent 任务完成度叫做 **Agent Goal Accuracy**。它评估的是 agent 是否识别并达成用户目标。官方文档明确说这是一个 **binary metric**:达成给 1,没有达成给 0。
|
|
93
|
+
|
|
94
|
+
Ragas 提供两个版本。
|
|
95
|
+
|
|
96
|
+
### Ragas 版本 1:With Reference
|
|
97
|
+
|
|
98
|
+
[`AgentGoalAccuracyWithReference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#with-reference) 的输入包括:
|
|
99
|
+
|
|
100
|
+
- `user_input`:多轮会话消息,通常包含 `HumanMessage`、`AIMessage`、`ToolCall`、`ToolMessage`。
|
|
101
|
+
- `reference`:期望/理想结果,也就是 reference outcome。
|
|
102
|
+
|
|
103
|
+
它的判断方式是:
|
|
104
|
+
|
|
105
|
+
```text
|
|
106
|
+
用户目标 + agent 多轮执行过程 + 最终状态
|
|
107
|
+
对比 reference outcome
|
|
108
|
+
=> 判断是否达成,输出 1 或 0
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
官方例子是订餐:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
用户:帮我订 8 点最近最好的中餐厅
|
|
115
|
+
agent:搜索中餐厅
|
|
116
|
+
工具:返回 Golden Dragon / Jade Palace
|
|
117
|
+
用户:选 Golden Dragon
|
|
118
|
+
agent:调用订座工具
|
|
119
|
+
工具:返回订座成功
|
|
120
|
+
agent:告诉用户订座成功
|
|
121
|
+
|
|
122
|
+
reference:8 点订到了某家中餐厅
|
|
123
|
+
score:1.0
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
这里重点不是 agent 有没有用某个固定工具名,也不是中间话术是否完全一样,而是最终结果是否满足 reference:**8 点中餐厅订座成功**。
|
|
127
|
+
|
|
128
|
+
#### With Reference 的优点
|
|
129
|
+
|
|
130
|
+
- 更适合离线数据集评测。
|
|
131
|
+
- 判断更稳定,因为目标状态由 reference 固定。
|
|
132
|
+
- 很适合业务流程型 agent:订票、下单、改配置、生成报告、修 bug、查询并汇总等。
|
|
133
|
+
|
|
134
|
+
#### With Reference 的缺点
|
|
135
|
+
|
|
136
|
+
- 需要为每个 case 写 reference outcome。
|
|
137
|
+
- reference 写得太宽会放过错误;写得太窄会误伤合理替代方案。
|
|
138
|
+
- 二值评分不够细,难以表达“部分完成”。
|
|
139
|
+
|
|
140
|
+
### Ragas 版本 2:Without Reference
|
|
141
|
+
|
|
142
|
+
[`AgentGoalAccuracyWithoutReference`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#without-reference) 不需要 reference。它会从 conversation 中同时推断:
|
|
143
|
+
|
|
144
|
+
- 用户原本想达成什么目标。
|
|
145
|
+
- agent 最终实际达成了什么结果。
|
|
146
|
+
|
|
147
|
+
然后判断两者是否一致:
|
|
148
|
+
|
|
149
|
+
```text
|
|
150
|
+
从对话推断 intended goal
|
|
151
|
+
从对话和工具结果推断 achieved outcome
|
|
152
|
+
比较 intended goal 与 achieved outcome
|
|
153
|
+
=> 输出 1 或 0
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
它和 DeepEval 的无参考任务完成度很像,但差别在于:
|
|
157
|
+
|
|
158
|
+
- DeepEval 输出连续分数,Ragas AgentGoalAccuracy 输出二值。
|
|
159
|
+
- DeepEval 更强调 full trace 中抽取 task/outcome 后做 alignment score。
|
|
160
|
+
- Ragas 更强调多轮消息和最终 goal achieved / not achieved 的判断。
|
|
161
|
+
|
|
162
|
+
#### Without Reference 的优点
|
|
163
|
+
|
|
164
|
+
- 不需要预先标注 reference,适合线上 trace 抽样评估。
|
|
165
|
+
- 适合用户目标比较自然、最终是否达成相对清楚的任务。
|
|
166
|
+
|
|
167
|
+
#### Without Reference 的风险
|
|
168
|
+
|
|
169
|
+
- 用户目标模糊时,LLM judge 可能推断错。
|
|
170
|
+
- 多目标任务里,二值结果会丢失“完成了 3/5 个要求”的信息。
|
|
171
|
+
- 如果 trace 缺少工具返回或最终状态,judge 可能只能根据 agent 自述判断,容易被“我已经完成了”误导。
|
|
172
|
+
|
|
173
|
+
### 两者最核心的差异
|
|
174
|
+
|
|
175
|
+
| 对比点 | DeepEval TaskCompletionMetric | Ragas AgentGoalAccuracy |
|
|
176
|
+
| --- | --- | --- |
|
|
177
|
+
| 默认是否需要 reference | 不需要 | 有 with-reference 和 without-reference 两种 |
|
|
178
|
+
| 分数类型 | 连续分 0-1,可 strict 二值 | 二值 0/1 |
|
|
179
|
+
| 主要评估对象 | trace 中抽取的 task 与 outcome 的对齐程度 | 用户目标是否被达成 |
|
|
180
|
+
| 是否强调完整 trace | 是,官方要求 tracing | 是,输入是多轮消息/工具调用 |
|
|
181
|
+
| 是否适合数据集离线评测 | 适合,但无参考时稳定性依赖 judge | with-reference 很适合 |
|
|
182
|
+
| 是否适合线上质量监控 | 适合 | without-reference 适合 |
|
|
183
|
+
| 对“部分完成”的表达 | 更自然,连续分可表达部分完成 | 原生表达较弱,除非拆成多个 goal 或扩展 rubric |
|
|
184
|
+
|
|
185
|
+
### 参考链接
|
|
186
|
+
|
|
187
|
+
- DeepEval Task Completion: https://deepeval.com/docs/metrics-task-completion
|
|
188
|
+
- Ragas Agentic or Tool use metrics: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/
|
|
189
|
+
- Ragas Agent Goal Accuracy with reference: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#with-reference
|
|
190
|
+
- Ragas Agent Goal Accuracy without reference: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#without-reference
|
|
191
|
+
|
|
192
|
+
## Q2:DeepEval / Ragas 的工具评估是否需要参考工具调用?Phoenix 是否不需要?
|
|
193
|
+
|
|
194
|
+
### 简短回答
|
|
195
|
+
|
|
196
|
+
基本是的。
|
|
197
|
+
|
|
198
|
+
| 项目 | 指标 | 是否需要参考工具调用 | 说明 |
|
|
199
|
+
| --- | --- | --- | --- |
|
|
200
|
+
| DeepEval | [`ToolCorrectnessMetric`](https://deepeval.com/docs/metrics-tool-correctness) | 需要 | `expected_tools` 是必填;核心分数是把 `tools_called` 和 `expected_tools` 做匹配。`available_tools` 可选,用于让 LLM 额外判断工具选择是否最优。 |
|
|
201
|
+
| Ragas | [`ToolCallAccuracy`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#tool-call-accuracy) | 需要 | 需要 `reference_tool_calls`,比较实际调用和期望调用的顺序、工具名、参数。 |
|
|
202
|
+
| Ragas | [`ToolCallF1`](https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/#tool-call-f1) | 需要 | 需要 `reference_tool_calls`,用 precision / recall / F1 统计实际工具调用与期望工具调用的匹配程度。 |
|
|
203
|
+
| Phoenix | [`Tool Selection`](https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-selection) | 不需要 reference tool calls | 需要 `input`、`available_tools`、`tool_selection`,由 LLM judge 判断选的工具是否正确。 |
|
|
204
|
+
| Phoenix | [`Tool Invocation`](https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-invocation) | 不需要 reference tool calls | 需要 `input`、`available_tools`、`tool_selection`,其中 `available_tools` 应包含 schema / 参数说明,LLM judge 判断调用参数和格式是否正确。 |
|
|
205
|
+
|
|
206
|
+
所以更精确地说:Phoenix 不是“什么参考都不需要”,它仍然需要 **可用工具列表 / 工具 schema** 作为判断依据;只是它不要求你为每个 case 预先标注一组“标准工具调用答案”。
|
|
207
|
+
|
|
208
|
+
### 它们也是局部片段级,而不是整条 trace 级吗?
|
|
209
|
+
|
|
210
|
+
是的,同理。
|
|
211
|
+
|
|
212
|
+
Phoenix `Tool Selection` 和 `Tool Invocation` 的默认粒度也更接近 **span-level / 局部工具决策级**,不是天然对整条 trace 给一个综合分。
|
|
213
|
+
|
|
214
|
+
官方文档里:
|
|
215
|
+
|
|
216
|
+
- `Tool Selection` 的 Supported Levels 是 `Span: Yes`,适合包含 tool calls 的 LLM spans,用来评估 individual tool selection decisions。
|
|
217
|
+
- `Tool Invocation` 的 Supported Levels 也是 `Span: Yes`,适合 tool spans 或包含 tool calls 的 LLM spans,用来评估 individual tool-calling decisions。
|
|
218
|
+
|
|
219
|
+
也就是说,典型用法是:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
Tool Selection:
|
|
223
|
+
一次 LLM 决定要不要调用工具、调用哪些工具
|
|
224
|
+
=> 跑一次 Tool Selection
|
|
225
|
+
|
|
226
|
+
Tool Invocation:
|
|
227
|
+
一次 LLM 生成具体工具调用参数
|
|
228
|
+
=> 跑一次 Tool Invocation
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
如果一条 trace 里有多次工具选择/调用,通常也是逐个片段评估后再聚合:
|
|
232
|
+
|
|
233
|
+
```text
|
|
234
|
+
trace_tool_selection_score =
|
|
235
|
+
所有工具选择片段的平均分 / 加权平均分
|
|
236
|
+
|
|
237
|
+
trace_tool_invocation_score =
|
|
238
|
+
所有工具调用片段的平均分 / 加权平均分
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Phoenix 文档也支持 multi-tool selection / multi-tool invocation:可以把一次 LLM 输出里的多个工具选择或多个工具调用放进同一个 `tool_selection` 字段里评估。但这仍然更像是“一个局部 LLM span 里包含多个工具调用”的评估,不等于整条 trace 的全局 evaluator。
|
|
242
|
+
|
|
243
|
+
### Phoenix Tool Selection 的评估逻辑
|
|
244
|
+
|
|
245
|
+
Phoenix `Tool Selection` 回答的是:**LLM 是否为当前任务选择了正确的工具**。
|
|
246
|
+
|
|
247
|
+
它关注 tool calling 的 **what**:
|
|
248
|
+
|
|
249
|
+
```text
|
|
250
|
+
用户要做什么?
|
|
251
|
+
系统有哪些可用工具?
|
|
252
|
+
LLM 实际选择了哪个/哪些工具?
|
|
253
|
+
=> 这些工具选得对不对?
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
它不关心参数是否完整、JSON 是否格式正确、日期是否转成了正确格式;这些属于 `Tool Invocation` 的范围。
|
|
257
|
+
|
|
258
|
+
#### 输入
|
|
259
|
+
|
|
260
|
+
Phoenix 官方文档中,`Tool Selection` 需要三个字段:
|
|
261
|
+
|
|
262
|
+
- `input`:用户问题或多轮会话上下文。
|
|
263
|
+
- `available_tools`:可用工具列表及描述。
|
|
264
|
+
- `tool_selection`:LLM 实际选择的工具。
|
|
265
|
+
|
|
266
|
+
例如:
|
|
267
|
+
|
|
268
|
+
```text
|
|
269
|
+
input:
|
|
270
|
+
User: I need to book a flight from New York to Los Angeles.
|
|
271
|
+
User: Tomorrow morning, the earliest available.
|
|
272
|
+
|
|
273
|
+
available_tools:
|
|
274
|
+
book_flight: Book a flight between two cities. Requires origin, destination, and date.
|
|
275
|
+
search_hotels: Search for hotel accommodations by city and dates.
|
|
276
|
+
get_weather: Get current weather conditions for a location.
|
|
277
|
+
cancel_booking: Cancel an existing flight or hotel reservation.
|
|
278
|
+
|
|
279
|
+
tool_selection:
|
|
280
|
+
book_flight
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### 判断标准
|
|
284
|
+
|
|
285
|
+
Phoenix 会用 LLM evaluator 产出二分类结果:
|
|
286
|
+
|
|
287
|
+
```text
|
|
288
|
+
label: correct | incorrect
|
|
289
|
+
score: 1.0 | 0.0
|
|
290
|
+
explanation: 评估理由
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
判为 `correct` 的典型条件:
|
|
294
|
+
|
|
295
|
+
- 工具存在于 `available_tools` 中。
|
|
296
|
+
- 该工具是当前用户任务下最合适的工具。
|
|
297
|
+
- 工具使用是安全且合适的。
|
|
298
|
+
- 如果任务需要多个工具,选择的工具数量也合理。
|
|
299
|
+
|
|
300
|
+
判为 `incorrect` 的典型条件:
|
|
301
|
+
|
|
302
|
+
- 调用了不存在的工具,也就是 hallucinated tool。
|
|
303
|
+
- 本来不需要工具,却调用了工具。
|
|
304
|
+
- 本来需要工具,却没有调用工具。
|
|
305
|
+
- 选择了无关或次优工具。
|
|
306
|
+
|
|
307
|
+
#### 它和 reference-based 工具评估的差异
|
|
308
|
+
|
|
309
|
+
DeepEval / Ragas 的工具评估通常是:
|
|
310
|
+
|
|
311
|
+
```text
|
|
312
|
+
实际工具调用 vs 预期工具调用
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Phoenix `Tool Selection` 更像是:
|
|
316
|
+
|
|
317
|
+
```text
|
|
318
|
+
实际工具选择 + 可用工具说明 + 用户任务
|
|
319
|
+
=> LLM judge 判断是否合理
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
所以它更适合没有标准答案的线上 trace 抽样;但也更依赖 judge 的判断质量,稳定性通常不如有 reference 的精确匹配。
|
|
323
|
+
|
|
324
|
+
### Phoenix Tool Invocation 的评估逻辑
|
|
325
|
+
|
|
326
|
+
Phoenix `Tool Invocation` 回答的是:**LLM 在调用工具时,参数、格式和内容是否正确**。
|
|
327
|
+
|
|
328
|
+
它关注 tool calling 的 **how**:
|
|
329
|
+
|
|
330
|
+
```text
|
|
331
|
+
工具选了以后,调用方式对不对?
|
|
332
|
+
参数有没有缺?
|
|
333
|
+
参数值是否符合用户上下文?
|
|
334
|
+
格式是否符合 schema?
|
|
335
|
+
有没有幻觉字段或不安全内容?
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Phoenix 文档明确说,`Tool Invocation` 不负责判断“是不是选对了工具”;如果要判断工具是否选对,应使用 `Tool Selection`。两个评估器是互补的。
|
|
339
|
+
|
|
340
|
+
#### 输入
|
|
341
|
+
|
|
342
|
+
`Tool Invocation` 同样需要三个字段:
|
|
343
|
+
|
|
344
|
+
- `input`:对话上下文,可以包含多轮历史。
|
|
345
|
+
- `available_tools`:工具 schema 或人类可读的工具参数说明。
|
|
346
|
+
- `tool_selection`:LLM 实际产生的工具调用,包含参数。
|
|
347
|
+
|
|
348
|
+
例如:
|
|
349
|
+
|
|
350
|
+
```text
|
|
351
|
+
input:
|
|
352
|
+
User: I need to book a flight from New York to Los Angeles.
|
|
353
|
+
User: Tomorrow morning, the earliest available.
|
|
354
|
+
|
|
355
|
+
available_tools:
|
|
356
|
+
book_flight: Book a flight between two cities
|
|
357
|
+
- origin (required): Departure city code, e.g. "JFK", "LAX"
|
|
358
|
+
- destination (required): Arrival city code
|
|
359
|
+
- date (required): Flight date in YYYY-MM-DD format
|
|
360
|
+
- time_preference (optional): "morning", "afternoon", or "evening"
|
|
361
|
+
|
|
362
|
+
tool_selection:
|
|
363
|
+
book_flight(origin="JFK", destination="LAX", date="2024-01-15", time_preference="morning")
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
这里 `available_tools` 最好不只是工具名,而是包含参数 schema、必填项、枚举值、格式要求。否则 evaluator 很难判断参数是否正确。
|
|
367
|
+
|
|
368
|
+
#### 判断标准
|
|
369
|
+
|
|
370
|
+
Phoenix 会检查:
|
|
371
|
+
|
|
372
|
+
- **必填参数是否存在**:例如 `origin`、`destination`、`date` 是否都有。
|
|
373
|
+
- **参数值是否来自对话上下文**:例如用户说 New York 到 Los Angeles,参数却填 Paris 就不对。
|
|
374
|
+
- **参数格式是否正确**:例如日期是否符合 `YYYY-MM-DD`。
|
|
375
|
+
- **是否出现 schema 外字段**:例如工具 schema 没有 `meal_preference`,LLM 却编了这个字段。
|
|
376
|
+
- **参数内容是否安全**:例如是否包含不该传给工具的 PII、token、敏感信息。
|
|
377
|
+
- **多工具调用是否都格式正确**:如果一次调用多个工具,需要一起判断。
|
|
378
|
+
|
|
379
|
+
输出同样是:
|
|
380
|
+
|
|
381
|
+
```text
|
|
382
|
+
label: correct | incorrect
|
|
383
|
+
score: 1.0 | 0.0
|
|
384
|
+
explanation: 评估理由
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
#### 一个边界例子
|
|
388
|
+
|
|
389
|
+
假设用户说:
|
|
390
|
+
|
|
391
|
+
```text
|
|
392
|
+
Book the earliest flight from New York to Los Angeles tomorrow morning.
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
工具调用是:
|
|
396
|
+
|
|
397
|
+
```text
|
|
398
|
+
book_flight(origin="NYC", destination="LAX", date="tomorrow")
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
这个调用可能在 `Tool Selection` 上是正确的,因为确实选了 `book_flight`。但在 `Tool Invocation` 上可能是错误的,因为:
|
|
402
|
+
|
|
403
|
+
- `origin` schema 要求 airport code,`NYC` 可能不是可接受机场码。
|
|
404
|
+
- `date` schema 要求 `YYYY-MM-DD`,但实际传了自然语言 `tomorrow`。
|
|
405
|
+
- 如果 schema 要求 `time_preference`,这里也可能缺参数。
|
|
406
|
+
|
|
407
|
+
这正是 Phoenix 把二者拆开的意义:
|
|
408
|
+
|
|
409
|
+
```text
|
|
410
|
+
Tool Selection: 选没选对工具
|
|
411
|
+
Tool Invocation: 选对工具后,调用方式对不对
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### 参考链接
|
|
415
|
+
|
|
416
|
+
- DeepEval Tool Correctness: https://deepeval.com/docs/metrics-tool-correctness
|
|
417
|
+
- Ragas Tool Call Accuracy / Tool Call F1: https://docs.ragas.io/en/stable/concepts/metrics/available_metrics/agents/
|
|
418
|
+
- Phoenix Tool Selection: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-selection
|
|
419
|
+
- Phoenix Tool Invocation: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-invocation
|
|
420
|
+
|
|
421
|
+
## Q3:Phoenix Tool Response Handling 的详细执行逻辑是什么?
|
|
422
|
+
|
|
423
|
+
### 简短结论
|
|
424
|
+
|
|
425
|
+
Phoenix [`Tool Response Handling`](https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-response-handling) 评估的是:**Agent 拿到工具返回之后,是否正确处理了工具结果,并据此产生了合适输出**。
|
|
426
|
+
|
|
427
|
+
它的默认评估粒度更接近 **一次工具调用/工具返回被后续 agent 输出消费的局部片段**,也就是 span-level evaluator,而不是天然对整条 trace 直接给一个总分。
|
|
428
|
+
|
|
429
|
+
它不回答:
|
|
430
|
+
|
|
431
|
+
- 工具是否选对:这是 `Tool Selection` 的职责。
|
|
432
|
+
- 工具参数是否正确:这是 `Tool Invocation` 的职责。
|
|
433
|
+
|
|
434
|
+
它回答:
|
|
435
|
+
|
|
436
|
+
```text
|
|
437
|
+
工具返回了什么?
|
|
438
|
+
Agent 后续输出/重试/跟进动作如何处理这个返回?
|
|
439
|
+
Agent 有没有准确使用工具结果、处理错误、避免泄露敏感信息?
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### 它是针对一次工具调用,还是整条 trace?
|
|
443
|
+
|
|
444
|
+
更准确地说:**它主要针对工具调用后的局部处理片段,不是整条 trace 级别的综合 evaluator**。
|
|
445
|
+
|
|
446
|
+
Phoenix 官方文档在 Supported Levels 里标的是:
|
|
447
|
+
|
|
448
|
+
```text
|
|
449
|
+
Span: Yes
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
适用对象是包含工具结果和 agent 后续输出的 LLM span / tool-consuming span。也就是说,典型用法是:
|
|
453
|
+
|
|
454
|
+
```text
|
|
455
|
+
一次工具调用 tool_call
|
|
456
|
+
+ 这次工具返回 tool_result
|
|
457
|
+
+ agent 随后的处理 output
|
|
458
|
+
=> 跑一次 Tool Response Handling
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
如果一条 trace 里有很多次工具调用,通常有两种做法:
|
|
462
|
+
|
|
463
|
+
1. **逐个工具调用/工具结果片段评估**
|
|
464
|
+
对每个“工具结果 -> agent 后续处理”的片段分别跑一次 evaluator,然后得到多条局部评分。
|
|
465
|
+
|
|
466
|
+
2. **把多个工具调用和结果合并成一次输入**
|
|
467
|
+
Phoenix 文档也说支持 multi-tool calls:如果 agent 调了多个工具,可以把所有 tool calls 和 results 放进输入里,让 evaluator 判断 agent 是否正确处理了所有结果。
|
|
468
|
+
|
|
469
|
+
但第二种更像是“手工构造一个包含多工具上下文的局部评估输入”,不等于 Phoenix 自动理解整条 trace 的所有节点、依赖关系和全局任务完成度。
|
|
470
|
+
|
|
471
|
+
所以如果要对整条 trace 得出一个 Tool Response Handling 总分,需要额外做聚合,例如:
|
|
472
|
+
|
|
473
|
+
```text
|
|
474
|
+
trace_tool_response_score =
|
|
475
|
+
所有可评估工具结果片段的平均分
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
或者更严格:
|
|
479
|
+
|
|
480
|
+
```text
|
|
481
|
+
trace_tool_response_pass =
|
|
482
|
+
所有关键工具结果片段都 correct
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
还可以按工具重要性加权:
|
|
486
|
+
|
|
487
|
+
```text
|
|
488
|
+
关键业务工具 > 辅助查询工具 > 非关键观察工具
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
### 输入是什么?
|
|
492
|
+
|
|
493
|
+
官方要求 4 个输入字段:
|
|
494
|
+
|
|
495
|
+
| 字段 | 类型 | 含义 |
|
|
496
|
+
| --- | --- | --- |
|
|
497
|
+
| `input` | string | 用户问题或对话上下文 |
|
|
498
|
+
| `tool_call` | string | Agent 发起的工具调用,包括工具名和参数 |
|
|
499
|
+
| `tool_result` | string | 工具返回结果,可以是正常数据、错误、部分结果 |
|
|
500
|
+
| `output` | string | Agent 收到工具结果后的处理结果,可以包含重试、后续调用、最终回复 |
|
|
501
|
+
|
|
502
|
+
TypeScript 版本字段名是 camelCase:
|
|
503
|
+
|
|
504
|
+
```text
|
|
505
|
+
toolCall
|
|
506
|
+
toolResult
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
一个最小例子:
|
|
510
|
+
|
|
511
|
+
```text
|
|
512
|
+
input:
|
|
513
|
+
What's the weather in Seattle?
|
|
514
|
+
|
|
515
|
+
tool_call:
|
|
516
|
+
get_weather(location="Seattle")
|
|
517
|
+
|
|
518
|
+
tool_result:
|
|
519
|
+
{"temperature": 58, "unit": "fahrenheit", "conditions": "cloudy"}
|
|
520
|
+
|
|
521
|
+
output:
|
|
522
|
+
Seattle is currently 58°F and cloudy.
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
如果 agent 在工具失败后做了重试,或者调用了多个工具,Phoenix 建议把完整处理序列放进 `output`,不要只放最后一句。多工具调用也可以放在同一次评估里。
|
|
526
|
+
|
|
527
|
+
### 中间处理逻辑是什么?
|
|
528
|
+
|
|
529
|
+
Phoenix 的实现形态是 **LLM classification evaluator**。它会把 `input`、`tool_call`、`tool_result`、`output` 放进内置 prompt,让 LLM judge 判断 `output` 是否正确处理了 `tool_result`。
|
|
530
|
+
|
|
531
|
+
可以把中间判断拆成 6 类检查。
|
|
532
|
+
|
|
533
|
+
#### 1. 是否准确抽取工具结果里的数据
|
|
534
|
+
|
|
535
|
+
检查 agent 输出中的实体、数字、日期、状态、字段是否来自 `tool_result`,有没有漏读或错读。
|
|
536
|
+
|
|
537
|
+
```text
|
|
538
|
+
tool_result:
|
|
539
|
+
{"restaurant": "Cafe Luna", "rating": 4.2}
|
|
540
|
+
|
|
541
|
+
output:
|
|
542
|
+
Cafe Luna has a 4.2 rating.
|
|
543
|
+
|
|
544
|
+
=> correct
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
如果输出把 4.2 写成 4.8,或者把 Cafe Luna 写成另一个餐厅,就是错误处理。
|
|
548
|
+
|
|
549
|
+
#### 2. 是否编造了工具结果中不存在的信息
|
|
550
|
+
|
|
551
|
+
这是 Tool Response Handling 的核心用途之一:检测 hallucinated data。
|
|
552
|
+
|
|
553
|
+
```text
|
|
554
|
+
tool_result:
|
|
555
|
+
{"results": [{"name": "Cafe Luna", "rating": 4.2}]}
|
|
556
|
+
|
|
557
|
+
output:
|
|
558
|
+
I found Cafe Luna (4.2 stars) and Mario's Italian (4.8 stars).
|
|
559
|
+
|
|
560
|
+
=> incorrect
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
因为 `Mario's Italian` 不在工具返回里,是 agent 自己编出来的。
|
|
564
|
+
|
|
565
|
+
#### 3. 是否正确转换日期、数字和结构化字段
|
|
566
|
+
|
|
567
|
+
工具结果经常是结构化数据,agent 需要转换给用户看。Phoenix 会判断转换是否正确:
|
|
568
|
+
|
|
569
|
+
- 数字单位是否正确。
|
|
570
|
+
- 日期格式是否正确。
|
|
571
|
+
- 状态字段是否正确解释。
|
|
572
|
+
- 结构化字段是否被正确组合。
|
|
573
|
+
|
|
574
|
+
例如工具返回 `temperature: 58, unit: fahrenheit`,输出成 `58°F` 是正确的;输出成 `58°C` 或 `14°F` 就可能是错误转换。
|
|
575
|
+
|
|
576
|
+
#### 4. 是否正确处理工具错误
|
|
577
|
+
|
|
578
|
+
如果 `tool_result` 是错误或部分结果,Phoenix 会看 agent 是否合理处理:
|
|
579
|
+
|
|
580
|
+
- transient error,例如 timeout、rate limit:是否重试。
|
|
581
|
+
- invalid argument error:是否修正参数再调用。
|
|
582
|
+
- partial result:是否说明限制,或继续补齐信息。
|
|
583
|
+
|
|
584
|
+
错误例子:
|
|
585
|
+
|
|
586
|
+
```text
|
|
587
|
+
tool_result:
|
|
588
|
+
{"error": "rate_limit", "retry_after": "5s"}
|
|
589
|
+
|
|
590
|
+
output:
|
|
591
|
+
I couldn't find any results.
|
|
592
|
+
|
|
593
|
+
=> incorrect
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
因为工具不是“没结果”,而是限流;更合理的处理是等待/重试或告诉用户暂时无法访问。
|
|
597
|
+
|
|
598
|
+
#### 5. 是否重复相同失败调用
|
|
599
|
+
|
|
600
|
+
Phoenix 把“重复 identical failed calls”也列为 incorrect 条件。如果工具已经因为同一个参数错误失败,agent 继续原样重试,多半说明它没有理解工具错误。
|
|
601
|
+
|
|
602
|
+
```text
|
|
603
|
+
tool_call:
|
|
604
|
+
book_flight(date="tomorrow")
|
|
605
|
+
|
|
606
|
+
tool_result:
|
|
607
|
+
{"error": "date must be YYYY-MM-DD"}
|
|
608
|
+
|
|
609
|
+
output:
|
|
610
|
+
Retry book_flight(date="tomorrow")
|
|
611
|
+
Retry book_flight(date="tomorrow")
|
|
612
|
+
|
|
613
|
+
=> incorrect
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
正确处理应该是把 `tomorrow` 转换成具体日期,再重新调用。
|
|
617
|
+
|
|
618
|
+
#### 6. 是否泄露工具返回中的敏感信息
|
|
619
|
+
|
|
620
|
+
如果工具返回里含有 credentials、internal URLs、PII 等,agent 不应该原样暴露给用户。
|
|
621
|
+
|
|
622
|
+
```text
|
|
623
|
+
tool_result:
|
|
624
|
+
{"status": "ok", "internal_url": "https://internal.service.local", "token": "sk-..."}
|
|
625
|
+
|
|
626
|
+
output:
|
|
627
|
+
Request succeeded. Debug token: sk-...
|
|
628
|
+
|
|
629
|
+
=> incorrect
|
|
630
|
+
```
|
|
631
|
+
|
|
632
|
+
即使工具结果本身真实存在,泄露敏感字段也是错误处理。
|
|
633
|
+
|
|
634
|
+
### 输出是什么?
|
|
635
|
+
|
|
636
|
+
Phoenix 输出一个 `Score` 对象,核心字段是:
|
|
637
|
+
|
|
638
|
+
| 字段 | 值 | 含义 |
|
|
639
|
+
| --- | --- | --- |
|
|
640
|
+
| `label` | `"correct"` 或 `"incorrect"` | 二分类判断 |
|
|
641
|
+
| `score` | `1.0` 或 `0.0` | 数值分,1 表示正确,0 表示错误 |
|
|
642
|
+
| `explanation` | string | LLM 生成的判定理由 |
|
|
643
|
+
| `direction` | `"maximize"` | 分数越高越好 |
|
|
644
|
+
| `metadata` | object | 额外信息,例如模型名;启用 tracing 时可包含 evaluation trace id |
|
|
645
|
+
|
|
646
|
+
正确条件可以概括为:
|
|
647
|
+
|
|
648
|
+
```text
|
|
649
|
+
label = correct
|
|
650
|
+
score = 1.0
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
当且仅当:
|
|
654
|
+
|
|
655
|
+
- 输出准确使用了工具结果。
|
|
656
|
+
- 没有编造工具结果中不存在的数据。
|
|
657
|
+
- 日期、数字、结构化字段转换正确。
|
|
658
|
+
- 可重试错误被合理重试,可修正参数错误被修正。
|
|
659
|
+
- 没有泄露敏感信息。
|
|
660
|
+
- 没有忽略工具结果。
|
|
661
|
+
|
|
662
|
+
错误条件可以概括为:
|
|
663
|
+
|
|
664
|
+
```text
|
|
665
|
+
label = incorrect
|
|
666
|
+
score = 0.0
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
典型错误包括:
|
|
670
|
+
|
|
671
|
+
- 输出包含工具结果中不存在的信息。
|
|
672
|
+
- 反转或误解工具结果含义。
|
|
673
|
+
- 日期、数字、结构化数据转换错误。
|
|
674
|
+
- 没有重试可重试错误。
|
|
675
|
+
- 没有修正可修正参数错误。
|
|
676
|
+
- 重复相同失败调用。
|
|
677
|
+
- 泄露工具返回中的敏感信息。
|
|
678
|
+
- 完全忽略工具结果。
|
|
679
|
+
|
|
680
|
+
### 和另外两个 Phoenix 工具评估器的关系
|
|
681
|
+
|
|
682
|
+
Phoenix 把工具调用链路拆成三段:
|
|
683
|
+
|
|
684
|
+
```text
|
|
685
|
+
Tool Selection:
|
|
686
|
+
该不该用这个工具?工具选得对不对?
|
|
687
|
+
|
|
688
|
+
Tool Invocation:
|
|
689
|
+
工具调用参数、格式、schema 是否正确?
|
|
690
|
+
|
|
691
|
+
Tool Response Handling:
|
|
692
|
+
工具返回之后,agent 是否正确使用结果、处理错误、避免泄露?
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
一个 agent 可能:
|
|
696
|
+
|
|
697
|
+
- `Tool Selection = correct`:选对了搜索天气工具。
|
|
698
|
+
- `Tool Invocation = correct`:参数也传对了 Seattle。
|
|
699
|
+
- `Tool Response Handling = incorrect`:工具返回 58°F cloudy,但 agent 输出成 80°F sunny。
|
|
700
|
+
|
|
701
|
+
所以 Tool Response Handling 补的是最后一段能力:**工具结果到最终行为/回复之间的正确性**。
|
|
702
|
+
|
|
703
|
+
### 参考链接
|
|
704
|
+
|
|
705
|
+
- Phoenix Tool Response Handling: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-response-handling
|
|
706
|
+
- Phoenix Tool Selection: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-selection
|
|
707
|
+
- Phoenix Tool Invocation: https://arize.com/docs/phoenix/evaluation/pre-built-metrics/tool-invocation
|
|
708
|
+
|
|
709
|
+
## Q4:当前轨迹评估里的“冗余”和 DeepEval StepEfficiencyMetric 有何不同?还需要怎么优化?
|
|
710
|
+
|
|
711
|
+
### 简短结论
|
|
712
|
+
|
|
713
|
+
两者都关注“agent 有没有走弯路、重复调用、无效重试”,但定位不同。
|
|
714
|
+
|
|
715
|
+
当前 Agent Insight 的“冗余”是 **轨迹质量综合评估里的一个维度**;DeepEval [`StepEfficiencyMetric`](https://deepeval.com/docs/metrics-step-efficiency) 是 **独立的 trace-only 步骤效率评估器**。
|
|
716
|
+
|
|
717
|
+
更关键的是:DeepEval 的 Step Efficiency 以“用户任务是否需要这些步骤”为中心;当前轨迹冗余更多是“这条 trace 里有没有明显重复、高频无效调用、绕路”的质量维度。
|
|
718
|
+
|
|
719
|
+
### 当前 Agent Insight 轨迹冗余的逻辑
|
|
720
|
+
|
|
721
|
+
当前预置轨迹评估器是 `preset-agent-trace-quality`,实现入口主要在:
|
|
722
|
+
|
|
723
|
+
- `src/lib/engine/evaluation/opencode-trajectory-evaluator.ts`
|
|
724
|
+
- `src/lib/engine/evaluation/trajectory-evaluator.ts`
|
|
725
|
+
- `src/lib/engine/evaluation/trace-summarizer.ts`
|
|
726
|
+
|
|
727
|
+
它先把完整 trace 压缩成事件级步骤:
|
|
728
|
+
|
|
729
|
+
```text
|
|
730
|
+
user / llm / tool / skill / task
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
每个步骤保留:
|
|
734
|
+
|
|
735
|
+
```text
|
|
736
|
+
index
|
|
737
|
+
agent
|
|
738
|
+
depth
|
|
739
|
+
kind
|
|
740
|
+
name
|
|
741
|
+
argsSummary
|
|
742
|
+
outputSummary
|
|
743
|
+
textContent
|
|
744
|
+
durationMs
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
然后让 LLM judge 输出三维分:
|
|
748
|
+
|
|
749
|
+
```text
|
|
750
|
+
completeness: 关键动作覆盖完整性
|
|
751
|
+
tool_choice: 工具/Skill 选择合理性
|
|
752
|
+
redundancy: 冗余程度
|
|
753
|
+
```
|
|
754
|
+
|
|
755
|
+
其中冗余维度的 prompt 口径是:
|
|
756
|
+
|
|
757
|
+
```text
|
|
758
|
+
基于 actual_flat_trace_steps 中是否有明显重复、绕路、高频无效调用,0.0 到 1.0。
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
并要求在 `dimension_details.redundancy` 中输出:
|
|
762
|
+
|
|
763
|
+
```text
|
|
764
|
+
consecutive_same_runs: 连续重复调用
|
|
765
|
+
heavy_repeated_calls: 高频重复调用
|
|
766
|
+
explanation: 冗余说明
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
所以当前“冗余”主要依赖 LLM 根据压缩步骤判断:
|
|
770
|
+
|
|
771
|
+
- 是否连续重复调用同一个工具。
|
|
772
|
+
- 是否某类工具调用次数异常高。
|
|
773
|
+
- 是否存在明显绕路。
|
|
774
|
+
- 是否有无效消耗。
|
|
775
|
+
|
|
776
|
+
代码里还有一个轻量规则辅助:`normalizeTrajectoryRedundancyDetails()` 会统计 tool / skill / task 调用次数,用来补齐 LLM 返回的 repeated call 名称和位置。但它更像是 **结果规范化 / 证据补齐**,不是一个完整的规则冗余评分器。
|
|
777
|
+
|
|
778
|
+
最终轨迹分是代码侧加权聚合:
|
|
779
|
+
|
|
780
|
+
```text
|
|
781
|
+
trajectory_score =
|
|
782
|
+
0.45 * completeness
|
|
783
|
+
+ 0.35 * tool_choice
|
|
784
|
+
+ 0.20 * redundancy
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
trace-only 模式下,没有 completeness,则只用:
|
|
788
|
+
|
|
789
|
+
```text
|
|
790
|
+
tool_choice + redundancy
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
### DeepEval StepEfficiencyMetric 的逻辑
|
|
794
|
+
|
|
795
|
+
DeepEval `StepEfficiencyMetric` 是一个 **LLM-as-a-judge、single-turn、referenceless、agent trace-only** 指标。
|
|
796
|
+
|
|
797
|
+
官方计算逻辑是:
|
|
798
|
+
|
|
799
|
+
```text
|
|
800
|
+
Step Efficiency Score = AlignmentScore(Task, Execution Steps)
|
|
801
|
+
```
|
|
802
|
+
|
|
803
|
+
它会做两件事:
|
|
804
|
+
|
|
805
|
+
1. **从 trace 中抽取 Task**
|
|
806
|
+
也就是用户真正想让 agent 完成的目标。
|
|
807
|
+
|
|
808
|
+
2. **评估 Execution Steps 是否高效服务于这个 Task**
|
|
809
|
+
LLM judge 会判断 agent 的执行步骤是否对完成任务严格必要。
|
|
810
|
+
|
|
811
|
+
DeepEval 明确说 Step Efficiency 会惩罚:
|
|
812
|
+
|
|
813
|
+
- duplicates:重复步骤。
|
|
814
|
+
- retries:不必要重试。
|
|
815
|
+
- detours:绕路。
|
|
816
|
+
- any actions not strictly required:任何不是完成任务严格需要的动作。
|
|
817
|
+
|
|
818
|
+
它和 `TaskCompletionMetric` 是分开的:一个 agent 可以最终完成任务,但路径很臃肿;也可以路径很短,但没有完成任务。
|
|
819
|
+
|
|
820
|
+
### 两者核心差异
|
|
821
|
+
|
|
822
|
+
| 对比点 | Agent Insight 当前“冗余” | DeepEval StepEfficiencyMetric |
|
|
823
|
+
| --- | --- | --- |
|
|
824
|
+
| 所属位置 | 轨迹质量综合评估的一个维度 | 独立步骤效率评估器 |
|
|
825
|
+
| 输入 | 压缩后的 `actual_flat_trace_steps`,可结合关键动作/Skill 上下文 | 完整 agent trace |
|
|
826
|
+
| 是否需要 reference | 不需要标准路径;可结合 Skill 关键动作 | 不需要 reference |
|
|
827
|
+
| 评估中心 | trace 中是否有明显重复、绕路、高频无效调用 | 执行步骤是否严格服务于用户 Task |
|
|
828
|
+
| 评分方式 | LLM 输出 `redundancy` 维度分,再进入总轨迹分加权 | LLM 输出独立 efficiency score |
|
|
829
|
+
| 证据形态 | `consecutive_same_runs`、`heavy_repeated_calls`、explanation | reason 中说明哪些步骤低效 |
|
|
830
|
+
| 粒度 | trace-level 的一个维度 | trace-level 专项指标 |
|
|
831
|
+
| 当前确定性规则 | 主要用于补齐重复调用详情,不主导评分 | 官方文档描述为 LLM judge 评分 |
|
|
832
|
+
|
|
833
|
+
### 当前实现存在的关键问题
|
|
834
|
+
|
|
835
|
+
#### 1. 分数方向不清晰,甚至可能反向
|
|
836
|
+
|
|
837
|
+
当前文档写的是:
|
|
838
|
+
|
|
839
|
+
```text
|
|
840
|
+
冗余:高 = 浪费明显,路径不够精炼
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
也就是说,`redundancy` 越高越坏。
|
|
844
|
+
|
|
845
|
+
但代码聚合里是:
|
|
846
|
+
|
|
847
|
+
```text
|
|
848
|
+
+ 0.20 * redundancy
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
这会导致一个问题:如果 `redundancy=1.0` 表示“非常冗余”,它反而会提高总轨迹分。
|
|
852
|
+
|
|
853
|
+
当前 prompt 也写“redundancy:冗余程度,0.0 到 1.0”,从语义看更像高分=更冗余;但代码 fallback 又在缺失时给 `redundancy=1`,这又像高分=更好。这里需要先统一方向。
|
|
854
|
+
|
|
855
|
+
这是最优先要修的地方。
|
|
856
|
+
|
|
857
|
+
#### 2. 冗余不是独立 evaluator,解释力有限
|
|
858
|
+
|
|
859
|
+
当前冗余只是三维中的一个维度,输出主要是 explanation 和重复调用列表。它没有像 DeepEval Step Efficiency 那样明确抽取:
|
|
860
|
+
|
|
861
|
+
```text
|
|
862
|
+
Task
|
|
863
|
+
Execution Steps
|
|
864
|
+
每一步是否 strictly required
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
所以它能发现“明显重复”,但不一定能系统判断:
|
|
868
|
+
|
|
869
|
+
- 这一步对任务是否必要。
|
|
870
|
+
- 这个重试是否合理。
|
|
871
|
+
- 这段搜索是否属于必要探索还是绕路。
|
|
872
|
+
- 多 agent 分工里的额外步骤是否有价值。
|
|
873
|
+
|
|
874
|
+
#### 3. 确定性统计还不够强
|
|
875
|
+
|
|
876
|
+
当前有调用次数统计,但没有形成完整的规则指标,例如:
|
|
877
|
+
|
|
878
|
+
- 相同工具 + 相同参数 + 相同错误的重复率。
|
|
879
|
+
- 连续失败后是否改变参数。
|
|
880
|
+
- 空结果工具调用比例。
|
|
881
|
+
- 无后续消费的工具结果比例。
|
|
882
|
+
- 工具调用 token / 耗时占比。
|
|
883
|
+
- 同一文件/URL/资源被重复读取次数。
|
|
884
|
+
- 截断 trace 下的统计可信度。
|
|
885
|
+
|
|
886
|
+
这些不该全交给 LLM judge。
|
|
887
|
+
|
|
888
|
+
#### 4. trace 压缩可能影响冗余判断
|
|
889
|
+
|
|
890
|
+
`trace-summarizer.ts` 默认最多保留 80 步,并且中间过长会截断为前半 + 后半。每个字段也会截到 200 字符。
|
|
891
|
+
|
|
892
|
+
这对上下文成本友好,但对“冗余/效率”有风险:
|
|
893
|
+
|
|
894
|
+
- 中间重复调用可能被截掉。
|
|
895
|
+
- 工具输出被截短后,judge 不知道重试是否合理。
|
|
896
|
+
- 多轮探索过程被压缩后,可能误判为绕路或漏判冗余。
|
|
897
|
+
|
|
898
|
+
### 建议怎么优化
|
|
899
|
+
|
|
900
|
+
#### 1. 先统一分数语义
|
|
901
|
+
|
|
902
|
+
建议二选一:
|
|
903
|
+
|
|
904
|
+
方案 A:把维度改名为 `efficiency`
|
|
905
|
+
|
|
906
|
+
```text
|
|
907
|
+
efficiency 高 = 路径精炼、高效
|
|
908
|
+
efficiency 低 = 冗余、绕路、无效消耗
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
然后聚合可以继续:
|
|
912
|
+
|
|
913
|
+
```text
|
|
914
|
+
+ 0.20 * efficiency
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
方案 B:保留 `redundancy`
|
|
918
|
+
|
|
919
|
+
```text
|
|
920
|
+
redundancy 高 = 冗余严重
|
|
921
|
+
redundancy 低 = 路径精炼
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
但聚合必须改成:
|
|
925
|
+
|
|
926
|
+
```text
|
|
927
|
+
+ 0.20 * (1 - redundancy)
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
并且 UI 文案、文档、字段名都要说明它是“缺陷分”,不是质量分。
|
|
931
|
+
|
|
932
|
+
我更建议方案 A。因为综合分里各维度最好都是“高分=好”,用户理解成本低。
|
|
933
|
+
|
|
934
|
+
#### 2. 增加 DeepEval 式的独立 Step Efficiency 评估器
|
|
935
|
+
|
|
936
|
+
把当前冗余维度升级/拆出为一个独立预置评估器:
|
|
937
|
+
|
|
938
|
+
```text
|
|
939
|
+
Step Efficiency / 步骤效率
|
|
940
|
+
```
|
|
941
|
+
|
|
942
|
+
输入:
|
|
943
|
+
|
|
944
|
+
```text
|
|
945
|
+
- 用户任务
|
|
946
|
+
- 完整或分层压缩 trace
|
|
947
|
+
- execution steps
|
|
948
|
+
- 工具调用统计
|
|
949
|
+
- 可选:最终任务完成度
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
中间逻辑:
|
|
953
|
+
|
|
954
|
+
```text
|
|
955
|
+
1. 抽取用户 Task
|
|
956
|
+
2. 抽取所有 execution steps
|
|
957
|
+
3. 标注每一步:
|
|
958
|
+
required | helpful | redundant | harmful | justified_retry | unjustified_retry | detour
|
|
959
|
+
4. 汇总低效步骤
|
|
960
|
+
5. 输出效率分和证据
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
输出:
|
|
964
|
+
|
|
965
|
+
```text
|
|
966
|
+
score: 0-1,高分=高效
|
|
967
|
+
redundant_steps: [...]
|
|
968
|
+
unjustified_retries: [...]
|
|
969
|
+
detours: [...]
|
|
970
|
+
repeated_calls: [...]
|
|
971
|
+
reason
|
|
972
|
+
confidence
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
这样它就和 DeepEval StepEfficiencyMetric 更接近,也能和现有轨迹质量总分解耦。
|
|
976
|
+
|
|
977
|
+
#### 3. 做“确定性规则 + LLM judge”的混合评分
|
|
978
|
+
|
|
979
|
+
建议先由代码生成派生特征:
|
|
980
|
+
|
|
981
|
+
```text
|
|
982
|
+
total_steps
|
|
983
|
+
tool_calls
|
|
984
|
+
same_tool_same_args_repeats
|
|
985
|
+
consecutive_same_tool_runs
|
|
986
|
+
failed_tool_retries
|
|
987
|
+
unchanged_failed_retries
|
|
988
|
+
empty_result_calls
|
|
989
|
+
unused_tool_results
|
|
990
|
+
duration_ms
|
|
991
|
+
token_cost
|
|
992
|
+
trace_truncated
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
再把这些结构化特征交给 LLM judge 做语义判断:
|
|
996
|
+
|
|
997
|
+
```text
|
|
998
|
+
这些重复是否合理?
|
|
999
|
+
这些重试是否必要?
|
|
1000
|
+
这些额外步骤是否服务于用户任务?
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
这样比单纯让 LLM 看压缩 trace 更稳,也比纯规则更能处理探索型任务。
|
|
1004
|
+
|
|
1005
|
+
#### 4. 区分“合理重试”和“无效重复”
|
|
1006
|
+
|
|
1007
|
+
不要把所有重复都判坏。需要单独标注:
|
|
1008
|
+
|
|
1009
|
+
```text
|
|
1010
|
+
justified_retry:
|
|
1011
|
+
transient error 后换参数/等待/换工具重试
|
|
1012
|
+
|
|
1013
|
+
unjustified_retry:
|
|
1014
|
+
相同参数、相同错误、连续重复
|
|
1015
|
+
|
|
1016
|
+
progressive_search:
|
|
1017
|
+
搜索关键词逐步收敛,有新信息
|
|
1018
|
+
|
|
1019
|
+
dead_loop:
|
|
1020
|
+
搜索/读取/命令没有产生新信息
|
|
1021
|
+
```
|
|
1022
|
+
|
|
1023
|
+
这是当前“冗余”最容易误判的地方。
|
|
1024
|
+
|
|
1025
|
+
#### 5. 把冗余证据从“工具名级别”升级到“调用签名级别”
|
|
1026
|
+
|
|
1027
|
+
现在 `heavy_repeated_calls` 更偏工具名统计,例如:
|
|
1028
|
+
|
|
1029
|
+
```text
|
|
1030
|
+
read: 8
|
|
1031
|
+
bash: 3
|
|
1032
|
+
```
|
|
1033
|
+
|
|
1034
|
+
但真正有意义的是调用签名:
|
|
1035
|
+
|
|
1036
|
+
```text
|
|
1037
|
+
read(path="same_file.ts"): 5
|
|
1038
|
+
bash(cmd="npm test"): 3
|
|
1039
|
+
web_search(query="same keywords"): 4
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1042
|
+
建议按:
|
|
1043
|
+
|
|
1044
|
+
```text
|
|
1045
|
+
tool name + normalized args + output/error fingerprint
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
来识别重复。
|
|
1049
|
+
|
|
1050
|
+
#### 6. 支持 trace-level 聚合和 span-level 证据
|
|
1051
|
+
|
|
1052
|
+
最终应该是:
|
|
1053
|
+
|
|
1054
|
+
```text
|
|
1055
|
+
trace_efficiency_score: 整条 trace 的步骤效率
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
但证据必须落到具体步骤:
|
|
1059
|
+
|
|
1060
|
+
```text
|
|
1061
|
+
step_index
|
|
1062
|
+
tool_name
|
|
1063
|
+
args_fingerprint
|
|
1064
|
+
issue_type
|
|
1065
|
+
why_redundant
|
|
1066
|
+
severity
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
这样用户看到低分时,能直接知道是哪几步浪费。
|
|
1070
|
+
|
|
1071
|
+
#### 7. 处理 trace 截断带来的置信度
|
|
1072
|
+
|
|
1073
|
+
如果 `traceSummary.truncated=true`,效率评估应该降低 confidence,或者标记:
|
|
1074
|
+
|
|
1075
|
+
```text
|
|
1076
|
+
efficiency_score_confidence = low
|
|
1077
|
+
reason = 中间步骤被截断,可能漏掉重复/重试证据
|
|
1078
|
+
```
|
|
1079
|
+
|
|
1080
|
+
否则长 trace 的效率分会显得过于确定。
|
|
1081
|
+
|
|
1082
|
+
### 一个推荐的优化方向总结
|
|
1083
|
+
|
|
1084
|
+
短期:
|
|
1085
|
+
|
|
1086
|
+
1. 修正 `redundancy` 分数方向。
|
|
1087
|
+
2. 明确 UI/文档里“高分=好”还是“高分=坏”。
|
|
1088
|
+
3. 增加确定性重复统计:相同工具+相同参数、连续失败重试、重复读取。
|
|
1089
|
+
|
|
1090
|
+
中期:
|
|
1091
|
+
|
|
1092
|
+
1. 把“冗余”改造成 `efficiency` 正向质量维度。
|
|
1093
|
+
2. 输出 step-level 证据列表,而不只是 explanation。
|
|
1094
|
+
3. 对合理重试和无效重复做分类。
|
|
1095
|
+
|
|
1096
|
+
长期:
|
|
1097
|
+
|
|
1098
|
+
1. 新增独立的 `Step Efficiency / 步骤效率` 预置评估器。
|
|
1099
|
+
2. 采用 DeepEval 式 `AlignmentScore(Task, Execution Steps)` 逻辑。
|
|
1100
|
+
3. 与任务完成度联动展示:完成但低效、未完成但路径高效、未完成且低效。
|
|
1101
|
+
|
|
1102
|
+
### 参考链接
|
|
1103
|
+
|
|
1104
|
+
- DeepEval Step Efficiency: https://deepeval.com/docs/metrics-step-efficiency
|
|
1105
|
+
- Agent Insight 轨迹评估实现:`src/lib/engine/evaluation/opencode-trajectory-evaluator.ts`
|
|
1106
|
+
- Agent Insight 轨迹分聚合:`src/lib/engine/evaluation/trajectory-evaluator.ts`
|
|
1107
|
+
- Agent Insight trace summarizer:`src/lib/engine/evaluation/trace-summarizer.ts`
|
|
1108
|
+
|
|
1109
|
+
## Q5:DeepEval PlanQualityMetric 对 agent 的意义在哪?对评估改进有什么作用?适用场景是什么?
|
|
1110
|
+
|
|
1111
|
+
### 简短结论
|
|
1112
|
+
|
|
1113
|
+
DeepEval [`PlanQualityMetric`](https://deepeval.com/docs/metrics-plan-quality) 评估的是:**agent 在执行前或执行中形成的计划,本身是否是一个能完成任务的好计划**。
|
|
1114
|
+
|
|
1115
|
+
它不是评估最终结果,也不是评估 agent 有没有照计划执行。它只看:
|
|
1116
|
+
|
|
1117
|
+
```text
|
|
1118
|
+
用户要完成什么任务?
|
|
1119
|
+
agent 想出来的 plan 是否合理、完整、可执行?
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
官方计算公式是:
|
|
1123
|
+
|
|
1124
|
+
```text
|
|
1125
|
+
Plan Quality Score = AlignmentScore(Task, Plan)
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
其中:
|
|
1129
|
+
|
|
1130
|
+
- `Task`:从 trace 中抽取的用户目标或任务意图。
|
|
1131
|
+
- `Plan`:从 trace 中 agent 的 thinking / reasoning 里抽取出来的计划。
|
|
1132
|
+
- `AlignmentScore`:LLM judge 判断这个计划和任务是否对齐。
|
|
1133
|
+
|
|
1134
|
+
### 对 agent 的意义
|
|
1135
|
+
|
|
1136
|
+
Plan Quality 的价值在于:它把 agent 失败原因里的 **“想错了”** 和 **“执行错了”** 分开。
|
|
1137
|
+
|
|
1138
|
+
很多 agent 失败不是因为工具调用能力差,而是第一步就规划错了:
|
|
1139
|
+
|
|
1140
|
+
- 没有识别任务的关键约束。
|
|
1141
|
+
- 漏掉必要步骤。
|
|
1142
|
+
- 把任务拆错方向。
|
|
1143
|
+
- 计划里用了不可用工具。
|
|
1144
|
+
- 计划过度复杂,导致后续执行绕路。
|
|
1145
|
+
- 没有先验证条件就直接行动。
|
|
1146
|
+
- 多 agent 场景里没有规划谁负责什么。
|
|
1147
|
+
|
|
1148
|
+
如果只看任务完成度,最终失败只能知道“没完成”;如果只看工具调用,只能看到“某个工具用错了”。Plan Quality 则能提前指出:
|
|
1149
|
+
|
|
1150
|
+
```text
|
|
1151
|
+
这个 agent 的路线图本身就不对。
|
|
1152
|
+
```
|
|
1153
|
+
|
|
1154
|
+
这对 agent 很重要,因为计划通常决定了后面工具选择、步骤效率、错误恢复和最终结果。
|
|
1155
|
+
|
|
1156
|
+
### 它和其他指标的区别
|
|
1157
|
+
|
|
1158
|
+
| 指标 | 回答的问题 |
|
|
1159
|
+
| --- | --- |
|
|
1160
|
+
| Task Completion | 最终有没有完成任务? |
|
|
1161
|
+
| Plan Quality | 一开始/过程中形成的计划本身好不好? |
|
|
1162
|
+
| Plan Adherence | agent 实际有没有遵守这个计划? |
|
|
1163
|
+
| Step Efficiency | 实际执行路径是否高效? |
|
|
1164
|
+
| Tool Correctness / Tool Selection | 工具是否选对? |
|
|
1165
|
+
|
|
1166
|
+
典型组合判断:
|
|
1167
|
+
|
|
1168
|
+
| 现象 | 说明 |
|
|
1169
|
+
| --- | --- |
|
|
1170
|
+
| Plan Quality 高,Plan Adherence 低 | 计划是好的,但执行偏离了。问题在执行控制、工具使用或中途决策。 |
|
|
1171
|
+
| Plan Quality 低,Plan Adherence 高 | agent 很认真地执行了一个坏计划。问题在规划能力或 prompt/skill 指导。 |
|
|
1172
|
+
| Plan Quality 高,Task Completion 低 | 计划方向对,但执行失败,可能是工具、环境、参数、权限、错误恢复问题。 |
|
|
1173
|
+
| Plan Quality 低,Task Completion 高 | 可能是靠运气、模型补救或任务简单完成了;长期稳定性风险较高。 |
|
|
1174
|
+
|
|
1175
|
+
### 对 agent 评估改进有什么作用?
|
|
1176
|
+
|
|
1177
|
+
#### 1. 帮助定位失败发生在“规划阶段”还是“执行阶段”
|
|
1178
|
+
|
|
1179
|
+
没有 Plan Quality 时,评估器常常只能看到最终失败和中间工具错误。
|
|
1180
|
+
|
|
1181
|
+
有了 Plan Quality 后,可以把失败拆成:
|
|
1182
|
+
|
|
1183
|
+
```text
|
|
1184
|
+
计划错了:
|
|
1185
|
+
agent 不知道该怎么做
|
|
1186
|
+
|
|
1187
|
+
计划对了但执行错了:
|
|
1188
|
+
agent 知道该怎么做,但执行控制/工具使用出问题
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
这对优化方向非常关键。
|
|
1192
|
+
|
|
1193
|
+
例如:
|
|
1194
|
+
|
|
1195
|
+
- 如果 Plan Quality 低,应改 system prompt、skill 指令、任务拆解模板、few-shot planning 示例。
|
|
1196
|
+
- 如果 Plan Quality 高但执行失败,应改工具 schema、工具选择、参数校验、错误恢复、执行 guardrail。
|
|
1197
|
+
|
|
1198
|
+
#### 2. 提前发现“表面成功但不可复用”的 agent
|
|
1199
|
+
|
|
1200
|
+
有些 agent 最终能完成任务,但计划是混乱的:
|
|
1201
|
+
|
|
1202
|
+
- 先乱查一堆信息,再偶然找到答案。
|
|
1203
|
+
- 没有先确认约束,但最后输出碰巧符合。
|
|
1204
|
+
- 计划漏了验证步骤,但样例刚好没暴露问题。
|
|
1205
|
+
|
|
1206
|
+
这种 agent 在单个 case 上可能分数不错,但换任务就容易崩。Plan Quality 能作为稳定性前置信号:
|
|
1207
|
+
|
|
1208
|
+
```text
|
|
1209
|
+
好结果 + 坏计划 = 潜在不稳定
|
|
1210
|
+
```
|
|
1211
|
+
|
|
1212
|
+
#### 3. 改进 prompt / skill 的可操作性
|
|
1213
|
+
|
|
1214
|
+
如果 agent 总是计划不好,通常说明指导材料不够好:
|
|
1215
|
+
|
|
1216
|
+
- skill 没有说明标准流程。
|
|
1217
|
+
- prompt 只告诉 agent 目标,没有告诉它关键约束。
|
|
1218
|
+
- 工具说明缺少适用场景。
|
|
1219
|
+
- 缺少“先判断、再行动、最后验证”的操作框架。
|
|
1220
|
+
|
|
1221
|
+
Plan Quality 的 reason 可以直接转成优化建议:
|
|
1222
|
+
|
|
1223
|
+
```text
|
|
1224
|
+
缺少验证步骤
|
|
1225
|
+
=> 在 skill 中增加“修改后必须运行测试/检查结果”的规则
|
|
1226
|
+
|
|
1227
|
+
计划没有处理异常路径
|
|
1228
|
+
=> 增加错误恢复策略
|
|
1229
|
+
|
|
1230
|
+
计划没有区分信息收集和执行动作
|
|
1231
|
+
=> 增加分阶段流程模板
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
#### 4. 支持多 agent / 子 agent 编排评估
|
|
1235
|
+
|
|
1236
|
+
多 agent 系统里,计划质量不只是“步骤列表是否合理”,还包括:
|
|
1237
|
+
|
|
1238
|
+
- 是否应该派发子 agent。
|
|
1239
|
+
- 子 agent 分工是否清楚。
|
|
1240
|
+
- 依赖关系是否正确。
|
|
1241
|
+
- 父 agent 是否保留最终整合责任。
|
|
1242
|
+
- 是否避免重复派发或互相等待。
|
|
1243
|
+
|
|
1244
|
+
Plan Quality 可以帮助发现:
|
|
1245
|
+
|
|
1246
|
+
```text
|
|
1247
|
+
agent 一开始就把任务交给了错误角色
|
|
1248
|
+
agent 没有规划父子 agent 的信息回流
|
|
1249
|
+
agent 把一个需要并行拆分的任务串行处理了
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
#### 5. 和 Step Efficiency 互补
|
|
1253
|
+
|
|
1254
|
+
Step Efficiency 看的是实际走过的路是否精炼;Plan Quality 看的是原本设计的路线是否合理。
|
|
1255
|
+
|
|
1256
|
+
两者可以组合判断:
|
|
1257
|
+
|
|
1258
|
+
```text
|
|
1259
|
+
Plan Quality 高 + Step Efficiency 低:
|
|
1260
|
+
好计划被执行得很啰嗦
|
|
1261
|
+
|
|
1262
|
+
Plan Quality 低 + Step Efficiency 高:
|
|
1263
|
+
计划很差,但执行很短;可能是“快速走错”
|
|
1264
|
+
|
|
1265
|
+
Plan Quality 高 + Step Efficiency 高:
|
|
1266
|
+
理想状态,计划好且执行精炼
|
|
1267
|
+
|
|
1268
|
+
Plan Quality 低 + Step Efficiency 低:
|
|
1269
|
+
规划和执行都需要优化
|
|
1270
|
+
```
|
|
1271
|
+
|
|
1272
|
+
### 适用场景
|
|
1273
|
+
|
|
1274
|
+
#### 1. 复杂多步任务
|
|
1275
|
+
|
|
1276
|
+
例如:
|
|
1277
|
+
|
|
1278
|
+
- 调研并形成报告。
|
|
1279
|
+
- 修复 bug 并验证。
|
|
1280
|
+
- 数据分析。
|
|
1281
|
+
- 多文件代码修改。
|
|
1282
|
+
- 自动化运维。
|
|
1283
|
+
- 业务流程办理。
|
|
1284
|
+
|
|
1285
|
+
这些任务如果没有好计划,后面很容易工具乱用、步骤重复或漏验证。
|
|
1286
|
+
|
|
1287
|
+
#### 2. 高风险任务
|
|
1288
|
+
|
|
1289
|
+
例如:
|
|
1290
|
+
|
|
1291
|
+
- 修改生产配置。
|
|
1292
|
+
- 执行数据库操作。
|
|
1293
|
+
- 删除/迁移文件。
|
|
1294
|
+
- 调用外部 API 完成不可逆业务动作。
|
|
1295
|
+
|
|
1296
|
+
这类场景里,先看计划是否包含确认、备份、验证、回滚,比只看最终结果更安全。
|
|
1297
|
+
|
|
1298
|
+
#### 3. Agent / Skill 调优
|
|
1299
|
+
|
|
1300
|
+
当你想判断一个 skill 是否真的让 agent 更会做事,而不是只让它某次碰巧答对时,Plan Quality 很有用。
|
|
1301
|
+
|
|
1302
|
+
它能回答:
|
|
1303
|
+
|
|
1304
|
+
```text
|
|
1305
|
+
新版 skill 是否让 agent 更早识别关键步骤?
|
|
1306
|
+
新版 prompt 是否减少了错误分解?
|
|
1307
|
+
agent 是否学会先验证再行动?
|
|
1308
|
+
```
|
|
1309
|
+
|
|
1310
|
+
#### 4. 多 agent 编排
|
|
1311
|
+
|
|
1312
|
+
适用于需要判断:
|
|
1313
|
+
|
|
1314
|
+
- 是否应该拆给子 agent。
|
|
1315
|
+
- 子任务划分是否合理。
|
|
1316
|
+
- 子 agent 顺序/依赖是否正确。
|
|
1317
|
+
- 父 agent 是否规划了最终合并和验证。
|
|
1318
|
+
|
|
1319
|
+
#### 5. 失败复盘
|
|
1320
|
+
|
|
1321
|
+
当一个 trace 最终失败时,Plan Quality 可以帮助排查:
|
|
1322
|
+
|
|
1323
|
+
```text
|
|
1324
|
+
失败是因为一开始计划错了?
|
|
1325
|
+
还是计划没问题,但某一步执行崩了?
|
|
1326
|
+
```
|
|
1327
|
+
|
|
1328
|
+
这能减少“所有失败都归因到工具调用”的误判。
|
|
1329
|
+
|
|
1330
|
+
### 不太适用的场景
|
|
1331
|
+
|
|
1332
|
+
#### 1. 单步问答或简单检索
|
|
1333
|
+
|
|
1334
|
+
例如:
|
|
1335
|
+
|
|
1336
|
+
```text
|
|
1337
|
+
“北京今天星期几?”
|
|
1338
|
+
“把这句话翻译成英文”
|
|
1339
|
+
```
|
|
1340
|
+
|
|
1341
|
+
这类任务几乎不需要显式计划,Plan Quality 的增益很小。
|
|
1342
|
+
|
|
1343
|
+
#### 2. trace 中没有可见计划
|
|
1344
|
+
|
|
1345
|
+
DeepEval 官方文档明确说:Plan Quality 会从 agent 的 thinking / reasoning 中抽取 plan;如果 trace 中没有清楚定义或暗示计划的语句,它会默认通过,给 `1`。
|
|
1346
|
+
|
|
1347
|
+
这点非常重要:如果你的 agent 不暴露 planning 信息,Plan Quality 分数可能虚高。
|
|
1348
|
+
|
|
1349
|
+
所以在不暴露推理/计划的框架里,需要谨慎使用。更合理的做法是只评估“可见计划”,例如:
|
|
1350
|
+
|
|
1351
|
+
- agent 明确输出的 Todo。
|
|
1352
|
+
- 对用户可见的行动计划。
|
|
1353
|
+
- tool call 之前的步骤说明。
|
|
1354
|
+
- 子 agent 派发说明。
|
|
1355
|
+
|
|
1356
|
+
不能为了评估而要求模型泄露隐藏推理。
|
|
1357
|
+
|
|
1358
|
+
#### 3. 高探索型任务
|
|
1359
|
+
|
|
1360
|
+
开放研究、创意生成、问题尚不清楚的诊断任务,计划可能需要动态变化。此时不能过度惩罚计划变化,而应区分:
|
|
1361
|
+
|
|
1362
|
+
```text
|
|
1363
|
+
合理重规划:根据新证据调整路线
|
|
1364
|
+
坏计划:一开始就漏掉核心目标或约束
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
### 总结
|
|
1368
|
+
|
|
1369
|
+
Plan Quality 的意义不是替代任务完成度,而是补上一个关键诊断维度:
|
|
1370
|
+
|
|
1371
|
+
```text
|
|
1372
|
+
最终结果之前,agent 有没有先想出一条靠谱路线?
|
|
1373
|
+
```
|
|
1374
|
+
|
|
1375
|
+
它最适合多步、高风险、多工具、多 agent 的场景。对评估改进来说,它能把优化方向从“结果错了”推进到“规划错了还是执行错了”,从而更准确地指导 prompt、skill、工具说明和 agent 编排的改动。
|
|
1376
|
+
|
|
1377
|
+
### 参考链接
|
|
1378
|
+
|
|
1379
|
+
- DeepEval Plan Quality: https://deepeval.com/docs/metrics-plan-quality
|