宇众不同

90% 的代码是 AI 写的,那评审怎么办

一条推文里的三个数字把我按住了:90% 的代码由 AI 写、PR 数量翻倍、回滚率反而降了 40%。

这三件事同时成立,说明「人逐行读代码」从来就不是质量的关键变量。但真正让人想往下读的,是它接下来做的事——没有取消评审,而是把评审从「合并前的一道闸门」拆成了七层流水线,并且明确写出每一层由谁负责、什么情况下允许零人工合并。

原文是 Claude Code 团队 10 月 15 日发在 claude.dev 的工程博客《How the Claude Code team does code review》,作者 Addy Osmani、Morgan Westlee Lunt、Qing Wang。下面是中文整理版:保留原文的层次结构与全部数字,行文按中文习惯重写,不做逐句直译。

原文:https://claude.dev/blog/solving-code-review-at-anthropic/
推文(推荐来源):https://x.com/0xlogiclog/status/2114893090448126059
中文整理,非官方译本;所有数据均出自原文自述口径,未附第三方审计。

一、先把问题换掉

压力是先从规模上来的。Anthropic 的 monorepo 里,每天落地的变更从今年 5 月的约 2,500 次涨到 9 月的 30,000 次以上。Claude Code 有自己的独立仓库,不在这个 monorepo 里,但同样在被推着跑。到这个速度,人工逐行评审已经不是「辛苦」,而是「物理上做不到」。

Claude Code 自己的代码里,约 90% 是 Claude 写的。6 月到 9 月,这个仓库合并的 PR 数量翻了一倍多,而需要回滚的比例下降了 超过 40%。

团队说他们没有取消评审,但做了三件事:把大部分「读」交给机器、把人类时间当成要优化的稀缺资源、把「撤销错误」做得又快又便宜。

关键的动作是一个提问方式的替换:

不问「有没有人读过这段代码」,而问「这次改动可能出什么问题,哪一层检查——自动的还是人的——最适合拦住它」。

这个问题一换,评审发生的时间点也变了。以前评审是路尽头的一道关卡:写完代码、开 PR、等同事。现在评审是持续运行的,更像写作时的拼写检查——大多数改动在被要求人类看一眼之前,已经被 Claude 审过并修过至少一轮。

二、真正的稀缺资源是人类时间

这句话要拆成两半看:人类时间既包括「人花在评审上的时间」,也包括「人花在修坏代码上的时间」。只砍掉前者没有意义,如果省下来的时间转头出现在后一个桶里。

所以他们的目标是:Claude Code 各个仓库(CLI、桌面端、Web 端、移动端)的绝大多数 PR,合并时至多有一个人类在环,且这个人可以是作者本人,同时不让回滚率和事故率上升。

怎么量?两条线:

  • 人类时间:每个 PR 的人类审批次数(看中位数和 P95)、人类评论数、PR 等待某个人的时长。
  • 护栏:回滚率和事故率。这两个指标一涨,说明人类时间没有省下来,只是搬了个位置。

三、一次变更要过七层

从工程师的笔记本(或者 Slack 里的一个 Claude 会话)到用户手里,一次典型变更要走这么一条路:

1. PR 出现之前,工作必须被验证过。

给 Claude 一些能跑的东西——测试、构建、一张可以和设计稿对比的截图——并要求它展示输出,而不是口头说「做完了」。然后再起一个全新上下文的子 agent 审 diff。这两条习惯来自他们的 best practices 文档。

开 PR 之前,很多人还会跑几个内部 skill:一个专门找 bug,一个专门简化 diff,一个做端到端行为检查;UI 改动还要对一遍设计规范。

Claude Code 的作者 Boris Cherny 说过,给 Claude 一个能验证自己工作的方式,可能是拿到好结果最重要的一件事,他估计这能让最终结果好 2 到 3 倍。

还有一条很实操的原则:当自动评审反复对同一件事告警,要在源头修掉它——改 skill、加一条 lint 规则,或者更新两个说明文件:

  • CLAUDE.md:告诉 Claude 这个项目是什么——技术栈、约定、目标和非目标。每次评审都会加载它,所以在大仓库里要写短,剩下的指向别的文档。评审器还会顺手标出违反其中约定的代码,以及让某一行过时的改动。
  • REVIEW.md:由 code owner 写,告诉评审器「我们这块代码什么才算要紧」。好的 REVIEW.md 都很短,但会说清这个仓库的「失败」长什么样——文档仓库的失败是「它在撒谎」,配置仓库的失败是「它路由错了」;限制 nits 的数量,列出可以直接跳过的路径,并且要求给出文件名和行号作为证据,而不是看着变量名猜。

