Claude Code 团队如何进行代码评审

Hacker News Top 新闻

摘要

Anthropic 分享 Claude Code 团队如何在 AI 写了约 90% 代码的情况下进行代码评审:通过多层自动化检查、把人工注意力集中在高风险环节,并在 PR 数量翻倍的同时将回滚率降低 40% 以上。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/10/16 19:41

# Claude Code 团队如何做代码审查 来源:https://claude.dev/blog/solving-code-review-at-anthropic/ 我们之前说过,Claude Code 自身约 90% 的代码是由 Claude 编写的。那么在如此高的产出速度下,我们要如何做代码审查?还有人在读代码吗?出了问题又是谁来兜底? 本文介绍 Claude Code 团队的代码审查流程及其演进过程。从六月到九月,Claude Code 代码库的合并请求数量翻了一倍以上,而需要回滚的比例下降了超过 40%。 我们没有取消审查,而是把大部分的"读代码"工作交给了机器,把人类的时间和注意力用在刀刃上,并投入大量精力让犯错之后的撤销变得快速而简单。 ## 重新思考代码审查的目的 当智能体开始写代码,变更的数量会急剧上升。在 Anthropic 的 monorepo 中,每天落地的变更从今年五月的约 2,500 个增长到九月的超过 30,000 个(https://www.anthropic.com/engineering/redesigning-source-control)。 Claude Code 拥有独立于 monorepo 的代码库,但也承受着巨大的压力。在这种交付速度下,人工逐行审查几乎是不可能完成的任务。 代码审查有两项职责: 1. 在上线前发现问题并修复 2. 在团队中建立共享上下文和对代码库的理解 本文主要聚焦第一项职责,但会在文末回到第二项。 我们认为,"有没有人读过代码"是一个不够精确的替代指标。真正该问的是:"这个变更可能出什么问题,以及哪一种检查——自动化的还是人工的——才是发现它的正确手段?" 这个问题也改变了审查*发生的时间点*。过去,审查是流程终点的一道关卡:写代码、开 PR、等同事审阅。 现在,审查是持续进行的,更像是你在写作时运行的拼写检查。大多数变更在被送到人面前之前,已经至少由 Claude 审查并修复过一轮。这能拦截大部分常规错误,把团队的注意力留给更高层次的问题和审视。 ## 稀缺资源:人类的时间与注意力 我们要把人类的时间和注意力保留给只有人类才能解决的问题,并确保其余问题由自动化检查兜住。以我们目前的变更速度,人类依然有大量工作要做,而且团队几乎每天都会遇到新的、前所未有的挑战。 人类的时间涵盖了审查成本的两面:人们花在审查上的时间,以及花在修复糟糕代码所造成问题上的时间。如果只是减少了前者,代价却转移到了后者,那并不能算节省。 因此,我们的目标是:Claude Code 相关代码库(CLI、桌面与 Web 应用、移动端应用)中的大多数 PR 在合并时最多只需一个人参与,这个人可以是作者本人,同时回滚率和事故率不升高。为了衡量人类时间,我们跟踪每个 PR 的人工批准次数(中位数和 95 分位)、人工评论数量,以及 PR 等待人工处理的时长。回滚率和事故率是护栏指标:如果它们上升了,说明我们并没有节省人类时间,只是把它挪了位置。 ## 一次变更的生命周期 一次典型的变更,从工程师的笔记本电脑(或 Slack 中的 Claude 会话)出发,会经过多层代码审查。 一次变更的生命周期 一次典型的 Claude Code 变更,从作者的机器到最终用户手中 **图 A**:路径的大部分是自动化的;人的注意力只花在有风险的地方 ## 逐层解析 是层层递进,而非一道关卡 六层检查,下面还有回滚兜底 **图 B**:每一层都能拦住一些问题,也会漏掉另一些。能穿过所有层的问题少之又少,剩下的交给回滚处理。 ### 1. 在任何人看到之前,工作先经过验证 如今大多数审查发生在 PR 创建之前。我们给 Claude 一些可以实际运行的东西——比如测试、构建,或一张用于与设计稿比对的截图——并要求它展示输出结果,而不是声称"我完成了"。然后由一个子智能体在全新的上下文下审查 diff。这两个习惯都源自我们的最佳实践指南(https://code.claude.com/docs/en/best-practices)。 在开 PR 之前,我们很多人还会运行几个内部技能:一个专门找 bug,一个简化 diff,一个端到端验证行为。UI 变更还会对照我们的设计规范进行检查。 Claude Code 的创造者 Boris Cherny 曾称,给 Claude 一种验证自身工作的方式,可能是获得良好结果最重要的因素(https://x.com/bcherny/status/2007179861115511237)。他估计这能让最终结果好上两到三倍,并写道:"验证在每个领域表现形式不同。它可能简单到运行一条 bash 命令,或者跑一遍测试套件,也可能是在浏览器或手机模拟器中测试应用。" **当自动审查反复标记同一个问题时,我们在源头上修复它:**改技能、加 lint 规则,或更新指导性文件,例如: - `CLAUDE.md` 告诉 Claude 这个项目是什么:技术栈、规范、目标与非目标。每次审查都会加载它,因此在大型代码库中我们要保持它足够精简,并在其中指向其他文档。审查者还会标记违反其中规范的代码,以及让其中某些内容过时的改动。 - `REVIEW.md` 由代码所有者撰写,告诉审查者在他们负责的这部分代码中什么最重要。我们会单独检查审查者是否真的遵循了它。写得好的 REVIEW.md 都很简短:说明在这类仓库中"失败"长什么样子(对文档来说是"它在撒谎",对配置来说是"它路由错了"),限制吹毛求疵的数量,列出可以跳过的路径,并要求给出文件和行号作为证据,而不是仅凭文件名猜测。它们还要求审查总结以数量开头,并且在没有需要修复的问题时直说。 ### 2. 每个 PR 都有 AI 审查 在人看到之前,每个 PR 都会先经过 Claude 的审查。它会对照整个代码库和 PR 中声明的意图来阅读 diff,并追问:这个变更解决了它要解决的问题吗?它适配这个系统吗?它会不会破坏别的东西? 在 bug 修复中,它会寻找根本原因。公开版本 Code Review for Claude Code(https://code.claude.com/docs/en/code-review)现已在 Team 和 Enterprise 计划中全面可用,而 `/code-review` 命令可以在本地运行一个轻量版本。 当我们发布研究预览版时(https://claude.com/resources/articles/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 就无法合并。你要么修复它,要么附上简短理由关闭该对话——这就是你清除误报的方式。 如果后续的提交修复了问题,该发现会自动清除。你可以用开源的 security review GitHub Action 或 `/security-review` 命令配置同样的流程。配置方法参见 Claude Code 中的自动化安全审查(https://support.claude.com/en/articles/11932705-automated-security-reviews-in-claude-code)。 ### 4. 具有阻断能力的自动化检查 老规矩:lint、类型检查、各平台的测试以及构建。(我们曾在这里写过如何为此规模扩展 CI(https://claude.com/resources/articles/agentic-coding-is-straining-ci-heres-how-we-scaled-test-impact-analysis-at-anthropic)。)一个典型的 CLI PR 在任何人查看之前可能会运行数十项检查。PR 模板会要求说明变更如何测试以及如何回滚。Claude 可以代为填写,但需要提出变更需求的人签字确认。 ### 5. 按风险分级的人工批准 文档修正和自动更新器的改动风险不同,因此审查要求也不同。 风险 | 示例 | 人工批准要求 ---|---|--- 低 | 文档、文案、仅内部功能、在 feature flag 之后的增量变更 | 自动化审查和安全检查全部通过后,无需人工 中 | 常规产品变更,以及对敏感区域(如缓存、自动更新器或系统提示词)的改动 | 一人 高 | 最高风险的代码,加上一小组始终需要两人审查的路径 | 两人 **由变更本身决定风险等级,而不是作者。**一个分类器阅读变更并选定其风险等级。第二个分类器会追问:即使这个变更的等级不需要额外的人,这一次是否需要?某些路径始终需要人工——代码所有者标记为敏感的任何路径,以及任何 CI workflow 文件。 **只有受信任的作者才能走轻量路径。**只有在仓库受信任名单上的作者(主要是拥有该仓库的团队)才能走轻量路径。其他所有人都需要第二个人批准。智能体的批准也永远不计入人工名额。自动化审查可以放行低风险变更,但不能占据要求人工的名额。 **谁发起了变更,谁就要对它负责。**在由智能体撰写的 PR 中,指挥智能体的人被视为必需审查者之一,与他们亲手写下代码时完全相同。 **一次批准只覆盖一个特定的提交。**如果有系统无法担保的新提交进入——比如智能体推送的代码,或有人手动解决的合并冲突——批准就必须重新给出。 ### 6. 合并队列、feature flag 与渐进发布 合并队列会将变更应用到 main 分支后重新运行所有检查,因此两个各自通过的 PR 不会组合出一个坏掉的 main。新功能通常先在 feature flag 之后面向 Anthropic 内部员工发布,我们高强度的使用往往能在用户之前发现回归问题。公开发布先推送到 `latest` 频道,`stable` 频道随后跟进。 ### 7. 快速发现,快速回滚 有些错误仍然会溜过去,所以最后一层是关于快速发现问题的。feature flag 可以在不部署的情况下直接关闭。Claude Code 有每周的值班轮换,事故复盘会追问:本应由哪一层拦截这个问题? 发现一次糟糕的合并,仍然依赖作者和值班人员,以及回滚和事故看板。我们目前还没有在这些数字上升时自动收紧审批的熔断机制;这里的工程师们希望在更多代码走向"零人工合并"之前实现它。 有位同事说,放慢速度确实能降低错误率,但主要是因为你在做的事情变少了。我们更愿意在发现问题和修复问题上变得更高效。 ## 我们如何让审查者变得更好 我们的代码审查流程在一个持续改进的循环中不断进化。 **每一次事故现在都是一个评测用例。**团队收集了过去引发事故的 PR,连同它们的前向修复和回滚,并让熟悉那段代码的工程师确认每个 bug 及其所在位置。审查者每天都会针对这个数据集运行评测。 我们的事故就是评测数据 由过去的事故和回滚构建,每天运行 **图 C**:评测集随每次事故增长,审查者的每次改动都要在完整评测集上打分。 **我们通过观察人们对评论的反应来衡量噪音。**如果不介意大量误报,抓 bug 变多是很容易的,所以我们需要一个制衡机制。我们把审查者留下的每条评论按 PR 上人员的回应方式分类:他们修复了它、说它是错的、说该行为是有意为之,或者认为它无关紧要。我们还会在已知干净的 PR 上运行审查者,统计它提出可能让人做出有害修改的建议的频率。我们写下来的优先级是:先抓真 bug,再减少审查轮次。 当作者是智能体时,噪音的代价更高。一个人可以在几秒钟内忽略一个 Nit。而智能体会去修复它,这意味着多一次提交和多一轮审查。 **审查必须收敛。**智能体作者和智能体审查者可以无限期地互相消耗。有一个 CLI PR 在一夜间经历了超过五十轮审查和修复,直到作者叫停。 当我们对审查者反复标记的内容运行 git blame 时,发现约 59% 的标记代码自审查者的第一次通过时就已经存在。审查者很少发现新 bug,它只是每一轮又多找出几个老问题。 这是我们自己造成的。我们已经习惯了默认跑好几轮,因为每一轮总能发现点新东西。对高风险变更来说这可能是值得的,但对每个 PR 都如此则不然。团队现在在跟踪召回率的同时也跟踪通过所需轮次,并对重新审查做了如下修改: - **轮次上限。**三轮之后,审查者会请作者退一步重新考虑整体方案。 - **前几轮之后,只对 diff 重新审查。** - **标记 bug 的类别**,让作者把每一处都改掉,而不是只改一行。 - **不重复**已经发布过的发现。 审查智能体还会在夜间对现有代码运行,帮助我们在老 bug 在别处暴露之前就发现它们。 能够收敛的审查 收敛性改动前后的内部 PR 对比 **图 D**:收敛性改动之后,内部 PR 的平均审查轮次更少了 ## 人类仍然参与的环节 把一位资深工程师从深度工作中拉出来去抓一个常规错误,代价远高于一次自动化审查。在 Anthropic,我们的工作已经从阅读每一个 diff 转移到机器不擅长的决策上: - **我们到底该不该做这件事?**方向、品味和范围。有一个团队宣称其审查瓶颈已解决,但仍然对团队之外的变更保留人工审查,这样才有人会问"我们真的应该做这个吗?" - **高风险代码**,如计费、自动更新器和 CI workflow。 - **架构决策**——它会设定一个其他人会效仿的模式。 - **阅读证据。**测试输出、运行的命令及其返回结果、截图、审查者的发现。如果你说不出这些检查会漏掉什么,那就要求一次真正的审查,而不是一个快速批准。 - **对结果负责。**无论代码是谁敲出来的,每一个上线的变更都由一个人负责。 由人来做决策的环节 五项决策留在人手中;其余环节由检查覆盖 **图 E**:人们从阅读每个 diff 转向机器不擅长的决策 ## 在团队中共享上下文 代码审查的第二项职责一直是传播对代码库的理解。阅读同事的 diff 是你了解发生了什么变化、各个部分如何衔接的方式。如果机器承担了大部分阅读工作,人又如何学习代码呢? 我们没有为这件事设立正式流程。团队中没有人头脑里装着 Claude Code 的完整心智模型,我们也不认为有人需要。当有人想理解代码库的某一部分时,他们会请 Claude 就那一部分写一份讲解文档。只需几分钟,而且反映的是代码今天的实际样子。 *示意图标题:"如果机器承担了大部分阅读工作,人又如何学习代码?"左侧,一个网格代表代码库,其中几个方块被高亮为 managed settings——你想要理解的那部分;没有人头脑中保有它的完整心智模型。一支箭头标着"就恰好这一部分问 Claude",示例问题是"Claude Code 如何检索 managed settings?",通向两个结果:Claude 写一份讲解文档,只需几分钟,反映代码今天的实际样子;以及,对某些人来说……*

相似文章

引用 Addy Osmani、Morgan Westlee Lunt 和 Qing Wang 的话

Simon Willison's Blog

Simon Willison 引用了 Addy Osmani、Morgan Westlee Lunt 和 Qing Wang 关于 Anthropic Claude Code 团队代码审查实践的观点,指出 AI 审查让代码审查从发布前的关卡变为写作过程中的持续检查,从而让人类审查专注于更高层次的问题。

Claude Code Ultrareview

Product Hunt

Claude Code Ultrareview 利用云端并行 AI 代理集群提供代码审查服务。