好的審查流程只是故事的一半,撐起它的工具同樣關鍵。Google 自研的 Critique 把一次 review 的完整生命週期——從建立變更到提交——都收進同一個工具裡。它的設計哲學可濃縮成一句話:信任與溝通是核心,工具只能增強、無法取代它們。
🧠 為什麼工具這樣設計
花在 code review 上的時間就是沒花在寫程式的時間,所以審查流程的任何最佳化,都是公司生產力的提升。Critique 的每個決策都服務於「讓審查無縫流動」這個目標,背後是四條指導原則:
- 簡潔性(Simplicity):UI 以「輕鬆完成審查」為目標,載入快、支援快捷鍵、避免不必要的選項。這是影響最深的原則——許多功能因為只服務少數人而被砍掉。
- 信任基礎(Foundation of Trust):審查的目的是賦能而非拖慢他人。信任作者會確實修改,就不必為了複查細微評論而多加一輪。所有變更在內部公開可見也是信任的體現。
- 通用溝通(Generic Communication):溝通問題很少能靠工具解決。Critique 寧可提供通用的評論方式(甚至直接建議修改),也不讓資料模型與流程更複雜。
- 工作流整合(Workflow Integration):一鍵跳到 Code Search、Cider(線上 IDE)、測試結果——但偏好連結而非嵌入,以免分散核心審查體驗。
NOTE
簡潔性與整合之間有張力。團隊曾想做一個把編輯、審查、搜尋合一的「Code Central」,最終仍決定讓程式碼審查保持為主焦點:功能從 Critique 連結出去,但在各自的子系統中實作。
🔁 六個階段的審查流程
Critique 的審查通常發生在提交前(precommit review)。整條流程是回合制的——永遠至少有一個人「輪到」行動。
階段 1 — 建立變更(Create / Preview)
作者在工作區寫好變更,上傳一個快照(snapshot)到 Critique,觸發自動化分析器(analyzers)執行。此時 Critique 讓作者換上 Reviewer 的帽子:以審查者視角看自己的 diff、看分析結果,先自我打磨。
- diff 元件基於最佳化的 LCS 演算法,支援語法高亮、交叉引用(Kythe)、字元級行內差異、忽略空白、搬移偵測(不天真地顯示成「這刪那增」)。
- 支援疊加與**並排(side-by-side)**兩種模式。
- 作者可把變更連到特定 bug 提供脈絡,送審時還能附上初步評論、直接向 Reviewer 提問。
階段 2 — 請求審查(Request Review)
作者對 diff 與分析結果滿意後,把變更「寄送(mail)」給一或多位 Reviewer。在 Google 規模下「找誰審」本身是個問題,Critique 會建議一組足以核准的 Reviewer,考量:誰擁有這段程式碼(ownership)、誰最近改過它、誰現在有空(未休假、同時區佳),以及 GwsQ 團隊別名設定。指派同時觸發 presubmit hook(跑測試、強制專案規範等)。
階段 3 & 4 — 評論與迭代(Comment → Reply)
評論是僅次於看 diff 的第二常見操作,且任何人都能評論(所謂 drive-by review)。
- 評論預設為 unresolved(未解決),代表作者必須處理;也可加 resolved 的資訊性/選擇性評論。
- 評論是逐條草擬、最後一次性「發佈」(atomic publish)——讓 Reviewer 看完整個變更再一口氣給出完整想法。
- 快捷回覆:作者按「Done」表示已處理、按「Ack」表示已閱讀(多用於資訊性評論)。
- Attention set(關注集合):Critique 標示目前輪到誰,名字以粗體呈現,回應了 code review「回合制」的本質。
// Reviewer 在這一行留下 unresolved 評論:
// 「這裡沒處理 items 為空陣列的情況,reduce 會丟錯 → Please Fix」
function averagePrice(items) {
return items.reduce((s, i) => s + i.price, 0) / items.length;
}
// 作者上傳新快照回應,並按下 Done:
function averagePrice(items) {
if (items.length === 0) return 0; // ← 依評論修正
return items.reduce((s, i) => s + i.price, 0) / items.length;
}步驟 3 與 4 可能來回多次;作者與 Reviewer 隨時能比較任兩個快照的差異。
階段 5 — 核准 / 評分(Approve / LGTM)
變更的「評分」分三部分:LGTM(我審過、符合標準、處理完評論即可提交)、Approval(作為把關者,我允許它進 codebase)、以及未解決評論數。當變更至少一個 LGTM + 足夠 Approval + 零未解決評論時即可提交,UI 以綠色頁首醒目標示。
- 每個變更都需要 LGTM(不論 Approval),確保至少兩雙眼睛看過。
- LGTM/Approval 是硬性要求(只有 Reviewer 能給、可隨時撤回);未解決評論是軟性要求(作者可自行標為已解決)。
- 刻意簡化:評等永遠是正面的(拿掉了早期的「Needs More Work」);要求重審就加評論但不給 LGTM。所有負面回饋都必須綁定具體待修項(unresolved comment),Reviewer 不能只「按反對」而不給有用回饋。
階段 6 — 提交,以及提交後的考古
Critique 提供一個提交按鈕,讓作者不必切到命令列——在同一工具內走完「建立到提交」的完整生命週期。若 presubmit 通過,變更即進 codebase。提交後,Critique 仍是**變更考古(change archaeology)**的工具:任何人都能瀏覽一般可見檔案的變更歷史、評論與演化過程,支援日後稽核、理解「為何這樣改」或「bug 如何被引入」。甚至支援提交後繼續評論。
TIP
系統對偏離常規流程留有彈性:Reviewer 可取消指派或轉交他人、作者可延後審查;緊急時作者甚至能強制提交、事後補審。
🔑 Takeaways
- 信任與溝通是核心,工具只能增強、無法取代——這是 Critique 全書的一句話總結。
- 六階段:建立/預覽 → 請求審查 → 評論 → 迭代回覆 → 核准(LGTM/Approval)→ 提交,全在同一工具內完成,減少情境切換。
- 評論預設 unresolved(作者必須回應)、批次一次發佈;LGTM/Approval 是硬需求、未解決評論是軟需求,體現對作者的信任。
- 每個變更至少一個 LGTM 確保「兩雙眼睛」;評等永遠正面,負面回饋必須綁定具體待修項。
- 小工作流最佳化(如 attention set 標示「輪到誰」)大幅降低摩擦;提交後 Critique 還是變更考古的入口。
No notes yet — jot your takeaways or Q&A here.