我们之前说过,Claude Code 自己的代码里大约 90% 是 Claude 写的。那么在这么大的产出量下,我们怎么审代码?还有人读代码吗?出了问题谁来兜底?
这篇文章讲的是 Claude Code 团队的代码审查流程,以及它是怎么演进的。从 6 月到 9 月,Claude Code 代码库合入的 PR 数量翻了一倍多,而被迫回滚的比例下降了 40% 以上。
我们没有取消审查。我们做的是把大部分"读代码"的工作交给机器,把人的时间和注意力用在刀刃上,并在"快速、方便地撤销错误"上投入了很多。
重新思考代码审查的目的
智能体开始写代码之后,变更数量涨得很快。在 Anthropic 的 monorepo 里,每天合入的变更从今年 5 月的约 2,500 次涨到 9 月的 3 万多次。
Claude Code 有自己的独立仓库,不在那个 monorepo 里,但同样压力很大。以这样的交付速度,逐行人工审查就算不是完全做不到,也非常困难。
代码审查干两件事:
- 在代码上线前发现并修复问题
- 在团队内建立共享背景和对代码库的理解
本文主要讲第一件事,第二件事放到最后再说。
我们认为,"有没有人读过这段代码"并不能准确回答真正的问题:"这次改动可能出什么错?应该由哪一道检查(自动的还是人工的)来发现它?"
换成这个问题之后,审查发生的时机也变了。以前审查是流程终点的关卡:写代码、开 PR、等同事来看。
现在审查是持续进行的,更像写东西时顺手跑的拼写检查。大多数改动在请人看之前,已经被 Claude 审过、改过至少一轮。大部分常见错误在这一步就挡住了,团队的时间可以留给更高层的问题。
稀缺资源:人的时间和注意力
我们希望把人的时间和注意力留给只有人才能解决的问题,其余的交给自动检查。按现在的变更速度,人要做的事依然多得惊人,团队几乎每天都会遇到新问题。
人的时间要算两头:审查花掉的时间,以及修复烂代码搞坏东西花掉的时间。如果省下的审查时间又出现在修复上,那等于没省。
所以我们的目标是:Claude Code 各仓库(CLI、桌面端、Web 应用和移动端)的大多数 PR,在最多只有一个人参与(这个人可以是作者)的情况下合入,同时回滚率和事故率不上升。衡量人工时间,我们看每个 PR 的人工审批次数(中位数和 95 分位)、人工评论数,以及 PR 等人回复的时间。回滚率和事故率是护栏:这两个数如果涨了,说明人时没有省下来,只是被挪到了别处。
一次改动的生命周期

一次典型改动,从工程师的笔记本(或 Slack 里的一个 Claude 会话)出发,要经过好几层代码审查。
图:一个 PR 的检查流程,自上而下。PR 之前,工作先经过验证。每个 PR 都要过:必需的 CI、Claude 代码审查和安全审查(全部自动),然后是基于风险的审批(由人决定)。接着是合并队列;合入之后先在内部用功能开关试用,再逐步放量,最后一步是监控、向前修复或回滚。
大部分路径是自动化的;人的注意力只放在有风险的地方
一层一层看

