Anthropic 的 monorepo,每天落地的变更从 5 月约 2,500 次,涨到 9 月超过 30,000 次。Claude Code 有一个独立于 monorepo 的仓库,6 月到 9 月,合并 PR 的数量翻了一倍多,revert 率却降了四成以上。

这组数字很容易被读成另一个 AI 编程神话。模型写得更多,人写得更少,团队跑得更快。

但我读完 Anthropic 这篇代码评审复盘,真正停下来的地方恰好相反。它讲的不是如何让 Agent 写更多代码,而是当机器已经能把代码库塞满时,人到底还该看什么。

这个问题离 Java 和 Spring 团队并不远。把 Claude Code 换成内部 Agent,把 monorepo 换成几十个服务,把每日变更换成持续不断的 PR,熟悉的焦虑就来了。以前评审慢,是因为人手不够。现在评审慢,可能是因为人还在用阅读每一行 diff 的方式,处理一台代码生成机吐出来的产物。

代码变多,不等于风险被分摊了。

以前的 Code Review,默认前提已经失效

传统 Code Review 有一个很朴素的分工。作者写代码,reviewer 逐行阅读,靠经验找 bug、挑命名、确认边界。作者的产出速度和 reviewer 的阅读速度,大体在一个量级,所以这套做法虽然累,仍然能转得动。

AI 把这个平衡直接掀掉了。

Anthropic 的说法很克制。Claude 写了 Claude Code 约九成的代码,但它没有把人从回路里拿掉,而是把人放到 human-on-the-loop 的位置。区别只差一个词,含义差很多。human-in-the-loop 是每一步都等人批准。human-on-the-loop 则允许系统自己跑,但人负责设计护栏、盯住异常,并在高风险处做决定。

这听着像是管理学术语,落到工程里其实很具体。

如果一个 Agent 提了 20 个 PR,你让资深工程师把 20 份 diff 从头读到尾,最后通常会发生两件事。第一,最熟悉业务的人被低价值阅读耗干。第二,真正危险的问题藏在第 17 个 PR 里,却因为所有 PR 看起来都工整、测试也都绿了而溜过去。

AI 生成的代码有一种很别扭的特性。它常常比人写得整齐,却未必比人写得更懂上下文。它能补齐 interface,能把 test fixture 铺得很全,甚至能把异常分支写得像模像样。但它不知道一个看似普通的字段,会不会被下游拿来做幂等键。它也不会天然知道某个 Spring 事务边界背后,是库存、优惠券还是一笔不能重复扣的钱。

所以,评审的瓶颈已经不只是发现语法和逻辑错误,而是识别那些没有写在代码里的约束。

这才是人的位置。

别把 AI review 当成第二双眼睛,它更像一道流水线

Anthropic 的做法里,有个很值得借的思路。他们不把自动评审当成在 PR 下多留几条评论的机器人,而是让多个检查器组成分层流程。每一层只解决自己擅长的问题,再把信号递给下一层。

这比让一个大模型拿到 diff 后问它有没有问题,靠谱得多。

可以把它拆成四道门。

第一道门是确定性检查。格式、依赖漏洞、静态分析、生成文件、迁移脚本、测试覆盖率,这些事情不需要模型表现得聪明。它们需要稳定、快,而且同一件事每次都给出同一个答案。Java 项目里的 Checkstyle、SpotBugs、ArchUnit、依赖许可证扫描,都该放在这里。

第二道门是变更理解。让模型回答的不是「这段代码有没有 bug」,而是「这个 PR 在改变什么行为」「它碰到了哪些模块」「有哪些隐含契约可能被影响」。这一步的输出应该是一页 briefing,给 reviewer 压缩阅读成本,而不是把十条模棱两可的评论扔到 PR 里。

第三道门才是对抗式审查。这里可以让不同 Agent 带着不同任务来找茬。一个盯权限与数据泄露,一个专门沿着异常路径走,一个检查并发与重试,一个把接口改动和消费者的实际调用放在一起看。它们不必都正确,但应该给出能复现的证据,文件、调用链、反例输入,缺一个就只能算提示,不能算阻塞。

第四道门留给人。人不再审查所有 token,而是审查风险排序是否合理,审查产品和架构上的取舍,审查那些自动化无法获得完整信息的东西。比如一个降级策略是否会让财务数据静默缺失,一个缓存改动会不会让租户隔离失效,或者一段重构是不是把未来三个月的维护成本悄悄转给了别的团队。

这里有个经常被忽略的细节。自动检查的价值不在于抓到多少问题,而在于让人能放心地不看一大批低风险内容。没有这层信任,AI review 只会制造更多待处理评论,最后把 PR 页面变成告警收集器。

评审质量不能只看拦下了多少 bug

很多团队开始上 AI review 后,第一反应是统计命中率。这个月模型抓了多少问题,评论被采纳多少条,少了几次线上事故。

这些数字有用,但不够。

假设一个机器人每天留 200 条评论,采纳率 20%。从报表看,它抓到了 40 个问题。可如果其中 35 个是命名、空格或已经被测试覆盖的小问题,资深工程师被迫在 200 条噪声中找那 5 个真风险,系统实际上是在消耗组织注意力。

Anthropic 文章里提到,团队把机器的阅读能力用来帮助人集中在高风险决策上。这是我觉得最成熟的部分。他们不是把吞吐当成唯一目标。6 月到 9 月,PR 增速很猛,但 revert 率还下降了超过 40%。至少从这个结果看,流程没有用稳定性去换速度。

