编码代理为何能运行又为何会崩溃

同一个模型。在网页聊天中 hallucinate 的那个模型,在 Claude Code 里却能一次提交 200 行功能代码。Codex 的 /goal 能整个解决一个 issue。模型并没有突然变聪明,改变的是结构。

为何能工作

对话式 AI 的循环是这样的:

LLM → 人 → LLM → 人

反馈全是自然语言。概率性生成接着概率性评估,精度以乘法劣化。

编程 Agent 的循环不同:

LLM → 代码生成 → 文件保存 → 测试执行 → pass/fail → LLM
LLM → 代码修改 → 构建 → 成功/失败 → LLM
LLM → 类型检查 → 错误信息 → LLM

循环中嵌入了确定性门控。文件系统原样保存写入的内容。测试要么 pass 要么 fail。编译器会明确告诉你哪里错了。这些无意中充当了棘轮的角色。

LLM 是 unreliable component。但在 unreliable component 之上构建 reliable protocol,这是工程学的基本功。TCP 在 unreliable network 之上实现 reliable delivery。RAID 在 unreliable disk 之上实现 reliable storage。ECC 在 unreliable memory 之上实现 reliable computation。

编程 Agent 能工作的原因相同。在 unreliable LLM 之上架设了 deterministic verifier(测试、构建、linter、类型检查器)。成功的原因不是模型性能,而是 topology。

那为何又会崩溃

说它能工作,但它时常崩溃。为什么?

因为棘轮偶然嵌入和有意设计,是两回事。

存在没有棘轮的区间

当 Agent 修改没有测试的代码会怎样?构建通过了,lint 也通过了,但功能已经坏了。在没有确定性门控的区间里,LLM 进行概率性判断,而概率性判断以乘法劣化。

200 个端点中 180 个有测试,20 个没有。Agent 完美处理了 180 个,在 20 个里悄悄埋下 bug。这就是"差不多都好了,但总觉得哪里不对"的原因。

反馈的信息量不足

做了一个排序 1000 个单词的实验。CPU 用 0.08ms 达到 100%。LLM 用 438 秒达到 97.7%。这本身已经令人惊叹——纯靠认知能力达到 97.7%。但真正的发现在别处。

对同样的结果,只改变反馈级别:

反馈结果
6 个错误 (99.4%)
“有错误”10 个错误 (99.0%) — 反而恶化
“有 23 个错误”1 个错误 (99.9%)
“6 个,在这些位置”0 个错误 (100%)

只告诉"错了",反而因过度修正而变糟。告诉错误数量,就有了目标值,它会执着地去找。连位置一起告诉,就能完美修复。

目前的 Agent 大多停留在第二个级别。测试失败时知道"有什么地方错了",但不会传达结构性的原因。虽然有错误信息,但那是症状,不是原因。

存在盲区,且重试无法解决

在排序实验中,LLM 在 R2 留下了 6 个错误。R3 报告"没有错误"。R4b 也报告"没有错误"。同样的 6 个错误,以同样的方式被遗漏。

没有提示时,无论重复多少次都收敛在 99.4%。告诉它"还剩 6 个"后才终于达到 100%。

编程 Agent 中也发生同样的事情。Agent 制造了 bug,self-review 判断"没有问题",再让它修复还是遗漏同一处。retry 不是解决方案。盲区是模型概率性特征带来的结构性限制,不是努力不够。

规模放大时乘法效应生效

97.7% 精度的步骤链接两次就是 0.977² = 95.4%。三次是 93.2%。十次是 79.2%。

Agent 修改单个文件做得很好。但让它重构涉及 100 个文件的代码呢?即使每步 97%,经过 100 步就是 0.97¹⁰⁰ = 4.8%。实际上等于保证失败。

这就是"vibe coding 在 200 个端点时崩溃"的数学解释。小项目中链接次数少,概率还撑得住;大项目中乘法效应灾难性地发作。

需要什么

能工作的原因和崩溃的原因指向同一个地方:确定性验证门控的有无。

当前的 Agent 依赖偶然嵌入的棘轮(测试、构建、linter)。如果有意识地去设计,它会更强大。

有意识地设计棘轮意味着:

第一,识别没有棘轮的区间。没有测试的代码、没有 schema 的 API、没有类型的数据。Agent 在概率性判断的每个地方都是薄弱环节。

第二,提高反馈的信息量。只返回 pass/fail 会引发过度修正。需要结构化地传达"在哪里、为什么、什么与预期不同"。

第三,在链接的中间插入确定性门控。一次性跑 10 步乘法效应是灾难性的,但每步都用棘轮锁定,劣化就会被重置。

LLM 是惊人的生成器。纯靠思考就能以 97.7% 的精度排序 1000 个单词。人类也做不到。但任何不是 100% 的东西,重复就会崩溃。0.977 的平方是 0.954。

编程 Agent 能工作,不是因为模型聪明,而是因为循环中嵌入了确定性门控。崩溃,是因为那个门控缺失了。

生成可以是概率性的。验证必须是确定性的。


相关文章