title: "也许我们不应该审查所有代码"
source_url: "https://martinfowler.com/rachels-ramblings/code-review.html"
author: "Martin Fowler"
excerpt: "公共早报 面对 AI 生成的代码,作者认为我们不应急于自动化代码审查,而应通过结对编程、协作设计和基于例外的审查将判断环节前移,因为代码审查已被赋予了它原本无法独自承担的重负。"
TL;DR
又或者,问题可能不在于 AI 打破了代码审查,而在于我们一直用代码审查来解决错误的问题
最近我在 Code Remix 的 DX 小组讨论中与 Brian Houck 同台,由 Moderne 主办。这是我参加过的最有意思的讨论之一,主要是因为我们有分歧。正如我的同事 Martin Fowler 所说,当人们有分歧且双方都有充分论据时,讨论才更有意思。Brian 和我确实做到了。
Brian 随后写了一篇深思熟虑的文章,题为《代码审查究竟是做什么用的?》。他对自己的立场显然充满热情,而我的立场也让我有足够的热情来写这篇回应。需要澄清的是,我认为我们大多数时候想要的是同一件事。我只是不认为代码审查是实现那些目标的最佳方式。不过 Brian 人很好,他还鼓励我写这篇文章。但如果说我不希望你们在看完本文后认为我是对的,那我就是在撒谎 :)
那么我们到底在争论什么?
AI 生成的代码比人类能够实际审查的要多得多。Brian 提供了一些相当惊人的数据:在 Meta,据报道每位工程师着陆的重大代码行数一年内增加了 106%,而 DX 自己的数据显示 PR 规模中位数增加了 64%。
他与我共同关心的问题是:简单地用自动化取代代码审查,可能会失去我们用它实现的所有其他功能。代码审查不仅仅是为了找 bug。它还是团队共享知识、指导初级工程师、建立集体所有权和传播架构理解的方式。
我的问题是:为什么我们要等到代码审查阶段才去做所有这些事情?
我从来不太喜欢以 Pull Request 作为软件开发流程的中心。并不是因为工程师不应该查看彼此的代码,而是因为我一直难以接受这样的理念:我们应该先构建、完成、包装好、抛给另一个人,然后才就"我们是否以正确的方式构建了正确的东西"这个重要问题展开对话。
更别提 Merge 冲突了。我在这上面浪费了太多生命。
将判断前移
我在 Thoughtworks 学到的早期原则之一是缩短反馈循环。如果反馈有价值,就不要删除它。把它移到离它所影响的决策更近的地方。
以我们声称代码审查能带来的那些价值为例。
如果我们想探索替代方案,我更愿意在实现其中一个方案之前就做这件事。
如果我们想传递知识,就去结对编程。坐在某人身边,无论是线下还是线上,当他们在推理一个问题时,你会学到比读完他们已完成的方案后多得多东西。
如果我们想让初级工程师学习资深工程师的思维方式,就让他们在资深工程师思考时与之协作。结对编程再次浮现在脑海中,但团队也可以在写代码(或指示 agent 写代码)之前,通过白板进行集体设计会议。
如果我们想要集体所有权,就组织团队,让人们真正地集体构建和运维软件,而不是依赖一个 Pull Request 来告诉每个人别人已经构建了什么。这里同样可以使用结对编程、集体编程,或围绕白板的团队设计会议。
如果我们想要架构对齐,就一起设计(我不会重复关于结对编程和团队设计会议的内容,哦等等……),然后将重要约束编码为适合度函数(fitness functions)。
而如果我们在审查代码格式、linting、已知安全问题或可以确定性测试的内容,就让它们自动化。2026 年了,我们真的不应该还在为空白符争论。
结对编程、基于主干的开发、自动化测试、静态分析、适合度函数和安全扫描都能将反馈提前。日益地,agent 也可以参与这些循环,挑战设计、测试假设、持续验证正在构建的内容,但真正的思考来自有经验的人类——如果我们希望这种经验能使整个团队受益,就必须比代码审查更早像一个团队一样行动。
基于例外的审查
以上并不意味着永远没有人审查代码。有些变更我绝对希望有另一个有经验的人来查看。一个例子是根本性的架构变更。假设我们作为更大的团队做了一个设计会议,我们可能希望作为团队来审查代码,或者确认它是否正确实现,或者讨论我们是否想改变什么。其他的例子可能包括跨越敏感安全边界的变更、具有巨大冲击范围的变更、不熟悉的关键系统部分,或者简单地说团队觉得"我对这个不太有信心"的情况。
这些恰恰是人类判断有价值的地方,但这与要求人类检查每一个变更截然不同——因为我们过去一直用这种仪式来建立信心。
我们现在知道继续走这条路是不可行的,所以代码审查才会一直作为一个问题或障碍出现。如果一个 agent 能产生十倍的代码,但每一行最终都要排队等待一位高级工程师来检查,我们并没有创建一个十倍的工程组织,我们只是创建了一个庞大的积压队列和一个新的瓶颈。
而且我不认为答案是让一个 AI agent 假装是人类审查者,这样我们就能以更高的速度保留完全相同的过程。那是在自动化仪式本身,而不是质疑这个仪式为什么存在。
不过 Brian 的论点中确实有一件事让我担心。他谈到团队累积认知债务和意图债务:软件在增长,但负责它的人对它为何以这种方式运作的理解却越来越少。我认为这是一个非常现实的问题。我只是不认为强制性的 Pull Request 是对这一问题的特别有力的防御。
如果 agent 要在未来产出更多的实现,我们需要更加审慎地通过协作设计、结对、良好的边界、可执行架构、共享运营责任,以及可能一些我们尚未发明的实践来维护人类的理解。
我们需要工程师理解系统,而不是 Diff。
也许这正是 AI 所暴露的。我们多年来将大量非凡的责任加载到了不起眼的代码审查上:质量门、安全检查、架构审查、辅导机制、知识共享系统、所有权模型。
在人类只能以一定速度产生代码的约束下,它是有用的——勉强有用。但这一约束正在消失。所以也许问题不在于如何更快地审查代码。也许问题在于,我们为什么要一开始等到代码审查阶段才进行所有这些重要的对话?