智能体时代还需要代码评审吗?

评论凸显了扩展性瓶颈与盲区

在我的职业生涯大部分时间里,代码评审都是一个相当简单的概念。

一位工程师写好代码、开一个 pull request,另一位工程师在合并之前审查它。第二位工程师寻找 bug、质疑设计决策、提出改进建议,最终给团队多一层信心:这个变更可以安全上线。

它是软件开发中如此平常的一环,以至于我们很少停下来质疑它背后的假设。

其中一个假设是:代码是另一位工程师写的。

这个假设正变得不再可靠。

今天,一个编码智能体可以实现整个功能、跑测试、修复失败、重构实现,并准备好 pull request。开出这个 PR 的工程师,可能把大部分时间花在审查和指挥智能体上,而不是自己写代码。

这让我不禁思考:我们传统的代码评审流程是否还有意义。

并不是因为我认为代码评审已经过时。恰恰相反:我们比以往任何时候都更需要验证。

但我认为,我们需要改变思考代码评审的方式。

1、代码评审最初是干什么的?

在决定代码评审该何去何从之前,值得先问问它最初在解决什么问题。

当一位工程师写出变更、另一位工程师来审查,我们就得到了第二双眼睛。审查者可能抓到作者漏掉的 bug、注意到某个抽象不对、识别出一个边界情况、质疑一个架构决策,或者只是问一句:为什么这里要这样实现?

代码评审也有它的社会维度。它在团队中创造共同的所有权和知识。代码不专属于写它的那个人。

这一切依然有价值。

但当作者是 AI 智能体时,传统流程的每一部分并不都同样有价值。

我开始把编码智能体想成某种有缺陷的同伴(flawed peers)。

想象你是一位资深工程师,身边有一位手速极快、能产出海量代码的同事。他们不知疲倦,对软件开发懂得惊人地多,很多问题解决得非常好。同时,他们对你的特定系统缺乏经验,偶尔会犯一些事后看来显而易见的错误。

你不会盲目合并他们的工作。

你会审查它。

你会给他们清晰的约束。

你会跑自动化检查。

你可能会请另一位专家看看特别重要的变更。

这听起来和我们现在正在构建的智能体开发工作流非常像。

2、开出 PR 的工程师已经是审查者了

这正是我认为传统 PR 规则开始变得有意思的地方。

假设一个团队历来要求每个 pull request 都有一个人类审查。

传统工作流大概是这样:

工程师 A 写代码 → 工程师 B 审查代码 → 合并。

现在考虑智能体工作流:

智能体写代码 → 工程师 A 审查代码 → 工程师 A 开 PR → 合并。

如果工程师 A 真的审查过实现、理解这个变更、并愿意为它负责,那么再要求另一个人做一次泛泛的审查,我们到底多得到了什么?

PR 被开出来并不会魔法般地让代码变得更可信。

有意义的事件发生在那之前:一位工程师检查了这项工作,并决定自己准备好为它负责。

这就是为什么我认为,应当谨慎对待"把批准次数当作质量代理"这种做法。

如果你的旧流程要求一次审查,那么有一个合理的论点是:一个由开 PR 的工程师彻底审查过的智能体生成变更,可能不再需要另一次泛泛的人类批准。

如果你的流程要求两次人类审查,那么也许智能体生成的变更由负责人做一次人类审查,PR 开出后再补一次人类审查。

具体政策取决于系统的风险和变更的类型。

重要的是这个原则:

按下批准按钮的次数,不等于执行验证的量。

3、信任工程师,换来责任心

这里还有一个文化问题。

如果一位资深工程师审查了智能体生成的变更、开出了 PR,并说"我愿意为它负责",我认为我们应当认真对待这句话。

我们常说希望工程师拥有 ownership(主人翁意识)。

但没有信任的 ownership 很难实现。

如果我们告诉工程师他们对代码负责,却又要求另一个人验证他们做出的每一个决定,我们就是在制造一个责任与权力不匹配的系统。

我更愿意走向这样一个模式,我们会说:

你审查过它。你理解它。你拥有它。

作为回报,我们应当期待工程师认真对待这份责任。

这并不意味着对所有变更一视同仁地信任。生产数据库迁移、认证变更或金融交易流程,理应获得与小的 UI 变更不同的验证策略。

它的意思是:我们的流程应当对风险和不确定性做出响应,而不是盲目地给每个 pull request 套用同样的审查人数。

4、更大的问题是代码量

还有一个我认为更重要的问题。

编码智能体让产出代码变得极其便宜。

这太棒了。

它也制造了一个问题。

如果生成代码变得足够便宜,产出的代码量增长可以远快于可用于审查它的人类注意力。

我们不能靠增加更多审查者来解决这个问题。

如果一个智能体产出十倍的代码,而我们的答案是让人手工检查十倍的代码,我们只不过是把瓶颈从"写软件"搬到了"验证软件"。

人类注意力是稀缺的。

所以我们需要对把注意力花在哪里更加挑剔。

5、不要审查那些你可以让它无法出错的东西

这正是架构成为代码评审更重要一环的地方。

有很多类 bug,我宁愿不依赖审查者发现它们。

我宁愿把系统设计成:错误的实现难以甚至无法被表达出来。

考虑一个数据库 schema。

如果数据库要求某个值满足特定约束,我们就不必完全依赖每个应用开发者记得正确校验它。数据库可以强制它。

或者考虑一个业务流程。

如果一个流程只能从 Pending 变为 Approved 或 Rejected,我们可以显式地表达这些状态,而不是允许任意字符串、指望每一段应用代码都能正确处理它们。

