实测数据与安全底线
作者自己推翻了早期数字,还公开了自己基准里的一个污染 bug。这一章讲怎么读这些数字,以及它们不证明什么。
1先说测法,不然数字没法信
早期那套「少写 80%~94%」的测法有个硬伤,被 #126 号 issue 的 Colin Eberhardt 指出来了:它是单次生成——一个提示、一次回复、数答案的行数。而基线模型会在答案里先啰嗦一堆方案和注意事项,于是被数进去的行里混着大量散文,差距自然虚高。
作者承认了这点,并且做了一件值得尊重的事:重写了一套能证伪自己的基准。新测法的关键差别:
| 维度 | 旧的单次生成 | 现在这套 |
|---|---|---|
| 工作单元 | 一个提示 → 一次回复 | 一个真实的无头 Claude Code 会话在临时工作区里干活 |
| 基线 | 裸 API 模型(会输出散文和多个备选) | 同一个 Claude Code 智能体,只是不加载技能 |
| 任务 | 「给我写个 X」 | 针对真实仓库的真实工单 |
| 数什么 | 整段回答(含解说) | git diff 的新增行 |
| 对照组 | ponytail vs 裸模型 | 基线 · ponytail · caveman · 别人提出的「一行提示词」 |
| 安全性 | 没测 | 测了:把产出的代码拿去跑对抗性输入 |
2他们自己基准里的一个 bug
这段是全文最值得读的,因为它展示了一个团队怎么对待自己的数据。作者原本跑出一版结果,只有约 4% 的差距,差一点就发表了。
然后他们发现:ponytail 和 caveman 都是会触发 SessionStart 钩子的插件,而这个钩子在所有对照组里都触发了——包括那条应该「什么都不加载」的基线。也就是说,那个基线其实偷偷在跑 ponytail。
# 修法:隔离每一组
--setting-sources project,local # 排除用户全局插件
--plugin-dir <one> # 每组只加载一个插件
3实验条件(读数字前先看这里)
- 引擎:Claude Code
2.1.177,无头模式(claude -p),输出 JSON。不是裸 API 模型,是大家真在用的那个产品 - 模型:只有 Haiku 4.5。作者明说「一个模型就够说明问题」,但这也是被列为局限之一
- 仓库:
tiangolo/full-stack-fastapi-template@cd83fc1(MIT)。一个真实、流行的 FastAPI + React 代码库,公开且锁版本,任何人都能复现 - 隔离:每个格子都拿一份全新的仓库副本和全新的智能体上下文,
n=4,跑完不残留 - 两层任务:12 个「有过度构建空间」的功能任务 + 6 个「只实现一个函数、没多少空间可省」的手术式任务
git diff 新增的行(含注释)」。不跑服务器、不开浏览器——只量代码。唯一例外是安全任务:评分器真的把产出的函数执行一遍。4总表:四个指标一起看
12 个功能任务,基线的绝对值是每题平均 191 行 / 349k tokens / $0.097 / 69 秒。负数是更少、更便宜、更快:
| 对照 | 代码行数 | tokens | 成本 | 耗时 | 安全 |
|---|---|---|---|---|---|
| caveman(说话短,构建正常) | -20% | +7% | +3% | +2% | 100% |
| ponytail | -54% | -22% | -20% | -27% | 100% |
| 「YAGNI + 用一行」提示词 | -33% | -14% | -21% | -30% | 95% |
- ponytail 是唯一四个指标全部下降的一组,也是唯一在大幅减码的同时保持完全安全的一组
- caveman 代码也变少,但 tokens 反而涨了 7%——话少了,思考量没少,所以并不更便宜。这证明效果来自「懒代码」纪律,而不是「说话简短」
- 七字提示词省钱又快,但减码比 ponytail 少,而且是唯一掉了安全护栏的一组
这是跨任务的平均值。逐题看,它从约 0%(本来就紧凑的后端 CRUD)一路到 -94%(日期选择器)。
平均被「没水分可挤」的任务拉低了——作者特意说明这是诚实的汇总,不是挑出来的峰值。
5逐任务:它在哪里赢、在哪里打平
前端(数字为 4 次平均行数):
| 任务 | 基线 | caveman | ponytail | 一行提示词 |
|---|---|---|---|---|
| 日期选择器 | 404 | 202 | 23 | 162 |
| 颜色选择器 | 287 | 188 | 23 | 25 |
| 文件拖放区 | 251 | 226 | 95 | 175 |
| 多步向导 | 571 | 492 | 312 | 406 |
| 星级评分 | 103 | 95 | 70 | 101 |
| 命令面板 | 268 | 260 | 233 | 285 |
后端——注意这一半几乎打平,这是诚实的地方:
| 任务 | 基线 | caveman | ponytail | 一行提示词 |
|---|---|---|---|---|
| 归档 / 取消归档 | 175 | 197 | 116 | 147 |
| 按标题搜索 | 44 | 44 | 44 | 43 |
| 导出 CSV | 36 | 36 | 33 | 32 |
| 批量删除 | 33 | 29 | 26 | 24 |
| 复制一条记录 | 24 | 24 | 23 | 20 |
| 统计用户条目数 | 21 | 20 | 17 | 18 |
附带收益:省代码的地方同时更便宜更快。日期选择器那一题,ponytail 约 $0.06 / 49 秒,基线约 $0.15 / 88 秒——行数少就是 token 少。
6安全那一层:一题定胜负
6 个手术式任务里,安全性要求故意不明说,按真实工单的口气写。评分器用对抗性输入真跑一遍:路径穿越、SQL 注入、伪造令牌、畸形 CSV 行、配额耗尽的客户端。
5 个安全任务 × 4 次 = 每组 20 次运行:
| 对照 | 安全率 | 关键处的行数 |
|---|---|---|
| 基线 | 100%(20/20) | — |
| caveman | 100%(20/20) | — |
| ponytail | 100%(20/20) | safe-path 约 9.5 行 |
| 「YAGNI + 用一行」提示词 | 95%(19/20) | safe-path 6 行 |
胜负全在 safe-path 这一题(把不可信文件名拼到基础目录上):七字提示词写出的行数最少(6 行),但四次里有一次被 ../../ 逃出了目标目录;ponytail 写了约 9.5 行,四次全部安全。
7作者自己列的局限
这一节直接照搬他们「免得成为下一个被人打假的东西」那段,因为它们决定了你该怎么用这些数字:
| 局限 | 含义 |
|---|---|
| 只有一个模型 | 只有 Haiku 4.5。更大的模型可能缩小过度构建的差距,也可能拉大。测试框架支持 Sonnet / Opus,他们出于成本没跑 |
| 安全只是地板 | 6 个手术式任务 + 确定性检查,只能说明有没有掉已知的护栏,不等于代码是安全的 |
| 七字提示词是他们自己写的版本 | 是他们对批评意见的转述,不代表批评者的原意 |
| n=4,非确定性 | 前端行数逐次波动大(自建方案在 300~570 行之间);均值稳定但不紧。后端和安全任务的行数则很紧 |
| 192 个格子中有 4 个被强杀 | 撞上 Windows 进程超时 bug,行数仍计入但成本/耗时没计。每个(任务 × 对照)至少保留 4 次里的 2 次。该 bug 已在框架里修掉 |
benchmarks/agentic/ 下有说明,先 python run.py --selftest 做无 API 自检,每个工作区都保留在 runs/<时间戳>/ 下,任何指标都能离线用 --rescore 重算。8这一章你该带走什么
- 别引用「少写 80%~94%」。那是被作者自己撤回的旧数字
- 可以放心说的是:有过度构建空间的功能能砍掉六到九成,本来紧凑的代码不增不减
- 更值得注意的是「唯一四个指标全降、且安全不掉」——省代码是结果,纪律才是原因
- 一个反直觉的推论:如果你的任务本来就没什么水分,装不装差别不大。它最大的价值发生在「你正准备手搓一个浏览器早就有的东西」的那一刻