TL;DR

本文核心观点:

  1. AI 编码的核心不是速度,是复杂度棘轮 — 系统只能变好,不能变坏
  2. 90% 测试覆盖率是相变点,不是线性改善 — DO-178C 民航标准早就验证了这个临界值
  3. AI 让 90% 覆盖率成本趋近于零 — 过去五十年这个成本太高,现在 agent 可以自动写测试
  4. 测试即文档,评估即验证 — 每轮编码输出的三样东西构成向上棘轮

📋 本文结构

  1. 软件曾经是脆的 — 五十年软件工程围绕一个假设组织
  2. 现在软件是软的了 — AI 改变了错误模型
  3. 复杂度棘轮 — 只向上走,不能向下
  4. 为什么是 90% — 相变点,不是目标线
  5. AI 让它免费 — agent 写测试消除了意志力成本
  6. 延伸思考

一、软件曾经是脆的

五十年以来,整个软件工程学科围绕一个假设组织:防止错误,因为错误是灾难性的。

代码必须在第一次就写对。漏掉一个边界情况,生产环境就崩溃。发布一次糟糕的数据库迁移,客户数据就没了。写一个内部有微妙逻辑的函数,当唯一理解它的人离职,没人知道它为什么能工作。

整个系统依赖人类保持谨慎——但人类并不严谨。

所以我们构建了 elaborate 的流程:code reviews、staging 环境、QA 团队、release trains——全都设计来在错误到达用户之前捕获它们。

这套流程勉强有效。但它很慢。而且它意味着任何软件系统的复杂度都有硬天花板:一个团队能同时装在脑子里的东西就是上限。


二、现在软件是软的了

不是说软件变得草率。意思是软件获得了前所未有的弹性。

当我说”模型在这里”,我的意思是 AI 编码 agents——Claude、GPT、Codex,以及围绕它们成长的生态——现在可以阅读代码、理解上下文、诊断错误、写出修复方案。不是完美的,但足够好,错误模型已经改变了。

数据库迁移崩了?agent 读取错误信息,理解跨 45 个版本的数据库 schema 历史,写修复方案,写测试。

文件同步在百万个符号链接上挂起?agent 诊断解析器超时问题,设定 30 秒边界,带测试发布修复。

提取管道有归属 bug?跨模型评估捕获它,prompt 迭代,数据库层添加 enforcement。

大多数代码级错误——逻辑 bug、解析失败、边界情况崩溃——agents 现在可以在下一轮诊断和修复。这是真正的新东西。


三、复杂度棘轮

Garry Tan 把这个机制叫做”复杂度棘轮”:

每一轮 AI 编码,agent 向代码库添加三样东西:测试 + 文档 + 评估结果。

这三样东西构成一个向上棘轮——系统只能变好,不能变坏。

每个测试覆盖一个可能的错误路径。随着覆盖率上升,可能潜入代码库的 bug 空间收缩。每次发布都比前一次更好测试,每个循环都在增加系统未来的稳定性。

关键在于:棘轮是单向的。添加的测试不会消失。它们锁定的正确行为不会回退。


四、为什么是 90%

这不是随意选的一个数字。90% 是相变点,不是目标线。

DO-178C 民航标准要求 A 级软件(灾难性故障会致死的系统)达到 90% 以上的 MC/DC 覆盖率。几十年航空工业的经验验证了这个临界值:低于这个阈值,残留的未覆盖路径会相互作用,产生不可预测的系统行为;高于这个阈值,系统行为变得可预测,残余风险可接受。

软件工程的”快速移动、打破东西”和”缓慢移动、安全发布”之争,本质上是未测试代码和已测试代码之间的权衡。90% 覆盖率是让速度和安全不再对立的那个点。


五、AI 让它免费

过去五十年,90% 测试覆盖率意味着大量的人类意志力投入。

写测试是重复的、不爽的、看起来像阻碍速度的工作。人类工程师在压力下会偷懒——跳过边界情况,用简单测试糊弄复杂场景,把覆盖率压到刚好通过评审的程度。这不是人的错,这是激励结构的问题。

现在,agent 可以为你写测试。

Garry Tan 的工作流:写代码的同时,agent 自动生成测试。代码和测试一起出现,不需要额外的意志力成本。结果是 90% 覆盖率实际上可以维持——不是因为团队更有纪律,而是因为写测试的负担消失了。

agent 不偷懒,不疲劳,不会在 deadline 前夕放弃测试覆盖率。


延伸思考

Garry Tan 提出的”复杂度棘轮”实际上是一个组织理论的洞见,不只是工程实践。

棘轮之所以有效,是因为它利用了不对称性:向上走很容易(添加测试),但向下走需要主动删除测试(而你不会这样做)。

大多数复杂系统缺少棘轮,因为初始设计没有建立这种不对称性。代码库会腐化,不是因为人不想写好代码,而是因为腐化的摩擦小于维护的摩擦。棘轮改变了摩擦的方向。

AI 的贡献不只是让测试更容易写,而是建立了一个自我强化的向上循环:更好的测试 → 更低的错误率 → 更敢改代码 → 更多的重构 → 更多的测试覆盖。

这个循环一旦建立,代码库的长期轨迹就变了。


相关链接

  • Garry Tan 原文:https://x.com/garrytan/status/2054064931515855118
  • GStack:https://github.com/garrytan/gstack
  • GBrain:https://github.com/garrytan/gbrain
  • 标签#Testing · #Software-Engineering · #Claude-Code

本系列相关: