我们说过,Claude Code 自身大约 90% 的代码由 Claude 写。那么我们怎么按这个产出量审代码?还有人读代码吗?出事了谁抓住?

本文讲 Claude Code 团队的代码审查流程及其演变。从 6 月到 9 月,合入 Claude Code 代码库的 pull request 翻了一倍多,而必须回退的比例下降超过 40%。

我们没有取消审查。但我们把大部分阅读交给机器,为人的时间与注意力做优化,并大力投入让错误能又快又容易撤销。

重新思考代码审查的目的

Agent 写代码时,改动量上升很快。在 Anthropic 的 monorepo,每天落地的改动从今年 5 月约 2500 到 9 月超过 30000。

Claude Code 在自己的仓库,与 monorepo 分开,但压力同样大。以这种速度交付,人工逐行审代码极其困难,甚至不可能。

代码审查做两件事:

  1. 在上线前发现并修复问题
  2. 在团队间建立共享上下文与代码库理解

本文主要聚焦发现与修复问题,文末会回到第二件事。

我们认为「人是否读过代码?」是「这次改动可能出什么问题,哪个检查——自动或人工——最适合抓住它?」的不精确代理。

问这个问题也改变了审查何时发生。以前审查是路尽头的门禁:写代码、开 PR、等同事。

现在审查持续跑,更像写字时的拼写检查。多数改动在请人看之前,至少已被 Claude 审过并修过一次。这抓住多数例行错误,把团队注意力留给更高层的问题与审视。

稀缺资源:人的时间与注意力

我们想把人的时间与注意力留给只有人能解决的问题,并确保自动检查抓住其余。以我们当前的改动速率,人仍有极多事要做,团队几乎每天都会碰到新而新奇的挑战。

人的时间覆盖审查成本的两边:人花在审查上的时间,以及花在修复坏代码造成问题上的时间。砍掉前者若只是出现在后者,并无帮助。

因此目标是:Claude Code 仓库(CLI、桌面与网页应用、移动应用)里多数 PR 最多一个人在环即可合入——可以是作者——且回退与事故不增加。为度量人的时间,我们跟踪每人次 PR 的人工批准(中位与第 95 百分位)、人工评论,以及 PR 等人多久。回退与事故率是护栏:若上升,我们没有省下人的时间,只是挪了位置。

一次改动的一生

一次典型改动,从工程师笔记本(或 Slack 里的 Claude 会话)出发,经过多层代码审查。

图:一次 pull request 的检查,自上而下。开 PR 前验证工作。每个 PR 上:必需 CI、Claude 代码审查与安全审查(全自动),再按风险人工批准。然后 merge queue;合入后先内部用 feature flag,再渐进发布,最后监视、向前修或回滚。

路径大半自动化;人的注意力用在风险所在处

逐层

图:六层自上而下叠:验证、必需 CI、AI 审查、安全审查、人工批准、merge queue 加 flags。各层漏洞位置不同。穿过某层漏洞的问题被更后层抓住;有一个穿过每层漏洞,落到底部的快速回滚。

每层抓住一些问题、漏掉另一些。很少能穿过全部;回滚处理其余。

1. 别人看之前先验证工作

多数审查现在发生在 PR 存在之前。我们给 Claude 能跑的东西——测试、构建,或对照设计的截图——并要求它展示输出,而不是说做完了。再让 subagent 用新鲜上下文审 diff。两种习惯来自我们的 最佳实践指南。

开 PR 前,许多人还会跑几个内部 Skills:一个找 bug,一个简化 diff,一个端到端查行为。UI 改动也会对照设计指南检查。

创建 Claude Code 的 Boris Cherny 称,给 Claude 验证工作的方式 大概是最重要的事,才能拿到好结果。他估计最终结果好两到三倍,并写到:「验证因领域而异。可能简单到跑一条 bash 命令,或跑测试套件,或在浏览器或手机模拟器里测 App。」

当自动审查者反复标同一类事,我们在源头修: 在 Skill 里、用 lint 规则,或更新说明文件,例如:

  • CLAUDE.md 告诉 Claude 项目是什么:技术栈、约定、目标与非目标。每次审查都会加载,因此在大型代码库我们保持短,并从那里指向其他文档。审查者也会标出违反其中约定的代码,以及让其中某行过时的改动。
  • REVIEW.md 由代码所有者写,告诉审查者他们那部分代码里什么重要。我们另外检查审查者是否真按它做。好的写得短:说明该仓库里失败长什么样(文档是「说谎」,配置是「误路由」),限制吹毛求疵,列出可跳过的路径,并要求文件与行号作证据,而不是凭名字猜。也要求摘要以计数开头,并在无事可修时直说。

