How I Review AI Code — (Meta Senior Staff Engineer)
John Kim(Meta senior staff software engineer)談 AI 時代怎麼 review code。逐字稿為 YouTube 自動字幕(ASR),由使用者提供。
統整
0. 他要回答的問題
社群分成兩派:一派說「還在 review 自己的 code 就是不夠快,agent 早就比你會 review」;另一派說「AI 還不夠好、會犯蠢錯、產出一堆 AI slop,你得慢下來看自己寫了什麼」。他的答案是 it depends——而整支影片就是在定義「depends 在 depend 什麼」。
前提先講清楚:AI coding 之後產出的程式碼量暴增,一個人可以同時開多個 agent,單一工程師要 review 完自己的 code 幾乎不可能,更別說還要 review 別人的。
F: 目前本人也是利用 AI 直接 code review 自己以及他人的 code, 唯一會大概看的就是整個程式碼的閱讀性(當然這很主觀),以及有沒有一些不理解的商業邏輯處,讓 AI 跟我解釋
1. 核心模型:把 codebase 想成一棵樹
- Trunk(樹幹):主要進入點(
app.js之類)、基礎設施(影像處理、網路層)——這裡出事會影響整個 app - Leaf(葉子):孤立寫出來的、或被 feature gate 完全隔開的程式碼——一次性元件、新 endpoint、新邏輯,沒有接進既有 production codebase
由這個模型直接推出他的主張:
Review 的深度應該取決於那段改動的 blast radius(爆炸半徑)。
- 動到核心影像渲染基礎設施、下游依賴一堆 → 花大量時間逐行讀
- 一次性的 leaf node → 讓 agent 跑 component test / snapshot test,看 PR 裡的證據+目視確認就好
F: 簡單來說就是影響越多的部分越是要人確認,但我怎麼知道說現在這一 Part 的影響範圍有多少,尤其是我整個應用龐大時怎麼判斷說標準在哪裡?
2. AI agent 要參與整條產線,不只是寫 code
從 planning → building → reviewing → launching 每一段都該有 agent 參與:
- planning:規劃 spec、確認功能完整、事先想好 evaluation 與 validation 標準
- building:做到 agentic validation——讓 AI 能自我驗證、自我修復,提高一次寫對的機率
- reviewing:本片主題
- launching:feature gate + 跑實驗
F: feature gate 是什麼? 實驗又是什麼? 不過其他的蠻 match 我在做的事情,目前流程就是 agent 生 spec -> agent 生技術文件 -> 然後各個實作 repo 的 agent 去 review 技術文件 -> agent 派發任務給各個實作 agent -> agent review -> 主 agent 對著文件做最後確認 -> 人確認
3. 從一開始就要 feature gate
Feature gating = 在 codebase 裡加一層分支邏輯,可以開關這個功能。正式做法有很多基礎設施(例如 LaunchDarkly 這類 feature toggle 服務),但最簡單就是加一個 boolean flag。
規劃新功能時的順序:
- 用 broad strokes 想整體,把所有東西都 gate 起來
- 把 leaf node 分出來(不碰既有 codebase 的部分)
- 整合層單獨思考、特別要 gate 住
- 有了 plan、roadmap、gating 之後才開始讓 agent 寫 code(做 atomic changes)
F: 個人懷疑這樣做的實用性以及整潔性,flag 最後要拿掉嗎?如果只是現有 code 修改加上新功能呢? 我的 code base 不就要寫判斷,那判段要 commit 嗎?
4. PR 裡要有「證據」
他對 PR 的要求是逼 agent 給證據(proof),證據有四類:
| 證據類型 | 說明 |
|---|---|
| Unit tests | 看測試名稱、掃一下 assert,就能快速判斷邏輯有沒有被測到 |
| Runtime evidence | runtime log——給 agent 更多可見性與「眼睛」 |
| Visual evidence | 螢幕截圖或影片(他每次改 UI 都要求附上) |
| Confidence level | 要求 agent 對自己的程式碼與 gating 各部分給出信心水準 |
有證據才能跑得快——因為你不必自己手動去驗證那些東西。 Agentic validation 是「能少讀 code」的核心:PR 上先有一堆證據,你就不用讀那麼多 code。
附帶提醒:agent 寫測試時要小心,應該做一個「不要寫沒用的測試」的 skill。
5. 實際怎麼分配力氣
- Leaf code:花很少時間,基本上只是掃過,確認沒有明顯錯得離譜的東西
- Trunk code:例如 reducer(有大量 shared state)——改動既有行為、而且沒有被 gate 起來時,花大量時間讀,因為它直接改到 production,會有連鎖與副作用
一切錨定在 safety,三個問題:
- 不該改變的對照體驗(control experience)是什麼?
- 這個改動出錯的話,能有多糟?
- 我能不能把它 roll back?(這題取決於有沒有 gating)
第三題能回答得出來,前兩題的 review 成本就能大幅下降。
6. Nits 已經死了
風格、寫法偏好這類 nit,交給 static checking(type check、lint)和 agent 處理就好。理由:現在寫的 code 量太大、code 流動性變高、refactor 變得頻繁又容易(尤其在有良好驗證的前提下),所以「我偏好這樣寫」已經不該出現在 code review 的對話裡。
7. 用 agent 來 review 的四個要點
- 用好的 review skill:Claude Code 與 Codex 內建的 review agent 都不錯(
/code review之類) - 一定要用「沒有生成過這段 code 的」另一個 agent——因為帶著原本上下文的 agent 會作弊,它會錨定在先前的對話上。這叫 adversarial review agent
- PR 要有 template:不給指引的話 agent 會寫出一大篇故事。他最大的 pet peeve 就是摘要與測試計畫比改動本身還長
- 把這些都做進 skill 裡
工具面:
- Codex 可以掛到 GitHub 上當 reviewer,PR 一開就跑(有獨立、為 review 微調過的模型;要花錢)
- 用 goals 來「顧」PR:常見問題是 agent 給一堆 comment、你修完重送、來回很多次。可以設定「每小時檢查這個 PR,處理 Codex agent 的所有 change request」——它會定時檢查、修問題、重跑本地的 agentic validation、更新 PR 說明再送出
8. Merge ready ≠ Launch ready:最後的 20%
照這套方式寫完一個功能、覺得「我做完了」的時候,其實只完成了 80%。
- 前面那段他叫 broad strokes:把東西 gate 好、先 land 進去
- 最後 20% 才是讓它可以上線:大量 refactor、清理 codebase
這 20% 他會先讓一批 agent audit 整份寫出來的 code,然後自己從高層次檢視:效能、bug、安全性、功能是否真的符合 spec,最後才是動畫這類細節。
這最後的 20%,花的時間和前面的 80% 一樣多——但它是最重要的部分,而且需要人的品味(human taste factor)。
9. 上線:跑實驗
即使使用者少、沒有統計檢定力(statistical power)跑不了正規 A/B test,他仍建議跑 A/B test 或 canary deployment:透過 feature gating 把流量一點一點放進新功能,就能很快看到 bug、crash、警報。
10. 結論
「所以你還讀不讀 code?」——讀,但它是個 gradient。
他目前的狀態:
- 他自己讀的 code 比以前更多,但有一個「旋鈕」:先問是不是 trunk change、有沒有大量依賴 → 往上調;再問安不安全、有沒有 gating → 往下調。越是單向門(one-way door)的改動,讀得越久
- 模型越來越好,所以將來大概會讀更少,但要錨定在 validation、agentic validation、以及 agent 提供的證據(錄影、log、截圖)
- 目標是打造 agentic safeguard / agentic garden:大量測試、大量驗證、大量 agent 在工作,同時用 gating 保住「把爛決定收回來」的能力
- 最後補充:你越理解自己的 codebase,review 越容易——因為你能很快看出哪些動到危險地帶、哪些只是 leaf
關鍵句中英對照(精選原話)
選 20 句承載論點的原話;逐字稿為自動字幕,口語填充詞已略。
| 原話 | 中譯 |
|---|---|
| ”the reality of code reviews is a gradient” | 「code review 的現實是一個漸層(光譜)」 |
| “it’s almost impossible of a task for a single engineer to review even their own code” | 「單一工程師連 review 自己的 code 都幾乎是不可能的任務」 |
| “I think of the codebase like a tree” | 「我把 codebase 想成一棵樹」 |
| “the review depth … should really be based on like the blast radius of that code change” | 「review 的深度,應該取決於那個改動的爆炸半徑」 |
| “if something goes wrong in that codebase it can affect the entire app” | 「那段 codebase 一出事,可能影響整個 app」 |
| “a leaf code is really code that is written in isolation or it’s completely gated off in a feature gate” | 「leaf code 就是孤立寫成、或被 feature gate 完全隔開的程式碼」 |
| “the AI agent should be part of the entire code’s journey to production” | 「AI agent 應該參與程式碼通往 production 的整段旅程」 |
| “you want to have agentic validation so that the AI can self-validate and self-fix itself” | 「你要有 agentic validation,讓 AI 能自我驗證、自我修復」 |
| “you really want to anchor and push your agents to give you proof” | 「你要把重心放在逼 agent 給你證據」 |
| “having proof and having more proof lets you move faster” | 「證據越多,你跑得越快」 |
| “agentic validation is a core concept of being able to read less code” | 「agentic validation 是『能少讀 code』的核心概念」 |
| “you’re really anchoring on safety” | 「你真正錨定的是安全性」 |
| “if this change went wrong how bad can it be and then can I roll this change back” | 「這個改動出錯會有多糟?我能不能把它收回來?」 |
| “I think that’s kind of dead” (about nits) | 「我覺得那(糾結寫法)差不多已經死了」 |
| “the agents will cheat” | 「那些 agent 會作弊」 |
| “a separate agent that is called an adversarial review agent” | 「一個獨立的 agent,叫做對抗式審查 agent」 |
| “my biggest pet peeve … is when … the summary and test plan is longer than the code changes itself” | 「我最受不了的就是:摘要和測試計畫比改動本身還長」 |
| “even if it’s merge ready I don’t think it’s launch ready” | 「就算可以 merge 了,我不認為它可以上線」 |
| “this last 20% actually takes as long as the first 80%“ | 「最後這 20%,花的時間跟前面 80% 一樣多」 |
| “still requires a lot of like human taste factor” | 「這仍然非常需要人的品味」 |
| “if you understand your codebase it’s actually easier to review the code” | 「你越理解自己的 codebase,review 就越容易」 |
值得記的英文表達
| 表達 | 用法 |
|---|---|
| blast radius | 改動的影響範圍。the blast radius of that code change |
| gradient | 連續光譜而非二分。code reviews is a gradient |
| trunk / leaf node | 樹幹/葉節點,這裡借來分類程式碼重要性 |
| feature gate / gating / toggle | 功能開關。gate all of the things out |
| anchor on X | 把重心錨定在 X。全片高頻:anchor on safety、anchor on validation |
| one-way door | 不可逆的決定(Amazon 用語)。more of that change is a one-way door |
| merge ready vs launch ready | 可合併 ≠ 可上線 |
| broad strokes | 粗略地、大方向地做。think in broad strokes |
| pet peeve | 最受不了的小事 |
| nits | code review 裡的雞毛蒜皮意見 |
| AI slop | AI 產出的低品質內容 |
| statistical power | 統計檢定力 |
| canary deployment | 金絲雀部署,小流量先行 |
| trickle your traffic | 讓流量一點一點流過去 |
| babysit a PR | 顧著一個 PR(持續盯、處理回饋) |
反覆出現的關鍵字
- anchor on safety — 全片的主軸句型,出現次數最多;他每談完一個做法都會回到這句
- blast radius / trunk / leaf — 他唯一提出的分類模型,後面所有建議都掛在上面
- it depends / gradient — 他刻意反覆強調的立場:拒絕二分法
- proof / evidence / validation — 四類證據是他「少讀 code」的交換條件
- agentic validation — 他自己的術語,連結到他另一支 agentic engineering 影片
- feature gating — 從 planning 講到 launch,每一段都回到它
- adversarial review agent — 工具層唯一被他標成「重要」的做法
- human taste factor — 最後 20% 的理由
矛盾點
影片內部
-
「AI 已經比大多數人更會 review」與整支影片的主張相衝突。 他說
AI is really good at reviewing code already, I actually do think it's better than most humans,但全片都在教你人要親自讀 trunk code、最後 20% 要靠人的品味。如果 AI 真的比大多數人好,那該被削減的是人讀 code 的部分才對——他沒有調和這兩句。(推論)可能的解釋是「比大多數人好」指的是找得出表面缺陷,而 trunk 的判斷與品味是另一種能力,但他沒有這樣區分。 -
「我讀的 code 比以前更多」vs「你將來會 review 更少 code」。
I read more code than I did before(11:49)與you will probably review less code(18:59)並列,中間沒有說明那個轉折什麼時候發生、靠什麼觸發。 -
80/20 這個比例自己拆了自己。 他說寫完覺得做完時「其實只有 80%」,但緊接著說最後 20% 花的時間和前面 80% 一樣多。那麼以時間計它根本是 50/50——80/20 講的是「功能份量」,但他用時間來強調重要性,兩個尺度混在同一句話裡。
-
nits 宣告死亡,但最後 20% 又把風格判斷找回來。 前面說「我偏好這樣寫」已經不該出現在 review 裡,後面卻說最後 20% 要大量 refactor、清理 codebase、靠 human taste。(推論)他要區分的大概是**「寫法偏好」vs「結構品質」**,但他用的字(taste、clean)正好是 nit 文化的用字。
-
證據本身是誰產生的,他沒有談。 四類證據(測試、log、截圖、信心水準)全部由 agent 自己提供,而他自己也說
the agents will cheat——那個「會作弊」的警告用在 review agent 上,卻沒有套用在產生證據的 agent 上。(推論)截圖可以只截對的那一格、測試可以挑會過的寫,這條風險他沒有處理。 -
逐字稿是自動字幕,有數處明顯轉寫錯誤(讀的時候要還原):
launch starkly→ LaunchDarkly;Clockode/Clock→ Claude Code;Codeex/codecs→ Codex;leaf notes→ leaf nodes;feature gaining→ feature gating;knits→ nits;enginic engineering→ agentic engineering。
與 vault 既有筆記
-
和 監督 AI 產出的檢查成本可能比自己寫還高 正面對撞。 那篇說檢查成本可能高到不如自己寫;他的解法是把檢查成本轉嫁給證據——
having proof lets you move faster because you don't have to manually check。 兩篇其實在同一條軸上的兩端:檢查成本高 → 要嘛自己寫,要嘛讓產出自帶可快速驗收的證據。 -
和 判準不是問題難不難,是有沒有標準化的驗收方式 高度一致,而且補上了做法。 那篇的判準是「有沒有標準化的驗收方式」;這支影片等於回答「驗收方式長什麼樣」——四類證據 + agentic validation + gating。
-
和 蓋出高於自己理解程度的系統,能動時落差是隱形的 互補但有張力。 那篇警告:沒有能力檢查時,檢查成本不是高,是無限。他最後那句
if you understand your codebase it's actually easier to review正好同意這點——但他整套方法的前提就是「少讀 code」,而少讀 code 正是理解程度下降的來源。(推論)兩者的接點是:trunk 必須親自讀,而這正是維持理解程度的最低成本路徑。 -
和 並行多個 AI agent 的 context switch 會偷走專注 的前提相反。 那篇講多開 agent 的注意力代價;他把「一個人可以同時開多個 agent」當成既成事實來推導結論,沒有算這筆注意力的帳。
-
「不要寫沒用的測試」對得上 測試分兩層:綁契約的是資產,綁實作的是拋棄式 和 單元測試不是有寫就好。 他只說「做一個 skill 擋掉沒用的測試」,沒有給判準;vault 裡那兩篇提供的正是判準。
抽出的原子筆記
- 把 codebase 想成一棵樹:trunk 與 leaf 的分界是有沒有被隔開 — review 深度由 blast radius 決定
- PR 要自帶證據,證據是少讀 code 的交換條件 — 四類 proof 與 agentic validation
- Review 要用沒生成過這段 code 的 agent — adversarial review agent、PR template、nits 已死
- Feature gate 最簡單就是一個 boolean flag — gating 是整套方法的樞紐
- 跑實驗不是為了成效,是為了早點看到爆炸 — canary/A-B 當偵測器而非量尺
- Merge ready 不等於 launch ready,最後 20% 和前面 80% 一樣久 — 人的力氣集中在最後一段
我自己的部分(來自讀這份統整時寫的註記):
- 我的 review 旋鈕是看不看得懂,他的是影響範圍 — 兩個旋鈕不重疊,我現在的篩法對齊的是舒適度不是風險
- 我的多 agent 產線:文件是交接介面,agent 之間互相審查 — 現行流程,以及缺的 gating 與實驗兩段
- 怎麼判斷一段改動的影響範圍? — 材料只給例子沒給方法
- Feature flag 的生命週期:什麼時候拿掉、既有 code 怎麼包? — 材料完全沒談 flag 清理
未抽:Codex 掛 GitHub、用 goals 顧 PR(工具操作,版本變動快,留在本篇)。