有限状态机就是这种方法的好例子。架构本身描述了哪些转移是有效的、哪些不是。

同样的思想适用于类型、契约、API 边界、校验、生成代码、静态分析、自动化测试,以及许多其他显式化的形式。

目标不是让开发者更小心。

目标是让某些错误成为不可能。

这改变了代码评审的经济学。

不再要求人类逐行检查、思考每一种可能的故障模式,我们可以把某些类别的验证移进系统本身。

审查者就可以把有限的认知能力花在真正需要人类判断的事情上。

6、验证成为一个分层体系

这提示了一个审查智能体生成代码的不同模型。

在底层,是约束和架构——它们阻止整类错误实现。

在其之上,是自动化验证:类型检查、测试、静态分析、安全扫描、契约测试、数据库约束、CI 检查,以及任何其他适合该系统的东西。

再往上,是审查变更并承担责任的工程师。

而对于我们想要更多信心的变更,还可以再加一层。

对抗性智能体。

7、如果审查者也是智能体呢?

我们不一定非要在"一次人类审查"和"三次人类审查"之间二选一。

我们可以引入专职智能体,它们的工作不是批准代码,而是努力找出我们不该信任它的理由。

想象一个职责只有安全的智能体。

它审查变更并提出这样的问题:"这个输入能被操纵吗?我们引入了授权绕过吗?有没有新的注入机会?这个变更暴露了本该保持私密的东西吗?"

另一个智能体可能专精性能。

它会寻找昂贵的查询、不必要的分配、N+1 数据库访问、争用、过多的网络调用,或其他性能问题。

我们还可以有专精可靠性、向后兼容、API 设计、测试、无障碍、架构,或任何对特定系统特别重要的关注点的智能体。

重要的是,这些智能体有专门的职责。

我不想要十个泛泛的智能体齐刷刷说 "LGTM"。

我想要对抗性智能体来试图击碎我对实现的信心。

安全智能体应该去找安全问题。性能智能体应该去找性能问题。架构智能体应该去找架构违规。

而且,和编码智能体一样,我们应该记住:它们是有缺陷的同伴。

安全智能体并不能证明我们的应用是安全的。性能智能体并不能证明系统是快的。

它们提供的是又一次独立的找问题尝试。

这仍然可以极具价值。

8、不延长交付周期的更多验证

这给了我们一个相对于传统方式的有趣替代方案。

今天,如果一个变更被认为很重要,我们的反应可能是增加更多人类审查者。

这会增加所需的人类注意力,也可能延长变更走完开发流程的时间。

在智能体工作流里,我们还有另一个选择。

我们可以在不必然增加参与人数的前提下提高验证量。

例如:

Coding Agent
     |
     v
Engineer reviews and takes ownership
     |
     +------> Security Agent
     |
     +------> Performance Agent
     |
     +------> Architecture Agent
     |
     +------> Testing Agent
     |
     v
Automated verification
     |
     v
Merge

不是每个变更都需要全部智能体。

文档变更大概不需要性能审查。数据库迁移大概比改一个按钮标签值得更多审视。

重要的是,验证可以变得可组合。

我们可以按照变更的风险来组装验证流水线。

9、规模化的代码评审

这让我对代码评审有了一个略有不同的思考方式。

面对更多生成代码的答案,不一定是审查更多代码。

而是让更少的代码需要人类审查。

我们可以通过几种方式做到这一点。

我们可以用架构和约束,让某些错误实现无法被表达。

我们可以用自动化去验证机器比人更擅长检查的东西。

我们可以用专门的对抗性智能体去搜索特定类别的问题。

然后,我们把人类工程师留给真正需要人类判断的决策。

这解决的是正确的问题吗?

这是正确的抽象吗?

这符合架构吗?

这些权衡合适吗?

这个行为对业务说得通吗?

这是我们真正想拥有和运营的东西吗?

这些是很难简化为一条自动化检查的难题。

检查一个数据库列是否可空则不是。

检查一个 API 契约是否向后兼容通常可以自动化。

检查每个状态转移是否有效可以编码进状态机。

我们能把越多这类东西移出人类认知,人类就能越有效地审查剩下的那些。

10、PR 没有死

我不认为代码评审会消失。

我认为代码评审的含义正在改变。

当人类写了大部分代码时,自然的工作流是让另一个人类检查作者的工作。

当智能体写了大部分代码时,工程师的角色就少了一些"打出实现的人",多了一些"理解它、验证它、为它承担责任的人"。

这并不意味着我们应该盲目信任智能体。

恰恰相反。

这意味着我们应该围绕它们构建更好的验证系统。

有些验证通过架构进行,有些通过约束,有些通过自动化,有些通过专门的对抗性智能体,还有一些通过资深工程师行使判断力。

目标不应该是为了更快而移除验证。

目标应该是在减少所需昂贵人类注意力的同时提高验证量。

也许智能体时代的问题不是:

"需要多少工程师来审查这个 PR?"

也许它是:

"获得对这个变更的信心,最便宜且可靠的途径是什么?"

有时答案仍然是另一个人类。

有时会是一个智能体。

有时会是一个测试、一个类型、一个数据库约束,或者一个让 bug 不可能发生的架构决策。

而有时,如果一位资深工程师已经审查过这项工作、并且愿意为它负责,也许答案就是信任他们。


原文链接: Do We Still Need Code Reviews in the Age of Coding Agents?

汇智网翻译整理,转载请标明出处