如果你正在给团队设计指标,我会建议把下面几类数据放在一起看。

  • 高严重级问题的 precision。被标为阻塞的问题,有多少最终被证实成立。
  • reviewer 的有效阅读时间。不是停留在 PR 页面的时长,而是人是否真的少读了无风险 diff。
  • 变更后的滞后事故。特别盯发布后一周内的回滚、热修和 SLO 波动。
  • 反馈闭环速度。一个错误评论被纠正后,规则或提示词多久能更新。
  • 规则逃逸率。那些没有触发任何告警、却由线上事故暴露的模式,是否被沉淀成新的检查。

后面两项最容易被漏掉。模型并不是装上就结束了,它会漂移,代码库也会变。上个月很好用的规则,服务拆分后可能开始误报。一次严重漏检,如果只是写在事故复盘里,三周后同类问题还会再来。

代码评审不是一套固定的关卡,它应该像测试一样持续生长。

对 Spring 服务而言,最先自动化的不是写代码

不少人会从「让 Agent 生成 Controller 和 CRUD」开始试验。这当然没问题,不过我更建议先从 review 的上下文收集开始。

原因很简单。生成代码的失误,通常能在局部看到。评审缺上下文的失误,往往要等到跨服务调用、灰度发布、数据回填一起发生才会露出来,代价更贵。

一个实际可落地的最小版本,大概可以这样搭。

PR 创建后,Webhook 拉起一个 review orchestrator。它先拿到 diff、关联 issue、模块 owner、接口契约、数据库迁移和最近同区域的 incident。不要一次性塞给大模型,先用规则将变更归类。例如改动 @Transactional、库存扣减、鉴权表达式、消息消费重试、Flyway migration 的 PR,直接提到高风险队列。

然后让 Agent 生成一份变更地图。它应该列出修改过的业务能力、受影响的上游下游、可能破坏的 invariant,以及建议 reviewer 先看的三个文件。对一个支付服务来说,invariant 可能是同一业务单只能扣款一次。对一个用户服务来说,可能是任何读取接口都不能越过 tenant boundary。

这里不要迷信 RAG。很多团队一听上下文就把所有 Confluence、所有历史 PR 都检索进来,结果模型得到一碗信息粥。更实用的办法是把重要约束写成短小、可版本化的规则卡。它们放在仓库里,跟代码一起变更。每张卡说清楚一件事,适用范围、不可违反的条件、验证方式和 owner。

例如。

1
2
3
4
5
规则卡  payment-idempotency
适用范围 payment-service 的 create 与 confirm 路径
不变量 同一个 businessOrderId 最多生成一笔成功扣款
验证 并发重复请求、消息至少一次投递、超时重试
owner payment-platform

这张卡对 reviewer 有用,对 Agent 更有用。因为它给的不是抽象原则,而是可检验的边界。

我不太认同「人只负责点 approve」的想象

有一种很诱人的未来叙事,Agent 写代码,Agent 测试,Agent review,人最后按一下 approve。这种流程看起来很省人,但它把人的责任压缩成了一个无法履行的签字动作。

如果人没有时间理解系统,approve 不是监督,只是责任转移。

现实里也该承认另一个立场。有些小改动确实不值得资深工程师反复阅读。文档修正、测试数据更新、明确的机械重构,完全可以在足够强的护栏下自动合并。团队若还要求每个改动都开一场人工评审,反而是在拿稀缺注意力做仪式感。

问题不在于自动合并,而在于你是否知道哪些改动可以自动合并。

这需要风险分级,不是模型自信度。模型说自己有 95% 把握,几乎不该成为放行理由。更应该看的信号包括改动触及的资产、可逆性、爆炸半径、测试的独立性、是否跨越了服务契约。一个只改 README 的 60% 自信模型,风险仍然很低。一个碰到权限判断的 99% 自信模型,仍然应该进人工队列。

回到开头的数据。Anthropic monorepo 每日落地的变更从约 2,500 次到 30,000 次以上,涨的不是一点效率,而是工程组织的节奏变了。以前一个 reviewer 可以靠认真覆盖大部分变更。现在想继续靠更努力地读代码,只会被吞吐量击穿。

真正的升级不是请更多 AI 来写代码,而是把人的判断力从逐行阅读里救出来。

机器可以负责把地图画出来,把重复检查跑完,把最可疑的路径圈出来。人需要继续为方向、边界和后果负责。

这门手艺不会消失,只是终于不用再假装它等于读得更快。

可以从明天开始做的三件事

如果团队已经在用 Claude Code、Cursor 或内部编码 Agent,我建议别急着采购一个更花哨的 review bot。先做三件小事。

第一,复盘过去三个月的线上问题,挑出重复出现的三类失误,写成仓库内的规则卡。它们比一份泛泛的 Code Review 指南更容易被执行。

第二,在 PR 模板里增加「行为改变」和「不可违反条件」两栏。作者和 Agent 都必须填。这个动作有点笨,但它会逼着生成代码的人把意图说出来。

第三,拿一个非核心服务跑两周影子模式。让 Agent 生成变更摘要和风险提示,不阻塞合并。两周后再看,哪些提示真的帮 reviewer 少走了弯路,哪些只是噪声。保留前者,删掉后者。

别一上来就追求全自动。

当代码生成速度已经足够快时,最稀缺的东西不是更多代码,而是足以承担后果的注意力。

参考资料