跳到正文
Anthropic:Claude.dev 開發者博客· Addy Osmani, Morgan Westlee Lunt, and Qing Wang·· 15 小時前精選AI 評分76

Claude Code 團隊如何進行程式碼審查

How the Claude Code team does code review

AI 導讀

Anthropic 的 Claude Code 團隊分享其程式碼審查流程,將多數常規檢查自動化,並按變更風險決定人工審批要求。6月至9月,合併的 PR 數量增逾一倍,而需要回滾的比例下降逾40%。流程涵蓋 PR 前驗證、Claude 與安全審查、CI、合併佇列及快速回滾;團隊亦將事故和回滾案例納入評估集,持續檢查審查器。

推薦理由

文章拆解 Claude Code 團隊如何把程式碼審查分成自動檢查、按風險配置人工審批與快速回滾,並以回滾和事故率作為節省人力的護欄。

正文 · 繁體中文

我們之前提過,Claude 編寫了 Claude Code 約九成的程式碼。那麼,面對如此龐大的程式碼產量,我們如何進行程式碼審查?現在還有人讀程式碼嗎?如果出現問題,又由誰發現?

本文介紹 Claude Code 團隊的程式碼審查流程及其演變。從 6 月到 9 月,Claude Code 程式碼庫中已合併的拉取請求數量增加逾一倍,而必須回退的比例則下降逾 40%。

我們沒有取消審查,而是把大部分閲讀工作交給機器,並以節省人員的時間和注意力為目標,同時投入大量資源,令錯誤能夠快速、輕易地回退。

重新思考程式碼審查的目的

當 Agent 編寫程式碼,變更數量會迅速增加。在 Anthropic 的 monorepo 中,每日合併的變更數量從今年 5 月約 2,500 增至 9 月逾 30,000。

Claude Code 使用獨立於 monorepo 的程式碼庫,但同樣面對巨大壓力。以這種速度發佈時,逐行人工審查程式碼極為困難,甚至幾乎不可能。

程式碼審查有兩個作用:

  1. 在發佈前找出並修正問題
  2. 在團隊中建立共同背景知識,並加深對程式碼庫的瞭解

本文主要探討如何找出並修正問題,但會在接近結尾時再談第二個作用。

我們認為,「有人讀過程式碼嗎?」並不能準確代表「這項變更可能出現甚麼問題,以及哪項檢查——自動化或人工——最適合找出問題?」

提出這個問題,也改變了審查發生的時機。過去,審查是流程末端的一道關卡:寫好程式碼、開啟 PR,然後等候同事審查。

現在,審查會持續進行,就像寫作時的拼字檢查。大部分變更在交由人員審閲之前,至少已由 Claude 審查並修正過一次。這樣可以找出大部分常見錯誤,讓團隊把注意力留給更高層次的問題和仔細審視。

稀缺資源:人員的時間和注意力

我們希望把人員的時間和注意力留給只有人才能解決的問題,並確保自動化檢查能找出其餘問題。以目前的變更速度,人員仍有大量工作要做;我們的團隊幾乎每天都會遇到新的、前所未見的挑戰。

人員時間涵蓋審查成本的兩方面:審查所花的時間,以及修復劣質程式碼造成的問題所花的時間。如果節省了前者,卻只是把時間轉移到後者,便沒有幫助。

因此,我們的目標是讓 Claude Code 各程式碼庫(CLI、桌面及網頁應用程式,以及流動應用程式)中的大部分拉取請求,在最多一人參與的情況下合併;這人可以是作者本人,而且回退或事故率不會上升。為了衡量人員所花的時間,我們會追蹤每個 PR 的人工核准次數(中位數及第 95 百分位數)、人工留言數,以及 PR 等待人員處理的時間。回退率和事故率是防護指標:如果這些數字上升,就代表我們沒有節省人員時間,只是把時間轉移到別處。

一項變更的歷程

一項典型變更從工程師的手提電腦(或 Slack 中的 Claude 對話)出發,會經過多個程式碼審查層面。