2. 每个 PR 都有一轮 AI 评审。

在人类看到之前,每个 PR 都先过一遍 Claude:把 diff 放在整个仓库和 PR 声明的意图之间对照——这个改动解决了它要解决的问题吗?符合系统设计吗?有没有弄坏别的东西?如果是 bug 修复,它会去追根因。

这块最有意思的是如何压制噪音:

  • 多个 agent 并行找 bug;
  • 再起一组独立的 agent 对每条发现投票,票数够了才允许发布;
  • 纯风格、诊断、清理类的发现直接丢弃(这两个过滤器是他们拿自己的 PR 做 A/B 测出来的);
  • 剩下的按严重度排序成行内评论,并标注 Important / Nit / Pre-existing——「Pre-existing」这一档专门用来告诉作者:这个 bug 不是你这次引入的。

然后是一条硬规矩:每条发现都必须被回应——要么修,要么带理由把线程关掉。经常是 agent 夜里就把修复捡走了,作者第二天回来,PR 已经又过了一轮。

公开版本 Code Review for Claude Code 现在已经在 Team 和 Enterprise 套餐上 GA,本地可以用 /code-review 跑一个轻量版。效果数据:研究预览上线时,内部 PR 拿到实质性评审意见的比例从 16% 涨到 54%。1000 行以上的 PR 大多能收到发现,小的通常干干净净。管理员可以给每个仓库设 Quick / Standard / Deep 三档——在「漏一个 bug 的代价大于多花评审时间」的地方,Deep 是划算的。

3. 安全评审也有阻断权。

安全是独立的一遍。只要 bug 评审或安全评审还有任何一条未关闭的发现,PR 就不能合并;你修掉它,或者写一句简短理由关掉线程(这也是声明误报的方式)。如果后续的 commit 真的修好了,发现会自动清除。

4. 自动检查也阻断。

就是常规那套:lint、类型检查、各平台测试、构建。一个典型的 CLI PR 在任何人看之前,可能已经跑了几十项检查。PR 模板要求填写「怎么测的」和「怎么撤销」,Claude 可以帮忙填,但提需求的那个人要签字。

5. 人工审批按风险分级,不按作者分级。

  • 低风险:文档、文案、纯内部功能、藏在 flag 后面的增量改动 —— 自动评审和安全检查全绿后,不需要人。

  • 中风险:普通产品改动,以及缓存、自动更新、系统提示词这类敏感区域 —— 1 人。

  • 高风险:最高风险的代码,加一小批永远需要两个人的路径 —— 2 人。

  • 分级由变更决定:一个分类器读这次改动、给出风险等级;第二个分类器再判断「即使等级说不用,这次改动是否需要额外一个人」。有些路径永远需要人——owner 标记为敏感的路径,以及任何 CI workflow 文件。

  • 轻量路径只给可信作者:只有仓库可信名单上的作者(基本就是拥有这个仓库的团队)才能走轻量路径,其他人一律需要第二个人批准。

  • agent 的批准永远不算人的批准:自动评审可以让一个低风险改动通过,但它填不了「这里必须有一个人」的那个位置。

  • 谁提的需求,谁背这个改动:agent 写的 PR 里,指挥 agent 的那个人算作必需评审人之一——跟亲手敲代码一样。

  • 一次批准只覆盖一个 commit:如果之后又落了系统无法担保的 commit(比如 agent 推送的、或有人手工解冲突的合并),批准要重新给。

6. 合并队列、flag、灰度。

合并队列会把改动重新应用到最新的 main 上,再跑一遍所有检查——避免两个各自通过的 PR 合起来把 main 弄坏。新行为通常先对 Anthropic 员工开 flag,内部的高强度使用往往能在用户之前暴露回归。对外发布先走 latest 渠道,stable 渠道滞后。

7. 快速发现,快速回滚。

总会有漏网的,所以最后一层只做一件事:快点发现。flag 不用发版就能关;Claude Code 有每周轮值的 on-call;事故复盘会追问:哪一层本该拦住它?

