homegraph 1.1.2 → 1.1.3

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.
Files changed (175) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +243 -243
  3. package/dist/bin/homegraph.js +371 -9
  4. package/dist/bin/homegraph.js.map +1 -1
  5. package/dist/db/migrations.js +18 -18
  6. package/dist/db/queries.js +140 -140
  7. package/dist/db/schema.sql +152 -152
  8. package/dist/directory.js +5 -5
  9. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  10. package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
  11. package/dist/installer/instructions-template.js +9 -9
  12. package/dist/installer/targets/shared.d.ts +5 -6
  13. package/dist/installer/targets/shared.d.ts.map +1 -1
  14. package/dist/installer/targets/shared.js +5 -6
  15. package/dist/installer/targets/shared.js.map +1 -1
  16. package/dist/mcp/liveness-watchdog.js +16 -16
  17. package/dist/mcp/server-instructions.js +69 -69
  18. package/dist/mcp/tools.d.ts +17 -4
  19. package/dist/mcp/tools.d.ts.map +1 -1
  20. package/dist/mcp/tools.js +192 -22
  21. package/dist/mcp/tools.js.map +1 -1
  22. package/dist/reasoning/reasoner.js +32 -32
  23. package/dist/spec/config.d.ts +43 -0
  24. package/dist/spec/config.d.ts.map +1 -0
  25. package/dist/spec/config.js +275 -0
  26. package/dist/spec/config.js.map +1 -0
  27. package/dist/spec/db/commit-node.d.ts +23 -0
  28. package/dist/spec/db/commit-node.d.ts.map +1 -0
  29. package/dist/spec/db/commit-node.js +62 -0
  30. package/dist/spec/db/commit-node.js.map +1 -0
  31. package/dist/spec/db/fragment-node.d.ts +23 -0
  32. package/dist/spec/db/fragment-node.d.ts.map +1 -0
  33. package/dist/spec/db/fragment-node.js +120 -0
  34. package/dist/spec/db/fragment-node.js.map +1 -0
  35. package/dist/spec/db/fts.d.ts +60 -0
  36. package/dist/spec/db/fts.d.ts.map +1 -0
  37. package/dist/spec/db/fts.js +285 -0
  38. package/dist/spec/db/fts.js.map +1 -0
  39. package/dist/spec/db/index.d.ts +13 -0
  40. package/dist/spec/db/index.d.ts.map +1 -0
  41. package/dist/spec/db/index.js +50 -0
  42. package/dist/spec/db/index.js.map +1 -0
  43. package/dist/spec/db/relations.d.ts +55 -0
  44. package/dist/spec/db/relations.d.ts.map +1 -0
  45. package/dist/spec/db/relations.js +158 -0
  46. package/dist/spec/db/relations.js.map +1 -0
  47. package/dist/spec/db/schema.d.ts +30 -0
  48. package/dist/spec/db/schema.d.ts.map +1 -0
  49. package/dist/spec/db/schema.js +87 -0
  50. package/dist/spec/db/schema.js.map +1 -0
  51. package/dist/spec/db/schema.sql +107 -0
  52. package/dist/spec/db/spec-node.d.ts +41 -0
  53. package/dist/spec/db/spec-node.d.ts.map +1 -0
  54. package/dist/spec/db/spec-node.js +114 -0
  55. package/dist/spec/db/spec-node.js.map +1 -0
  56. package/dist/spec/evolve/impact-locator.d.ts +13 -0
  57. package/dist/spec/evolve/impact-locator.d.ts.map +1 -0
  58. package/dist/spec/evolve/impact-locator.js +25 -0
  59. package/dist/spec/evolve/impact-locator.js.map +1 -0
  60. package/dist/spec/evolve/llm-client.d.ts +50 -0
  61. package/dist/spec/evolve/llm-client.d.ts.map +1 -0
  62. package/dist/spec/evolve/llm-client.js +176 -0
  63. package/dist/spec/evolve/llm-client.js.map +1 -0
  64. package/dist/spec/evolve/logic-checker.d.ts +12 -0
  65. package/dist/spec/evolve/logic-checker.d.ts.map +1 -0
  66. package/dist/spec/evolve/logic-checker.js +48 -0
  67. package/dist/spec/evolve/logic-checker.js.map +1 -0
  68. package/dist/spec/evolve/pipeline.d.ts +40 -0
  69. package/dist/spec/evolve/pipeline.d.ts.map +1 -0
  70. package/dist/spec/evolve/pipeline.js +314 -0
  71. package/dist/spec/evolve/pipeline.js.map +1 -0
  72. package/dist/spec/evolve/spec-rewriter.d.ts +42 -0
  73. package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -0
  74. package/dist/spec/evolve/spec-rewriter.js +254 -0
  75. package/dist/spec/evolve/spec-rewriter.js.map +1 -0
  76. package/dist/spec/graph/queries.d.ts +58 -0
  77. package/dist/spec/graph/queries.d.ts.map +1 -0
  78. package/dist/spec/graph/queries.js +215 -0
  79. package/dist/spec/graph/queries.js.map +1 -0
  80. package/dist/spec/mining/diff-parser.d.ts +33 -0
  81. package/dist/spec/mining/diff-parser.d.ts.map +1 -0
  82. package/dist/spec/mining/diff-parser.js +166 -0
  83. package/dist/spec/mining/diff-parser.js.map +1 -0
  84. package/dist/spec/mining/git-scanner.d.ts +91 -0
  85. package/dist/spec/mining/git-scanner.d.ts.map +1 -0
  86. package/dist/spec/mining/git-scanner.js +266 -0
  87. package/dist/spec/mining/git-scanner.js.map +1 -0
  88. package/dist/spec/mining/pipeline.d.ts +53 -0
  89. package/dist/spec/mining/pipeline.d.ts.map +1 -0
  90. package/dist/spec/mining/pipeline.js +165 -0
  91. package/dist/spec/mining/pipeline.js.map +1 -0
  92. package/dist/spec/mining/scope-resolver.d.ts +45 -0
  93. package/dist/spec/mining/scope-resolver.d.ts.map +1 -0
  94. package/dist/spec/mining/scope-resolver.js +103 -0
  95. package/dist/spec/mining/scope-resolver.js.map +1 -0
  96. package/dist/spec/mining/spec-extractor.d.ts +69 -0
  97. package/dist/spec/mining/spec-extractor.d.ts.map +1 -0
  98. package/dist/spec/mining/spec-extractor.js +369 -0
  99. package/dist/spec/mining/spec-extractor.js.map +1 -0
  100. package/dist/spec/types.d.ts +149 -0
  101. package/dist/spec/types.d.ts.map +1 -0
  102. package/dist/spec/types.js +15 -0
  103. package/dist/spec/types.js.map +1 -0
  104. package/dist/spec/utils.d.ts +166 -0
  105. package/dist/spec/utils.d.ts.map +1 -0
  106. package/dist/spec/utils.js +461 -0
  107. package/dist/spec/utils.js.map +1 -0
  108. package/package.json +58 -57
  109. package/scripts/add-lang/bench.sh +60 -60
  110. package/scripts/add-lang/check-grammar.mjs +75 -75
  111. package/scripts/add-lang/dump-ast.mjs +103 -103
  112. package/scripts/add-lang/verify-extraction.mjs +70 -70
  113. package/scripts/agent-eval/ab-adoption.sh +91 -91
  114. package/scripts/agent-eval/ab-hook.sh +86 -86
  115. package/scripts/agent-eval/ab-impl.sh +78 -78
  116. package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
  117. package/scripts/agent-eval/ab-sufficiency.sh +78 -78
  118. package/scripts/agent-eval/arms-F.sh +21 -21
  119. package/scripts/agent-eval/arms-matrix.sh +37 -37
  120. package/scripts/agent-eval/audit.sh +68 -68
  121. package/scripts/agent-eval/bench-readme.sh +28 -28
  122. package/scripts/agent-eval/bench-why-repo.sh +22 -22
  123. package/scripts/agent-eval/block-read-hook.sh +19 -19
  124. package/scripts/agent-eval/hook-settings.json +15 -15
  125. package/scripts/agent-eval/itrun.sh +120 -120
  126. package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
  127. package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
  128. package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
  129. package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
  130. package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
  131. package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
  132. package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
  133. package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
  134. package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
  135. package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
  136. package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
  137. package/scripts/agent-eval/offload-eval-setup.sh +24 -24
  138. package/scripts/agent-eval/offload-eval-styles.sh +71 -71
  139. package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
  140. package/scripts/agent-eval/offload-eval.md +76 -76
  141. package/scripts/agent-eval/parse-arms.mjs +116 -116
  142. package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
  143. package/scripts/agent-eval/parse-run.mjs +45 -45
  144. package/scripts/agent-eval/parse-session.mjs +93 -93
  145. package/scripts/agent-eval/probe-context.mjs +21 -21
  146. package/scripts/agent-eval/probe-explore.mjs +40 -40
  147. package/scripts/agent-eval/probe-node.mjs +20 -20
  148. package/scripts/agent-eval/probe-sweep.mjs +119 -119
  149. package/scripts/agent-eval/probe-trace.mjs +20 -20
  150. package/scripts/agent-eval/redirect-read-hook.sh +38 -38
  151. package/scripts/agent-eval/run-agent.sh +34 -34
  152. package/scripts/agent-eval/run-all.sh +69 -69
  153. package/scripts/agent-eval/run-arms.sh +56 -56
  154. package/scripts/agent-eval/seq-matrix.mjs +137 -137
  155. package/scripts/build-bundle.sh +118 -118
  156. package/scripts/extract-release-notes.mjs +130 -130
  157. package/scripts/local-install.sh +41 -41
  158. package/scripts/npm-sdk.js +75 -75
  159. package/scripts/npm-shim.js +246 -246
  160. package/scripts/pack-npm.sh +119 -119
  161. package/scripts/prepare-release.mjs +270 -270
  162. package/scripts/qa_eval/README.md +407 -404
  163. package/scripts/qa_eval/_test_deveco_probe.py +41 -41
  164. package/scripts/qa_eval/agent_runner.py +526 -526
  165. package/scripts/qa_eval/data/.gitignore +4 -4
  166. package/scripts/qa_eval/data/test-set.jsonl +2 -22
  167. package/scripts/qa_eval/eval_metrics.py +274 -233
  168. package/scripts/qa_eval/external_agent.py +976 -671
  169. package/scripts/qa_eval/llm_config.py +92 -92
  170. package/scripts/qa_eval/memory_monitor.py +132 -132
  171. package/scripts/qa_eval/my_answer_accuracy.py +187 -187
  172. package/scripts/qa_eval/requirements.txt +2 -2
  173. package/scripts/qa_eval/run_pipeline.py +804 -711
  174. package/scripts/qa_eval/stats_efficiency.py +279 -279
  175. package/scripts/qa_eval/stats_scores.py +207 -207
@@ -1,404 +1,407 @@
1
- # QA Eval — 四段式 A/B 评测流水线
2
-
3
- 内置多轮 Agent + Judge + 统计 + 报告,对齐 CodeGenie / Trae 评测框架:**Agent 跑题 → Judge 打分 → 分数统计 → 效率统计 → A/B 对比**。
4
-
5
- - **国内可用**:Agent / Judge 均走 OpenAI 兼容接口,支持 **DashScope Qwen** **智谱 GLM**
6
- - **不依赖** Claude / ragas / langchain
7
- - **被测仓库**:运行时用 `--repo` / `-r` 指定,无默认路径
8
- ## 目录
9
-
10
- ```
11
- scripts/qa_eval/
12
- ├── agent_runner.py # Stage 1:内置多轮 Agent(with / without 两路)
13
- ├── my_answer_accuracy.py # Judge 指标(双 prompt 0–5 归一化)
14
- ├── eval_metrics.py # Stage 2:对 JSONL 批量打分
15
- ├── stats_scores.py # Stage 3:answer_accuracy_score 汇总
16
- ├── stats_efficiency.py # Stage 4:解析 Agent 日志(首响应/轮次/耗时/Token/内存)
17
- ├── memory_monitor.py # 进程树 RSS 采样(Linux /proc)
18
- ├── external_agent.py # Claude Code / DevEco Code 外部 Agent 跑题
19
- ├── run_pipeline.py # 编排 Stage 1–4 + A/B 报告
20
- ├── requirements.txt
21
- ├── data/ # 仅测试集 + 报告(可入库)
22
- │ ├── test-set.jsonl
23
- │ └── report-{host}.txt
24
- └── log/ # 流水线中间产物(不入库)
25
- ├── result-with-{host}.jsonl
26
- ├── result-without-{host}.jsonl
27
- ├── result-*-{host}-scored.jsonl
28
- ├── agent-with-{host}.log
29
- ├── agent-without-{host}.log
30
- └── eval_metrics.log
31
- ```
32
-
33
- **Git 入库规则**
34
-
35
- | 路径 | 是否提交 |
36
- |------|----------|
37
- | `scripts/qa_eval/*.py`、`README.md`、`requirements.txt` | 是 |
38
- | `data/test-set.jsonl` | 是(测试集) |
39
- | `data/report*.txt` | 否(报告,留在 data/ 但不入库) |
40
- | `log/` 下全部 | |
41
- | `__pycache__/` | |
42
-
43
- ## 整体流程
44
-
45
- ```
46
- test-set.jsonl
47
-
48
- Stage 1 agent_runner.py(run_pipeline ab 内置)
49
- with : HomegraphQuery + ReadFile
50
- without : SearchText(rg) + FindFiles + ReadFile
51
- 产出: log/result-*-{host}.jsonl + log/agent-*-{host}.log
52
-
53
- Stage 2 eval_metrics.py → log/result-*-{host}-scored.jsonl
54
-
55
- Stage 3 stats_scores.py → 准确率汇总(并入 report-{host}.txt)
56
- Stage 4 stats_efficiency.py → 效率汇总(终端 + report-{host}.txt)
57
-
58
- run_pipeline.py ab → data/report-{host}.txt
59
- ```
60
-
61
- **A/B 唯一变量**:Agent 是否可用 homegraph。两臂使用**同一模型、同一 max_turns**;without **不是裸 LLM**,仍是多轮 grep/read Agent。
62
-
63
- ## 快速开始
64
-
65
- ```bash
66
- pip install -r scripts/qa_eval/requirements.txt \
67
- -i https://pypi.tuna.tsinghua.edu.cn/simple
68
-
69
- export DASHSCOPE_API_KEY="sk-xxxxxxxx"
70
- # 或使用智谱(Key 格式 id.secret,不要加 sk- 前缀):
71
- # export ZHIPU_API_KEY="xxxxxxxx.yyyyyyyy"
72
-
73
- cd /path/to/homegraph && npm run build
74
- node dist/bin/homegraph.js sync /path/to/your/repo
75
-
76
- python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo
77
- # 智谱显式指定:
78
- # python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu
79
- # python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu --model glm-4-flash```
80
-
81
- ### Agent 宿主(`--agent-host`)
82
-
83
- | 宿主 | 说明 | Agent 前置条件 | 报告文件 |
84
- |------|------|----------------|----------|
85
- | `builtin`(默认) | Python 内置多轮 Agent + 智谱/DashScope | `ZHIPU_API_KEY` 或 `DASHSCOPE_API_KEY` | `report-builtin.txt` |
86
- | `claude-code` | **Claude Code CLI**(`claude -p` + MCP) | `claude login` 已登录 | `report-claude.txt` |
87
- | `deveco-code` | **DevEco Code / opencode CLI** | `deveco` 在 PATH,且 **DevEco 自己的** provider 已登录(见下) | `report-deveco.txt` |
88
-
89
- **注意**:`--provider zhipu` 只影响 **builtin Agent** 和 **Judge**;`deveco-code` / `claude-code` 使用各自 CLI 的账号与凭证,不会读取 `ZHIPU_API_KEY`。
90
-
91
- DevEco 首次使用需配置模型(凭证保存在用户目录,**不是** DEVECO_HOME):
92
-
93
- ```bash
94
- deveco providers login # 选 Zhipu AI,输入 API Key
95
- # 凭证目录(Windows): C:\Users\<你>\.config\deveco
96
- ```
97
-
98
- TUI 若提示 **DEVECO_HOME**,那是 DevEco **Studio** 安装路径(需 6.1+),仅编译/推包需要;**跑 qa_eval 可跳过**。你当前 Studio 为 5.1,填 `C:\Program Files\Huawei\DevEco Studio` 会校验失败,属正常。
99
-
100
- homegraph MCP 写在**被测仓库**的 `.deveco/deveco.jsonc`;智谱 Key 仍读 `~/.config/deveco`。
101
-
102
- **Judge 打分**(Stage 2)三种宿主共用,仍需 `ZHIPU_API_KEY` 或 `DASHSCOPE_API_KEY`(与 `--provider` 一致)。
103
-
104
- #### 怎么跑
105
-
106
- ```bash
107
- cd /path/to/homegraph
108
- npm run build
109
- node dist/bin/homegraph.js sync /path/to/your/repo
110
-
111
- # 内置 Agent(智谱)
112
- export ZHIPU_API_KEY="your-id.your-secret"
113
- python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu --agent-host builtin
114
- # → report-builtin.txt
115
-
116
- # Claude Code(Agent 用 Claude 自己的账号,Judge 仍用上面的 Key)
117
- which claude && claude login # 必须先登录,否则每题返回 Not logged in
118
- python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu --agent-host claude-code
119
- # → report-claude.txt
120
-
121
- # DevEco Code(Agent DevEco 自己的 provider,Judge 仍用 ZHIPU_API_KEY)
122
- where deveco
123
- deveco providers reset # 仅凭证损坏/换机时需要
124
- deveco # TUI 里配置智谱等模型后再跑评测
125
- python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu --agent-host deveco-code
126
- # 指定 DevEco 模型(可选,格式 provider/model):
127
- # python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu --agent-host deveco-code --deveco-model zhipuai/glm-4.5-flash
128
- # report-deveco.txt
129
-
130
- # 三种依次跑(各写各的报告,不会互相覆盖)
131
- python scripts/qa_eval/run_pipeline.py hosts -r /path/to/your/repo --provider zhipu
132
-
133
- # 等价于 hosts 的子集:
134
- python scripts/qa_eval/run_pipeline.py hosts -r /path/to/your/repo --agent-hosts claude-code,deveco-code --provider zhipu```
135
-
136
- 产出示例(每种宿主一套,互不覆盖):
137
-
138
- | 宿主 | JSONL / 日志(`log/`) | 报告(`data/`) |
139
- |------|------------------------|-----------------|
140
- | builtin | `log/result-with-builtin.jsonl`、`log/agent-with-builtin.log` | `data/report-builtin.txt` |
141
- | claude-code | `log/result-with-claude.jsonl`、`log/agent-with-claude.log` | `data/report-claude.txt` |
142
- | deveco-code | `log/result-with-deveco.jsonl`、`log/agent-with-deveco.log` | `data/report-deveco.txt` |
143
-
144
- (without 臂同理:`result-without-{host}.jsonl`、`agent-without-{host}.log`)
145
-
146
- **若全局 `homegraph sync` `Cannot find module 'arkanalyzer'`**:用本地 `dist/bin/homegraph.js`(pipeline 会自动优先找本地 build)。
147
-
148
- ### `ab` 各阶段产出
149
-
150
- | 阶段 | 终端 | 文件 |
151
- |------|------|------|
152
- | Stage 1 Agent | 每题进度 | `log/result-*.jsonl`、`log/agent-*.log` |
153
- | Stage 2 Judge | eval_metrics 进度 | `log/result-*-scored.jsonl` |
154
- | Stage 3–4 报告 | **效率明细**(两路任务列表 + 平均值) | **`data/report-{host}.txt`** |
155
-
156
- 终端最后一行示例:
157
-
158
- ```
159
- A/B 完整报告已写入: .../scripts/qa_eval/data/report-deveco.txt
160
- ```
161
-
162
- ### `report-{host}.txt` 结构
163
-
164
- ```
165
- ################################################################################
166
- # A/B 完整评测报告 #
167
- ################################################################################
168
-
169
- 【输入文件】
170
- 【WITH homegraph】效率明细 ← 逐题 + 汇总(见下方「效率指标」)
171
- 【WITHOUT homegraph】效率明细
172
- 【WITH / WITHOUT homegraph】准确率统计 ← 见下方「准确率指标」
173
- 按类别准确率 category_l1 分组 with/without 均分与 Δ
174
- 逐题对比 ← 每题得分、答案摘要;末尾 with 赢/平/输 计数
175
- 【A/B 汇总表】 ← 两臂核心指标并排 + Δ(with−without)
176
- ```
177
-
178
- 只重打报告、不重跑 Agent/Judge(无需 `--repo`):
179
-
180
- ```bash
181
- python scripts/qa_eval/run_pipeline.py ab --no-agent --no-judge
182
- ```
183
- ## Stage 1 — Agent(`agent_runner.py`)
184
-
185
- 内置 Qwen 多轮工具 Agent,默认最多 **8 轮**(`--max-turns`)。
186
-
187
- | | 工具 | 说明 |
188
- |----|------|------|
189
- | **with** | `HomegraphQuery`、`ReadFile` | homegraph 检索符号,再读源码 |
190
- | **without** | `SearchText`、`FindFiles`、`ReadFile` | rg 全文搜索 + glob 找文件 |
191
-
192
- with 臂跑前会检查被测仓库已索引(`.homegraph/``.homegraph/`);without 臂不需要索引。
193
-
194
- 每条 JSONL 写入字段示例:
195
-
196
- ```json
197
- {
198
- "id": "R01",
199
- "query": "getColorString 函数在哪个文件里定义?",
200
- "reference_answer": "...",
201
- "output_answer": "---\nHomegraphQuery\nquery: getColorString\n...\n---\n\n定义在 camera/common/.../ColorUtil.ets。",
202
- "agent_backend": "agent-with-homegraph",
203
- "agent_usage": { "total_tokens": 1296 },
204
- "agent_duration_ms": 7830,
205
- "agent_memory_mb": { "peak_rss_mb": 412.5, "avg_rss_mb": 380.2 }
206
- }
207
- ```
208
-
209
- `agent_memory_mb` 为 Agent 进程树(含 homegraph MCP 子进程)在答题期间的 RSS 采样。
210
-
211
- `output_answer` 中工具调用包在 `--- ... ---` 块里(与 CodeGenie 格式一致);Judge 会自动剥掉再打分。
212
-
213
- ### Agent 日志格式(`agent-*.log`)
214
-
215
- ```
216
- 2026-06-23 09:25:21.052447 Evaluate 1:
217
- 2026-06-23 09:25:21.052571 the 1 turn
218
- 2026-06-23 09:25:22.321954 first token ← 第一次 LLM API 返回后写入
219
- 2026-06-23 09:25:22.321954 totalTokenCount = 349
220
- 2026-06-23 09:25:27.771606 the 2 turn
221
- 2026-06-23 09:25:28.861895 totalTokenCount = 947
222
- 2026-06-23 09:25:30.102441 peakRssMb = 412.5
223
- 2026-06-23 09:25:30.102441 avgRssMb = 380.2
224
- ...
225
- ```
226
-
227
- `stats_efficiency.py` 解析这些行得到逐题效率与**内存**。**首响应** = 从 `Evaluate N:` 到第一次 LLM API 返回的耗时;**峰值内存** = 该题进程树 RSS 峰值(MB,Linux `/proc`)。
228
-
229
- ### 外部 Agent(可选)
230
-
231
- 若用 CodeGenie / Trae 等外部 Agent 产出同格式 JSONL + 日志:
232
-
233
- ```bash
234
- python scripts/qa_eval/run_pipeline.py ab --no-agent
235
- # 或只重打 Judge + 报告
236
- python scripts/qa_eval/run_pipeline.py ab --no-agent --no-judge
237
- ```
238
-
239
- ## Stage 2 — Judge 打分(`eval_metrics.py`)
240
-
241
- ```bash
242
- python scripts/qa_eval/eval_metrics.py \
243
- -i scripts/qa_eval/log/result-with-builtin.jsonl \
244
- -o scripts/qa_eval/log/result-with-builtin-scored.jsonl \
245
- -w 2
246
- ```
247
-
248
- | 参数 | 默认 | 说明 |
249
- |------|------|------|
250
- | `-i` / `--input` | — | Agent 产出 JSONL |
251
- | `-o` / `--output` | `*-scored.jsonl` | 打分结果 |
252
- | `-w` / `--workers` | `1` | 并发线程数 |
253
- | `-m` / `--model` | `qwen3-235b-a22b-instruct-2507` | Judge 模型 |
254
-
255
- 追加字段:`answer_accuracy_score`(0–1)、`evaluation_status`(`success` / `failed`)。
256
-
257
- ## Stage 3 分数统计(`stats_scores.py`)
258
-
259
- ```bash
260
- python scripts/qa_eval/stats_scores.py \
261
- -i scripts/qa_eval/log/result-with-builtin-scored.jsonl
262
- ```
263
-
264
- 输出(每臂各一份):总/成功/失败样本数,均值、中位数、最小/最大、标准差、方差,五档分数分布,评估成功率。`run_pipeline ab` 会将其并入 `report-{host}.txt`。
265
-
266
- ## Stage 4 — 效率统计(`stats_efficiency.py`)
267
-
268
- ```bash
269
- python scripts/qa_eval/stats_efficiency.py \
270
- -l scripts/qa_eval/log/agent-with-builtin.log
271
- ```
272
-
273
- 输出:
274
-
275
- - **逐题**(任务明细):首响应、轮次、总时间、总 Token、**峰值内存 (MB)**
276
- - **汇总**(统计结果):任务总数、平均首响应、平均轮次、平均总时间、平均总 Token、**平均/最大峰值内存**、合计总 Token
277
-
278
- 日志缺失时回退为 JSONL 的 `agent_usage` 逐题 Token(无轮次/耗时/首响应)。
279
-
280
- **homegraph 价值**:对比 with / without 汇总行的**平均轮次、平均总时间、平均总 Token**(汇总表同列);轮次越少、耗时越短、Token 越少,说明 homegraph 减少了盲目 grep/read。
281
-
282
- ## `run_pipeline.py` 命令
283
-
284
- ### `ab` — A/B 全流程
285
-
286
- ```bash
287
- python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo [选项]
288
- ```
289
-
290
- | 参数 | 默认 | 说明 |
291
- |------|------|------|
292
- | `--repo`, `-r` | — | **被测仓库**(跑 Agent 时必填) || `--dataset`, `-d` | `data/test-set.jsonl` | 测试集 |
293
- | `--with-jsonl` / `--without-jsonl` | `log/result-*.jsonl` | Agent 产出 |
294
- | `--with-scored` / `--without-scored` | `log/result-*-scored.jsonl` | Judge 产出 |
295
- | `--with-log` / `--without-log` | `log/agent-*.log` | Agent 日志 |
296
- | `--report` | `data/report-{host}.txt` | 完整报告路径(默认随 `--agent-host`) |
297
- | `--model`, `-m` | `qwen3-235b-a22b-instruct-2507` | Agent + Judge 模型 |
298
- | `--workers`, `-w` | `1` | Judge 并发 |
299
- | `--max-turns` | `8` | Agent 最多工具轮次(仅 builtin) |
300
- | `--agent-host` | `builtin` | `builtin` / `claude-code` / `deveco-code` / `all` |
301
- | `--homegraph-bin` | 自动检测 | 本地 `dist/bin/homegraph.js` 优先 |
302
- | `--no-agent` | — | 跳过 Stage 1,沿用已有 JSONL |
303
- | `--no-judge` | — | 跳过 Stage 2,沿用已有 scored |
304
-
305
- ### `score` — 单路 Judge + 统计
306
-
307
- ```bash
308
- python scripts/qa_eval/run_pipeline.py score \
309
- -i scripts/qa_eval/log/result-with-builtin.jsonl \
310
- -l scripts/qa_eval/log/agent-with-builtin.log
311
- ```
312
-
313
- ## 测试集格式(`test-set.jsonl`)
314
-
315
- 每行一条:
316
-
317
- ```json
318
- {
319
- "id": "R01",
320
- "query": "getColorString 函数在哪个文件里定义?",
321
- "reference_answer": "getColorString 定义在 camera/common/src/main/ets/utils/ColorUtil.ets。",
322
- "category_l1": "检索",
323
- "category_l2": "函数",
324
- "level0": "camera",
325
- "level1": "ColorUtil",
326
- "difficulty": "简单",
327
- "language": "ArkTS"
328
- }
329
- ```
330
-
331
- `category_*`、`level*`、`difficulty` 仅用于报告分组,Judge 不读取。
332
-
333
- ## 结果怎么读
334
-
335
- ### 【A/B 汇总表】— 核心对比(`report-{host}.txt` 末尾)
336
-
337
- | 指标 | 含义 | A/B 怎么看 |
338
- |------|------|------------|
339
- | 准确率 均值 | Judge 给出的 `answer_accuracy_score`(0–1)全题平均 | Δ > 0 表示 with 答案质量更高 |
340
- | 准确率 中位数 | 同上,中位数(抗极端值) | 与均值交叉验证 |
341
- | Judge 成功/总数 | 成功打分的题数 / 总题数 | 应接近 100%;失败需查 API/JSONL |
342
- | 平均轮次 | 每题 Agent 调用 LLM 的工具循环次数(日志 `the N turn` 的最大 N)再求平均 | **越低越好**;with 理想上更低 |
343
- | 平均耗时 (秒) | 每题从 `Evaluate N:` 到下一题开始的端到端时间再求平均 | **越短越好** |
344
- | 平均 Token (k) | 每题 Agent 消耗 Token(日志 `totalTokenCount` 累加)再求平均,单位 k | **越少越好** |
345
- | 平均首响应 (秒) | 每题从 `Evaluate N:` 到第一次 LLM API 返回再求平均 | 参考项,非 homegraph 主指标 |
346
- | 平均峰值内存 (MB) | 每题 Agent+MCP 进程树 RSS 峰值再求平均 | **越低越好**;with 不应显著高于 without |
347
- | 最大峰值内存 (MB) | 单题 RSS 峰值的最大值 | 观察是否 OOM 风险 |
348
-
349
- Δ 列均为 **with without**(正数表示 with 更高/更多/更慢,视指标而定)。
350
-
351
- ### 准确率明细(每臂「准确率统计」段)
352
-
353
- | 指标 | 含义 |
354
- |------|------|
355
- | `answer_accuracy_score` 均值 / 中位数 | 该臂答案质量 |
356
- | 最小值 / 最大值 | 最差、最好单题得分 |
357
- | 标准差 / 方差 | 分数离散程度 |
358
- | 分数分布(五档) | 0–0.2 … 0.8–1.0 各档题数与占比 |
359
- | 评估成功率 | 成功 Judge 数 / 总样本数 |
360
-
361
- ### 效率明细(每臂「效率明细」段)
362
-
363
- | 粒度 | 指标 | 含义 |
364
- |------|------|------|
365
- | 逐题 | 首响应 | 该题第一次 LLM 返回耗时 |
366
- | 逐题 | 轮次 | 该题 LLM 工具循环次数 |
367
- | 逐题 | 总时间 | 该题端到端耗时 |
368
- | 逐题 | 总 Token | 该题 Agent Token 消耗 |
369
- | 逐题 | 峰值内存 | 该题进程树 RSS 峰值 (MB) |
370
- | 汇总 | 平均峰值内存 / 最大峰值内存 | 内存占用汇总 |
371
- | 汇总 | 平均首响应 / 平均轮次 / 平均总时间 / 平均总 Token | 上表逐题指标的平均值 |
372
- | 汇总 | 合计总 Token | 该臂 20 题 Token 总和 |
373
-
374
- ### 分组与逐题(report-{host}.txt 中部)
375
-
376
- | 区块 | 内容 |
377
- |------|------|
378
- | 按类别准确率 | 按 `category_l1`(检索 / 解读 / 依赖)分组的 with/without 均分与 Δ |
379
- | 逐题对比 | 每题 ID、类别、with/without 得分与 Δ、问题与答案摘要 |
380
- | 逐题对比末尾 | **with 更高 / 持平 / without 更高** 题数统计 |
381
-
382
- ## 常见问题
383
-
384
- | 现象 | 处理 |
385
- |------|------|
386
- | Claude 准确率全 < 0.1 / `Not logged in` | Agent 未登录:`claude login` 后重跑;pipeline 现会在首题探测并 fail-fast |
387
- | `deveco-code` exit 1 / `Model not found: glm-4-flash` | `--provider zhipu` 的模型只给 Judge/builtin;deveco 用 `deveco models` 里的 `zhipuai/...` 名,或加 `--deveco-model zhipuai/glm-4.5-flash` |
388
- | `401` / Judge 全失败 | 检查 API Key:`DASHSCOPE_API_KEY`(DashScope)或 `ZHIPU_API_KEY`(智谱,格式 `id.secret`);智谱请加 `--provider zhipu`,勿把智谱 Key 设到 `DASHSCOPE_API_KEY` |
389
- | `Cannot find module 'arkanalyzer'` | `npm run build`,用 `node dist/bin/homegraph.js sync` |
390
- | `rg not found on PATH` | `sudo apt install ripgrep`(without 臂需要) |
391
- | 日志解析 0 条任务 | 确认 log `Evaluate N:` |
392
- | 首响应全为 0 | log bug;重跑 Agent 或依赖自动回退逻辑 |
393
- | `claude` / `opencode` 未找到 | 安装 Claude Code DevEco Code,并加入 PATH |
394
- | 内存全为 N/A | Windows `/proc`,内存采样自动跳过(不影响跑题);Linux/WSL 上才有峰值内存 || 分数偏低但答案看起来对 | 检查 `output_answer` 是否只剩工具块、无最终自然语言答案 |
395
- | pip | 用清华镜像(见快速开始) |
396
-
397
- ## 最小通路(仅 Judge 单条)
398
-
399
- ```bash
400
- export DASHSCOPE_API_KEY="sk-xxx"
401
- head -1 scripts/qa_eval/log/result-with-builtin.jsonl > /tmp/one.jsonl
402
- python scripts/qa_eval/eval_metrics.py -i /tmp/one.jsonl -o /tmp/one-scored.jsonl
403
- python scripts/qa_eval/stats_scores.py -i /tmp/one-scored.jsonl
404
- ```
1
+ # QA Eval — 四段式 A/B 评测流水线
2
+
3
+ 内置多轮 Agent + Judge + 统计 + 报告,对齐 CodeGenie / Trae 评测框架:**Agent 跑题 → Judge 打分 → 分数统计 → 效率统计 → A/B 对比**。
4
+
5
+ - **国内可用**:builtin Agent / Judge OpenAI 兼容接口(DashScope Qwen 或智谱 GLM
6
+ - **多 Agent 宿主**:builtin Python Agent、Claude Code CLI、DevEco Code CLI
7
+ - **不依赖** ragas / langchain
8
+ - **被测仓库**:运行时用 `--repo` / `-r` 指定,无默认路径
9
+
10
+ ## 测试输入
11
+
12
+ **格式**:JSONL,一行一条,UTF-8。
13
+
14
+ ```json
15
+ {
16
+ "id": "R01",
17
+ "query": "...",
18
+ "reference_answer": "...",
19
+ "category_l1": "检索",
20
+ "category_l2": "函数"
21
+ }
22
+ ```
23
+
24
+ | 字段 | 必填 | 说明 |
25
+ |------|------|------|
26
+ | `id` | 是 | 题号,如 `R01` / `E03` / `D05` |
27
+ | `query` | 是 | 给 Agent 的问题 |
28
+ | `reference_answer` | 是 | 参考答案(Judge 对照) |
29
+ | `category_l1` | 建议 | 一级分类:`检索` / `解读` / `依赖`(仅报告分组) |
30
+ | `category_l2` | 可选 | 二级分类(仅报告分组) |
31
+ | `level0` / `level1` / `difficulty` / `language` | 可选 | 元数据,Judge 不读取 |
32
+
33
+ **默认测试集**:`scripts/qa_eval/data/test-set.jsonl`(完整集 20 条:检索 7 + 解读 7 + 依赖 6;可按需增删行)。
34
+
35
+ ## 目录结构
36
+
37
+ ```
38
+ scripts/qa_eval/
39
+ ├── agent_runner.py # Stage 1a:builtin 多轮 Agent(with / without)
40
+ ├── external_agent.py # Stage 1b:Claude Code / DevEco Code 外部 Agent
41
+ ├── my_answer_accuracy.py # Judge 指标(双 prompt 0–5 归一化)
42
+ ├── eval_metrics.py # Stage 2:对 JSONL 批量打分
43
+ ├── stats_scores.py # Stage 3:answer_accuracy_score 汇总
44
+ ├── stats_efficiency.py # Stage 4:解析 Agent 日志(首响应/轮次/耗时/Token/内存)
45
+ ├── memory_monitor.py # 进程树 RSS 采样(Linux /proc;WSL 可用)
46
+ ├── llm_config.py # DashScope / 智谱 provider 预设
47
+ ├── run_pipeline.py # 编排 Stage 1–4 + A/B 报告
48
+ ├── _test_deveco_probe.py # DevEco 单题探测脚本(开发调试用)
49
+ ├── requirements.txt
50
+ ├── data/ # 测试集 + 报告(报告不入库)
51
+ │ ├── test-set.jsonl # 测试集(入库)
52
+ │ └── report-{host}.txt # 完整 A/B 报告(gitignore,留在 data/)
53
+ └── log/ # 流水线中间产物(整目录 gitignore)
54
+ ├── result-with-{host}.jsonl
55
+ ├── result-without-{host}.jsonl
56
+ ├── result-*-{host}-scored.jsonl
57
+ ├── agent-with-{host}.log
58
+ ├── agent-without-{host}.log
59
+ ├── eval_metrics.log # Judge 运行日志(若有)
60
+ └── traces/ # DevEco session 导出(仅 deveco-code 宿主)
61
+ ├── with-deveco/
62
+ │ └── R01-ses_*.json
63
+ └── without-deveco/
64
+ └── R01-ses_*.json
65
+ ```
66
+
67
+ **Git 入库规则**
68
+
69
+ | 路径 | 是否提交 |
70
+ |------|----------|
71
+ | `scripts/qa_eval/*.py`、`README.md`、`requirements.txt` | 是 |
72
+ | `data/test-set.jsonl` | 是 |
73
+ | `data/report*.txt` | |
74
+ | `log/` 下全部 | 否 |
75
+ | `__pycache__/` | 否 |
76
+
77
+ **与旧版路径对照**(若你手头是早期文档):
78
+
79
+ | 旧路径 | 现路径 |
80
+ |--------|--------|
81
+ | `data/test.jsonl` | `data/test-set.jsonl` |
82
+ | `data/result-*.jsonl` | `log/result-*-{host}.jsonl` |
83
+ | `data/agent-*.log` | `log/agent-*-{host}.log` |
84
+ | `data/report.txt` | `data/report-{host}.txt` |
85
+
86
+ ## 测试流程
87
+
88
+ ```
89
+ test-set.jsonl
90
+
91
+ Stage 1 agent_runner.py / external_agent.py(run_pipeline ab 内置)
92
+ with : homegraph MCP / HomegraphQuery + ReadFile
93
+ without : grep/rg + read(无 homegraph)
94
+ 产出: log/result-*-{host}.jsonl + log/agent-*-{host}.log
95
+ (deveco-code 额外产出 log/traces/{arm}-deveco/*.json)
96
+
97
+ Stage 2 eval_metrics.py → log/result-*-{host}-scored.jsonl
98
+
99
+ Stage 3 stats_scores.py → 准确率汇总(并入 report-{host}.txt)
100
+ Stage 4 stats_efficiency.py 效率 + 内存汇总(终端 + report-{host}.txt)
101
+
102
+ run_pipeline.py ab → data/report-{host}.txt
103
+ ```
104
+
105
+ **A/B 唯一变量**:Agent 是否可用 homegraph。两臂使用**同一 Agent 宿主、同一 max_turns(builtin)**;without **不是裸 LLM**,仍是多轮 grep/read Agent。
106
+
107
+ ### Stage 1 工具对照
108
+
109
+ | 臂 | builtin 工具 | Claude / DevEco |
110
+ |----|--------------|-----------------|
111
+ | **with** | `HomegraphQuery`、`ReadFile` | MCP `homegraph_explore` / `homegraph_node` 等 + 内置 read/grep |
112
+ | **without** | `SearchText`(rg)、`FindFiles`、`ReadFile` | 仅内置 grep/read;DevEco 在 `.deveco/deveco.jsonc` 中 deny homegraph 工具 |
113
+
114
+ ## 测试输出
115
+
116
+ ### 核心指标(`report-{host}.txt` 末尾【A/B 汇总表】)
117
+
118
+ | 指标 | 含义 | A/B 怎么看 |
119
+ |------|------|------------|
120
+ | 准确率 均值 | Judge 的 `answer_accuracy_score`(0–1)全题平均 | Δ > 0 表示 with 答案质量更高 |
121
+ | 准确率 中位数 | 同上,中位数(抗极端值) | 与均值交叉验证 |
122
+ | Judge 成功/总数 | 成功打分数 / 总题数 | 应接近 100%;失败查 API/JSONL |
123
+ | 平均轮次 | 每题 LLM 工具循环次数(日志 `the N turn` 最大 N)再平均 | **越低越好**;with 理想上更低 |
124
+ | 平均耗时 (秒) | 每题从 `Evaluate N:` 到下一题开始的端到端时间再平均 | **越短越好** |
125
+ | 平均 Token (k) | 每题 `totalTokenCount` 累加再平均,单位 k | **越少越好** |
126
+ | 平均首响应 (秒) | 每题从 `Evaluate N:` 到第一次 LLM 返回再平均 | 参考项 |
127
+ | 平均峰值内存 (MB) | Agent + MCP 子进程树 RSS 峰值再平均 | **越低越好**;Linux/WSL 才有数 |
128
+ | 最大峰值内存 (MB) | 单题 RSS 峰值最大值 | 观察 OOM 风险 |
129
+
130
+ Δ 列均为 **with − without**。
131
+
132
+ ### JSONL 产出字段(Stage 1)
133
+
134
+ 每条在测试集字段基础上追加:
135
+
136
+ ```json
137
+ {
138
+ "output_answer": "---\nHomegraphQuery\n...\n---\n\n最终自然语言答案…",
139
+ "agent_status": "success",
140
+ "agent_error": null,
141
+ "agent_backend": "deveco-code-with-homegraph",
142
+ "agent_host": "deveco-code",
143
+ "agent_model": "glm-4.5-flash",
144
+ "agent_turns": 2,
145
+ "agent_duration_ms": 73200,
146
+ "agent_usage": { "total_tokens": 9249 },
147
+ "agent_memory_mb": { "peak_rss_mb": 412.5, "avg_rss_mb": 380.2 },
148
+ "ab_arm": "with-homegraph",
149
+ "deveco_session_id": "ses_101dd0359ffeWUPIajCOuBEQtx",
150
+ "agent_trace_file": "log/traces/with-deveco/R02-ses_101dd0359ffeWUPIajCOuBEQtx.json",
151
+ "agent_tools_used": ["homegraph_homegraph_explore", "read"],
152
+ "agent_used_homegraph": true,
153
+ "agent_answer_source": "session_export"
154
+ }
155
+ ```
156
+
157
+ | 字段 | 说明 |
158
+ |------|------|
159
+ | `output_answer` | 工具调用块(`---` 包裹)+ 最终答案;Judge 会剥工具块再打分 |
160
+ | `agent_status` | `success` / `error` |
161
+ | `agent_memory_mb` | 答题期间进程树 RSS(见「内存采样」) |
162
+ | `deveco_session_id` | DevEco 会话 ID(`deveco-code` 宿主) |
163
+ | `agent_trace_file` | 相对 `scripts/qa_eval/` 的 session 导出 JSON 路径 |
164
+ | `agent_used_homegraph` | with 臂是否实际调用了 homegraph MCP 工具 |
165
+
166
+ Judge 追加:`answer_accuracy_score`(0–1)、`evaluation_status`(`success` / `failed`)。
167
+
168
+ ### Agent 日志格式(`agent-*-{host}.log`)
169
+
170
+ ```
171
+ 2026-06-23 09:25:21.052447 Evaluate 1:
172
+ 2026-06-23 09:25:21.052571 the 1 turn
173
+ 2026-06-23 09:25:22.321954 first token 第一次 LLM API 返回
174
+ 2026-06-23 09:25:22.321954 totalTokenCount = 349
175
+ 2026-06-23 09:25:27.771606 the 2 turn
176
+ 2026-06-23 09:25:28.861895 totalTokenCount = 947
177
+ 2026-06-23 09:25:30.102441 sessionID = ses_... ← DevEco 专有
178
+ 2026-06-23 09:25:30.102441 tools = homegraph_homegraph_explore, read
179
+ 2026-06-23 09:25:30.102441 session export → log/traces/with-deveco/R01-ses_....json
180
+ 2026-06-23 09:25:30.102441 peakRssMb = 412.5
181
+ 2026-06-23 09:25:30.102441 avgRssMb = 380.2
182
+ 2026-06-23 09:25:30.102441 completed (73200ms)
183
+ ```
184
+
185
+ ## Agent 轨迹(Trace)
186
+
187
+ **适用宿主**:主要为 `deveco-code`(每题自动 `deveco export <session_id>`)。
188
+
189
+ | 查看方式 | 命令 / 路径 |
190
+ |----------|-------------|
191
+ | 导出 JSON | `log/traces/{with\|without}-deveco/<ID>-ses_<session>.json` |
192
+ | DevEco CLI | `deveco export <session_id>` `deveco session list`(标题 `qa-eval-{arm}-{id}`) |
193
+ | 报告索引 | `report-{host}.txt` 中【Agent 轨迹 / DevEco Session】表 |
194
+
195
+ 轨迹 JSON 含完整 `messages` / `parts`(用户问题、工具 input/output、assistant 文本、token 统计),用于人工复盘 Agent 是否按预期调用 `homegraph_explore`。
196
+
197
+ `claude-code` 宿主将 stream-json 解析进 `output_answer`,不单独落 trace 文件。
198
+
199
+ ## 内存采样
200
+
201
+ - **实现**:`memory_monitor.py` Agent 子进程存活期间每 0.25s 采样进程树 RSS(Linux `/proc`)。
202
+ - **写入**:JSONL `agent_memory_mb`;日志 `peakRssMb` / `avgRssMb`;报告「平均/最大峰值内存」。
203
+ - **平台**:**Linux 原生 / WSL** 有数据;**Windows 原生** 无 `/proc`,显示 `N/A`,不影响跑题与准确率/耗时/Token 指标。
204
+ - **采样范围**:builtin / 外部 CLI 的 **子进程树**(含 homegraph MCP 子进程)。
205
+
206
+ ## Agent 宿主(`--agent-host`)
207
+
208
+ | 宿主 | 说明 | Agent 前置条件 | 报告文件 |
209
+ |------|------|----------------|----------|
210
+ | `builtin`(默认) | Python 内置多轮 Agent + 智谱/DashScope | `ZHIPU_API_KEY` 或 `DASHSCOPE_API_KEY` | `report-builtin.txt` |
211
+ | `claude-code` | Claude Code CLI(`claude -p` + MCP) | `claude login` 已登录 | `report-claude.txt` |
212
+ | `deveco-code` | DevEco Code / opencode CLI | `deveco` 在 PATH,DevEco provider 已配置 | `report-deveco.txt` |
213
+
214
+ **注意**:`--provider zhipu` 只影响 **builtin Agent** 和 **Judge**;`deveco-code` / `claude-code` 使用各自 CLI 的账号,不读 `ZHIPU_API_KEY`。
215
+
216
+ ### DevEco Code 配置要点
217
+
218
+ ```bash
219
+ deveco providers login # Zhipu AI,输入 API Key
220
+ # 凭证目录(Windows): C:\Users\<你>\.config\deveco
221
+ ```
222
+
223
+ - pipeline 会在被测仓库写入 `.deveco/deveco.jsonc`(with 臂挂 homegraph MCP + agent prompt;without 臂 deny homegraph 工具)。
224
+ - TUI 若提示 **DEVECO_HOME**,那是 DevEco **Studio** 安装路径(编译用);**跑 qa_eval 可跳过**。
225
+ - 可选 `--deveco-model zhipuai/glm-4.5-flash`(格式 `provider/model`,用 `deveco models` 查看)。
226
+ - 可选 `--deveco-attach http://127.0.0.1:4096` 或 `QA_EVAL_DEVECO_ATTACH` 复用已运行的 `deveco serve`,减少冷启动。
227
+
228
+ Judge(Stage 2)三种宿主共用,仍需 `ZHIPU_API_KEY` 或 `DASHSCOPE_API_KEY`。
229
+
230
+ ## 快速开始
231
+
232
+ ```bash
233
+ pip install -r scripts/qa_eval/requirements.txt \
234
+ -i https://pypi.tuna.tsinghua.edu.cn/simple
235
+
236
+ export DASHSCOPE_API_KEY="sk-xxxxxxxx"
237
+ # 或智谱(Key 格式 id.secret,不要加 sk- 前缀):
238
+ # export ZHIPU_API_KEY="xxxxxxxx.yyyyyyyy"
239
+
240
+ cd /path/to/homegraph && npm run build
241
+ node dist/bin/homegraph.js sync /path/to/your/repo
242
+
243
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo
244
+ # 智谱:
245
+ # python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo --provider zhipu
246
+ ```
247
+
248
+ ### 三种宿主示例
249
+
250
+ ```bash
251
+ # builtin
252
+ export ZHIPU_API_KEY="your-id.your-secret"
253
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/repo --provider zhipu --agent-host builtin
254
+
255
+ # Claude Code(Agent 用 Claude 账号,Judge 仍用 ZHIPU_API_KEY)
256
+ claude login
257
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/repo --provider zhipu --agent-host claude-code
258
+
259
+ # ③ DevEco Code
260
+ deveco providers login
261
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/repo --provider zhipu --agent-host deveco-code
262
+ # python scripts/qa_eval/run_pipeline.py ab -r /path/to/repo --provider zhipu --agent-host deveco-code --deveco-model zhipuai/glm-4.5-flash
263
+
264
+ # 三种依次跑(各写各的报告)
265
+ python scripts/qa_eval/run_pipeline.py hosts -r /path/to/repo --provider zhipu
266
+ ```
267
+
268
+ 产出示例(每种宿主一套,互不覆盖):
269
+
270
+ | 宿主 | JSONL / 日志(`log/`) | 报告(`data/`) |
271
+ |------|------------------------|-----------------|
272
+ | builtin | `result-with-builtin.jsonl`、`agent-with-builtin.log` | `report-builtin.txt` |
273
+ | claude-code | `result-with-claude.jsonl`、`agent-with-claude.log` | `report-claude.txt` |
274
+ | deveco-code | `result-with-deveco.jsonl`、`agent-with-deveco.log`、`traces/` | `report-deveco.txt` |
275
+
276
+ 只重打报告、不重跑 Agent/Judge(无需 `--repo`):
277
+
278
+ ```bash
279
+ python scripts/qa_eval/run_pipeline.py ab --no-agent --no-judge
280
+ # 保留上次 log 中间文件:
281
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/repo --keep-log
282
+ ```
283
+
284
+ ### `report-{host}.txt` 结构
285
+
286
+ ```
287
+ ################################################################################
288
+ # A/B 完整评测报告 #
289
+ ################################################################################
290
+
291
+ 【输入文件】
292
+ 【WITH homegraph】效率明细 ← 逐题 + 汇总(首响应/轮次/耗时/Token/内存)
293
+ 【WITHOUT homegraph】效率明细
294
+ 【WITH / WITHOUT homegraph】准确率统计
295
+ 按类别准确率 ← category_l1 分组 with/without 均分与 Δ
296
+ 逐题对比 ← 得分、答案摘要;with 赢/平/输 计数
297
+ 【Agent 轨迹 / DevEco Session】 ← deveco-code 专有(session_id + 轨迹路径)
298
+ 【A/B 汇总表】 ← 两臂核心指标并排 + Δ
299
+ ```
300
+
301
+ ## Stage 2 Judge(`eval_metrics.py`)
302
+
303
+ ```bash
304
+ python scripts/qa_eval/eval_metrics.py \
305
+ -i scripts/qa_eval/log/result-with-builtin.jsonl \
306
+ -o scripts/qa_eval/log/result-with-builtin-scored.jsonl \
307
+ -w 2 --provider zhipu
308
+ ```
309
+
310
+ | 参数 | 默认 | 说明 |
311
+ |------|------|------|
312
+ | `-i` / `--input` | — | Agent 产出 JSONL |
313
+ | `-o` / `--output` | `*-scored.jsonl` | 打分结果 |
314
+ | `-w` / `--workers` | `1` | 并发线程数 |
315
+ | `-m` / `--model` | 随 provider | Judge 模型 |
316
+ | `--provider` | 自动检测 | `dashscope` / `zhipu` |
317
+
318
+ ## Stage 3 / 4 — 统计脚本
319
+
320
+ ```bash
321
+ python scripts/qa_eval/stats_scores.py \
322
+ -i scripts/qa_eval/log/result-with-builtin-scored.jsonl
323
+
324
+ python scripts/qa_eval/stats_efficiency.py \
325
+ -l scripts/qa_eval/log/agent-with-builtin.log
326
+ ```
327
+
328
+ `stats_efficiency.py` 输出逐题首响应、轮次、总时间、总 Token、**峰值内存**;日志缺失时回退 JSONL `agent_usage`(无轮次/耗时/首响应)。
329
+
330
+ ## `run_pipeline.py` 命令
331
+
332
+ ### `ab` — A/B 全流程
333
+
334
+ ```bash
335
+ python scripts/qa_eval/run_pipeline.py ab -r /path/to/your/repo [选项]
336
+ ```
337
+
338
+ | 参数 | 默认 | 说明 |
339
+ |------|------|------|
340
+ | `--repo`, `-r` | | **被测仓库**(跑 Agent 时必填) |
341
+ | `--dataset`, `-d` | `data/test-set.jsonl` | 测试集 |
342
+ | `--with-jsonl` / `--without-jsonl` | `log/result-*.jsonl` | Agent 产出 |
343
+ | `--with-scored` / `--without-scored` | `log/result-*-scored.jsonl` | Judge 产出 |
344
+ | `--with-log` / `--without-log` | `log/agent-*.log` | Agent 日志 |
345
+ | `--report` | `data/report-{host}.txt` | 完整报告路径 |
346
+ | `--model`, `-m` | provider | builtin Agent + Judge 模型 |
347
+ | `--provider` | 自动检测 | `dashscope` / `zhipu` |
348
+ | `--workers`, `-w` | `1` | Judge 并发 |
349
+ | `--max-turns` | `8` | builtin Agent 最多工具轮次 |
350
+ | `--agent-host` | `builtin` | `builtin` / `claude-code` / `deveco-code` / `all` |
351
+ | `--homegraph-bin` | 自动检测 | 优先本地 `dist/bin/homegraph.js` |
352
+ | `--deveco-model` | `zhipuai/glm-4.5-flash` | DevEco Agent 模型(仅 deveco-code) |
353
+ | `--deveco-attach` | `$QA_EVAL_DEVECO_ATTACH` | 复用 `deveco serve` 地址 |
354
+ | `--no-agent` | — | 跳过 Stage 1 |
355
+ | `--no-judge` | | 跳过 Stage 2 |
356
+ | `--keep-log` | | Agent 前**不清空** `log/` |
357
+
358
+ ### `hosts` 多宿主依次跑
359
+
360
+ 等价于对 `builtin,claude-code,deveco-code` 各跑一遍 `ab`:
361
+
362
+ ```bash
363
+ python scripts/qa_eval/run_pipeline.py hosts -r /path/to/repo --provider zhipu
364
+ python scripts/qa_eval/run_pipeline.py hosts -r /path/to/repo --agent-hosts claude-code,deveco-code
365
+ ```
366
+
367
+ ### `score` 单路 Judge + 统计
368
+
369
+ ```bash
370
+ python scripts/qa_eval/run_pipeline.py score \
371
+ -i scripts/qa_eval/log/result-with-builtin.jsonl \
372
+ -l scripts/qa_eval/log/agent-with-builtin.log
373
+ ```
374
+
375
+ ## 外部 Agent 产出(可选)
376
+
377
+ 若用 CodeGenie / Trae 等外部系统产出**同格式** JSONL + 日志:
378
+
379
+ ```bash
380
+ python scripts/qa_eval/run_pipeline.py ab --no-agent -r /path/to/repo
381
+ ```
382
+
383
+ ## 常见问题
384
+
385
+ | 现象 | 处理 |
386
+ |------|------|
387
+ | Claude 准确率全低 / `Not logged in` | `claude login` 后重跑;pipeline 首题会 fail-fast |
388
+ | `deveco-code` exit 1 / `Model not found` | `deveco models` 里的 `zhipuai/...` 名,或 `--deveco-model zhipuai/glm-4.5-flash` |
389
+ | DevEco `ServeError` / 端口占用 | `netstat -ano \| findstr :4096` 后结束进程,或不加 `--deveco-attach` |
390
+ | DevEco 凭证损坏 | `deveco providers reset` 后重新 login |
391
+ | `401` / Judge 全失败 | 检查 Key;智谱用 `--provider zhipu`,Key 格式 `id.secret` |
392
+ | `Cannot find module 'arkanalyzer'` | `npm run build`,用 `node dist/bin/homegraph.js sync` |
393
+ | `rg not found on PATH` | 安装 ripgrep(without builtin 需要) |
394
+ | 日志解析 0 条任务 | 确认 log `Evaluate N:` |
395
+ | 内存全为 N/A | Windows 原生无 `/proc`;用 WSL/Linux 测内存,或忽略该列 |
396
+ | with 臂未用 homegraph | 看报告轨迹表 `HG` 列或 `agent_used_homegraph`;DevEco with 臂有专用 prompt |
397
+ | 分数偏低但答案看起来对 | 检查 `output_answer` 是否只剩工具块、无最终自然语言答案 |
398
+ | pip 慢 | 清华镜像(见快速开始) |
399
+
400
+ ## 最小通路(仅 Judge 单条)
401
+
402
+ ```bash
403
+ export DASHSCOPE_API_KEY="sk-xxx"
404
+ head -1 scripts/qa_eval/log/result-with-builtin.jsonl > /tmp/one.jsonl
405
+ python scripts/qa_eval/eval_metrics.py -i /tmp/one.jsonl -o /tmp/one-scored.jsonl
406
+ python scripts/qa_eval/stats_scores.py -i /tmp/one-scored.jsonl
407
+ ```