一項變更的歷程

一項典型的 Claude Code 變更:從作者的裝置到用戶手上

圖 A流程大部分已自動化;人員的注意力會投放在有風險之處

逐層檢查

多層檢查,而非單一關卡

六層檢查,底層設有回退機制

圖 B每一層都能找出部分問題,也會漏掉其他問題。只有少數問題能通過所有層,剩餘問題則由回退機制處理。

1. 工作會先經過驗證,其他人才會查看

現在大部分審查都在 PR 建立前進行。我們會給 Claude 一些可執行的內容,例如測試、建置,或用來與設計比對的螢幕截圖,並要求它展示輸出,而不是隻説已完成。接着,子代理會在全新上下文中審查差異。這兩種做法都源自我們的 最佳實踐指南。

開啟 PR 前,我們當中許多人也會執行幾項內部技能:一項搜尋錯誤,一項簡化差異,另一項則端到端檢查行為。UI 變更也會按照我們的設計指引進行檢查。

Claude Code 的建立者 Boris Cherny 曾表示,讓 Claude 能夠驗證自己的工作,可能是取得良好成果最重要的一環。他估計這會令最終結果提升兩至三倍,並寫道:「驗證方式因領域而異。可以只是執行 bash 命令、執行測試套件,或在瀏覽器或手機模擬器中測試應用程式。」

自動審查器不斷標記同一問題時,我們會從源頭修正:在技能中加入修正、加入 lint 規則,或更新指引文件,例如:

  • CLAUDE.md會告訴 Claude 專案的概況:技術堆疊、慣例、目標及非目標。每次審查都會載入這份文件,因此在大型程式碼庫中,我們會保持文件簡短,並從中連結到其他文件。審查器亦會標記違反其中慣例的程式碼,以及會令其中某一行內容過時的變更。
  • REVIEW.md由程式碼負責人撰寫,告訴審查器其負責的程式碼部分有哪些重點。我們會另外檢查審查器是否確實遵從這些指引。寫得好的指引都很簡短,會説明在該儲存庫中問題會如何呈現(文件方面是「內容不實」,設定方面是「路由錯誤」),限制瑣碎問題的數量,列出要略過的路徑,並要求提供檔案和行數作為證據,而不是根據名稱猜測。指引亦會要求摘要以數量開頭,並在沒有需要修正的事項時明確説明。

2. 每個 PR 都進行 AI 審查

每個 PR 都會在人工查看前先由 Claude 審查。它會對照整個儲存庫及 PR 所述意圖來檢視差異,並提出以下問題:這項變更有否解決問題、是否符合系統,或會否破壞其他部分?

修正錯誤時,Claude 會尋找根本原因。公開版本 Code Review for Claude Code 現已在 Team 和 Enterprise 方案正式推出,而 /code-review 會在本機執行較輕量的版本。

我們推出研究預覽版時,獲得實質審查意見的內部 PR 比例由 16% 升至 54%。大部分超過 1,000 行的 PR 都會收到問題回報,而大部分小型 PR 則不會發現問題。管理員可將各儲存庫設定為 Quick、Standard 或 Deep。若漏掉一個錯誤的代價高於額外審查時間,Deep 就值得採用。

問題回報會先由其他代理驗證,再交由人員審查。多個代理會同時搜尋錯誤。接着,另一組代理會就每項發現投票;只有在足夠多代理認為問題屬實時,才會發布。純粹涉及風格、診斷或清理的發現會被剔除。在保留這些篩選條件前,我們先在自己的 PR 上進行 A/B 測試。最終保留的內容會以內嵌註解形式顯示,並按嚴重程度排序。每項都會標上 Important、Nit 或 Pre-existing,避免讓 PR 未有引入的錯誤看起來像是作者造成的。

每項發現事項都必須回覆。你要麼修正問題,要麼説明原因後結束討論串。Agent 經常會在夜間接手修正,因此作者回來查看 PR 時,往往已經完成另一輪審查。