2. 每个 pull request 都有 AI 审查

每个 PR 在人看之前先经 Claude 审查。它对照整仓与 PR 声明的意图读 diff,并问:改动是否解决了问题、是否契合系统,或是否弄坏别的东西?

对 bug 修复,它找根因。公开版 Code Review for Claude Code 现已对 Team 与 Enterprise 计划正式可用;/code-review 在本地跑更轻的版本。

我们 发布研究预览 时,内部 PR 收到实质性审查评论的比例从 16% 到 54%。多数超过 1000 行的 PR 有发现,多数小 PR 干干净净回来。管理员把各仓库设为 Quick、Standard 或 Deep。漏掉一个 bug 的代价高于多花审查时间的地方,Deep 值得。

发现在人审之前由其他 Agent 核验。 若干 Agent 同时找 bug。再由另一组对每个发现投票,足够多人同意真实才贴出。仅关于风格、诊断或清理的发现丢掉。我们在自己的 PR 上 A/B 测过这些过滤器再保留。剩下的按严重程度排序成行内评论。每条标 Important、Nit 或 Pre-existing,因此 PR 未引入的 bug 不会看起来像作者的错。

每个发现必须被回应。 要么修,要么带理由解决线程。常有 Agent 隔夜接手修复,作者回来时 PR 已经又过一轮。

3. 可阻塞的安全审查

安全也有独立自动审查。bug 审查或安全审查还有未解决发现时,PR 不能合入。要么修,要么用短理由关线程——这就是清误报的方式。

若后续 commit 修了问题,发现会自行清除。可用开源安全审查 GitHub Action 或 /security-review 命令搭同样的东西。设置见 Claude Code 里的自动安全审查。

4. 可阻塞的自动检查

常规那些:lint、类型检查、每平台测试、构建。(我们写过为此量级扩展 CI 的文章,在这里。)典型 CLI PR 在任何人看之前可能跑几十项检查。PR 模板问改动如何测过、如何撤销。Claude 可填,但要求改动的人对它签字。

5. 按风险缩放的人工批准

文档修复与自动更新器改动风险不同,审查也不同。

风险 示例 人工批准
低 文档、文案、仅内部功能、flag 后的加法改动 自动审查与安全检查绿了后不要求
中 普通产品改动,以及缓存、自动更新器或系统提示词等敏感区域 一人
高 最高风险代码,外加始终需要两人的一小批路径 两人

定档的是改动,不是作者。 分类器读改动并选风险档。第二个分类器问:即使档位说不需要,这次改动是否仍要另一人。有些路径始终要人:所有者列为敏感的任何东西,以及任何 CI workflow 文件。

只有受信作者走更轻路径。 只有仓库受信列表上的作者走更轻路径,多半是拥有该仓的团队。其他人需要第二人批准。Agent 的批准永不算人的。自动审查可清低风险改动,但不能填需要人的名额。

提示改动的人要对它负责。 在 Agent 写的 PR 上,指挥 Agent 的人算作必需审查者之一,与亲手打代码一样。

批准覆盖某一个具体 commit。 若落地系统无法担保的新 commit——如 Agent 的 push,或有人手解的合并——批准必须再给一次。

6. Merge queue、flags 与渐进发布

Merge queue 对带改动的 main 重跑每项检查,因此两个分开通过的 PR 不能合出坏掉的 main。新行为通常先对 Anthropic 员工开 flag,我们大量使用常在用户之前暴露回归。公开发布先走 latest 通道,stable 通道滞后。

7. 快速检测、快速回滚

有些错误仍会穿过,因此最后一层是尽快抓住。Flags 无需部署即可关掉。Claude Code 有每周 on-call 轮值,事故回顾问哪一层本该抓住问题。

发现坏合入仍依赖作者与 on-call,以及回退与事故看板。我们尚无那些数字移动时收紧批准的断路器;这里的工程师希望在更多代码走向零人合入之前先有它们。

一位同事说减速确实降低错误率,但多半因为你样样做得更少。我们宁愿更快发现并修好问题。