图:六层自上而下叠放:验证、必需 CI、AI 审查、安全审查、人工审批,以及合并队列加功能开关。每层的漏洞位置不同。从某一层漏洞漏过去的问题,由后面的层接住;所有层都漏掉的,落到最底下的快速回滚。
每层都能挡住一些问题、漏掉另一些。很少有问题能穿过所有层,剩下的由回滚兜底。
1. 先自证,再给别人看
现在大部分审查发生在 PR 创建之前。我们给 Claude 一些能跑的验证手段,比如测试、构建,或者截图与设计稿对比,要求它拿出运行结果,而不是嘴上说"做完了"。然后由一个子智能体用全新的上下文审一遍 diff。这两个习惯都来自我们的最佳实践指南。
开 PR 之前,很多人还会跑几个内部 skill:一个找 bug,一个简化 diff,一个端到端验证行为。UI 改动还会对照设计规范检查。
Claude Code 的创造者 Boris Cherny 说过,给 Claude 一个验证自己工作的手段,可能是拿到好结果最重要的一件事。他估计这能让最终结果好上两到三倍。他写道:"验证方式因领域而异,可以简单到跑一条 bash 命令、跑一遍测试,或者在浏览器或手机模拟器里试一下应用。"
**自动审查总是反复指出同一类问题时,我们从源头解决:**改 skill、加 lint 规则,或者更新这几类指导文件:
CLAUDE.md告诉 Claude 这个项目是什么:技术栈、约定、目标和非目标。每次审查都会加载它,所以在大型代码库里我们会写得很短,其余内容指向其他文档。审查器还会标出违反其中约定的代码,以及让它某一行过时的改动。REVIEW.md由代码 owners 撰写,告诉审查器他们那部分代码里什么才重要。我们另外单独检查审查器是否真的照做了。写得好的都很短。它们会说明在那个仓库里"出错"长什么样(对文档来说是"说的不是事实",对配置来说是"路由配错"),限制吹毛求疵的数量,列出要跳过的路径,并要求给出文件和行号作为证据,而不是望文生义地猜测。它们还要求审查总结以数量开头,如果没什么要改就直说。
2. 每个 PR 都过 AI 审查
每个 PR 在给人看之前,都会先过一遍 Claude 的审查。它对照整个仓库和 PR 声明的意图去读 diff,问三个问题:这个改动解决了它要解决的问题吗?它和系统契合吗?有没有弄坏别的什么?
如果是 bug 修复,它会去找根因。对外版本 Code Review for Claude Code 已在 Team 和 Enterprise 套餐上全面可用;/code-review 可以在本地跑一个更轻量的版本。
我们发布研究预览版时,内部 PR 中获得实质性审查意见的比例从 16% 升到了 54%。超过 1,000 行的 PR 大多会审出问题,小 PR 大多干净通过。管理员可以给每个仓库设定 Quick、Standard 或 Deep 档。在漏掉一个 bug 的代价高于多花审查时间的地方,Deep 档是值得的。
审查发现的问题,在给人看之前先由其他智能体验证。 几个智能体同时找 bug,然后由另一组对每条发现投票,同意"这是真问题"的票数够多才会发出来。只涉及风格、诊断信息或清理类问题的发现会被丢掉。这些过滤器我们先在自己的 PR 上做过 A/B 测试,才保留下来。剩下的以行内评论的形式出现,按严重程度排序。每条都标成 Important(重要)、Nit(小问题)或 Pre-existing(既有问题),这样 PR 没引入的 bug 就不会看着像作者的锅。
每条发现都必须有回应。 要么修掉,要么说明理由把讨论关掉。很多时候智能体会在夜里把修复做掉,作者回来时 PR 已经又过了一轮。
3. 能拦人的安全审查
安全有单独的一套自动审查。只要 bug 审查或安全审查还有未处理的发现,PR 就不能合入。你要么修掉,要么用简短的理由关闭讨论,误报就是这么清掉的。
如果后续提交修好了问题,发现会自动消除。你也可以用开源的安全审查 GitHub Action 或 /security-review 命令搭一套同样的流程。配置方法见 Claude Code 中的自动化安全审查。
4. 会拦截的自动检查
常规的那一套:lint、类型检查、各平台测试,还有构建。(关于如何为这种量级扩展 CI,我们写过一篇文章。)一个普通的 CLI PR,在人看一眼之前可能已经跑了几十项检查。PR 模板要求填写改动是怎么测的、怎么撤销。Claude 可以代填,但签字确认的是提出改动的那个人。
5. 人工审批,按风险分级
修个文档和改自动更新器,风险不一样,审查方式也不一样。
| 风险 | 例子 | 人工审批 |
|---|---|---|
| 低 | 文档、文案、仅内部使用的功能、开关后面的增量改动 | 自动审查和安全检查全绿后无需人工 |
| 中 | 普通产品改动,以及缓存、自动更新器、系统提示词这类敏感区域的改动 | 1 人 |
| 高 | 风险最高的代码,外加一小批始终需要两人审批的路径 | 2 人 |
定级看改动,不看作者。 一个分类器读取改动内容并判定风险等级。第二个分类器判断这次具体改动是否还需要额外一个人,即使按等级不需要。有些路径永远需要人:owners 标记为敏感的,以及任何 CI 工作流文件。
只有受信任的作者才能走轻量路径。 只有在仓库受信任名单上的作者(基本就是负责它的团队)才能走轻量流程。其他人一律需要第二个人审批。智能体的审批也永远不算人的审批。自动审查可以放行低风险改动,但填不了需要人的那个位置。
谁发起的改动,谁负责。 智能体写的 PR 里,指挥智能体的那个人算作必需的审批人之一,和自己亲手敲代码一样。
一次审批只对某个具体提交有效。 如果又有系统无法担保的新提交进来,比如智能体推的,或者有人手动解决的合并,就必须重新审批。
6. 合并队列、功能开关和逐步放量
合并队列会把改动应用到 main 上重新跑一遍所有检查,这样两个单独都能通过的 PR,不会合起来把 main 搞坏。新行为通常先放在功能开关后面给 Anthropic 员工用,我们内部的高强度使用常常比用户更早暴露回归。公开发布先推 latest 渠道,stable 渠道跟在其后。
7. 快速发现,快速回滚
总会有漏网的错误,所以最后一层讲的是快速发现。功能开关不用发版就能关掉。Claude Code 有每周轮值的 on-call,事故复盘会问一个问题:这个问题本该由哪一层发现?
发现糟糕的合并,目前还是靠作者、on-call,以及回滚和事故看板。我们还没有"熔断器"——指标一动就自动收紧审批的那种机制;团队里的工程师希望在更多代码转向零人工合并之前先有它。
有位同事说,放慢速度确实能降低错误率,但主要是因为什么都做得少了。我们宁愿把"发现和修复问题"这件事做得更快。
我们怎么让审查器变得更好