3. 可阻止合併的安全審查

安全問題也會接受獨立的自動化審查。只要錯誤審查或安全審查仍有任何未解決的發現事項,PR 就不能合併。你要麼修正問題,要麼簡短説明原因後結束討論串,這樣就能清除誤報。

如果後續提交修正了問題,該發現事項就會自動清除。你也可以透過開源安全審查 GitHub Action 或 /security-review 指令設定相同流程。設定方法載於Claude Code 中的自動化安全審查。

4. 可阻止合併的自動化檢查

常見檢查包括 lint、型別檢查、在每個平台上執行測試,以及建置。(我們曾在這裏介紹如何擴展 CI 以應付這種工作量。)典型的 CLI pull request 可能要通過數十項檢查,才會有人查看。PR 範本會詢問如何測試這項變更,以及如何撤銷變更。Claude 可以填寫這些內容,但提出變更的人必須確認。

5. 按風險調整的人手審批

修正文檔和修改自動更新程式的風險不同,因此兩者的審查要求也不同。

風險範例人手審批
低文檔、文案、僅供內部使用的功能,以及由旗標控制的新增變更自動化審查和安全檢查全部通過後,無需人手審批
中一般產品變更,以及涉及快取、自動更新程式或系統提示詞等敏感範疇的變更一人
高風險最高的程式碼,以及少數始終需要兩人審批的路徑兩人

風險級別由變更決定,而非作者。分類器會分析變更並選定其風險級別。另一個分類器則會判斷,即使按風險級別毋須額外人手審批,這項特定變更是否仍需要另一人審批。有些路徑始終需要人手審批,包括負責人列為敏感的路徑,以及任何 CI 工作流程檔案。

只有受信任的作者才可採用較寬鬆的審查流程。只有列於儲存庫受信任名單上的作者才可採用較寬鬆的審查流程,主要是負責該儲存庫的團隊。其他人都需要另一人審批。Agent 的審批也不會算作人手審批。自動化審查可以批准低風險變更,但不能代替必須由人員填補的審批名額。

指示提出變更的人須為變更負責。對於由 Agent 撰寫的 PR,指示 Agent 的人會計作所需審查者之一,就如同由他們親自編寫程式碼一樣。

審批只適用於特定提交。如果有新的提交加入,而系統無法確認其可信性,例如 Agent 推送的提交,或有人手動解決合併問題後產生的提交,就必須重新審批。

6. 合併佇列、旗標及逐步發布

合併佇列會在套用變更後,針對 main 重新執行所有檢查,避免兩個 PR 分別通過檢查,合併後卻令 main 出現問題。新功能通常會先透過旗標向 Anthropic 員工發布;我們的大量使用往往能在用戶發現前揭示回歸問題。公開版本會先發布到 latest 頻道。stable 頻道則稍後跟進。

7. 快速偵測,快速回滾

有些錯誤仍會漏網,因此最後一層的重點是迅速發現問題。無需部署即可關閉旗標。Claude Code 設有每週值班輪替,事故檢討則會追問哪一層本應偵測到問題。

發現不良合併仍要依靠作者、值班人員,以及回退和事故儀錶板。我們目前還沒有在這些數字變動時收緊審批的熔斷機制;這裏的工程師希望在更多程式碼轉為無人參與的合併之前,先建立這些機制。

一位同事説,放慢速度確實能降低錯誤率,但主要是因為各方面做得都少了。我們更希望提升發現和修復問題的速度。

如何提升審查器的能力

我們的程式碼審查流程持續循環改進。

現在,每宗事故都會納入評測。團隊收集了過往引發事故的 PR,以及相關的後續修正和回退提交,並請熟悉相關程式碼的工程師確認每個錯誤及其所在位置。審查器每天都會使用這批資料進行評測。

我們的事故就是評測集

以過往事故和回退提交建立,每天執行

圖 C每宗事故都會擴充評測集,而審查器的每項改動都會根據整個評測集評分。

