
1. 從提示詞到產線為什么代碼審查需要多智能體代碼審查這件事寫過幾年代碼的人都有體會。它表面上是一個“看代碼”的動作實際上背后牽扯的東西特別多風格一致性、潛在缺陷、安全邊界、可維護性、團隊規(guī)范、上下文理解甚至還包括“這個改動會不會把隔壁模塊搞崩”。一個人盯著幾百行 diff 看半小時眼睛花了不說漏掉的概率還很高。所以當大模型能力起來之后幾乎所有人的第一反應都是能不能讓 AI 幫我審代碼我最早也是這么干的。寫一個提示詞把 diff 貼進去讓模型輸出問題列表。剛開始覺得挺香但用久了就發(fā)現(xiàn)單提示詞方案有幾個繞不過去的坎。第一模型容易“什么都想說”把無關緊要的命名風格和真正的邏輯漏洞混在一起噪音極大。第二長 diff 一進去模型注意力就被稀釋前面看得細后面看得粗。第三也是最要命的同一個提示詞既要它找 bug又要它評風格還要它判斷安全風險等于讓一個人同時干三份工結果每份都干得一般。LinkedIn 工程團隊公開分享過他們在這方面的實踐思路核心結論很明確代碼審查不是一個任務而是一組任務的集合應該用多智能體來拆。這個判斷我完全認同。所謂多智能體不是搞一堆花哨的框架而是把“審查”這個籠統(tǒng)目標拆成幾個職責單一的 agent每個 agent 有自己的提示詞、自己的關注范圍、自己的輸出格式最后再有一個匯總環(huán)節(jié)把結果合并去重。這樣做的好處是每個 agent 的提示詞可以寫得非常聚焦模型不用在一堆目標之間做取舍輸出質量自然就上去了。這篇文章我想聊的就是這條鏈路從最開始怎么寫提示詞到怎么拆成多智能體再到怎么把它真正放到產線里跑起來。適合兩類人看一類是已經在用 AI 輔助 review、但覺得效果不穩(wěn)定的開發(fā)者另一類是想把 AI 審查接入 CI 流程、但不知道從哪下手的工程團隊。我會盡量把每一步的“為什么”講清楚而不是只丟一個結論。2. 單提示詞方案的三個真實瓶頸2.1 注意力稀釋長 diff 下的“前緊后松”我先說一個大家可能都遇到過的現(xiàn)象。當你把一個 500 行的 diff 塞給模型讓它找問題它往往在前 100 行能給出比較具體的意見到后面就開始說“整體看起來不錯建議補充測試”這種廢話。這不是模型偷懶而是注意力機制本身的特性決定的。上下文越長每個 token 分到的注意力權重就越平均模型對細節(jié)的捕捉能力會下降。我做過一個粗略的對比測試同一段包含一個空指針風險的代碼放在 diff 的開頭位置模型能穩(wěn)定識別把它挪到 diff 的 70% 位置識別率大概掉到一半挪到末尾基本就漏了。這個測試不嚴謹?shù)厔莺芮宄?。單提示詞方案下你沒法控制模型“先看哪里、后看哪里”它只能按順序掃一遍越往后越糊。2.2 目標沖突一個提示詞裝不下所有訴求第二個瓶頸是目標沖突。你寫提示詞的時候如果同時要求“找出邏輯錯誤”“檢查命名規(guī)范”“評估安全風險”“判斷性能影響”模型在生成時其實是在做多目標優(yōu)化。它會把有限的輸出預算分配給不同的目標結果就是每個方向都淺嘗輒止。更麻煩的是不同目標的“嚴重程度”標準不一樣。一個變量命名不規(guī)范和一個 SQL 注入風險在同一個列表里并列出現(xiàn)reviewer 看了只會覺得吵。我踩過的坑是早期提示詞里寫了“請全面審查代碼”結果模型輸出了一大堆“建議添加注釋”“變量名可以更清晰”這類低價值內容真正的問題反而被淹沒了。后來我把提示詞改成“只找會導致運行時錯誤的缺陷”輸出質量立刻上了一個臺階。這說明什么說明提示詞的約束力來自于它敢不敢放棄。你讓它什么都管它就什么都管不好。2.3 輸出格式漂移難以直接接入產線第三個瓶頸是格式。單提示詞方案下你很難保證模型每次都按同一個結構輸出。今天它給你一段自然語言描述明天給你一個帶編號的列表后天又變成 markdown 表格。對于人工看來說這沒什么但如果你想把它接入 CI讓結果自動發(fā)到 PR 評論里格式不穩(wěn)定就是災難。你得寫一堆正則去解析解析失敗還得兜底維護成本極高。多智能體方案在這點上優(yōu)勢明顯每個 agent 的提示詞里可以強制約定輸出 JSON schema匯總 agent 再按固定結構合并。格式穩(wěn)定了下游的自動化才有基礎。這也是為什么我認為多智能體不是為了“更智能”而是為了“更可控”。可控性才是產線化的前提。3. 多智能體拆解把審查拆成四個專職角色3.1 角色劃分的邏輯按“關注面”而不是按“文件類型”拆多智能體第一個要決定的就是怎么拆。我見過一些方案是按文件類型拆一個 agent 看 Python一個看 Java一個看前端。這種拆法我不太推薦因為文件類型和審查關注點并不一一對應。一個 Python 文件里可能同時有邏輯缺陷、安全問題、性能隱患你按語言拆等于每個 agent 還是要面對多目標問題。更合理的拆法是按“關注面”拆。LinkedIn 的思路大致是分成幾類缺陷檢測、安全審查、風格與可維護性、測試覆蓋。我自己的實踐里也基本沿用這個劃分但做了一點調整把“風格”和“可維護性”合并因為這兩者經常重疊另外單獨加了一個“上下文一致性”agent專門看這個改動和周邊代碼是否協(xié)調。下面這張表是我目前用的角色劃分Agent 角色關注范圍輸出重點典型誤報來源缺陷檢測空指針、邊界條件、并發(fā)問題、資源泄漏會導致運行時錯誤的問題對框架約定不熟悉安全審查注入、越權、敏感信息泄露、依賴風險可被利用的安全問題對業(yè)務上下文不了解風格與可維護性命名、復雜度、重復代碼、注釋影響長期維護的問題團隊規(guī)范差異上下文一致性接口變更、調用方影響、數(shù)據流跨模塊影響倉庫信息不完整這個劃分的核心邏輯是每個 agent 的“判斷標準”是獨立的。缺陷檢測只看“會不會出錯”安全審查只看“會不會被攻擊”它們之間不需要互相妥協(xié)。這樣每個提示詞都可以寫得很“極端”反而提高了召回率。3.2 每個 agent 的提示詞該怎么寫提示詞是多智能體方案里最核心的資產。我寫這類提示詞有一個基本原則先定義“不要什么”再定義“要什么”。因為模型天生傾向于“多說話”你不明確禁止它就會把一堆低價值內容塞進來。以缺陷檢測 agent 為例我的提示詞結構大概是這樣的你是一個專注于運行時缺陷的代碼審查員。 你的唯一目標是找出會導致程序在運行時出錯的問題。 不要報告命名、注釋、格式、風格相關的問題。 不要報告“建議補充測試”這類非缺陷內容。 如果某段代碼你不確定是否有缺陷標記為“待確認”不要直接判定為缺陷。 關注以下類型 - 空指針或未初始化變量 - 數(shù)組越界、邊界條件錯誤 - 資源未釋放文件、連接、鎖 - 并發(fā)競態(tài)條件 - 異常處理缺失或吞異常 輸出格式嚴格 JSON { issues: [ { file: 文件路徑, line: 行號, type: 缺陷類型, severity: high/medium/low, description: 問題描述, suggestion: 修復建議 } ] }注意幾個細節(jié)。第一我明確寫了“不要報告什么”這比只寫“要報告什么”更有效。第二我加了“待確認”這個中間狀態(tài)因為模型在不確定時如果被迫二選一往往會選錯。給它一個緩沖選項誤報率會下降。第三輸出格式用 JSON 并且給了完整 schema這樣下游解析幾乎不會出錯。安全審查 agent 的提示詞結構類似但關注點換成注入、越權、敏感信息。這里有個經驗安全審查 agent 需要額外的“業(yè)務上下文”輸入。比如一個接口是否對外暴露、參數(shù)是否來自用戶輸入這些信息光看 diff 是看不出來的。所以我在調用安全 agent 時會額外拼接一段“變更說明”讓模型知道這個改動的意圖。3.3 匯總 agent去重、排序、降噪四個 agent 跑完你會得到四份問題列表。如果直接合并會出現(xiàn)大量重復同一個空指針缺陷 agent 報了上下文一致性 agent 也可能報。所以需要一個匯總 agent 來做三件事去重、排序、降噪。去重的邏輯不能只靠行號因為不同 agent 可能對同一行給出不同描述。我的做法是讓匯總 agent 按“文件行號問題類型”做粗粒度聚類然后對同一簇內的描述做語義合并保留最具體的那條。排序則按嚴重程度high 在前l(fā)ow 在后。降噪是最關鍵的一步匯總 agent 會過濾掉那些“只有單個 agent 報告、且嚴重程度為 low”的問題因為這類問題大概率是誤報。這里有個反直覺的點匯總 agent 不應該是一個更強的模型而應該是一個更“保守”的模型。它的任務不是發(fā)現(xiàn)新問題而是做減法。我用的是一個中等規(guī)模的模型提示詞里明確寫“你的任務是合并和過濾不要新增任何問題”。如果用一個很強的模型做匯總它反而會“自作主張”加一些自己的判斷破壞前面 agent 的職責邊界。4. 從提示詞到產線工程化落地的關鍵環(huán)節(jié)4.1 觸發(fā)時機什么時候跑審查多智能體審查跑起來是有成本的四個 agent 加一個匯總token 消耗是單提示詞的好幾倍。所以不能每次 push 都全量跑。我的策略是分兩級輕量級審查和完整審查。輕量級審查只在 PR 創(chuàng)建時跑一次只啟用缺陷檢測和安全審查兩個 agent關注 high 級別問題。完整審查在 PR 標記為“ready for review”時跑四個 agent 全開。這樣既保證了早期反饋又控制了成本。另外對于 draft PR我基本不跑審查因為那時候代碼還在改跑了也是浪費。還有一個細節(jié)增量審查。如果一個 PR 已經審查過作者又推了新 commit沒必要全量重跑。我的做法是只對新增的 diff 跑審查然后把結果和之前的結果合并。這需要在工程上記錄“上次審查到的 commit hash”實現(xiàn)起來不復雜但能省不少錢。4.2 結果呈現(xiàn)怎么讓 reviewer 愿意看審查結果如果只是丟一個長列表reviewer 是不會看的。我在這上面踩過坑早期直接把 JSON 轉成 markdown 評論發(fā)到 PR結果沒人理。后來我做了三件事接受度明顯提升。第一按文件分組。reviewer 看 PR 是按文件看的你把問題按文件聚合他就能對著看。第二只展示 high 和 mediumlow 級別的問題折疊起來需要展開才看。第三每條問題附帶“為什么”。模型輸出的 description 里我會要求它寫清楚“這個問題的觸發(fā)條件是什么”而不是只說“這里可能有問題”。比如“當 user 為 null 時第 42 行的 user.getName() 會拋 NPE”這比“空指針風險”有用得多。另外我會給每條問題加一個“置信度”標簽。這個置信度不是模型自己說的而是根據“有幾個 agent 報告了這個問題”來算的多個 agent 都報的置信度高只有一個 agent 報的置信度低。reviewer 看到高置信度的會優(yōu)先處理低置信度的可以快速掃過。4.3 反饋閉環(huán)讓 agent 越跑越準多智能體方案最大的優(yōu)勢之一是它天然適合做反饋閉環(huán)。因為每個 agent 的職責是獨立的你可以單獨評估每個 agent 的準確率然后針對性優(yōu)化。我的做法是在 PR 評論里加兩個按鈕“有用”和“誤報”。reviewer 點擊后數(shù)據回流到后臺。每周統(tǒng)計一次看哪個 agent 的誤報率最高然后針對性調整它的提示詞。比如缺陷 agent 如果經常把“框架已經保證非空”的場景誤報為空指針我就在提示詞里加一條“如果參數(shù)來自框架注入且框架文檔保證非空不要報告”。這個閉環(huán)跑起來之后大概兩三個月整體誤報率能降一半左右。關鍵是不要試圖一次性把提示詞寫到完美而是先跑起來用真實反饋來迭代。提示詞工程本質上是一個數(shù)據驅動的過程沒有反饋你就是在盲調。5. 實操中踩過的坑與排查技巧5.1 常見問題速查表下面這張表是我在實際運行中整理出來的高頻問題基本覆蓋了 80% 的異常情況現(xiàn)象可能原因排查方向解決方式某個 agent 完全不輸出提示詞被截斷或格式錯誤檢查提示詞長度和 JSON schema縮短提示詞簡化 schema輸出 JSON 解析失敗模型加了額外說明文字檢查是否有“以下是結果”前綴提示詞強調“只輸出 JSON”同一問題被報多次去重邏輯太粗檢查聚類鍵是否合理加入語義相似度判斷長 diff 漏報嚴重上下文超限檢查 diff 行數(shù)分片審查按文件拆分誤報集中在某類代碼提示詞缺少排除規(guī)則統(tǒng)計誤報類型針對性加“不要報告”規(guī)則匯總后問題變多匯總 agent 自作主張檢查匯總提示詞明確“只合并不新增”5.2 三個我踩過的具體坑第一個坑是提示詞里的“示例”反而害了我。早期我在缺陷檢測提示詞里放了幾個“正確輸出示例”想引導模型格式。結果模型開始模仿示例里的問題類型明明代碼里沒有空指針它也要硬找一個報上來。后來我把示例全部刪掉只保留 schema 定義誤報率立刻下降。教訓是示例會錨定模型的判斷格式用 schema 約束就夠了不要用內容示例。第二個坑是分片策略沒做好導致跨文件問題漏報。我一開始按文件分片每個文件單獨跑 agent。結果一個接口簽名改了、調用方沒改的問題因為分在兩個文件里誰都沒報。后來我加了一個“上下文一致性”agent專門看跨文件的接口變更才補上這個缺口。所以分片可以但一定要有一個 agent 負責“全局視角”。第三個坑是成本失控。四個 agent 全量跑一個大 PR 能燒掉不少 token。我后來做了兩件事一是對 diff 做預處理過濾掉純格式變更比如只改了縮進這類變更不觸發(fā)審查二是對低風險文件比如測試文件、文檔跳過安全審查 agent。這兩個優(yōu)化下來成本大概降了 40%。5.3 一個容易被忽略的細節(jié)時區(qū)與并發(fā)如果團隊是跨時區(qū)的審查結果的“新鮮度”很重要。我遇到過一個問題亞洲團隊晚上推的代碼歐洲團隊早上才看到審查結果但那時候作者已經下班了反饋循環(huán)被拉長。后來我把審查觸發(fā)改成“push 后立即跑”而不是“等 CI 全部通過再跑”這樣作者還在線的時候就能看到反饋修復效率高很多。并發(fā)方面如果多個 PR 同時觸發(fā)審查要注意 agent 調用的限流。我的做法是加一個簡單的隊列每個 PR 的審查任務排隊執(zhí)行避免同時打滿 API 配額。這個隊列不需要很復雜一個 Redis list 就夠了。6. 多智能體方案的邊界與適用場景6.1 它不適合什么場景多智能體審查不是萬能的。我明確不建議在以下場景用它第一代碼量極小的改動比如改一個常量、修一個 typo跑四個 agent 純屬浪費單提示詞甚至人工看一眼就夠了。第二探索性原型代碼這類代碼本來就不追求質量審查結果只會是噪音。第三沒有明確規(guī)范的團隊如果團隊自己都沒想清楚什么算“好代碼”agent 的判斷標準也無從談起。還有一個邊界是領域知識密集的代碼。比如涉及復雜業(yè)務規(guī)則的代碼agent 很難判斷某個邏輯是否符合業(yè)務預期。這類問題最終還是得靠人。我的定位是多智能體審查負責“通用問題”人負責“領域問題”。兩者是互補不是替代。6.2 什么團隊最適合上手我覺得最適合上手的是那種“有一定代碼規(guī)范、PR 流程成熟、但 reviewer 時間緊張”的團隊。這類團隊的特點是規(guī)范已經存在只是執(zhí)行不到位reviewer 不是不想看是沒時間細看。多智能體審查正好能幫他們做第一輪過濾把明顯的問題擋在前面讓 reviewer 專注于真正需要人判斷的部分。反過來如果團隊連基本的 CI 都沒有PR 流程也很隨意那先別急著上多智能體。先把基礎流程建起來再考慮用 AI 提效。工具是放大器流程是底座底座不穩(wěn)放大器只會放大混亂。6.3 后續(xù)可以怎么擴展這套框架跑穩(wěn)之后有幾個自然的擴展方向。一是接入更多 agent比如專門看性能的、專門看數(shù)據庫查詢的、專門看 API 兼容性的。二是做個性化不同團隊、不同倉庫可以用不同的 agent 組合和提示詞。三是和 IDE 集成讓開發(fā)者在寫代碼的時候就能看到審查結果而不是等到 PR 階段。我個人最看好的方向是第三個。PR 階段的審查畢竟是“事后”如果能在編碼階段就給出反饋修復成本會低很多。不過這需要解決延遲問題本地跑四個 agent 不太現(xiàn)實可能得做成“輕量本地 重量云端”的混合模式。這個我還在摸索等有成熟經驗了再單獨寫一篇。最后分享一個我在實際使用中的體會多智能體審查的價值不在于它能發(fā)現(xiàn)多少人發(fā)現(xiàn)不了的問題而在于它能穩(wěn)定地、不知疲倦地把已知類型的問題擋在 PR 之前。人的注意力是波動的agent 不是。把重復性的、規(guī)則明確的審查工作交給 agent把需要判斷力和領域知識的留給人類這個分工才是可持續(xù)的。至于提示詞怎么寫、agent 怎么拆都是在這個分工前提下不斷調優(yōu)的細節(jié)沒有一勞永逸的答案只有持續(xù)迭代的過程。