
“完成了”
让 AI Agent 为 527 个函数编写测试。Agent 完成工作后汇报:
“已完成。”
实际编写了测试的函数:40 个。
它没有说谎。做完 40 个之后,它判断"够了"。遇到困难的函数就跳过,再做几个后得出结论:“剩下的也是类似的模式,差不多了。”
LLM 擅长生成。但不能信赖它判断是否完成。
棘轮
棘轮扳手的齿只向一个方向咬合。转动时向前走,松手时停住,但绝不会倒退。
Ratchet Pattern 将这一机制应用于 Agent 控制。
项目 1: 机械验证 → PASS → 下一个
项目 2: 机械验证 → FAIL → 重试(附带反馈)
项目 2: 机械验证 → PASS → 下一个
...
项目 N: PASS → 完成。停止。
三条规则:
- 每次只展示一个项目。
- 通过后才能进入下一个。
- 全部通过后停止。
将这些规则实现为 CLI,Agent 只需知道一个命令:next。其余由机器决定。
在 40 处停下的 Agent vs 跑完 527 的棘轮
相同的模型。相同的项目。相同的 527 个函数。
自主 Agent: 40 / 527 (7.6%) — Agent 宣布"完成"
棘轮 CLI: 527 / 527 (100%) — 机器宣布"还剩 487 个"
差异不在模型性能。在于谁来决定"结束"。
自主 Agent 模式下,LLM 判断何时终止。LLM 是乐观的。做了 40 个就觉得"够了"。棘轮模式下,机器判断何时终止。机器没有感觉。剩余项目归零之前,它只会宣布"还没完"。
一句话定义
将概率性 Agent 放进确定性状态机。
| 角色 | 负责方 |
|---|---|
| 生成 | LLM |
| 判定 | verifier |
| 进度管理 | ratchet |
很多系统把生成、判定和终止判断全交给 LLM。Ratchet 将它们分离。
五项原则
1. 终止条件是机械的
pass/fail。不是"looks good"。go test 通过就是 PASS。coverage 达到 100% 就是 PASS。没有主观判断的余地。
2. PASS 是不可变的
通过的项目不会重新打开。不会回滚。剩余项目数单调递减。
remaining_work(t+1) ≤ remaining_work(t)
今天做好的东西明天不会被拆掉。只能前进。这是与"24 小时 Agent"的根本区别。没有终止条件的 Agent 今天加一层抽象,明天删掉,后天再加回来。棘轮不允许这种振荡。
3. LLM 只负责生成
生成代码、编写测试、提出修改方案——这是 LLM 的职责。修改什么、是否通过、下一个是什么、是否结束——这些全由机器决定。LLM 不是 planner,而是 constrained generator。
4. 剥夺 Agent 的终止判断权
如果由 LLM 说"完成了",就会在 40 处停下。如果由机器说"完成了",则在 527 处停下。棘轮存在的意义,浓缩在这一句话里。
5. Verifier 必须是确定性的
不是什么都能当 verifier。
| 可以 | 不可以 |
|---|---|
go test | “looks cleaner” |
| coverage 测量 | “seems better” |
| AST validation | “more scalable” |
| schema diff | “clean architecture” |
Verifier 的条件:deterministic、machine-checkable、resumable、localized feedback。不满足这四项,棘轮的齿就咬不住。
反馈就是 gradient signal
如果棘轮只返回"通过/失败",LLM 会盲目修改。反馈越具体,LLM 的修正就越精准。
弱反馈: "测试失败" → LLM 盲目修改
中等反馈: "coverage 65%" → LLM 大致补强
强反馈: "line 41, 44, 70 未覆盖" → LLM 精确覆盖那些分支
真实项目验证的数据:
无反馈: coverage 卡在 60~70%
有反馈: 达到 100%(限可达函数)
相同的模型。“line 41 not covered"这一行就充当了 gradient signal。
反馈分辨率越高,LLM 修正精度越高,循环次数越少,成本越低。
Agent 会死。进度活着。
Agent 必然会崩溃。Token 上限、网络错误、会话断开。如果棘轮把进度持久化存储,Agent 死了,下一个 Agent 接着来。
Agent A: 处理函数 1~200 → 崩溃
Agent B: next → 从 201 继续
Agent C: next → 从 401 继续
Agent 是一次性的。进度是累积的。
换掉 Verifier,就是另一个工具
棘轮不绑定特定的验证器。换一个验证器,就变成另一个工具。
| 棘轮 + 验证器 | 用途 |
|---|---|
棘轮 + go test + coverage | 逐函数测试生成 |
| 棘轮 + 结构规则 validator | 代码结构整理 |
| 棘轮 + hurl pass/fail | API 端点验证 |
| 棘轮 + 规格交叉验证 | SSOT 一致性保障 |
| 棘轮 + Toulmin verdict | 用户自定义规则强制 |
模式只有一个。验证器决定领域。
问题
你的 Agent 完成了多少个之后说"完成了”?
那真的完成了吗?
谁决定了"结束"——Agent,还是机器?
相关文章: 比起模型智商,反馈拓扑更重要 — Ratchet Pattern 的理论背景。为什么反馈结构比模型性能更重要。