我们的代码审查流程在一个循环里持续改进。
每次事故都变成一个 eval 用例。 团队收集了过去引发事故的 PR,连同它们的向前修复和回滚,让熟悉那段代码的工程师确认每个 bug 以及它所在的位置。审查器每天都会在这套用例上跑一遍。
图:一次事故或回滚变成一个经专家核对的用例,加入 eval 集合。审查器的一次改动进入每日 eval 运行,对照所有用例打分;分数上升就保留,下降就丢弃,然后下一轮改动再来一遍。
eval 随每次事故增长,审查器的每次改动都要在全量用例上打分。
我们通过观察人们怎么处理评论来衡量噪音。 只要不介意误报一堆非 bug,多抓 bug 很容易,所以这里需要有制约。我们把审查器留下的每条评论按 PR 上的人的反应分类:改掉了、说它错了、说这个行为是有意为之,或者判断为无关紧要。我们还会在已知干净的 PR 上跑审查器,统计它多频繁地报出会导致有害改动的意见。我们写下来的优先级是:先抓真 bug,其次才是减少审查轮次。
作者是智能体时,噪音的代价更高。人可以几秒钟把一个小问题挥手带过;智能体会去修它,于是又多一个提交、多一轮审查。
审查必须收敛。 智能体作者和智能体审查器可以无限地互相忙碌下去。有一个 CLI PR,一晚上来回审了五十多轮修复,最后是作者喊了停。
我们对审查器反复指出的代码跑了 git blame,其中大约 59% 是从审查器第一轮起就存在的代码。审查器很少在发现新 bug,它只是每轮多翻出几个老 bug。
这局面也有我们自己加码的成分。我们习惯了默认跑好几轮,因为每轮总能抓到点新东西。对高风险改动这可能值得,但没必要每个 PR 都这样。团队现在把"过审轮数"和召回率放在一起跟踪,并改了复审规则:
- 轮数上限。 三轮之后,审查器会请作者退一步,重新考虑方案。
- 只复审 diff。 前几轮之后,只复审新增的 diff。
- 按"问题类型"标记,让作者修复所有同类实例,而不只是一行。
- 不重复发已经发过的发现。
审查智能体还会每晚扫一遍现有代码,在旧 bug 于别处冒头之前把它们找出来。
图:收敛工作前后对比:一轮审查加修复后就通过的 PR 从 65% 升到 78%;需要五轮及以上的 PR 从 8.9% 降到 1.5%;平均过审轮数从 2.08 降到 1.32。
收敛改进之后,内部 PR 的审查轮数减少

人留在哪些环节
把资深工程师从深度工作中拽出来去抓一个常规错误,代价远高于一次自动审查。团队里的人仍然负责:
- 决定要不要做。 方向、品味和范围。有一个团队声称自己的审查瓶颈已经解决,但对团队外的改动仍然保留人工审查,为的是有人问一句"这事到底该不该做?"
- 审查高风险代码,比如计费、自动更新器和 CI 工作流。
- 审查架构,尤其是会定下被别人照抄的模式的架构。
- 看证据。 测试输出、跑过的命令及其返回、截图、审查器的发现。如果你说不出这些检查会漏掉什么,那就要一次真正的审查,而不是快速点个通过。
- 对结果负责。 每一个上线的改动都有一个具体的人负责,不管代码是谁敲的。
在团队内共享背景
代码审查的第二件事一直是传播对代码库的理解。读同事的 diff 是你了解改了什么、各部分怎么拼在一起的方式。如果读代码的大部分工作交给了机器,人还怎么学习代码?
这件事我们没有正式流程。团队里没人脑子里装着 Claude Code 的完整模型,我们也不认为谁需要。有人想弄懂代码库的某一部分时,就让 Claude 针对那一小片写一份讲解。几分钟就好,反映的是代码当前的样子。

