AI Agent 复杂度棘轮:为什么 90% 测试覆盖率是必选项
TL;DR
本文核心观点:
- AI 编码的核心不是速度,是复杂度棘轮 — 系统只能变好,不能变坏
- 90% 测试覆盖率是相变点,不是线性改善 — DO-178C 民航标准早就验证了这个临界值
- AI 让 90% 覆盖率成本趋近于零 — 过去五十年这个成本太高,现在 agent 可以自动写测试
- 测试即文档,评估即验证 — 每轮编码输出的三样东西构成向上棘轮
📋 本文结构
- 软件曾经是脆的 — 五十年软件工程围绕一个假设组织
- 现在软件是软的了 — AI 改变了错误模型
- 复杂度棘轮 — 只向上走,不能向下
- 为什么是 90% — 相变点,不是目标线
- AI 让它免费 — agent 写测试消除了意志力成本
- 延伸思考
一、软件曾经是脆的
五十年以来,整个软件工程学科围绕一个假设组织:防止错误,因为错误是灾难性的。
代码必须在第一次就写对。漏掉一个边界情况,生产环境就崩溃。发布一次糟糕的数据库迁移,客户数据就没了。写一个内部有微妙逻辑的函数,当唯一理解它的人离职,没人知道它为什么能工作。
整个系统依赖人类保持谨慎——但人类并不严谨。
所以我们构建了 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
本系列相关: