第 15 章 · 评测驱动:Harness 也是变量
本篇目标:设计一组可复现的对照实验,把「感觉变好了」变成数字。 全章只遵守一条纪律:固定环境才能比模型,固定模型才能比 Harness。
15.1 为什么必须单独讲评测
原文:
"A benchmark score partly reflects the harness used for the test, not only the model."
社区 最有力的证据:LangChain 报告只改 Harness、模型不变,coding agent 在 Terminal Bench 2.0 从 top 30 升到 top 5(The Anatomy of an Agent Harness, 2026-03-10)。排名移动 25 位,权重一个字节没动。
推论有两条,方向相反,都重要:
| 场景 | 必须固定 | 否则 |
|---|---|---|
| 比模型 A vs 模型 B | Harness 必须完全一致 | 你测的是 Harness 差异 |
| 比 Harness X vs Harness Y | 模型、题面、环境必须完全一致 | 你测的是模型波动 |
原文 极简模式存在的首要理由就是第一条:只留持久化 bash 与 str_replace_editor,锁死系统提示词,砍掉压缩、规划、Skills、子 Agent、搜索、定时任务、时钟上下文——把 Harness 变量的方差压到最小。
15.2 六步跑分法(沿用原文,补上官方依据)
Step 1 · 准备绝对干净的目录
mkdir -p ~/dsh-bench && cd ~/dsh-bench
git clone <你的测试仓库> repo
cd repo
git checkout -b bench/baseline
Step 2 · 把任务写成一份「题面」,两个模型用同一份
实现一个 JSON Schema 校验器,要求:
1. 支持 type、properties、required、enum 四个关键字
2. 返回所有错误路径,不只是第一个
3. 为这四个关键字各写一组单元测试
4. 运行测试并确认全部通过
题面要求:可机器判定、无歧义、不依赖联网、不依赖墙上时间。
Step 3 · 在极简模式下跑 A
Step 4 · 记录这些数字(不是感觉) 原文
| # | 指标 | 为什么记 |
|---|---|---|
| 1 | 总耗时 | 效率基线 |
| 2 | 工具调用总次数 | 反映 loop 效率与死循环 |
| 3 | Token 消耗(输入 / 输出分开记) | 输入反映 Harness 固定开销,输出反映啰嗦程度 |
| 4 | 测试是否全绿 | 硬通过率 |
| 5 | 改了多少行才变绿 | 原文点评:「这个数字最能说明代码质量——有的模型改 5 行搞定,有的重写 300 行」 |
Step 5 · 彻底重置,再跑 B
git checkout bench/baseline
git clean -fd
git clean -fd 不可省:清掉 node_modules、缓存、编译产物等未跟踪残留,否则 B 组会继承 A 组的副作用。
Step 6 · 把 PTC 也拉进来当第三组 原文。三组同题面同环境,才能同时比较模型与编排方式。
官方 BENCHMARK.md 给出的补充纪律:按 docs/user/guide/python-sdk.md 安装 SDK 并运行 jsonrpc-agent minimal variant,独立 benchmark 任务必须使用独立 workspace 与独立 session id。
15.3 从跑分到 eval suite
一次跑分是点,eval suite 是面。社区 生产做法:
| 设计项 | 要求 |
|---|---|
| 用例来源 | 来自真实输入,不要凭空编造 |
| 覆盖面 | 成功样本 + 失败样本 + 边界样本 + 对抗样本 |
| 评分方式 | Exact Match / Contains / LLM as a judge |
| Judge 温度 | temperature = 0 |
| 确定性优先 | 能精确匹配就别用模型判 |
| Trace | 每次 model call / tool call 记 status、start、finish、duration |
| 载荷 | payload 脱敏且限制大小 |
验证 Harness 改动的唯一正确方法 社区:
keep the model fixed → change ONE part of the harness → rerun the SAME suite
三个限定词缺一不可:固定模型、只改一处、同一套题。同时改三条规则然后分数涨了,你不知道是哪条起效,也不知道哪条其实在拖后腿。
15.4 Self-verification:一个值得单独抄的模式
社区 Terminal Bench 2.0 的结果里,self-verification middleware 直接带来了排名跃升。它在 Harness 层的实现就是一个 Stop hook:
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "prompt",
"prompt": "结束前确认:(1) 测试通过了吗?不确定就跑一次。(2) typecheck 通过了吗?(3) 是否写了任务范围外的文件?任一为否,继续。"
}]
}]
}
}
代价是每次会话多一个模型回合;收益是消灭「Agent 停了但测试还是红的」这一整类输出。这是一个极干净的 Harness 投资案例:可量化、可回滚、与模型无关。
判据 19:任何 Harness 改动,都要能写出「预期影响哪个指标、影响方向、如何证伪」。写不出来的改动,不做。
15.5 常见的无效实验
| 陷阱 | 后果 | 修正 |
|---|---|---|
| A/B 两组用不同系统提示词长度 | 输入 token 差异混入结论 | dump-config 比对,逐行对齐 |
没 git clean -fd |
B 组继承 A 组产物 | 重置脚本化,跑前校验 git status |
| 只跑一次 | 采样波动被当成改进 | 每臂至少 3 次,报均值与方差 |
| 用「我觉得更好」当指标 | 不可证伪 | 换成 15.2 的 5 个数字 |
| 拿公开 leaderboard 分数对比自建环境 | Harness 不同,不可比 | 只在同一环境内做相对比较 |
| 同时改模型与 Harness | 归因不可能 | 一次只动一个变量 |
| 用 LLM-as-judge 且不固定温度 | judge 自身漂移 | temperature=0,并给出 rubric |
| 只报成功样本 | 掩盖回归 | 保留全部失败样本与 trace |
15.6 本章产出与验收
核心产出:一份 A/B 对照实验报告,含题面、重置脚本、三臂(标准 / 极简 / PTC 或 模型 A / B)、5 个指标、失败样本、结论与证伪条件。
验收点:
- 能默写「固定什么才能比什么」
- 能说出
git clean -fd在实验里的作用 - 能设计一份至少含 10 个真实用例的 eval suite
- 能对着自己的一次 Harness 改动,写出预期影响与证伪条件
- 能指出 15.5 里至少 3 个自己曾经犯过的陷阱
延伸阅读
| 来源 | URL | 等级 |
|---|---|---|
DSH BENCHMARK.md |
https://github.com/deepseek-ai/deepseek-harness/blob/master/BENCHMARK.md | 官方 |
| 官方文档 · Python SDK | https://deepseek-harness.github.io/deepseek-harness/guide/python-sdk | 官方 |
| 官方文档 · Token 计量 / 会话遥测 | https://deepseek-harness.github.io/deepseek-harness/reference/subsystems/token-meter | 官方 |
| LangChain, The Anatomy of an Agent Harness(top30→top5) | https://www.langchain.com/blog/the-anatomy-of-an-agent-harness | 社区 |
| Heym, Harness Engineering(eval / A/B 方法) | https://heym.run/blog/harness-engineering | 社区 |
| codeongrass, The Outer Harness(self-verification) | https://codeongrass.com/blog/outer-harness-real-work-ai-coding-agents | 社区 |
| FDE-Wiki · 专题三 评估驱动开发 | https://fde-wiki.github.io/topic03 | 社区 |
| 原文(六步跑分与 5 个数字) | https://mp.weixin.qq.com/s/rsfp0Kie5xlDOKDsE3Fqvw | 原文 |