戰(zhàn))
1. 為什么我要自己搭一套 open-code-review代碼審查這件事做過團(tuán)隊(duì)協(xié)作的人都有體會(huì)。理想狀態(tài)下每次提交都有人認(rèn)真看、認(rèn)真提意見把問題攔在合并之前?,F(xiàn)實(shí)往往是另一回事提交堆成山審查者掃兩眼就點(diǎn)了通過等到線上出問題再回頭翻記錄發(fā)現(xiàn)那個(gè)空指針早就寫在 diff 里了只是沒人注意到。我所在的團(tuán)隊(duì)規(guī)模不大七八個(gè)人后端前端加起來每天十幾到二十次提交。之前試過幾種方案純?nèi)斯彶榭孔杂X結(jié)果就是誰忙誰跳過用平臺(tái)自帶的審查功能規(guī)則是死的只能查格式和明顯的靜態(tài)問題業(yè)務(wù)邏輯層面的隱患基本查不出來也試過讓每個(gè)人提交前自己過一遍清單但人總有惰性清單寫著寫著就變成擺設(shè)。后來我把目光轉(zhuǎn)向了 LLM Agent 這條路。核心想法很直接既然大模型能讀懂代碼、能理解上下文那讓它扮演一個(gè)永不疲倦的初級(jí)審查者角色先把明顯的問題篩一遍人只需要看它篩出來的重點(diǎn)效率應(yīng)該能提上來。這個(gè)思路落地下來就是我現(xiàn)在用的這套 open-code-review 流程——一個(gè)跑在本地、掛在 Git 鉤子上、用 CLI 調(diào) LLM Agent 做代碼審查的小工具鏈。它解決的問題很具體在git commit或git push之前自動(dòng)把本次改動(dòng)的 diff 喂給 LLM讓它按預(yù)設(shè)的審查維度輸出意見有嚴(yán)重問題就攔住提交沒大問題就放行并附上建議。適合誰來參考我覺得是三類人一是小團(tuán)隊(duì)里負(fù)責(zé)工程效率的那個(gè)人二是自己寫項(xiàng)目想有個(gè)第二雙眼睛的獨(dú)立開發(fā)者三是對(duì) CLI、Git 鉤子、LLM Agent 這套組合感興趣、想動(dòng)手試試的技術(shù)愛好者。不需要你是 AI 專家但得會(huì)用命令行、懂基本的 Git 操作。下面我把整套東西拆開講從設(shè)計(jì)思路到具體實(shí)現(xiàn)再到踩過的坑盡量說透。2. 整體設(shè)計(jì)與技術(shù)選型思路2.1 為什么是 CLI Git 鉤子 LLM Agent 這個(gè)組合先說選型邏輯。做代碼審查工具擺在面前的路其實(shí)有幾條做成 IDE 插件、做成 CI 流水線的一環(huán)、做成獨(dú)立的 CLI 工具。我最后選了 CLI 加 Git 鉤子理由有三條。第一侵入性最低。IDE 插件要適配不同編輯器團(tuán)隊(duì)里有人用 VS Code有人用 JetBrains 系列還有人習(xí)慣 Vim統(tǒng)一不了。CI 流水線的問題在于反饋太晚代碼都推上去了才告訴你哪里有問題改起來要走一遍完整流程。Git 鉤子掛在本地提交那一刻就觸發(fā)反饋?zhàn)羁於也灰蕾嚾魏纹脚_(tái)配置。第二CLI 天然適合做管道。Git 本身提供了git diff、git diff --cached這類命令輸出是結(jié)構(gòu)化的文本直接就能喂給下一個(gè)程序。LLM Agent 的調(diào)用方式無論是走 API 還是走本地命令行工具本質(zhì)上也是輸入文本、輸出文本。CLI 把這兩端串起來中間不需要任何圖形界面腳本化程度高改起來也方便。第三LLM Agent 負(fù)責(zé)理解規(guī)則引擎負(fù)責(zé)攔截。純規(guī)則的工具查不出業(yè)務(wù)邏輯問題純 LLM 又容易幻覺把沒問題的代碼說成有問題。我的做法是讓 LLM 輸出結(jié)構(gòu)化的審查結(jié)果再用一層簡(jiǎn)單的規(guī)則判斷嚴(yán)重程度決定是攔截還是放行。這樣既利用了模型的語義理解能力又保留了確定性的控制權(quán)。提示這里說的 LLM Agent指的是能接收文本輸入、按指令返回文本輸出的模型調(diào)用方式。它和傳統(tǒng)意義上的AI 模型區(qū)別在于Agent 通常帶有一層任務(wù)編排邏輯比如先讀 diff、再按維度分析、最后格式化輸出而不是單純的一次問答。2.2 審查維度怎么定從什么都查到只查值得查的一開始我想讓模型什么都查命名規(guī)范、注釋完整性、性能、安全、可讀性、測(cè)試覆蓋……結(jié)果輸出一大堆噪音比信號(hào)還多。后來我砍到四個(gè)核心維度每個(gè)維度給明確的判斷標(biāo)準(zhǔn)。審查維度關(guān)注點(diǎn)攔截級(jí)別邏輯正確性空指針、邊界條件、死循環(huán)、資源未釋放嚴(yán)重?cái)r截安全隱患硬編碼密鑰、SQL 拼接、未校驗(yàn)輸入嚴(yán)重?cái)r截可維護(hù)性函數(shù)過長(zhǎng)、重復(fù)代碼、魔法數(shù)字建議不攔截命名與注釋變量名含義不清、關(guān)鍵邏輯缺注釋建議不攔截這個(gè)分級(jí)很關(guān)鍵。如果所有問題都攔截開發(fā)者會(huì)被煩死最后直接--no-verify跳過鉤子工具就廢了。只有真正會(huì)導(dǎo)致 bug 或安全問題的才攔截其余作為建議輸出讓人自己判斷。2.3 模型調(diào)用的兩種路徑API 直連與本地 CLI調(diào)用 LLM 有兩條路。一條是直接調(diào) API用 HTTP 請(qǐng)求把 diff 發(fā)過去拿回結(jié)果。另一條是走本地已經(jīng)裝好的 CLI 工具比如一些命令行形式的模型客戶端通過子進(jìn)程調(diào)用。我兩條都試過。API 直連的優(yōu)點(diǎn)是可控超時(shí)、重試、并發(fā)都能自己管缺點(diǎn)是得管密鑰團(tuán)隊(duì)里每個(gè)人都要配還得考慮費(fèi)用。本地 CLI 的優(yōu)點(diǎn)是復(fù)用已有的登錄態(tài)不用額外配密鑰缺點(diǎn)是不同人裝的版本不一樣輸出格式可能有差異而且有些 CLI 工具在 Windows 終端下的行為不太一致。最后我選的是以 API 直連為主、本地 CLI 為備選的方案。主流程走 API配置集中管理如果檢測(cè)到本地有可用的 CLI 工具也允許切換過去方便在沒有網(wǎng)絡(luò)或想省費(fèi)用的場(chǎng)景下用。# 檢查本地是否有可用的模型 CLI 工具 which codex 2/dev/null echo codex cli available which claude 2/dev/null echo claude cli available這段檢測(cè)邏輯放在腳本開頭根據(jù)檢測(cè)結(jié)果決定走哪條路徑。實(shí)測(cè)下來這種雙通道設(shè)計(jì)讓工具在不同環(huán)境下都能跑起來適應(yīng)性好很多。3. 核心細(xì)節(jié)解析與實(shí)操要點(diǎn)3.1 Git 鉤子的選擇pre-commit 還是 pre-pushGit 鉤子有好幾種和代碼審查相關(guān)的主要是pre-commit和pre-push。這兩個(gè)的區(qū)別直接決定了工具的使用體驗(yàn)。pre-commit在每次提交時(shí)觸發(fā)粒度細(xì)反饋快。但問題是提交往往很頻繁有時(shí)候只是改個(gè)錯(cuò)別字也要跑一遍審查浪費(fèi)時(shí)間。而且提交階段拿到的 diff 是暫存區(qū)的內(nèi)容如果開發(fā)者習(xí)慣git add .一把梭diff 會(huì)很大審查質(zhì)量反而下降。pre-push在推送前觸發(fā)粒度粗但更接近一次完整的改動(dòng)。推送前通常已經(jīng)完成了若干次提交diff 是這一批提交的合集模型能看到的上下文更完整審查意見也更有價(jià)值。我最后選的是pre-push 為主、pre-commit 可選。默認(rèn)掛在 pre-push 上如果某個(gè)項(xiàng)目想更嚴(yán)格可以額外掛 pre-commit。這樣既保證了審查質(zhì)量又不會(huì)讓日常提交變得卡頓。# 安裝 pre-push 鉤子 cat .git/hooks/pre-push EOF #!/bin/bash # open-code-review pre-push hook exec $(dirname $0)/../../scripts/review.sh --mode pre-push EOF chmod x .git/hooks/pre-push注意鉤子腳本的路徑要用相對(duì)路徑或者環(huán)境變量不要寫死絕對(duì)路徑。團(tuán)隊(duì)里每個(gè)人的項(xiàng)目目錄不一樣寫死了別人就用不了。3.2 diff 的提取與預(yù)處理別把整個(gè)倉庫喂給模型這是最容易踩坑的地方。一開始我圖省事直接git diff HEAD~1把最近一次提交的全部改動(dòng)丟給模型結(jié)果 token 消耗巨大而且模型經(jīng)常跑偏去評(píng)論一些和本次改動(dòng)無關(guān)的舊代碼。正確的做法是只提取本次推送涉及的改動(dòng)。pre-push 鉤子會(huì)通過標(biāo)準(zhǔn)輸入傳入將要推送的引用信息可以從中解析出本地分支和遠(yuǎn)程分支再用git diff拿到精確的差異。# 從 pre-push 的標(biāo)準(zhǔn)輸入解析推送范圍 while read local_ref local_sha remote_ref remote_sha; do if [ $remote_sha 0000000000000000000000000000000000000000 ]; then # 新分支對(duì)比默認(rèn)分支 rangeorigin/main..$local_sha else range$remote_sha..$local_sha fi git diff $range -- . :(exclude)*.lock :(exclude)*.min.js done這里有兩個(gè)細(xì)節(jié)值得說。一是排除鎖文件和壓縮文件這些文件 diff 又長(zhǎng)又沒意義喂給模型純屬浪費(fèi)。二是限制單次 diff 的大小如果改動(dòng)超過一定行數(shù)我設(shè)的是 800 行就只取核心文件或者提示開發(fā)者拆分提交。模型對(duì)超長(zhǎng)輸入的處理能力有限塞太多反而效果差。3.3 提示詞的設(shè)計(jì)讓模型輸出結(jié)構(gòu)化結(jié)果提示詞寫得好不好直接決定審查質(zhì)量。我試過很多版本最后穩(wěn)定下來的結(jié)構(gòu)是這樣的先給角色設(shè)定再給審查維度再給輸出格式最后給 diff。你是一名資深代碼審查者。請(qǐng)審查以下代碼改動(dòng)按四個(gè)維度分析 1. 邏輯正確性是否有空指針、邊界條件錯(cuò)誤、資源泄漏 2. 安全隱患是否有硬編碼密鑰、注入風(fēng)險(xiǎn)、未校驗(yàn)輸入 3. 可維護(hù)性是否有過長(zhǎng)函數(shù)、重復(fù)代碼、魔法數(shù)字 4. 命名與注釋命名是否清晰、關(guān)鍵邏輯是否有注釋 輸出格式要求 - 每個(gè)問題一行格式為[級(jí)別] 文件:行號(hào) - 問題描述 - 級(jí)別只能是 SEVERE 或 SUGGEST - 如果沒有問題輸出 NO_ISSUE - 不要輸出任何額外解釋 代碼改動(dòng)如下這個(gè)提示詞的關(guān)鍵在于輸出格式的強(qiáng)約束。模型如果自由發(fā)揮輸出會(huì)五花八門腳本沒法解析。限定成[級(jí)別] 文件:行號(hào) - 描述這種格式后用簡(jiǎn)單的文本處理就能提取出嚴(yán)重問題決定是否攔截。提示提示詞里的不要輸出任何額外解釋這句很重要。模型有很強(qiáng)的解釋欲不加這句約束它會(huì)在結(jié)果前后加一堆總的來說這段代碼……之類的廢話解析起來很麻煩。3.4 結(jié)果解析與攔截邏輯模型返回結(jié)果后腳本要做兩件事解析出嚴(yán)重問題、決定是否攔截。# 解析模型輸出提取 SEVERE 級(jí)別的問題 severe_count$(echo $review_result | grep -c ^\[SEVERE\]) if [ $severe_count -gt 0 ]; then echo 發(fā)現(xiàn) $severe_count 個(gè)嚴(yán)重問題推送已攔截 echo $review_result | grep ^\[SEVERE\] exit 1 else echo 審查通過建議如下 echo $review_result | grep ^\[SUGGEST\] exit 0 fiexit 1會(huì)讓 Git 中止推送exit 0則放行。這個(gè)邏輯簡(jiǎn)單但有效。實(shí)測(cè)下來攔截率控制在 5% 到 10% 之間比較合適太高說明提示詞太嚴(yán)太低說明沒起到作用。4. 完整實(shí)操流程與關(guān)鍵環(huán)節(jié)實(shí)現(xiàn)4.1 環(huán)境準(zhǔn)備Git、CLI 工具與模型接入先把基礎(chǔ)環(huán)境搭好。Git 的安裝不用多說Windows 上裝 Git for WindowsMac 上用 HomebrewLinux 用包管理器。裝完之后確認(rèn)git --version能正常輸出。然后是模型接入。如果走 API 路徑需要準(zhǔn)備一個(gè) API 密鑰放在環(huán)境變量里不要寫進(jìn)代碼。# 把密鑰放進(jìn) shell 配置文件不要提交到倉庫 echo export REVIEW_API_KEYyour-key-here ~/.bashrc echo export REVIEW_API_ENDPOINThttps://your-endpoint/v1/chat/completions ~/.bashrc source ~/.bashrc如果走本地 CLI 路徑確認(rèn)對(duì)應(yīng)的命令行工具已經(jīng)裝好并且能正常調(diào)用。有些 CLI 工具在 Windows 終端下會(huì)有編碼問題建議在 Git Bash 或 WSL 里跑兼容性更好。# 驗(yàn)證本地 CLI 工具是否可用 codex --version 2/dev/null || echo codex cli not found4.2 腳本主體從 diff 提取到結(jié)果輸出整個(gè)腳本我拆成了幾個(gè)函數(shù)主流程清晰一些。核心邏輯是解析推送范圍、提取 diff、調(diào)用模型、解析結(jié)果、決定攔截。#!/bin/bash set -euo pipefail REVIEW_MODE${1:-pre-push} MAX_DIFF_LINES800 extract_diff() { local range$1 git diff $range -- . \ :(exclude)*.lock \ :(exclude)*.min.js \ :(exclude)package-lock.json \ | head -n $MAX_DIFF_LINES } call_model() { local diff_content$1 local prompt prompt$(cat PROMPT 你是一名資深代碼審查者。請(qǐng)審查以下代碼改動(dòng)按四個(gè)維度分析 1. 邏輯正確性 2. 安全隱患 3. 可維護(hù)性 4. 命名與注釋 輸出格式[級(jí)別] 文件:行號(hào) - 問題描述 級(jí)別只能是 SEVERE 或 SUGGEST無問題輸出 NO_ISSUE PROMPT ) curl -s -X POST $REVIEW_API_ENDPOINT \ -H Authorization: Bearer $REVIEW_API_KEY \ -H Content-Type: application/json \ -d $(jq -n --arg p $prompt --arg d $diff_content \ {model:review-model, messages:[{role:user,content:($p \n\n $d)}]}) \ | jq -r .choices[0].message.content } main() { local diff_content diff_content$(extract_diff $REVIEW_RANGE) if [ -z $diff_content ]; then echo 無改動(dòng)跳過審查 exit 0 fi local result result$(call_model $diff_content) # 解析與攔截邏輯見 3.4 節(jié) parse_and_gate $result } main這里用到了jq來構(gòu)造和解析 JSON它是處理 JSON 的利器建議提前裝好。set -euo pipefail這行讓腳本在出錯(cuò)時(shí)立即退出避免錯(cuò)誤被吞掉。4.3 參數(shù)計(jì)算diff 行數(shù)上限怎么定MAX_DIFF_LINES這個(gè)參數(shù)不是拍腦袋定的。模型的上下文窗口有限diff 太長(zhǎng)會(huì)被截?cái)鄬?dǎo)致審查不完整。我按經(jīng)驗(yàn)算了一下主流模型的上下文窗口在 8K 到 128K token 之間1 行代碼平均 10 到 15 個(gè) token加上提示詞本身占用的部分留出安全余量后diff 控制在 800 行左右比較穩(wěn)妥。如果改動(dòng)確實(shí)很大有兩個(gè)處理方式一是按文件拆分逐個(gè)文件審查二是只審查核心文件跳過測(cè)試文件和文檔。我在腳本里加了個(gè)判斷如果 diff 超過上限就按文件分組每組單獨(dú)調(diào)用一次模型。# 按文件拆分大 diff if [ $(echo $diff_content | wc -l) -gt $MAX_DIFF_LINES ]; then git diff $range --name-only | while read -r file; do file_diff$(git diff $range -- $file) [ -n $file_diff ] call_model $file_diff done fi4.4 與 Git 工作流的整合工具做好之后要讓它自然地融入日常流程。我的做法是在項(xiàng)目根目錄放一個(gè)scripts/文件夾把審查腳本放進(jìn)去然后在.git/hooks/里放一個(gè)薄薄的鉤子腳本調(diào)用它。這樣腳本可以跟著倉庫走團(tuán)隊(duì)成員拉下來就能用。# 在項(xiàng)目里初始化鉤子 mkdir -p scripts cp review.sh scripts/ cat .git/hooks/pre-push EOF #!/bin/bash exec $(git rev-parse --show-toplevel)/scripts/review.sh --mode pre-push EOF chmod x .git/hooks/pre-pushgit rev-parse --show-toplevel能拿到倉庫根目錄這樣不管在哪個(gè)子目錄下操作路徑都是對(duì)的。這個(gè)細(xì)節(jié)很多人會(huì)忽略導(dǎo)致鉤子在子目錄里跑不起來。注意.git/hooks/目錄不會(huì)被提交到倉庫所以每個(gè)成員都要手動(dòng)裝一次鉤子??梢栽?README 里寫清楚安裝步驟或者寫個(gè)install-hooks.sh腳本一鍵安裝。5. 常見問題與排查技巧實(shí)錄5.1 模型調(diào)用失敗從超時(shí)到密鑰錯(cuò)誤模型調(diào)用是最容易出問題的環(huán)節(jié)。我把遇到過的錯(cuò)誤整理成了一張表方便對(duì)照排查?,F(xiàn)象可能原因排查方法請(qǐng)求超時(shí)網(wǎng)絡(luò)慢或 diff 太長(zhǎng)縮短 diff增加超時(shí)時(shí)間401 未授權(quán)密鑰錯(cuò)誤或過期檢查環(huán)境變量重新生成密鑰429 限流調(diào)用頻率過高加退避重試降低并發(fā)返回空結(jié)果提示詞或 diff 格式問題打印原始響應(yīng)檢查 JSON 結(jié)構(gòu)輸出格式不對(duì)模型沒遵守格式約束強(qiáng)化提示詞加格式示例超時(shí)這個(gè)問題我遇到最多。默認(rèn)的 curl 超時(shí)是無限的模型如果卡住整個(gè)推送就掛在那里。后來我加了--max-time 60超過 60 秒就放棄提示開發(fā)者手動(dòng)審查。curl -s --max-time 60 -X POST $REVIEW_API_ENDPOINT ...5.2 誤報(bào)與漏報(bào)怎么調(diào)提示詞誤報(bào)是指模型把沒問題的代碼說成有問題漏報(bào)是指真正的問題沒被發(fā)現(xiàn)。這兩個(gè)是此消彼長(zhǎng)的關(guān)系調(diào)提示詞就是在找平衡點(diǎn)。誤報(bào)多的時(shí)候我會(huì)在提示詞里加一句只報(bào)告確定的問題不確定的不要報(bào)告。漏報(bào)多的時(shí)候我會(huì)在提示詞里加具體的檢查清單比如特別注意數(shù)組越界、空指針解引用、未關(guān)閉的文件句柄。實(shí)測(cè)下來給具體的檢查項(xiàng)比給抽象的要求效果好得多。模型對(duì)檢查是否有空指針這種具體指令的執(zhí)行率明顯高于檢查代碼質(zhì)量這種模糊指令。5.3 Windows 環(huán)境下的兼容性問題Windows 下跑這套東西坑比 Linux 和 Mac 多。最常見的是路徑分隔符和換行符的問題。Git Bash 里路徑用/但有些工具期望\混用會(huì)出錯(cuò)。換行符方面Windows 用 CRLFLinux 用 LF腳本從 Windows 傳到 Linux 上跑經(jīng)常因?yàn)閈r導(dǎo)致命令找不到。解決辦法是在倉庫根目錄加一個(gè).gitattributes文件強(qiáng)制腳本文件用 LF 換行。*.sh text eollf另外Windows 終端下調(diào)用某些 CLI 工具時(shí)輸出編碼可能是 GBK 而不是 UTF-8導(dǎo)致中文亂碼??梢栽谀_本開頭設(shè)置export LANGen_US.UTF-8或者chcp 65001來統(tǒng)一編碼。5.4 鉤子被繞過怎么讓團(tuán)隊(duì)真正用起來技術(shù)上做好了不代表團(tuán)隊(duì)會(huì)用。我見過太多人遇到鉤子攔截第一反應(yīng)是git push --no-verify跳過。要讓工具真正發(fā)揮作用得從兩方面入手。一是降低誤報(bào)率。誤報(bào)是繞過鉤子的頭號(hào)原因。如果十次攔截里有五次是誤報(bào)沒人會(huì)認(rèn)真對(duì)待。我花了大概兩周時(shí)間調(diào)提示詞把誤報(bào)率壓到 20% 以下團(tuán)隊(duì)的接受度明顯提高。二是讓審查結(jié)果有價(jià)值。如果模型輸出的都是變量名不夠清晰這種無關(guān)痛癢的建議大家看兩次就不看了。我在提示詞里強(qiáng)調(diào)只報(bào)告會(huì)導(dǎo)致 bug 或安全問題的情況讓每條意見都值得一看。提示可以在團(tuán)隊(duì)里約定繞過鉤子需要在提交信息里說明原因。這不是強(qiáng)制但是一種軟約束能減少隨意繞過的行為。5.5 費(fèi)用控制別讓審查變成燒錢機(jī)器走 API 路徑的話費(fèi)用是個(gè)現(xiàn)實(shí)問題。每次推送都調(diào)用模型一天下來調(diào)用次數(shù)不少。我的控制策略有三條。第一只在有實(shí)際改動(dòng)時(shí)調(diào)用。如果 diff 為空直接跳過不浪費(fèi)調(diào)用。第二限制 diff 長(zhǎng)度。前面說的 800 行上限既是為了審查質(zhì)量也是為了控制 token 消耗。第三緩存相同 diff 的結(jié)果。如果同一個(gè) diff 被審查過直接讀緩存不再調(diào)用。用 diff 的哈希值做 key存在本地文件里。cache_key$(echo $diff_content | md5sum | cut -d -f1) cache_file/tmp/review-cache/$cache_key if [ -f $cache_file ]; then result$(cat $cache_file) else result$(call_model $diff_content) echo $result $cache_file fi這三條加起來費(fèi)用能降下來一大半。實(shí)測(cè)下來一個(gè)七八人的團(tuán)隊(duì)每月的審查費(fèi)用控制在很低的水平。6. 我在這套流程里踩過的坑和攢下的經(jīng)驗(yàn)6.1 關(guān)于提示詞迭代的一點(diǎn)心得提示詞不是一次寫好的是迭代出來的。我最初的版本只有一句話審查這段代碼輸出質(zhì)量慘不忍睹。后來每次遇到誤報(bào)或漏報(bào)就針對(duì)性地加一條約束或檢查項(xiàng)慢慢打磨出現(xiàn)在這個(gè)版本。我的建議是建一個(gè)提示詞的版本記錄每次改動(dòng)都記下來改了什么、為什么改、效果如何。這樣過一段時(shí)間回頭看能清楚知道哪些約束是有效的哪些是多余的。我現(xiàn)在的提示詞里有幾條約束是早期加的后來發(fā)現(xiàn)根本沒用刪掉之后輸出反而更干凈。6.2 關(guān)于模型選擇的實(shí)際體驗(yàn)不同模型在代碼審查上的表現(xiàn)差異挺大。有的模型對(duì)語法細(xì)節(jié)敏感能揪出很隱蔽的空指針有的模型擅長(zhǎng)理解業(yè)務(wù)邏輯能發(fā)現(xiàn)這個(gè)判斷條件寫反了這類問題還有的模型輸出特別啰嗦每條意見都要解釋半天。我的做法是按維度選模型。邏輯正確性和安全隱患這兩個(gè)維度用對(duì)代碼理解深的模型可維護(hù)性和命名注釋這兩個(gè)維度用輸出簡(jiǎn)潔的模型。如果只用一個(gè)模型就選綜合表現(xiàn)最均衡的那個(gè)。提示模型的能力在快速變化今天表現(xiàn)好的模型過幾個(gè)月可能就被超越了。建議每隔一段時(shí)間重新評(píng)估一次不要一套配置用到底。6.3 關(guān)于團(tuán)隊(duì)協(xié)作的觀察工具上線之后我觀察到一個(gè)有意思的現(xiàn)象審查意見的質(zhì)量比數(shù)量重要得多。一開始模型輸出一大堆建議大家看都不看。后來我把建議精簡(jiǎn)到每次不超過五條而且每條都標(biāo)注了具體文件和行號(hào)大家的閱讀率明顯提高。另一個(gè)觀察是開發(fā)者對(duì)被攔截的容忍度取決于攔截的準(zhǔn)確性。如果攔截的都是真問題大家會(huì)認(rèn)可這個(gè)工具如果攔截里有誤報(bào)信任度會(huì)迅速下降。所以寧可漏報(bào)不要誤報(bào)這是我在調(diào)提示詞時(shí)一直堅(jiān)持的原則。6.4 后續(xù)可以擴(kuò)展的方向這套流程目前跑得挺穩(wěn)但還有幾個(gè)方向可以繼續(xù)做。一是把審查結(jié)果沉淀下來存到數(shù)據(jù)庫里定期分析哪些類型的問題出現(xiàn)最多反過來指導(dǎo)編碼規(guī)范。二是支持自定義審查規(guī)則讓每個(gè)項(xiàng)目可以配置自己的檢查項(xiàng)比如某個(gè)項(xiàng)目特別在意性能就加一條性能檢查。三是和 CI 流水線打通本地審查通過之后CI 上再跑一遍雙重保險(xiǎn)。這些擴(kuò)展我還在陸續(xù)做有進(jìn)展了再單獨(dú)寫一篇分享。代碼審查這件事工具能幫上忙但最終還是要靠人。工具的價(jià)值在于把人的注意力從找明顯問題轉(zhuǎn)移到判斷復(fù)雜邏輯上這才是它真正省時(shí)間的地方。