我們會觀察人們如何處理評論,以衡量噪音。只要不介意標出大量非錯誤內容,要找出更多錯誤並不難,因此我們需要一項檢查來把關。我們會根據 PR 上的人如何回應,為審查器留下的每則評論分類:對方修正了問題、表示判斷有誤、表示該行為是刻意設計,或認為問題無關緊要。我們也會在已知沒有問題的 PR 上執行審查器,並計算它有多常報告一些可能導致他人作出有害改動的內容。我們明確記錄的優先事項是先找出真正的錯誤,其次才是減少審查輪次。

當作者是 Agent 時,噪音的代價更高。人只需幾秒便可略過一項瑣碎意見;Agent 卻會修正它,這代表要多一次提交和多一輪審查。

審查必須收斂。Agent 作者和 Agent 審查器可能會無止境地讓彼此忙碌。有一個 CLI PR 在一夜之間經歷了五十多輪審查和修正,最後由作者叫停。

我們對審查器反覆標出的內容執行 git blame 後發現,其中約 59% 的程式碼在審查器首次檢查時已經存在。審查器很少找到新錯誤,只是在每一輪中多找出幾個舊錯誤。

問題也是我們自己造成的。我們已習慣預設進行多輪審查,因為每一輪都能找出新問題。對高風險改動來説,這可能值得;但不適用於每個 PR。團隊現在會像追蹤召回率一樣追蹤通過審查所需的輪數,並改變重新審查的方式:

  • 設定輪數上限。經過三輪後,審查器會要求作者停下來,重新考慮整體方案。
  • 最初幾輪之後,只重新審查差異內容。
  • 指出錯誤類型,讓作者修正所有同類問題,而不只是單一程式碼行。
  • 不重複提出已經發佈的問題。

審查 Agent 也會每晚檢查現有程式碼,協助我們在舊錯誤於其他地方造成問題之前將其找出。

讓審查收斂

收斂改動前後的內部拉取請求

圖 D收斂改動後,每個內部拉取請求所需的審查輪數減少

人類仍參與的環節

為了找出常見錯誤而打斷資深工程師的深度工作,成本遠高於自動化審查。在 Anthropic,我們的工作已從閲讀每個差異,轉為作出機器不擅長的決策:

  • 我們到底應否開發這個?方向、品味與範圍。有個團隊雖然宣稱已解決程式碼審查瓶頸,仍會由人工審查團隊以外提交的變更,因此有人會問:「我們真的要做這件事嗎?」
  • 高風險程式碼,例如計費、自動更新程式及 CI 工作流程。
  • 架構,會成為其他人仿效的模式。
  • 解讀證據。測試輸出、執行的命令及其回傳結果、螢幕截圖,以及審查者的發現。如果你説不出這些檢查會漏掉甚麼,就應要求正式審查,而不是快速批准。
  • 為結果負責。每項正式推出的變更都有人負責,無論程式碼由誰輸入。

由人作決定之處

五項決策仍由人作出;其他環節都會執行檢查

FIG E人們不再逐一閲讀每份差異,而是轉而處理機器不擅長作出的決策

在團隊內分享背景資訊

程式碼審查一直有第二個作用:讓團隊成員瞭解程式碼庫。閲讀隊友的差異,是瞭解哪些地方有所改動,以及各部分如何配合的方法。如果大部分閲讀工作都由機器完成,大家又如何瞭解程式碼?

我們沒有為此制定正式流程。團隊中沒有人能在腦中完整掌握 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 製作一個小型視覺化工具,展示程式碼的相關部分,並按照那個人喜歡的方式講解。

如果目標是善用人力,不逐行閲讀無關緊要的差異會更有效。一行文案的修改幾乎教不了你甚麼;而針對你即將修改的模組撰寫説明,則能讓你學到很多。我們也習慣在公開 Slack 頻道中工作,這有助於你看到其他人正在製作甚麼。

由你合併,就由你負責