我们中有些人更进一步,让 Claude 做一个小工具,把那部分代码可视化,并按照自己喜欢的学法学。
如果目标是好好花人的注意力,这比逐行读琐碎的 diff 强。一行文案改动几乎教不会你什么;为即将修改的模块读一份讲解,能学到很多。我们默认在公开 Slack 频道里工作的文化也有帮助——别人在造什么,你能同步看到。
"你合入的,你负责"
你合入了一个小改动或中等改动,之后出了问题,团队惯例是通常由你来修。有几件事让它不至于演变成灾难:
- 改动小,所以好审、好 debug、好回滚。
- 一切可逆。 功能开关、回滚和分阶段发布能在几分钟内撤掉大部分错误。
- 影响面决定门槛。 代价高的代码,参与的人和检查都更多。
- 回归暴露得快,靠遥测和内部使用。
- 这不是追责。 负责修复意味着你掌握的背景最多;事故复盘看的是系统,不是人。
责任也是共享的。团队大部分工作都在公开频道里进行,谁都能看到别人在做什么、接手一个话题,或者让 Claude 去补一个缺口,反馈也来自不拥有这段代码的人。这种开放是质量能维持在高位、而不必对每一行都设关卡的重要原因。
当我们改变方向
智能体让"开始做一件事"变得很便宜,所以有些工作不该合入。通常频道里会有人问为什么、指出早先的某个决定,或者建议一条更简单的路,然后作者关掉 PR 或者改变它的形态。
代码写得快,关掉 PR 不觉得可惜。诀窍是在讨论早期就提出不同方向,而不是在 PR 做完之后丢一条阻塞性评论。
怎么把这套流程搬到你的团队
和你的团队照做,大部分拼图现在都已经有了。
PR 之前
- 给智能体一些它能跑的检查,列在简短的
CLAUDE.md里,再加上跑格式化和 lint 的 hooks。 - 在本地跑
/code-review和/security-review,或者用全新上下文的子智能体做一次审查。 - 加一个
REVIEW.md,把重复出现的审查意见挪进去。
每个 PR 上
- 强制要求 CI,并在 PR 模板里加上"测试""风险"和"如何回滚"几栏。
- 先在一个仓库上加 AI 审查器(Code Review for Claude Code,或 Claude Code GitHub Action),调几周
REVIEW.md,再铺开。 - 加上自动安全审查,并要求所有审查讨论在合入前解决。
- 审查投入与风险匹配:常规改动快速过一遍,漏一个 bug 代价高的地方做深度审查(Code Review 里的 Quick、Standard 或 Deep)。
- 给审查轮数设上限;前几轮之后只复审新增的 diff。
审批
- 把风险分级写下来,按改动定级而不是按作者;先严格,再用证据逐步放宽。
- 轻量审批路径只留给你信任的作者。
- 用 CODEOWNERS 和分支保护,让 auth、计费、CI 和发布工作流、安装程序永远需要人。
- 绝不让机器人的审批替代必需的人工审批;有新提交就撤销已有审批。
合并及之后
- 使用合并队列、功能开关、先内部使用、分阶段发布和一键回滚。
- 把事故和回滚变成 eval 集合;审查器的 prompt、工具或模型一改,就重新打分。
- 度量人工时间,以回滚率和事故率作为护栏。
接下来往哪走
Code Review 的发布公告里说,批准一个 PR 仍然由人决定;这个产品发布的是发现,不是批准。我们自己的仓库走得更远:由 owners 决定哪些低风险改动可以仅凭自动检查合入,这条界线还在移动。
审查漏掉东西时,我们会问:模型当时面前缺了什么?然后把补丁打进 CLAUDE.md、一个 skill,或者一项新检查。目标一直没变:每个改动花掉的人工时间更少,回滚不比以前多。
如果你的团队允许智能体提 PR,我们想听听你们自动化了哪些检查、哪些仍然需要人,以及你觉得我们哪里做错了。
感谢 Emma Webb、Michael Segner 和 Amie Rotherham 的审阅。
-
作者:Addy Osmani、Morgan Westlee Lunt、Qing Wang(技术团队成员)
-
发布时间:2026-10-15
-
原文:https://claude.dev/blog/solving-code-review-at-anthropic/