我们如何让审查者更好

我们的代码审查流程在循环中持续改进。

任何事故现在都是评测。 团队收集导致事故的过往 PR,连同向前修与回退,并让了解那段代码的工程师确认每个 bug 及位置。审查者每天对照该集合跑。

图:事故或回退变成经专家核过的用例并加入评测集。对审查者的改动进入每日评测跑,对照每个用例打分;分数升则保留、不升则丢掉,循环从下一改动再开始。

评测随每起事故增长,对审查者的每次改动都对照全部打分。

我们通过观察人对评论做什么来度量噪声。 若不介意标很多非 bug,很容易抓住更多 bug,所以需要制衡。我们按 PR 上的人如何回应给审查者留下的每条评论分类:修了、说错了、说行为是有意的,或判定无关紧要。我们也在已知干净的 PR 上跑审查者,数它报告「若有人据此做有害改动」的频率。我们写明的优先级是:先抓住真 bug,其次减少审查轮次。

作者是 Agent 时噪声更贵。人几秒就能挥掉一个 nit。Agent 会修,意味着又一个 commit、又一轮审查。

审查必须收敛。 Agent 作者与 Agent 审查者可无限互相忙。一个 CLI PR 隔夜过了五十多轮审查与修复,才被作者停下。

我们对审查者反复标的东西跑 git blame,约 59% 是审查者第一遍起就存在的代码。审查者很少找新 bug,而是每轮多找几个旧的。

我们自己也让情况更糟。我们习惯默认跑好几轮,因为每遍总能抓住新东西。对风险高的改动可能值得,但对每个 PR 不值得。团队现在跟踪 rounds-to-pass 与召回,并改了再审:

  • 轮次上限。 三轮后,审查者请作者退后重新考虑做法。
  • 前几遍之后只审 diff。
  • 标出 bug 类别, 让作者修每一处实例,不是一行。
  • 不重复 已贴出的发现。

审查 Agent 也每晚跑过现有代码,帮我们在旧 bug 出现在别处之前抓住它们。

图:收敛工作前后:一轮审查与修复后通过的 PR 从 65% 到 78%;需要五轮及以上的从 8.9% 到 1.5%;通过前平均审查次数从 2.08 到 1.32。

收敛改动后,内部 PR 每 PR 审查轮次更少

人仍在环的地方

把资深工程师从深度工作拉出来抓例行错误,成本远高于自动审查。团队里的人仍负责:

  • 决定是否要做。 方向、品味与范围。一个宣称审查瓶颈已解决的团队,仍对团队外的改动保留人工审查,以便有人问「我们到底该不该做这个?」
  • 审查风险代码,如计费、自动更新器与 CI workflows。
  • 审查架构——会立下他人会照搬的模式的那些。
  • 读证据。 测试输出、跑过的命令与返回、截图、审查者发现。若说不出检查会漏什么,要真审查而不是快速批准。
  • 对结果负责。 每个上线的改动都有人问责,不论谁打的字。

在团队间共享上下文

代码审查的第二份工作一直是传播代码库理解。读同事的 diff 是你了解改了什么、零件如何契合的方式。若机器做大部分阅读,人怎么学代码?

我们没有正式流程。团队里没人在脑子里保留 Claude Code 的完整心智模型,我们认为也不需要。有人想理解代码库某部分时,让 Claude 刚好为那一切片写讲解。几分钟,且反映今天的代码。

Diagram titled “If machines do most of the reading, how does anyone learn the code?” On the left, a grid stands for the codebase, with a few squares highlighted as managed settings, the part you want to understand; nobody keeps a complete mental model of it in their head. An arrow labeled “Ask Claude about exactly that slice”, with the example question “How does Claude Code retrieve managed settings?”, leads to two outcomes: Claude writes an explainer, which takes minutes and reflects the code as it is today; and, for some, Claude builds a small artifact that visualizes that part of the code and teaches it the way that person likes to learn. Along the bottom: reading trivial diffs line by line, a one-line copy change teaches you almost nothing; an explainer for the module you are about to change teaches you a lot.

有些人更进一步,让 Claude 做小 artifact,可视化那部分代码,并用那人喜欢的方式教。