原文很坦白地列了还没做到的事:目前没有「回滚率或事故率恶化就自动收紧审批」的熔断器,而团队希望在更多代码走向零人工合并之前先有这个东西。

关于速度,有位同事的说法值得抄下来:放慢确实会降低错误率,但主要因为你什么都做得更少了。

四、怎么让评审者自己变好

这套流程不是一次设计出来的,而是一个闭环。

事故就是 eval。 团队收集了历史上引发过事故的 PR(连同它们的 forward-fix 和回滚),请熟悉那段代码的工程师确认「bug 是什么、长在哪里」,做成一个评测集,每天对评审器跑分。评审器的 prompt、工具或模型有任何改动,先跑分,分数涨了才留,不涨就丢。

用人的反应来量噪音。 想多抓 bug 很容易,只要你不介意报一堆不是 bug 的东西。所以他们把评审器留下的每条评论按「人怎么反应」分类:他修了、他说这错了、他说这是有意为之、他觉得不重要。同时也在已知干净的 PR 上跑评审器,统计它多久会给出一条「照着改反而会变坏」的建议。写下来的优先级是:先抓真 bug,其次减少评审轮次。

噪音对 agent 更贵。 人可以几秒钟挥掉一个 nit;agent 会去改,改了就是一个新 commit、一轮新评审。

评审必须收敛。 一个 agent 作者加一个 agent 评审者,可以互相忙到天荒地老——有个 CLI PR 一夜之间跑了五十多轮评审和修复,最后是作者手动叫停的。他们对「评审器反复告警的东西」跑了 git blame,发现约 59% 是评审器第一轮就已经存在的旧代码:它很少在发现新 bug,只是每一轮多发现几个旧 bug。

更糟的是他们自己也在加剧它:因为「每一轮总能捞到点新东西」,默认跑好几轮变成了习惯。这在高风险改动上值得,但不该发生在每个 PR 上。于是改了四条规则:

  • 轮次上限:三轮之后,评审器要求作者退一步,重新考虑方案。
  • 只看新 diff:头几轮之后,只审新增的部分。
  • 标记一整类 bug:让作者一次性修掉所有同类实例,而不是修一行。
  • 不重复:已经发过的发现不再发。

另外,评审 agent 还会在夜间对存量代码跑,趁旧 bug 在别处冒头之前先抓出来。

收敛前后的对比(内部 PR):

  • 一轮评审加修复就通过的:65% → 78%
  • 需要五轮以上的:8.9% → 1.5%
  • 平均评审轮次:2.08 → 1.32

五、人还留在哪些环节

把资深工程师从深度工作里拽出来抓一个常规错误,成本远高于一次自动评审。团队里人依然负责这些事:

  • 决定要不要做。 方向、品味、范围。有一个宣布「评审瓶颈已解决」的团队,仍然保留了对团队外部改动的人类评审——总得有人问一句「这事我们到底该不该做」。
  • 审高风险代码。 计费、自动更新、CI workflow。
  • 审架构。 那些会被别人抄走的模式。
  • 读证据。 测试输出、跑的命令和它的返回、截图、评审器的发现。原文有一句很锋利的话:如果你说不出这些检查会漏掉什么,那就该要一次真正的评审,而不是一个快速批准。
  • 对结果负责。 每一个上线的改动,都有一个人对它负责,不管代码是谁敲的。

六、共享上下文:这件事没有正式流程

代码评审的第二个职能,一直是传播对代码库的理解——读同事的 diff,是你知道「什么变了、各块怎么拼起来」的方式。如果大部分「读」都交给了机器,人怎么学代码?

原文的回答很干脆:我们没有正式流程,也没人脑子里装着 Claude Code 的完整模型,而且我们认为不需要。

想搞懂某一块代码时,直接让 Claude 针对那一小块写一份讲解:几分钟,而且反映的是当下的代码。有些人更进一步,让 Claude 生成一个小制品,把这块代码可视化,按他自己习惯的学习方式来教他。

他们的判断是:如果目标是「把人类注意力花在刀刃上」,这比逐行读琐碎的 diff 强得多。一行文案改动几乎什么都教不了你;一个你正要改的模块的讲解,能教你很多。

前提是文化:团队默认在开放的 Slack 频道里工作,你在别人建东西的过程中就看见了。

七、「你合并,你负责」

