homegraph 1.1.2 → 1.2.0
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/LICENSE +21 -21
- package/README.md +268 -243
- package/dist/arkts/ohos-api-index.d.ts +15 -0
- package/dist/arkts/ohos-api-index.d.ts.map +1 -0
- package/dist/arkts/ohos-api-index.js +190 -0
- package/dist/arkts/ohos-api-index.js.map +1 -0
- package/dist/arkts/ohos-sdk-input.d.ts +36 -0
- package/dist/arkts/ohos-sdk-input.d.ts.map +1 -0
- package/dist/arkts/ohos-sdk-input.js +214 -0
- package/dist/arkts/ohos-sdk-input.js.map +1 -0
- package/dist/bin/command-supervision.d.ts +12 -0
- package/dist/bin/command-supervision.d.ts.map +1 -0
- package/dist/bin/command-supervision.js +86 -0
- package/dist/bin/command-supervision.js.map +1 -0
- package/dist/bin/homegraph.d.ts +1 -1
- package/dist/bin/homegraph.js +971 -71
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/db/index.d.ts +20 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +39 -0
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +58 -19
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +14 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +314 -143
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +172 -152
- package/dist/directory.d.ts +32 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +88 -5
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.d.ts +2 -0
- package/dist/extraction/arkts-batch-worker.d.ts.map +1 -0
- package/dist/extraction/arkts-batch-worker.js +28 -0
- package/dist/extraction/arkts-batch-worker.js.map +1 -0
- package/dist/extraction/context.d.ts +11 -0
- package/dist/extraction/context.d.ts.map +1 -1
- package/dist/extraction/context.js +20 -0
- package/dist/extraction/context.js.map +1 -1
- package/dist/extraction/index.d.ts +16 -2
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +619 -380
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts-state-decorators.d.ts +13 -0
- package/dist/extraction/languages/arkts-state-decorators.d.ts.map +1 -0
- package/dist/extraction/languages/arkts-state-decorators.js +26 -0
- package/dist/extraction/languages/arkts-state-decorators.js.map +1 -0
- package/dist/extraction/languages/arkts-viewtree.d.ts +4 -2
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.js +21 -6
- package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +98 -2
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1290 -61
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +56 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +198 -1
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/ohos-api-consumer.d.ts +34 -0
- package/dist/extraction/languages/ohos-api-consumer.d.ts.map +1 -0
- package/dist/extraction/languages/ohos-api-consumer.js +283 -0
- package/dist/extraction/languages/ohos-api-consumer.js.map +1 -0
- package/dist/extraction/parse-pool.d.ts +126 -0
- package/dist/extraction/parse-pool.d.ts.map +1 -0
- package/dist/extraction/parse-pool.js +319 -0
- package/dist/extraction/parse-pool.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +17 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +21 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +198 -27
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +76 -17
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -4
- package/dist/index.js.map +1 -1
- package/dist/installer/instructions-template.js +9 -9
- package/dist/installer/targets/shared.d.ts +5 -6
- package/dist/installer/targets/shared.d.ts.map +1 -1
- package/dist/installer/targets/shared.js +5 -6
- package/dist/installer/targets/shared.js.map +1 -1
- package/dist/mcp/daemon-paths.d.ts +30 -3
- package/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/dist/mcp/daemon-paths.js +50 -10
- package/dist/mcp/daemon-paths.js.map +1 -1
- package/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/dist/mcp/daemon-registry.js +7 -3
- package/dist/mcp/daemon-registry.js.map +1 -1
- package/dist/mcp/daemon.d.ts +48 -0
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +196 -32
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/engine.d.ts +17 -0
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +73 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +25 -43
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/liveness-watchdog.js +16 -16
- package/dist/mcp/ppid-watchdog.d.ts +18 -0
- package/dist/mcp/ppid-watchdog.d.ts.map +1 -1
- package/dist/mcp/ppid-watchdog.js +37 -0
- package/dist/mcp/ppid-watchdog.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +25 -0
- package/dist/mcp/query-cache.d.ts.map +1 -0
- package/dist/mcp/query-cache.js +191 -0
- package/dist/mcp/query-cache.js.map +1 -0
- package/dist/mcp/query-pool.d.ts +94 -0
- package/dist/mcp/query-pool.d.ts.map +1 -0
- package/dist/mcp/query-pool.js +297 -0
- package/dist/mcp/query-pool.js.map +1 -0
- package/dist/mcp/query-worker.d.ts +24 -0
- package/dist/mcp/query-worker.d.ts.map +1 -0
- package/dist/mcp/query-worker.js +87 -0
- package/dist/mcp/query-worker.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +5 -7
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +72 -74
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +94 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +877 -71
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-config.d.ts +20 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +42 -2
- package/dist/project-config.js.map +1 -1
- package/dist/reasoning/login.js +1 -1
- package/dist/reasoning/login.js.map +1 -1
- package/dist/reasoning/reasoner.js +32 -32
- package/dist/resolution/c-fnptr-synthesizer.d.ts +0 -28
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +765 -79
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +72 -11
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +32 -0
- package/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/dist/resolution/cooperative-yield.js +42 -0
- package/dist/resolution/cooperative-yield.js.map +1 -0
- package/dist/resolution/index.d.ts +11 -2
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +72 -4
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +22 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +317 -20
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/spec/config.d.ts +39 -0
- package/dist/spec/config.d.ts.map +1 -0
- package/dist/spec/config.js +304 -0
- package/dist/spec/config.js.map +1 -0
- package/dist/spec/db/commit-node.d.ts +23 -0
- package/dist/spec/db/commit-node.d.ts.map +1 -0
- package/dist/spec/db/commit-node.js +62 -0
- package/dist/spec/db/commit-node.js.map +1 -0
- package/dist/spec/db/fragment-node.d.ts +24 -0
- package/dist/spec/db/fragment-node.d.ts.map +1 -0
- package/dist/spec/db/fragment-node.js +128 -0
- package/dist/spec/db/fragment-node.js.map +1 -0
- package/dist/spec/db/fts.d.ts +74 -0
- package/dist/spec/db/fts.d.ts.map +1 -0
- package/dist/spec/db/fts.js +324 -0
- package/dist/spec/db/fts.js.map +1 -0
- package/dist/spec/db/index.d.ts +13 -0
- package/dist/spec/db/index.d.ts.map +1 -0
- package/dist/spec/db/index.js +50 -0
- package/dist/spec/db/index.js.map +1 -0
- package/dist/spec/db/relations.d.ts +55 -0
- package/dist/spec/db/relations.d.ts.map +1 -0
- package/dist/spec/db/relations.js +158 -0
- package/dist/spec/db/relations.js.map +1 -0
- package/dist/spec/db/schema.d.ts +33 -0
- package/dist/spec/db/schema.d.ts.map +1 -0
- package/dist/spec/db/schema.js +119 -0
- package/dist/spec/db/schema.js.map +1 -0
- package/dist/spec/db/schema.sql +117 -0
- package/dist/spec/db/spec-node.d.ts +41 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -0
- package/dist/spec/db/spec-node.js +114 -0
- package/dist/spec/db/spec-node.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +13 -0
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -0
- package/dist/spec/evolve/impact-locator.js +25 -0
- package/dist/spec/evolve/impact-locator.js.map +1 -0
- package/dist/spec/evolve/llm-client.d.ts +50 -0
- package/dist/spec/evolve/llm-client.d.ts.map +1 -0
- package/dist/spec/evolve/llm-client.js +176 -0
- package/dist/spec/evolve/llm-client.js.map +1 -0
- package/dist/spec/evolve/logic-checker.d.ts +12 -0
- package/dist/spec/evolve/logic-checker.d.ts.map +1 -0
- package/dist/spec/evolve/logic-checker.js +24 -0
- package/dist/spec/evolve/logic-checker.js.map +1 -0
- package/dist/spec/evolve/pipeline.d.ts +42 -0
- package/dist/spec/evolve/pipeline.d.ts.map +1 -0
- package/dist/spec/evolve/pipeline.js +567 -0
- package/dist/spec/evolve/pipeline.js.map +1 -0
- package/dist/spec/evolve/spec-rewriter.d.ts +42 -0
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -0
- package/dist/spec/evolve/spec-rewriter.js +230 -0
- package/dist/spec/evolve/spec-rewriter.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +155 -0
- package/dist/spec/graph/queries.d.ts.map +1 -0
- package/dist/spec/graph/queries.js +440 -0
- package/dist/spec/graph/queries.js.map +1 -0
- package/dist/spec/llm/client.d.ts +29 -0
- package/dist/spec/llm/client.d.ts.map +1 -0
- package/dist/spec/llm/client.js +123 -0
- package/dist/spec/llm/client.js.map +1 -0
- package/dist/spec/llm/index.d.ts +3 -0
- package/dist/spec/llm/index.d.ts.map +1 -0
- package/dist/spec/llm/index.js +11 -0
- package/dist/spec/llm/index.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +13 -0
- package/dist/spec/llm/prompts.d.ts.map +1 -0
- package/dist/spec/llm/prompts.js +75 -0
- package/dist/spec/llm/prompts.js.map +1 -0
- package/dist/spec/mining/diff-parser.d.ts +33 -0
- package/dist/spec/mining/diff-parser.d.ts.map +1 -0
- package/dist/spec/mining/diff-parser.js +166 -0
- package/dist/spec/mining/diff-parser.js.map +1 -0
- package/dist/spec/mining/git-scanner.d.ts +103 -0
- package/dist/spec/mining/git-scanner.d.ts.map +1 -0
- package/dist/spec/mining/git-scanner.js +307 -0
- package/dist/spec/mining/git-scanner.js.map +1 -0
- package/dist/spec/mining/pipeline.d.ts +53 -0
- package/dist/spec/mining/pipeline.d.ts.map +1 -0
- package/dist/spec/mining/pipeline.js +178 -0
- package/dist/spec/mining/pipeline.js.map +1 -0
- package/dist/spec/mining/scope-resolver.d.ts +45 -0
- package/dist/spec/mining/scope-resolver.d.ts.map +1 -0
- package/dist/spec/mining/scope-resolver.js +103 -0
- package/dist/spec/mining/scope-resolver.js.map +1 -0
- package/dist/spec/mining/spec-extractor.d.ts +69 -0
- package/dist/spec/mining/spec-extractor.d.ts.map +1 -0
- package/dist/spec/mining/spec-extractor.js +369 -0
- package/dist/spec/mining/spec-extractor.js.map +1 -0
- package/dist/spec/types.d.ts +149 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +15 -0
- package/dist/spec/types.js.map +1 -0
- package/dist/spec/utils.d.ts +167 -0
- package/dist/spec/utils.d.ts.map +1 -0
- package/dist/spec/utils.js +463 -0
- package/dist/spec/utils.js.map +1 -0
- package/dist/sync/worktree.d.ts +9 -0
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +40 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.d.ts +2 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.js +19 -2
- package/dist/ui/shimmer-progress.js.map +1 -1
- package/dist/upgrade/index.js +1 -1
- package/dist/upgrade/index.js.map +1 -1
- package/package.json +58 -57
- package/scripts/add-lang/bench.sh +60 -60
- package/scripts/add-lang/check-grammar.mjs +75 -75
- package/scripts/add-lang/dump-ast.mjs +103 -103
- package/scripts/add-lang/verify-extraction.mjs +70 -70
- package/scripts/agent-eval/ab-adoption.sh +91 -91
- package/scripts/agent-eval/ab-hook.sh +86 -86
- package/scripts/agent-eval/ab-impl.sh +78 -78
- package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
- package/scripts/agent-eval/ab-sufficiency.sh +78 -78
- package/scripts/agent-eval/arms-F.sh +21 -21
- package/scripts/agent-eval/arms-matrix.sh +37 -37
- package/scripts/agent-eval/audit.sh +68 -68
- package/scripts/agent-eval/bench-readme.sh +28 -28
- package/scripts/agent-eval/bench-why-repo.sh +22 -22
- package/scripts/agent-eval/block-read-hook.sh +19 -19
- package/scripts/agent-eval/hook-settings.json +15 -15
- package/scripts/agent-eval/itrun.sh +120 -120
- package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
- package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
- package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
- package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
- package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
- package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
- package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
- package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
- package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
- package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
- package/scripts/agent-eval/offload-eval-setup.sh +24 -24
- package/scripts/agent-eval/offload-eval-styles.sh +71 -71
- package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
- package/scripts/agent-eval/offload-eval.md +76 -76
- package/scripts/agent-eval/parse-arms.mjs +116 -116
- package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
- package/scripts/agent-eval/parse-run.mjs +45 -45
- package/scripts/agent-eval/parse-session.mjs +93 -93
- package/scripts/agent-eval/probe-context.mjs +21 -21
- package/scripts/agent-eval/probe-explore.mjs +40 -40
- package/scripts/agent-eval/probe-node.mjs +20 -20
- package/scripts/agent-eval/probe-sweep.mjs +119 -119
- package/scripts/agent-eval/probe-trace.mjs +20 -20
- package/scripts/agent-eval/redirect-read-hook.sh +38 -38
- package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
- package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
- package/scripts/agent-eval/run-agent.sh +34 -34
- package/scripts/agent-eval/run-all.sh +69 -69
- package/scripts/agent-eval/run-arms.sh +56 -56
- package/scripts/agent-eval/seq-matrix.mjs +137 -137
- package/scripts/build-bundle.sh +118 -118
- package/scripts/exp_boundary_eval/README.md +247 -0
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/_test_mcp_chain.py +78 -0
- package/scripts/exp_boundary_eval/_test_stdin.py +8 -0
- package/scripts/exp_boundary_eval/_utils.py +1116 -0
- package/scripts/exp_boundary_eval/analyze.py +1313 -0
- package/scripts/exp_boundary_eval/data/agents.json +109 -0
- package/scripts/exp_boundary_eval/data/experiments.json +140 -0
- package/scripts/exp_boundary_eval/deveco_arm.py +519 -0
- package/scripts/exp_boundary_eval/run_all.py +378 -0
- package/scripts/exp_boundary_eval/run_one.py +165 -0
- package/scripts/exp_boundary_eval/run_session.py +158 -0
- package/scripts/exp_boundary_eval/setup.py +120 -0
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -0
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -0
- package/scripts/exp_boundary_eval/win_node_launcher.py +24 -0
- package/scripts/extract-release-notes.mjs +130 -130
- package/scripts/local-install.sh +41 -41
- package/scripts/npm-sdk.js +75 -75
- package/scripts/npm-shim.js +268 -246
- package/scripts/ohos-sdk-publish.mjs +133 -0
- package/scripts/pack-npm.sh +119 -119
- package/scripts/prepare-release.mjs +270 -270
- package/scripts/qa_eval/README.md +407 -404
- package/scripts/qa_eval/_test_deveco_probe.py +41 -41
- package/scripts/qa_eval/agent_runner.py +526 -526
- package/scripts/qa_eval/data/.gitignore +4 -4
- package/scripts/qa_eval/data/test-set.jsonl +2 -22
- package/scripts/qa_eval/eval_metrics.py +274 -233
- package/scripts/qa_eval/external_agent.py +976 -671
- package/scripts/qa_eval/llm_config.py +92 -92
- package/scripts/qa_eval/memory_monitor.py +132 -132
- package/scripts/qa_eval/my_answer_accuracy.py +187 -187
- package/scripts/qa_eval/requirements.txt +2 -2
- package/scripts/qa_eval/run_pipeline.py +804 -711
- package/scripts/qa_eval/stats_efficiency.py +279 -279
- package/scripts/qa_eval/stats_scores.py +207 -207
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# test-set.jsonl tracked; reports + other artifacts stay local.
|
|
2
|
-
*
|
|
3
|
-
!.gitignore
|
|
4
|
-
!test-set.jsonl
|
|
1
|
+
# test-set.jsonl tracked; reports + other artifacts stay local.
|
|
2
|
+
*
|
|
3
|
+
!.gitignore
|
|
4
|
+
!test-set.jsonl
|
|
@@ -1,22 +1,2 @@
|
|
|
1
|
-
{"id": "R01", "level0": "camera", "level1": "ColorUtil", "category_l1": "检索", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "getColorString 函数在哪个文件里定义?", "reference_answer": "getColorString 定义在 camera/common/src/main/ets/utils/ColorUtil.ets,是一个 export function。"}
|
|
2
|
-
{"id": "R02", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "检索", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "launchPhotosFromDesktop 函数定义在哪个文件?", "reference_answer": "launchPhotosFromDesktop 定义在 platform/src/main/ets/BenchmarkHub.ets,与 BenchmarkHub 类同文件导出。"}
|
|
3
|
-
{"id": "R03", "level0": "photos", "level1": "BenchmarkPhotosLink", "category_l1": "检索", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "photosBenchmarkEntry 函数在哪里?", "reference_answer": "photosBenchmarkEntry 定义在 photos/common/src/main/ets/benchmark/BenchmarkPhotosLink.ets。"}
|
|
4
|
-
{"id": "R04", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "检索", "category_l2": "类", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub 类在哪个文件?", "reference_answer": "BenchmarkHub 类定义在 platform/src/main/ets/BenchmarkHub.ets。"}
|
|
5
|
-
{"id": "R05", "level0": "photos", "level1": "DeviceInfo", "category_l1": "检索", "category_l2": "类", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub 引用的 Photos DeviceInfo 类在哪个路径?", "reference_answer": "BenchmarkHub 从 @benchmark/photos-common/src/main/ets/default/utils/DeviceInfo.ets 导入 DeviceInfo;类定义在 photos/common/src/main/ets/default/utils/DeviceInfo.ets。"}
|
|
6
|
-
{"id": "R06", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "检索", "category_l2": "常量", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub 里 PHOTOS_BUNDLE 常量的值是什么?", "reference_answer": "PHOTOS_BUNDLE 在 platform/src/main/ets/BenchmarkHub.ets 中定义为字符串 'com.ohos.photos'。"}
|
|
7
|
-
{"id": "R07", "level0": "platform", "level1": "package", "category_l1": "检索", "category_l2": "文件", "difficulty": "简单", "language": "ArkTS", "query": "@benchmark/platform 包对外 re-export 了哪些 BenchmarkHub 相关符号?", "reference_answer": "platform/index.ets 重新导出 BenchmarkHub、launchPhotosFromDesktop、openCameraWithScene,来源均为 ./src/main/ets/BenchmarkHub。"}
|
|
8
|
-
|
|
9
|
-
{"id": "E01", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "解读", "category_l2": "模块/功能/算法", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub 这个模块在整个 benchmark 工程里是干什么的?", "reference_answer": "BenchmarkHub 是跨应用集成 hub,用于 monorepo 模块互联的 homegraph benchmark fixture;文件头注释说明其职责是 cross-app integration hub / monorepo module wiring。"}
|
|
10
|
-
{"id": "E02", "level0": "monorepo", "level1": "workspace", "category_l1": "解读", "category_l2": "模块/功能/算法", "difficulty": "困难", "language": "ArkTS", "query": "这个 benchmark 工程是如何把 photos、camera、scene_board 和 platform 组织成 monorepo 的?", "reference_answer": "根目录 build-profile.json5 声明约 153 个模块;根 package.json 用 npm workspaces 映射 @benchmark/* 包;platform 为 @benchmark/platform,photos/common、camera/common、scene_board 的 windowsceneinterfaces 分别对应 @benchmark/photos-common、@benchmark/camera-common、@benchmark/windowscene-interfaces。各 bridge 文件通过 package import 而非相对路径引用。"}
|
|
11
|
-
{"id": "E03", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "解读", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub.isTabletLayout() 是如何判断平板布局的?", "reference_answer": "BenchmarkHub.isTabletLayout() 直接调用从 photos-common 导入的 PhotosDeviceInfo.isTablet(),自身不包含判断逻辑,而是委托 photos 模块的 DeviceInfo。"}
|
|
12
|
-
{"id": "E04", "level0": "camera", "level1": "ColorUtil", "category_l1": "解读", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "getColorString() 在什么条件下返回 #0A59F7,什么条件下返回 #FF0000?", "reference_answer": "在 ColorUtil.ets 中,若 CameraAppCapability.getInstance().getIsNovaProduct() 为真,或 DeviceInfo.isTablet() 为真,则返回 '#0A59F7';否则返回 '#FF0000'。"}
|
|
13
|
-
{"id": "E05", "level0": "monorepo", "level1": "bridge", "category_l1": "解读", "category_l2": "设计模式/系统架构", "difficulty": "困难", "language": "ArkTS", "query": "BenchmarkPhotosLink、BenchmarkCameraLink、BenchmarkSceneLink 这类 bridge 文件的设计意图是什么?", "reference_answer": "它们是各子应用模块指向 platform hub 的 benchmark 桥接文件,使用 @benchmark/platform 等 package import(非相对路径),刻意制造跨 workspace 包的静态依赖,供 homegraph 索引和跨模块调用链评测。"}
|
|
14
|
-
{"id": "E06", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "解读", "category_l2": "代码片段", "difficulty": "简单", "language": "ArkTS", "query": "launchPhotosFromDesktop() 返回的字符串格式是什么?", "reference_answer": "返回形如 launch:${PHOTOS_BUNDLE}:${layout} 的字符串,其中 layout 由 isTabletLayout() 决定为 'tablet' 或 'phone',PHOTOS_BUNDLE 为 com.ohos.photos。示例:launch:com.ohos.photos:tablet。"}
|
|
15
|
-
{"id": "E07", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "解读", "category_l2": "类", "difficulty": "简单", "language": "ArkTS", "query": "BenchmarkHub.productSuite() 返回什么?", "reference_answer": "返回 string[],按顺序包含 SCENE_BUNDLE、PHOTOS_BUNDLE、CAMERA_BUNDLE,即 com.ohos.sceneboard、com.ohos.photos、com.ohos.camera。"}
|
|
16
|
-
|
|
17
|
-
{"id": "D01", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "依赖", "category_l2": "跨语言依赖", "difficulty": "困难", "language": "ArkTS", "query": "BenchmarkHub.ets 通过 @benchmark 包 import 依赖了哪些其他 workspace 模块?", "reference_answer": "BenchmarkHub.ets 依赖三处 @benchmark 包:@benchmark/photos-common 的 DeviceInfo.ets、@benchmark/camera-common 的 ColorUtil.ets(getColorString)、@benchmark/windowscene-interfaces 的 Context.d.ts。"}
|
|
18
|
-
{"id": "D02", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "依赖", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "openCameraWithScene() 内部调用了 BenchmarkHub 的哪些方法?", "reference_answer": "openCameraWithScene 只调用 BenchmarkHub.cameraAccentColor() 获取 accent 颜色,再拼进返回字符串 open:${CAMERA_BUNDLE}:accent=${color}。"}
|
|
19
|
-
{"id": "D03", "level0": "scene_board", "level1": "BenchmarkSceneLink", "category_l1": "依赖", "category_l2": "模块/功能/算法", "difficulty": "困难", "language": "ArkTS", "query": "sceneBoardBenchmarkEntry() 的跨模块调用链是怎样的?", "reference_answer": "sceneBoardBenchmarkEntry(BenchmarkSceneLink.ets)依次调用 BenchmarkHub.cameraAccentColor()、launchPhotosFromDesktop()、openCameraWithScene();后两者在 platform/BenchmarkHub.ets,cameraAccentColor 又依赖 camera-common 的 getColorString,launchPhotosFromDesktop 依赖 photos-common 的 DeviceInfo.isTablet()。"}
|
|
20
|
-
{"id": "D04", "level0": "photos", "level1": "BenchmarkPhotosLink", "category_l1": "依赖", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "photosBenchmarkEntry() 如何连接到 camera 相关逻辑?", "reference_answer": "photosBenchmarkEntry 从 @benchmark/platform 导入 openCameraWithScene,调用 BenchmarkHub.productSuite() 和 openCameraWithScene(),从而经 platform hub 间接依赖 camera-common 的 getColorString。"}
|
|
21
|
-
{"id": "D05", "level0": "camera", "level1": "BenchmarkCameraLink", "category_l1": "依赖", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "cameraBenchmarkEntry() 如何依赖 photos 模块?", "reference_answer": "cameraBenchmarkEntry 调用 BenchmarkHub.isTabletLayout()(委托 photos-common DeviceInfo.isTablet())和 launchPhotosFromDesktop()(同样依赖 isTabletLayout),并通过 launchPhotosFromDesktop 连到 photos bundle 常量。"}
|
|
22
|
-
{"id": "D06", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "依赖", "category_l2": "类", "difficulty": "困难", "language": "ArkTS", "query": "从 photos 的 DeviceInfo.isTablet() 到 sceneBoardBenchmarkEntry 的完整静态依赖路径是什么?", "reference_answer": "DeviceInfo.isTablet()(photos-common)← BenchmarkHub.isTabletLayout() ← launchPhotosFromDesktop()(platform)← sceneBoardBenchmarkEntry()(BenchmarkSceneLink.ets,scene_board 经 @benchmark/platform 导入)。sceneBoardBenchmarkEntry 还在同一函数内调用 cameraAccentColor 和 openCameraWithScene。"}
|
|
1
|
+
{"id": "R01", "level0": "camera", "level1": "ColorUtil", "category_l1": "检索", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "getColorString 函数在哪个文件里定义?", "reference_answer": "getColorString 定义在 camera/common/src/main/ets/utils/ColorUtil.ets,是一个 export function。"}
|
|
2
|
+
{"id": "R02", "level0": "platform", "level1": "BenchmarkHub", "category_l1": "检索", "category_l2": "函数", "difficulty": "简单", "language": "ArkTS", "query": "launchPhotosFromDesktop 函数定义在哪个文件?", "reference_answer": "launchPhotosFromDesktop 定义在 platform/src/main/ets/BenchmarkHub.ets,与 BenchmarkHub 类同文件导出。"}
|
|
@@ -1,233 +1,274 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
Stage 2 — RAG Answer Accuracy Evaluation (LLM-as-Judge).
|
|
4
|
-
|
|
5
|
-
Reads agent-produced JSONL (query + output_answer + reference_answer),
|
|
6
|
-
strips tool-call blocks, scores 0–1 via MyAnswerAccuracy.
|
|
7
|
-
|
|
8
|
-
Usage:
|
|
9
|
-
export DASHSCOPE_API_KEY="sk-..."
|
|
10
|
-
python scripts/qa_eval/eval_metrics.py \\
|
|
11
|
-
-i scripts/qa_eval/log/result-with-builtin.jsonl \\
|
|
12
|
-
-o scripts/qa_eval/log/result-with-builtin-scored.jsonl \\
|
|
13
|
-
-w 2
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
import argparse
|
|
19
|
-
import asyncio
|
|
20
|
-
import json
|
|
21
|
-
import logging
|
|
22
|
-
import os
|
|
23
|
-
import statistics
|
|
24
|
-
import sys
|
|
25
|
-
import threading
|
|
26
|
-
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
27
|
-
from pathlib import Path
|
|
28
|
-
|
|
29
|
-
from tqdm import tqdm
|
|
30
|
-
|
|
31
|
-
_SCRIPT_DIR = Path(__file__).resolve().parent
|
|
32
|
-
LOG_DIR = _SCRIPT_DIR / "log"
|
|
33
|
-
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
|
34
|
-
|
|
35
|
-
if str(_SCRIPT_DIR) not in sys.path:
|
|
36
|
-
sys.path.insert(0, str(_SCRIPT_DIR))
|
|
37
|
-
|
|
38
|
-
from my_answer_accuracy import MyAnswerAccuracy # noqa: E402
|
|
39
|
-
from llm_config import PROVIDER_DASHSCOPE, PROVIDER_ZHIPU, provider_help, resolve_llm_config # noqa: E402
|
|
40
|
-
|
|
41
|
-
os.environ.setdefault("NO_PROXY", "localhost,127.0.0.1")
|
|
42
|
-
|
|
43
|
-
logging.basicConfig(
|
|
44
|
-
level=logging.INFO,
|
|
45
|
-
format="%(asctime)s - %(levelname)s - %(message)s",
|
|
46
|
-
handlers=[
|
|
47
|
-
logging.FileHandler(LOG_DIR / "eval_metrics.log"),
|
|
48
|
-
logging.StreamHandler(),
|
|
49
|
-
],
|
|
50
|
-
)
|
|
51
|
-
logger = logging.getLogger(__name__)
|
|
52
|
-
|
|
53
|
-
file_write_lock = threading.Lock()
|
|
54
|
-
|
|
55
|
-
DEFAULT_INPUT = LOG_DIR / "result-with-builtin.jsonl"
|
|
56
|
-
DEFAULT_OUTPUT = LOG_DIR / "result-with-builtin-scored.jsonl"
|
|
57
|
-
DEFAULT_MODEL = "qwen3-235b-a22b-instruct-2507"
|
|
58
|
-
DEFAULT_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
59
|
-
DEFAULT_API_KEY_ENV = "DASHSCOPE_API_KEY"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
class RAGEvaluator:
|
|
63
|
-
"""Answer accuracy judge with concurrent processing."""
|
|
64
|
-
|
|
65
|
-
def __init__(
|
|
66
|
-
self,
|
|
67
|
-
llm_model: str,
|
|
68
|
-
*,
|
|
69
|
-
api_key: str,
|
|
70
|
-
base_url: str,
|
|
71
|
-
extra_body: dict | None = None,
|
|
72
|
-
) -> None:
|
|
73
|
-
self.scorer = MyAnswerAccuracy.create(
|
|
74
|
-
api_key=api_key,
|
|
75
|
-
base_url=base_url,
|
|
76
|
-
model=llm_model,
|
|
77
|
-
extra_body=extra_body,
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
async def evaluate_answer_accuracy_single(self, sample_data: dict) -> dict:
|
|
81
|
-
return await self.scorer.evaluate_answer_accuracy_single(sample_data)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Stage 2 — RAG Answer Accuracy Evaluation (LLM-as-Judge).
|
|
4
|
+
|
|
5
|
+
Reads agent-produced JSONL (query + output_answer + reference_answer),
|
|
6
|
+
strips tool-call blocks, scores 0–1 via MyAnswerAccuracy.
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
export DASHSCOPE_API_KEY="sk-..."
|
|
10
|
+
python scripts/qa_eval/eval_metrics.py \\
|
|
11
|
+
-i scripts/qa_eval/log/result-with-builtin.jsonl \\
|
|
12
|
+
-o scripts/qa_eval/log/result-with-builtin-scored.jsonl \\
|
|
13
|
+
-w 2
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import asyncio
|
|
20
|
+
import json
|
|
21
|
+
import logging
|
|
22
|
+
import os
|
|
23
|
+
import statistics
|
|
24
|
+
import sys
|
|
25
|
+
import threading
|
|
26
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
|
|
29
|
+
from tqdm import tqdm
|
|
30
|
+
|
|
31
|
+
_SCRIPT_DIR = Path(__file__).resolve().parent
|
|
32
|
+
LOG_DIR = _SCRIPT_DIR / "log"
|
|
33
|
+
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
|
34
|
+
|
|
35
|
+
if str(_SCRIPT_DIR) not in sys.path:
|
|
36
|
+
sys.path.insert(0, str(_SCRIPT_DIR))
|
|
37
|
+
|
|
38
|
+
from my_answer_accuracy import MyAnswerAccuracy # noqa: E402
|
|
39
|
+
from llm_config import PROVIDER_DASHSCOPE, PROVIDER_ZHIPU, provider_help, resolve_llm_config # noqa: E402
|
|
40
|
+
|
|
41
|
+
os.environ.setdefault("NO_PROXY", "localhost,127.0.0.1")
|
|
42
|
+
|
|
43
|
+
logging.basicConfig(
|
|
44
|
+
level=logging.INFO,
|
|
45
|
+
format="%(asctime)s - %(levelname)s - %(message)s",
|
|
46
|
+
handlers=[
|
|
47
|
+
logging.FileHandler(LOG_DIR / "eval_metrics.log"),
|
|
48
|
+
logging.StreamHandler(),
|
|
49
|
+
],
|
|
50
|
+
)
|
|
51
|
+
logger = logging.getLogger(__name__)
|
|
52
|
+
|
|
53
|
+
file_write_lock = threading.Lock()
|
|
54
|
+
|
|
55
|
+
DEFAULT_INPUT = LOG_DIR / "result-with-builtin.jsonl"
|
|
56
|
+
DEFAULT_OUTPUT = LOG_DIR / "result-with-builtin-scored.jsonl"
|
|
57
|
+
DEFAULT_MODEL = "qwen3-235b-a22b-instruct-2507"
|
|
58
|
+
DEFAULT_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
59
|
+
DEFAULT_API_KEY_ENV = "DASHSCOPE_API_KEY"
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class RAGEvaluator:
|
|
63
|
+
"""Answer accuracy judge with concurrent processing."""
|
|
64
|
+
|
|
65
|
+
def __init__(
|
|
66
|
+
self,
|
|
67
|
+
llm_model: str,
|
|
68
|
+
*,
|
|
69
|
+
api_key: str,
|
|
70
|
+
base_url: str,
|
|
71
|
+
extra_body: dict | None = None,
|
|
72
|
+
) -> None:
|
|
73
|
+
self.scorer = MyAnswerAccuracy.create(
|
|
74
|
+
api_key=api_key,
|
|
75
|
+
base_url=base_url,
|
|
76
|
+
model=llm_model,
|
|
77
|
+
extra_body=extra_body,
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
async def evaluate_answer_accuracy_single(self, sample_data: dict) -> dict:
|
|
81
|
+
return await self.scorer.evaluate_answer_accuracy_single(sample_data)
|
|
82
|
+
|
|
83
|
+
async def close(self) -> None:
|
|
84
|
+
await self.scorer.client.close()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
async def evaluate_all_async(evaluator: RAGEvaluator, items: list[dict]) -> list[dict]:
|
|
88
|
+
processed: list[dict] = []
|
|
89
|
+
try:
|
|
90
|
+
for item in items:
|
|
91
|
+
processed.append(await evaluator.evaluate_answer_accuracy_single(item))
|
|
92
|
+
finally:
|
|
93
|
+
await evaluator.close()
|
|
94
|
+
return processed
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def process_single_item_sync(
|
|
98
|
+
*,
|
|
99
|
+
llm_model: str,
|
|
100
|
+
api_key: str,
|
|
101
|
+
base_url: str,
|
|
102
|
+
extra_body: dict | None,
|
|
103
|
+
item: dict,
|
|
104
|
+
) -> dict:
|
|
105
|
+
loop = asyncio.new_event_loop()
|
|
106
|
+
asyncio.set_event_loop(loop)
|
|
107
|
+
evaluator = RAGEvaluator(
|
|
108
|
+
llm_model,
|
|
109
|
+
api_key=api_key,
|
|
110
|
+
base_url=base_url,
|
|
111
|
+
extra_body=extra_body,
|
|
112
|
+
)
|
|
113
|
+
try:
|
|
114
|
+
return loop.run_until_complete(evaluator.evaluate_answer_accuracy_single(item))
|
|
115
|
+
finally:
|
|
116
|
+
loop.run_until_complete(evaluator.close())
|
|
117
|
+
loop.close()
|
|
118
|
+
asyncio.set_event_loop(None)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def load_jsonl(path: Path) -> list[dict]:
|
|
122
|
+
items: list[dict] = []
|
|
123
|
+
with path.open("r", encoding="utf-8") as f:
|
|
124
|
+
for line_no, line in enumerate(f, 1):
|
|
125
|
+
line = line.strip()
|
|
126
|
+
if not line:
|
|
127
|
+
continue
|
|
128
|
+
try:
|
|
129
|
+
items.append(json.loads(line))
|
|
130
|
+
except json.JSONDecodeError as e:
|
|
131
|
+
logger.error("第 %s 行 JSON 解析失败: %s", line_no, e)
|
|
132
|
+
return items
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def resolve_api_key(env_name: str) -> str | None:
|
|
136
|
+
key = os.environ.get(env_name, "").strip()
|
|
137
|
+
if key:
|
|
138
|
+
return key
|
|
139
|
+
fallback = os.environ.get("OPENAI_API_KEY", "").strip()
|
|
140
|
+
return fallback or None
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def main() -> int:
|
|
144
|
+
parser = argparse.ArgumentParser(description="RAG Answer Accuracy Evaluation (LLM-as-Judge)")
|
|
145
|
+
parser.add_argument("--input", "-i", type=str, default=str(DEFAULT_INPUT), help="Agent 产出的 JSONL")
|
|
146
|
+
parser.add_argument("--output", "-o", type=str, default=str(DEFAULT_OUTPUT), help="打分后的 JSONL")
|
|
147
|
+
parser.add_argument("--workers", "-w", type=int, default=1, help="并发线程数")
|
|
148
|
+
parser.add_argument(
|
|
149
|
+
"--provider",
|
|
150
|
+
choices=[PROVIDER_DASHSCOPE, PROVIDER_ZHIPU],
|
|
151
|
+
default=None,
|
|
152
|
+
help=provider_help(),
|
|
153
|
+
)
|
|
154
|
+
parser.add_argument("--model", "-m", type=str, default=None, help="Judge 模型(默认随 provider)")
|
|
155
|
+
parser.add_argument("--base-url", type=str, default=None, help="OpenAI 兼容 API 端点(默认随 provider)")
|
|
156
|
+
args = parser.parse_args()
|
|
157
|
+
|
|
158
|
+
input_file = Path(args.input)
|
|
159
|
+
output_file = Path(args.output)
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
llm = resolve_llm_config(provider=args.provider, model=args.model, base_url=args.base_url)
|
|
163
|
+
except RuntimeError as e:
|
|
164
|
+
print(f"错误: {e}", file=sys.stderr)
|
|
165
|
+
return 1
|
|
166
|
+
|
|
167
|
+
print(f"输入文件: {input_file}")
|
|
168
|
+
print(f"输出文件: {output_file}")
|
|
169
|
+
print(f"并发线程数: {args.workers}")
|
|
170
|
+
print(f"LLM provider: {llm.provider}")
|
|
171
|
+
print(f"评估模型: {llm.model}")
|
|
172
|
+
|
|
173
|
+
if not input_file.is_file():
|
|
174
|
+
print(f"错误: 输入文件 {input_file} 不存在")
|
|
175
|
+
return 1
|
|
176
|
+
|
|
177
|
+
api_key = llm.api_key
|
|
178
|
+
|
|
179
|
+
all_items = load_jsonl(input_file)
|
|
180
|
+
total_items = len(all_items)
|
|
181
|
+
print(f"读取到 {total_items} 个样本")
|
|
182
|
+
|
|
183
|
+
if total_items == 0:
|
|
184
|
+
print("没有找到有效的样本数据")
|
|
185
|
+
return 1
|
|
186
|
+
|
|
187
|
+
for i, item in enumerate(all_items, 1):
|
|
188
|
+
if not str(item.get("query", "")).strip():
|
|
189
|
+
print(f"错误: 第 {i} 条缺少 query")
|
|
190
|
+
return 1
|
|
191
|
+
if not str(item.get("reference_answer", "")).strip():
|
|
192
|
+
print(f"错误: 第 {i} 条缺少 reference_answer")
|
|
193
|
+
return 1
|
|
194
|
+
if not str(item.get("output_answer", "")).strip():
|
|
195
|
+
logger.warning("第 %s 条 (%s) output_answer 为空,Judge 可能得 0 分", i, item.get("id", "?"))
|
|
196
|
+
|
|
197
|
+
output_file.parent.mkdir(parents=True, exist_ok=True)
|
|
198
|
+
output_file.write_text("", encoding="utf-8")
|
|
199
|
+
|
|
200
|
+
evaluator = RAGEvaluator(
|
|
201
|
+
llm.model,
|
|
202
|
+
api_key=api_key,
|
|
203
|
+
base_url=llm.base_url,
|
|
204
|
+
extra_body=llm.extra_body,
|
|
205
|
+
)
|
|
206
|
+
print("初始化 Judge 完成")
|
|
207
|
+
|
|
208
|
+
processed_items: list[dict] = []
|
|
209
|
+
results_lock = threading.Lock()
|
|
210
|
+
|
|
211
|
+
if args.workers <= 1:
|
|
212
|
+
processed_items = asyncio.run(evaluate_all_async(evaluator, all_items))
|
|
213
|
+
with output_file.open("w", encoding="utf-8") as writer:
|
|
214
|
+
for row in processed_items:
|
|
215
|
+
writer.write(json.dumps(row, ensure_ascii=False) + "\n")
|
|
216
|
+
else:
|
|
217
|
+
with ThreadPoolExecutor(max_workers=max(1, args.workers)) as executor:
|
|
218
|
+
futures = {
|
|
219
|
+
executor.submit(
|
|
220
|
+
process_single_item_sync,
|
|
221
|
+
llm_model=llm.model,
|
|
222
|
+
api_key=api_key,
|
|
223
|
+
base_url=llm.base_url,
|
|
224
|
+
extra_body=llm.extra_body,
|
|
225
|
+
item=item,
|
|
226
|
+
): item
|
|
227
|
+
for item in all_items
|
|
228
|
+
}
|
|
229
|
+
for future in tqdm(as_completed(futures), total=len(all_items), desc="评估答案准确性"):
|
|
230
|
+
try:
|
|
231
|
+
processed_item = future.result()
|
|
232
|
+
with results_lock:
|
|
233
|
+
processed_items.append(processed_item)
|
|
234
|
+
if len(processed_items) % 5 == 0:
|
|
235
|
+
with file_write_lock:
|
|
236
|
+
with output_file.open("a", encoding="utf-8") as writer:
|
|
237
|
+
for row in processed_items[-5:]:
|
|
238
|
+
writer.write(json.dumps(row, ensure_ascii=False) + "\n")
|
|
239
|
+
except Exception as e:
|
|
240
|
+
logger.error("样本处理任务异常: %s", e)
|
|
241
|
+
|
|
242
|
+
remaining = len(processed_items) % 5
|
|
243
|
+
if remaining:
|
|
244
|
+
with file_write_lock:
|
|
245
|
+
with output_file.open("a", encoding="utf-8") as writer:
|
|
246
|
+
for row in processed_items[-remaining:]:
|
|
247
|
+
writer.write(json.dumps(row, ensure_ascii=False) + "\n")
|
|
248
|
+
|
|
249
|
+
if processed_items:
|
|
250
|
+
successful = [x for x in processed_items if x.get("evaluation_status") == "success"]
|
|
251
|
+
scores = [float(x.get("answer_accuracy_score", 0.0)) for x in processed_items]
|
|
252
|
+
print("\n评估完成!")
|
|
253
|
+
print(f"总样本数: {total_items}")
|
|
254
|
+
print(f"成功评估: {len(successful)}")
|
|
255
|
+
print(f"失败评估: {total_items - len(successful)}")
|
|
256
|
+
if successful:
|
|
257
|
+
ok_scores = [float(x["answer_accuracy_score"]) for x in successful]
|
|
258
|
+
print(f"平均答案准确性得分: {statistics.mean(ok_scores):.4f}")
|
|
259
|
+
print(f"最高得分: {max(ok_scores):.4f}")
|
|
260
|
+
print(f"最低得分: {min(ok_scores):.4f}")
|
|
261
|
+
print(f"\n结果已写入: {output_file}")
|
|
262
|
+
else:
|
|
263
|
+
print("没有成功处理任何样本")
|
|
264
|
+
return 1
|
|
265
|
+
|
|
266
|
+
return 0
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
if __name__ == "__main__":
|
|
270
|
+
try:
|
|
271
|
+
raise SystemExit(main())
|
|
272
|
+
except KeyboardInterrupt:
|
|
273
|
+
print("\n用户中断了程序执行")
|
|
274
|
+
raise SystemExit(130)
|