若目标是好好花人的注意力,这胜过逐行读琐碎 diff。一行文案改动几乎教不了你什么。你即将改的模块的讲解教很多。默认在开放 Slack 频道工作的文化也有帮助:别人在建什么,你边建边看见。

「你落地,你拥有」

若你落地小或中等改动、仍出了问题,团队规范通常是你来修。几件事避免这变糟:

  • 改动小, 因此好审、好调、好回退。
  • 一切可逆。 Flags、回退与分阶段发布几分钟内撤销多数错误。
  • 爆炸半径定门槛。 昂贵代码需要更多人与更多检查。
  • 回归经遥测与内部使用快速浮现。
  • 不是追责。 拥有修复意味着你上下文最多;事故回顾看系统。

所有权也是共享的。团队许多人在 开放频道 工作,任何人都能看见别人在建什么、接上线程,或让 Claude 补缺口;不拥有该代码的人也会给反馈。这种开放是质量在没有每行门禁时仍保持高的重要原因。

我们改方向时

Agent 让开工变便宜,因此有些活不该落地。通常频道里有人问为什么、指向更早决定,或建议更简单路线,作者就关闭或重塑 PR。

既然代码写得快,关 PR 不觉得亏。窍门是在线程里尽早提出不同方向,而不是在已完成 PR 上当阻塞评论。

你怎么采用这套流程

用你的团队做这件事的多数零件今天已存在。

开 pull request 前

  • 给 Agent 能跑的检查,列在短 CLAUDE.md 里,外加跑格式化与 linter 的 hooks。
  • 本地跑 /code-review 与 /security-review,或新鲜上下文的 subagent 审查。
  • 加 REVIEW.md,并把反复出现的审查评论迁进去。

每个 pull request 上

  • 要求 CI,并在 PR 模板加「Testing」「Risk」「How to revert」。
  • 在一个仓库加 AI 审查者(Code Review for Claude Code,或 Claude Code GitHub Action),调几周 REVIEW.md,再扩大。
  • 加自动安全审查,并要求合入前解决每个审查线程。
  • 按风险匹配审查力度:例行改动快速过,漏 bug 代价高的地方 deep(Code Review 里的 Quick、Standard 或 Deep)。
  • 限制审查轮次;前几轮后只再审新 diff。

批准

  • 写下风险档,由改动而非作者定;先严后随证据放宽。
  • 更轻批准路径留给你信任的作者。
  • 用 CODEOWNERS 与分支保护,让鉴权、计费、CI 与发布 workflows、安装器始终需要人。
  • 永不让 bot 批准替代必需的人;新 commit 上撤销批准。

合入之后

  • 用 merge queue、feature flags、先内部用、分阶段发布与一步回滚。
  • 把事故与回退变成评测集,审查者的提示词、工具或模型变时重新打分。
  • 度量人的时间,以回退与事故率为护栏。

走向何方

Code Review 的 公告 说批准 PR 仍是人的决定;产品贴发现,不贴批准。我们自己的仓库走得更远,让所有者决定哪些低风险改动仅靠自动检查合入,这条线还在移动。

审查漏了什么时,我们问模型面前缺了什么,并把修复放进 CLAUDE.md、Skill 或新检查。目标没变:每改动更少人时,回退不比以前多。

若你的团队让 Agent 开 pull request,我们想听听你自动化了哪些检查、哪些仍要人,以及你认为我们哪里错了。

感谢 Emma Webb、Michael Segner 与 Amie Rotherham 审阅。


附录:原文图示

原文嵌入了以下图示,官网的 Markdown 导出里没有,这里另存成图片附在文末。

图 A — 一次改动的一生 FIG A: The life of a change 一次典型 Claude Code 改动,从作者机器到用户。路径大半自动化;人的注意力用在风险所在处。

图 B — 层,不是一道门 FIG B: Layers, not one gate 六层检查,其下是回滚。每层抓住一些问题、漏掉另一些;回滚处理其余。

图 C — 事故即评测 FIG C: Our incidents are the eval 由过往事故与回退建成,每天跑。评测随每起事故增长,对审查者的每次改动都对照全部打分。

图 D — 收敛的审查 FIG D: Review that converges 内部 pull request,收敛改动前后。收敛改动后每内部 PR 审查轮次更少。

共享上下文插图 If machines do most of the reading, how does anyone learn the code? 「在团队间共享上下文」一节的图示:「若机器做大部分阅读,人怎么学代码?」