如果你合併了一項小型或中型變更,之後仍然出了問題,團隊的慣例通常是由你負責修復。以下做法有助於避免情況失控:

  • 變更幅度小,因此容易審查、除錯及回退。
  • 所有變更都可還原。功能旗標、回退操作及分階段發布,能在幾分鐘內撤銷大部分錯誤。
  • 影響範圍決定審查標準。出錯代價高的程式碼需要更多人審查和更多檢查。
  • 迴歸問題會迅速浮現,可透過遙測資料及內部使用情況察覺。
  • 這不是為了追究責任。負責修復代表你掌握最多背景;事故檢討則會檢視整個系統。

責任亦由團隊共同承擔。團隊中許多人會在公開頻道工作,任何人都能看到其他人在做甚麼、接續討論,或讓 Claude 補上不足;意見也會來自並不負責相關程式碼的人。這種開放文化,是在不逐行設置關卡的情況下維持高質素的重要一環。

改變方向時

Agent 令啟動項目的成本很低,因此有些工作不應合併。通常會有人在頻道中詢問原因、指出先前的決定,或建議更簡單的做法,然後作者便會關閉 PR 或調整 PR 內容。

由於程式碼撰寫得很快,關閉 PR 不會令人覺得有所損失。關鍵是在討論串早期提出不同方向,而不是等 PR 完成後才以阻擋合併的意見提出。

如何採用這套流程

如今,與團隊實行這套做法所需的大部分要素都已具備。

建立拉取請求之前

  • 為 Agent 提供可自行執行的檢查項目,並列於簡短的CLAUDE.md中;另外加入可執行格式化工具和 lint 工具的 hooks。
  • 在本機執行/code-review和/security-review,或讓子 Agent 在全新上下文中進行審查。
  • 新增REVIEW.md,並將重複出現的審查意見整理至其中。

每個拉取請求

  • 將 CI 列為必須通過的檢查,並在 PR 範本中加入「測試」、「風險」和「如何回退」欄目。
  • 先在一個儲存庫加入 AI 審查工具(Code Review for Claude Code,或 Claude Code GitHub Action),調整REVIEW.md數週,再擴大採用。
  • 加入自動化安全審查,並要求合併前解決所有審查討論串。
  • 按風險調整審查力度:常規更改快速審查;若漏掉錯誤的代價高昂,則深入審查(Code Review 中的 Quick、Standard 或 Deep)。
  • 限制審查輪數;完成最初幾輪後,只重新審查新增的差異內容。

批准

  • 記錄風險級別,按更改而非作者來設定;先採用嚴格標準,再根據證據放寬。
  • 為你信任的作者保留較寬鬆的批准流程。
  • 使用 CODEOWNERS 和分支保護,確保身份驗證、帳單、CI、發布工作流程及安裝程式始終需要人工審查。
  • 不要讓機械人的批准取代必需的人工批准;有新提交時撤銷既有批准。

合併及後續

  • 使用合併佇列、功能旗標、先供內部使用、分階段發布,以及一步回退。
  • 將事故和回退案例納入評測集;每當審查器的提示詞、工具或模型有變更時,重新評分。
  • 衡量人工投入時間,並以回退率和事故率作為防護指標。

未來走向

Code Review 的公告指出,批准拉取請求仍由人員決定;產品會列出發現事項,而非作出批准。我們自己的儲存庫做得更進一步,讓擁有者決定哪些低風險更改可僅憑自動檢查結果合併,而這條界線仍在不斷移動。

當審查漏掉問題時,我們會追查模型當時缺少哪些資訊,並將修正納入CLAUDE.md、技能或新的檢查項目。目標始終不變:減少每項更改所需的人工時間,同時確保回退次數不多於以往。

如果你的團隊讓 Agent 建立拉取請求,我們想了解你們已將哪些檢查自動化、哪些仍需人工處理,以及你認為我們有哪些地方做錯。

感謝 Emma Webb、Michael Segner 和 Amie Rotherham 提供審查意見。

來源:Anthropic:Claude.dev 開發者博客 · claude.dev