如果你落地了一个中小改动、之后出了问题,团队惯例是通常由你来修。有几件事让它不至于变成灾难:

  • 改动小,所以好评审、好 debug、好回滚。
  • 一切可回滚:flag、revert、分阶段发布,几分钟就能撤销大部分错误。
  • 爆炸半径决定标准:贵的代码配更多人、更多检查。
  • 回归浮现得快:靠遥测和内部使用。
  • 这不是追责:你来修是因为你上下文最多;事故复盘看的是系统。

所有权同时也是共享的。很多人在开放频道里工作,任何人都能看到别人在建什么、接手一个线程,或者把 Claude 指向一个缺口;反馈也常来自并不拥有这块代码的人。这种开放,是「不在每一行上设关卡、质量依然守得住」的重要前提。

八、什么时候该把方向改掉

agent 让「开始一件事」变得很便宜,所以注定有些东西不该落地。通常的情况是:频道里有人问一句为什么、指回早先的某个决定、或者提一条更简单的路,作者就把 PR 关掉或重塑。

因为代码写得快,关掉一个 PR 并不让人觉得损失。诀窍是在早期就在线程里提出不同方向,而不是在完成的 PR 上留一条阻塞评论。

九、想在自己团队照做,清单在这

PR 之前

  • 给 agent 一些它能跑的检查,写进一份简短的 CLAUDE.md;加 hooks 跑 formatter 和 linter。
  • 本地跑 /code-review 和 /security-review,或者起一个全新上下文的子 agent 审一遍。
  • 加一个 REVIEW.md,把重复出现的评审意见搬进去。

每个 PR

  • 强制 CI;PR 模板加「Testing / Risk / How to revert」三项。
  • 先在一个仓库上 AI 评审,用几周时间把 REVIEW.md 调顺,再推广。
  • 加自动安全评审,并要求合并前所有评审线程 resolved。
  • 评审力度匹配风险:常规改动快过,漏一个 bug 很贵的地方用 Deep。
  • 限制轮次;头几轮之后只审新 diff。

审批

  • 把风险分级写下来,由变更决定而不是由作者决定;先严,有证据再松。
  • 轻量审批路径只留给你信任的作者。
  • 用 CODEOWNERS 和分支保护,保证 auth、计费、CI、发布流程、安装器永远需要人。
  • 永远不要让 bot 的批准替代必需的人类批准;新 commit 使旧批准失效。

合并及之后

  • 合并队列、feature flag、内部先用、分阶段发布、一键回滚。
  • 把事故和回滚变成 eval 集;评审器的 prompt、工具、模型一变就重新打分。
  • 度量人类时间,用回滚率和事故率当护栏。

十、后记

原文最后说,产品层面 Code Review 仍然只发布发现、不做批准,批准依旧是人类的事;他们自己的仓库走得更远一些,让 owner 决定哪些低风险改动可以只靠自动检查合并,而这条线还在移动。目标一直没变:每次变更花更少的人类时间,回滚不比以前更多。

三点我自己的读后补充:

第一,这套流程真正的产出不是「AI 评审」,而是「证据」。 每一层都在生产可核验的东西:测试的真实输出、跑过的命令和返回、对比设计稿的截图、带文件名和行号的发现、agent 之间的投票。人类的工作从「读代码」变成了「读证据 + 定方向」。这也是为什么「如果你说不出这些检查会漏什么,就该要一次真正的评审」这句话是整套设计的地基。

第二,最容易抄错的是顺序。 很多团队看到「AI 评审」就先上工具,却没先做好三件更笨的事:改动小、一切可回滚、CI 硬阻断。缺了这三样,AI 评审产生的每一条噪音都会变成真实成本,三个月后大家的结论就是「AI 评审没用」。原文把回滚放在最底层,不是巧合。

第三,59% 这个数字值得贴在墙上。 评审器反复告警的,大部分是它第一轮就看见过的旧代码——它没有记忆,也没有「这一轮只看新 diff」的边界,于是把「发现问题」变成了「刷存在感」。任何做 AI review 的人,如果不做轮次上限和去重,最终都会得到一个把作者和 agent 一起拖进死循环的系统。那个跑了五十多轮的 CLI PR,就是没有这条规则时的默认结局。

原文:https://claude.dev/blog/solving-code-review-at-anthropic/(Addy Osmani, Morgan Westlee Lunt, Qing Wang,2026-10-15)
版权归原作者所有。本文为中文整理与节译,非官方译本。