做 code review agent 之前,我先拆了阿里的 open-code-review
做 code review agent 之前,我先拆了阿里的 open-code-review
最近在規劃一個 PR 開出來就自動 review 的 agent,一開始的想像很單純,把 diff 丟給模型,給它幾個讀檔的工具,讓它自己去翻呼叫端跟測試,最後吐一份 findings 出來,但越往下規劃越發現一件事,選哪些檔案、行號對不對、結果怎麼貼到 PR,這些其實都能寫成 code,每拆一塊出來,agent 能做的事就少一塊,到最後我開始懷疑,那這東西到底還需不需要是 agent?
剛好在 GitHub 上看到 alibaba/open-code-review,阿里內部用了兩年的 AI code review 工具,開源之後拿了 4.8 萬顆星(2026-10-27),它的 README 開頭就在講我卡住的這件事,所以乾脆 clone 下來,把 prompt 跟流程從頭爬了一遍。
通用 agent 的三個問題
它點名的對象很直接,就是拿 Claude Code 這類通用 agent 加一個 review skill 來做 review,它說會遇到三個問題,PR 一大 agent 就開始挑著看,有些檔案根本沒被看過,回報的行號常常對不上實際位置,然後 prompt 改一點點結果就差很多,很難 debug。
它認為根本原因是整個流程完全由模型決定,沒有任何硬性的約束,所以它的解法是把「絕對不能錯」的步驟從模型手上拿走,交給程式保證,模型只留在需要判斷的地方。
這個說法聽起來很像廢話,但實際去看它怎麼切,才知道切得有多細,那麼來看看整條流程長什麼樣子。
整條流程
git diff
├─ 選檔(程式):過濾 gitignore、生成檔
├─ 分組(模型提議,程式驗證):相關檔案綁成一組
├─ 配規則(程式):依副檔名套不同的 checklist
├─ 每組一個 sub-agent,各自獨立 context,可以平行跑
│ plan(只列計畫,不呼叫工具)
│ main loop(讀檔、搜尋,用 code_comment 回報,task_done 結束)
│ 第 2 輪(拿掉 plan,帶著已確認的問題再看一次)
├─ 定位(程式比對,失敗才請模型重抄)
└─ 查核過濾(模型,只看 diff,偏向保留)
分組這一步很能代表它的風格,檔案少於 4 個就不分組,超過才讓模型分,而模型回傳的是檔案的索引數字,不是路徑,這樣它就沒有機會把路徑抄錯,回傳之後程式還會再檢查一次,每組最多 10 個檔案、每組不能超過 token 上限,模型負責提議,最後由程式把關。
規則也是一樣,它有一張 glob 對規則檔的對照表,**/*.{ts,tsx,js} 套 TS 的規則、**/pom.xml 套 Maven 的規則,每一組只塞它用得到的 checklist,不是把所有規則整包丟給模型,再寫一句「如果是 TS 檔請注意...」讓它自己挑。
main loop 的工具只有六個,file_read、file_read_diff、file_find、code_search、code_comment、task_done,prompt 裡有一條我覺得是專門針對「挑著看」寫的,呼叫 task_done 之前,必須確認這一組裡的每個檔案都各自看過一遍,看了實作檔不代表看過它的 header 或設定檔。
不讓模型數行號
整個專案我覺得最聰明的設計在這裡。
回報問題的 code_comment 工具,參數裡面根本沒有行號:
{
"content": "問題描述",
"existing_code": "從 diff 原樣抄下來的那幾行",
"suggestion_code": "建議的改法",
"category": "bug | security | performance | ..."
}
程式拿 existing_code 去 diff 裡用滑動視窗比對,找出真正的行號,模型很不會數行號,但很會抄字串,所以把它的工作換成它擅長的那種,比對失敗的話,才另外呼叫一次模型,給它 diff 跟這則 comment,要它把相關的那幾行原樣抄出來,再比一次。
另外結果是用工具呼叫回報的,每發現一個問題就呼叫一次 code_comment,不是最後吐一大段 JSON,這樣中途被回合上限切斷,已經找到的問題也不會丟,程式也可以逐則檢查格式,它甚至有一個 comment_args_repair.go 專門修模型給錯的參數格式,這對比較弱的模型應該特別有用。
查核要偏向保留
review 跑完之後,它會再跑一次查核,把被證明是錯的 comment 刪掉,這個 prompt 是整個專案寫得最用心的,開頭就先講清楚兩種錯的代價不一樣:
Keeping an incorrect comment costs a reviewer a few seconds of attention. Removing a correct comment silently destroys a real finding.
留一則錯的 comment,reviewer 只花幾秒,刪掉一則對的,這個發現就消失了,而且沒有人知道,所以它的預設是全部保留,只有兩種情況可以刪,一種是 comment 講的程式碼根本不在它那個檔案的 diff 裡,另一種是 diff 裡有某一行字面上直接推翻它的說法,例如 comment 說某個變數沒用到,diff 裡明明有用到,需要推理兩步以上才看得出矛盾的,就不算。
然後還有一份保護清單,記憶體安全、併發、行為或相容性的改變、沒用到的參數,這幾類就算查核者很確定 comment 是錯的也不准刪,原因是這幾類最容易誤刪,誤刪的代價也最高,而查核者對自己判斷的信心,剛好在這幾類最不可靠。
還有一個細節,查核者只看得到 diff,主 agent 卻看過整個 repo,所以 prompt 特別寫了「你看不到的東西,agent 可能看到了」,避免資訊比較少的一方去推翻資訊比較多的一方。
一開始我自己的規劃是讓每個 finding 附一個信心分數,用分數來篩,看完這段就把它拿掉了,模型自己打的分數通常都是 0.8、0.9,分不出好壞,規則明確的第二道關卡可靠多了。
第二輪拿掉 plan
改動超過 50 行,它會先跑一個 plan 任務,plan 看得到工具清單但不能真的呼叫,只輸出「哪裡可能有風險、該用哪個工具去確認」,再把這份計畫塞給主迴圈,等於先花一次便宜的呼叫,幫 agent 排好調查順序。
但它在第二輪會把 plan 拿掉,原始碼裡的註解是這樣寫的:
// Round 2+ strips the plan to avoid it acting as a coverage ceiling.
plan 幫 agent 聚焦,同時也讓 agent 只查 plan 列出來的東西,變成一個天花板,所以第二輪不給 plan,改成帶上前一輪已經確認的問題,讓它去找漏掉的,又不會重複回報,一個設計同時有好處跟副作用,它沒有假裝副作用不存在,而是再用另一個步驟去補,這種地方很能看出是真的在線上跑過、被數據打過臉的。
七條設計原則
爬完之後,我把它的設計品味整理成七條,之後自己做的每一步都拿來對照:
- 能用程式保證的,就不要靠 prompt 拜託模型,選檔、上限、行號都屬於這類
- 模型的輸出一律經過程式驗證,分組回傳索引再檢查,comment 要靠字串比對才能定位
- 把模型不擅長的事,換成它擅長的形式,不要它數行號,改成要它抄出那幾行
- 一個大任務拆成幾個小任務,每個任務的輸入和輸出都很窄,plan、review、定位、查核各自分開
- 結果用工具呼叫回報,不要用一段自由文字,連結束也是呼叫工具
- 錯誤的代價不對稱時,預設往代價小的那邊偏,查核時寧可多留,也不要誤刪
- 每一道約束都對應一個實際觀察到的失敗,它的工具集就是從線上的 tool call trace 分析出來的,不是一開始就設計好的
第 7 條對我最有用,意思是不要一開始就把這些機制全部抄過來,先做最簡單的版本,準備一個埋好 bug 的靶場,看它在哪裡失敗,再回來看 open-code-review 是怎麼解那個失敗的,這樣每一個機制我都會知道它為什麼存在。
那到底該不該做成 agent
那麼回到一開始的問題,我後來用兩個問題來分。
第一個問題是,這個檢查能不能在看到輸入之前就寫好?能的話就寫成 code,lint、型別、像素比對都是,不能的話才需要模型,例如 PR 說明寫「分頁改成從 1 開始」,結果有一行 page * pageSize 忘了改,原本的 test 用 page = 0 測照樣會過,CI 全綠,但讀 diff 的模型看得出來說明跟程式碼對不上,這個判斷沒辦法事先寫成 assert,因為它依賴這次 PR 的意圖,而這個意圖在 PR 開出來之前根本不存在。
第二個問題是,要做哪些步驟能不能事先決定?能的話是 workflow,程式控制流程,中間呼叫一兩次模型,不能的話才是 agent,套到 code review 上,查核、定位補救、plan 都是單次呼叫,真正需要 agent 的只有「要不要去翻呼叫端、翻哪一個、翻完要不要再去看測試」這一段,因為下一步要做什麼取決於上一步看到什麼。
所以「越做越發現都能寫成 code」其實是對的,最後的系統是一大堆 code、幾個 workflow 裡的模型呼叫,加上一個很小的 agent 迴圈,agent 沒有消失,只是被放到唯一需要它的位置。
GitHub 自己的 Copilot code review 也是走這條路,2026 年 3 月改成 agentic 架構,會自己呼叫工具去翻 repo,同時又把 CodeQL 跟 ESLint 這些確定性的工具接進來,只是它把這些複雜度藏在一個按鈕後面,用起來才感覺很簡單。
一些冷水
查資料的時候也看到不少冷水,記下來提醒自己:
- open-code-review 自己的論文(AACR-Bench,200 個真實 PR、1,505 個專家標註的問題),SEM-F1 是 25.10%,Claude Code 是 11.57%,贏了兩倍多,token 少用 5 到 15 倍,但最好的也只有 25%,所以它只能當建議,不能當 merge 的關卡
- 另一篇研究分析了 5.4 萬則 Copilot、Cursor、Codex 留的 review comment,被拒絕的理由第一名是「這是刻意的設計決定」,第二名才是建議本身錯誤,模型不知道專案有哪些限制,這要靠自己補背景資料
- 同一篇也發現,附上建議程式碼的 comment 解決率從 64.6% 提高到 75.5%,而 comment 寫得越長,越少被採納
- 有一個找了 29 位專業開發者的對照實驗,發現先看過自動 review 的人,注意力會集中在被標出來的地方,不太會再去找其他問題,結果多抓到的是低嚴重度的問題,高嚴重度的並沒有變多,也沒有比較省時間,所以「先讓 AI 掃一遍」有可能反而讓人類的 review 變窄
Hacker News 上有一句話我覺得講得很準,AI is great at reviewing code. It is not great at reviewing intention. 它抓得到說明跟程式碼不一致,但判斷不了這個改動本身該不該做,那一塊還是得留給人。
結論
一開始做 agent 都會覺得什麼都要交給模型才夠酷,但認真做下去,大部分的東西最後都會變回 code,這不是 agent 沒用,而是它本來就只該出現在「事先寫不出規則、步驟也決定不了」的那一小塊,open-code-review 厲害的地方不在 prompt 寫得多好,而在於它很清楚哪些事不該讓模型做,以及模型做了之後要怎麼驗證,所以我最後沒有直接拿它來用,而是照著它的思路自己慢慢刻,再拿它當對照組量差距,畢竟框架能讓你很快套出結果,但哪天遇到內部模型比較弱、規範又特別多的環境,還是得知道每一道約束是為了擋住什麼吧。
參考資料
- alibaba/open-code-review
- OpenCodeReview: Determinism over Non-Determinism for Cost-Effective Agent-Based Code Review
- "Go Home Copilot, You're Drunk": Understanding Developer Responses to Agent-Generated Code Review Comments
- Deep Learning-based Code Reviews: A Paradigm Shift or a Double-Edged Sword?
- Copilot code review now runs on an agentic architecture
- New public preview features in Copilot code review
- How Accurate Is AI Code Review? False Positives, Recall, and Trust
- Hacker News: AI coding agents generate more code, but not more software
Waiting7777
WoW Arena 冠軍轉前端,用電競 meta 思維拆解技術趨勢。
相關文章
AI AgentsSEO+1把個人網站變得 agent-friendly:一個週末補完 9 個 well-known 路由
從 Link headers 到 WebMCP,isitagentready 給了我 9 個作業,我花一個週末全部交完。
2026年11月4日 · Waiting7777 · 7 分鐘閱讀
繼續閱讀 →
AI Agents開發者工具+1Orca 七個月拿下 10 萬顆星:我拆了它的 GitHub 數據,看到 agent 開發真正的瓶頸
一個由 agent 寫出來、拿來管 agent 的開源 IDE。19,000 個 commit、979 次 release 背後,最值得看的數字是 2,525 個放了一個月還沒人處理的 PR。
2026年10月20日 · Waiting7777 · 7 分鐘閱讀
繼續閱讀 →
AI Agents自動化測試+1跑了兩週 Agent QA Pipeline — 真實數字、踩到的坑、重來我會怎麼做
這是 post-mortem,不是 case study。做對的三件事、做錯的三件事、以及為什麼這套東西接下來要抽成 `claude-qa-pipeline` OSS。
2026年10月20日 · Waiting7777 · 6 分鐘閱讀
繼續閱讀 →這篇文章對你有幫助嗎?
每週一篇 — 技術趨勢背後的商業邏輯
AI 產業在變什麼、工程師該注意什麼——拆清楚寄到你的信箱。