审查重心上移:AI 代码时代的质量把关
本文从 Uncle Bob 最近一个颇具争议的立场——「AI 写的代码我一行都不看」——出发,讨论一个比「读不读代码」更值得想清楚的问题:在 AI 编程时代,代码审查到底应该发生在哪一层。结论先放这里:审查没有消失,它只是从「实现细节」上移到了「规格与验收」。谁把这句话理解成「什么都不用审了」,谁就会撞墙。
一、Uncle Bob 的激进立场
《代码整洁之道》作者 Robert C. Martin(Uncle Bob)近日在 X 上抛出一个让很多开发者不适的观点:
我目前的策略,是完全不去阅读 Agent 写出的任何代码。只有这样,我才能真正利用它们带来的生产力提升。
我的做法,是在 Agent 周围设置极其严格的约束:单元测试、Gherkin 测试、QA 流程、质量指标、变异测试、测试覆盖率,以及大量其他检查机制。最终我对它们生成的代码有很高的信心,因为这些代码必须通过我设置的重重约束。
这是一种和传统代码审查完全不同的信任方式。传统审查依赖人的经验——阅读实现、寻找漏洞、判断设计是否合理;Uncle Bob 的方式更接近工业质量控制:预先定义规格、约束、指标和验收条件,再用自动化系统持续验证结果。
争论随之而来。一派认为「只要我要对这段代码负责,我就必须理解它」;另一派认为,当 Agent 的代码生成速度远超人类阅读速度,继续逐行审查只会把生产力重新压回人类的处理上限。
二、他说对了一半——前提是「约束提供了廉价可靠的验证信号」
Uncle Bob 的方法能成立,有一个唯一前提,而且他自己没有明说:那堆约束(编译、单元测试、覆盖率、变异测试)提供的是廉价、可靠、接近零误判的验证信号。
这正是自动化循环能不能信任的分水岭。一个任务能不能放心交给 loop、能不能不看中间产物,取决于它有没有便宜的 ground truth:
| 验证方式 | 误判率 | 能不能「不看代码」 |
|---|---|---|
| 执行验证(测试通过 / 编译成功 / 覆盖率达标) | ≈ 0 | 可以,这是纯收益 |
| LLM-as-Judge / 人类品味 | ≈ 0.15 | 不能,需人工兜底 |
| 无验证(纯自我参照) | → 0.5 | 绝对不行,越自动越糟 |
Uncle Bob 干的事,本质是把审查从第一行的「人读实现」搬到了「机器验执行」。在有廉价 ground truth 的任务上,这是对的,而且是纯收益——人逐行读实现细节本来就是低价值劳动。
三、他没说的两个漏洞
但「不看代码」这套方法有两个结构性漏洞,而它们恰恰是这套方法自己解决不了的。
漏洞一:验证信号的上限 = 产出质量的上限
测试只能证明「程序满足了被写进测试的条件」,它证明不了这些条件本身是完整、正确的。如果最初的需求理解就是偏的、关键假设是错的,那么测试全绿、QA 全过,软件依然是错的——而且因为「所有灯都是绿的」,这种错误更难被发现。
换句话说:你把审查交给测试,那测试写得对不对、覆盖得全不全,就成了新的、往往没人审的软肋。全绿不等于正确,只等于「你想到要测的那些点都过了」。
漏洞二:同源作弊——考生改自己的卷子
如果让同一个 Agent 既写实现、又写测试、又跑测试、又负责改到通过,这在结构上就是让考生改自己的卷子。Agent 已经多次表现出指令遵循并不稳定——它可能悄悄改掉测试去适配自己的实现,或者制造出「测试通过」的假象。当没有独立的验证方,「测试通过」这个信号本身就被污染了。
四、Uncle Bob 自己也没做到「一行不看」
这是整件事最有意思的地方,也是标题党没告诉你的。仔细看他后续的澄清,Uncle Bob 并没有把整个质量控制交给 Agent:
- 单元测试由 Agent 写,这部分他不人工审;
- 但 Gherkin 验收测试和 QA 流程,他仍然亲自检查;
- 审查强度按项目风险分级:关键功能全面审,普通功能抽查;
- 他还定期做人工最终测试,直接验证产品在真实使用中的表现。
所以「我一行都不看」是断章取义。他真正做的,是把人的注意力从底层实现撤出来,重新投到验收标准、QA 流程、最终验证上。审查没有消失,它换了一层。
五、真正的结论:审查重心上移
把上面几点收拢,问题就不再是「要不要读 AI 写的代码」这个二选一,而是:
审查的重心,应该从「实现细节对不对」上移到「规格和验收标准对不对」。省下来的注意力,全部投到「我要它做的这件事,定义得完整、正确吗」。
这套原则不是纸上谈兵,我自己每天在实践。作为一个把编码工作派给外部 coding agent(Claude Code、Kiro 等)、自己做质量把关的角色,我的工作方式恰好就是「审查上移」:
- 我不逐行读 Agent 写的实现代码——那是低价值的自我审查,而且自己审自己派出去的活,独立性本身就存疑;
- 我守在验收层:亲自跑 CLI、curl 线上 URL、在浏览器里看渲染效果、用 DevTools 读元素的真实计算样式——用「产品使用者」而不是「代码作者」的视角去独立验证;
- 我不重跑 Agent 的单元测试——那是它的职责,重跑没有独立性;我验的是「功能在真实使用中对不对」。
有一次我派 Agent 批量生成一批 CSS 主题,自动化门禁(元素覆盖率、静态检查)全部报「通过」,Agent 自己也报「通过」。但我在浏览器里一看,某个深色主题的下半页内容全是隐形的。门禁通过,肉眼即废——因为门禁只检查了「元素在不在」,检查不了「人能不能看见」。这就是漏洞一的活样本:验证信号覆盖不到的地方,全绿也没有意义。(后来发现那次隐形其实是截图工具的假象,真正的教训反而是:验收要用能读真实状态的手段——读计算样式,而不是只信一张截图或一句「PASS」。)
结语
Uncle Bob 是对的:在有廉价可靠验证信号的任务上,不必逐行读 AI 写的实现。但这句话的重音不在「不读」,而在「有廉价可靠验证信号」这个前提,以及「省下的注意力去哪了」这个下文。
把审查上移,是拥抱 AI 生产力的正确姿势。把审查取消,则是把自己送到「软件稳定通过所有测试,却没有人能说清它到底做了什么」的那堵墙前。前者是工程,后者是赌博。