/ai-review — 跨模型二審
把剛做完的東西(程式碼、文案、研究報告)交給另一個模型家族看一眼, 把它的意見消化進你的最終回報 —— 而不是自己審自己。
🤖 R2-D2 時刻:R2 與 C-3PO 吵了六集,但每次都是那個「跟你看法不同的傢伙」 補上你漏掉的那一半。自己檢查自己,只會確認自己本來就相信的事。
為什麼需要
自審有結構性上限:判準是自己定的,推理自洽就過關。同一個模型跑「再檢查一次」, 多半只會把原本的結論換句話說 —— 它沒有理由懷疑自己的前提。
換一個模型家族來看,它不受你的推理路徑約束,會抓到你抓不到的東西: 被自己判成「顯然沒問題」的假設、沒標來源的宣稱、會反轉結論的漏洞。
這支 skill 是 damage-report 的升級路徑:
damage-report 是自審五問,接上 ai-review 就變成自審+異質視角。
動作
決定送什麼:要被審的那份東西(檔案,或用
-讀 stdin)。 🔒 送出去就是給第三方模型看 —— 憑證、金鑰、個資、客戶資料自己判斷不要送。選 rubric:
code(程式碼)/copy(對外文案)/research(研究與決策文件), 或直接給你自己的 rubric 檔路徑。跑:
<本skill目錄>/scripts/ai-review.sh <檔案> --rubric code --context "這東西要解什麼"常用選項:
--model/--effort low|medium|high/--strict/--soft-fail/--no-save。⚠️ 一律用完整路徑呼叫,不要打裸的
ai-review——ai-review是個很容易撞名的名字, 你的PATH上可能已經有另一支同名執行檔(別的工具、你自己寫的、或這支 skill 的私人變體)。 打裸命令名會叫到那一支,而且它可能看起來也在做二審,你不會發現叫錯了。看狀態:除用法錯誤(exit 1,訊息在 stderr)外,stdout 最後一行一定是
AI_REVIEW_STATUS: <狀態>。ok→ 進第 5 步。skipped_*→ 本次沒有二審(沒裝/沒登入);腳本已在畫面上印好逐步引導, 照著做或跳過都行。回報時明講「本次僅自審」,不要假裝審過。failed_*→ 後端出錯(額度/網路/政策/版本/空回覆),原始錯誤已印在畫面上。
消化,不要轉述:把二審意見併進你原本的回報(哪幾條採納、哪幾條不採納與理由), 🚫 不要另開一段「二審說……」把責任外包給它 —— 判斷還是你的。
狀態與退出碼
設計原則:狀態走 stdout,退出碼只分「真失敗」。
沒裝二審後端是預期中的降級,不是錯誤 —— 若它回非零,在 set -e、skill runner
或 $(…) 裡會直接中止上層流程,「正常降級」根本輪不到人處理。
| 狀態 | 意思 | 退出碼 |
|---|---|---|
ok |
有拿到意見(=後端回了非空輸出;意見對不對,靠你消化判斷) | 0 |
skipped_not_installed |
找不到後端 CLI | 0(--strict 下 3) |
skipped_not_logged_in |
有裝但看起來沒登入 | 0(--strict 下 3) |
failed_quota |
額度/頻率限制 | 2 |
failed_network |
網路/連線 | 2 |
failed_policy |
地區或組織政策擋下 | 2 |
failed_version |
後端 CLI 版本不相容 | 2 |
failed_empty |
後端回空內容 | 2 |
failed_unknown |
無法歸類 | 2 |
| (不印狀態) | 用法錯誤:沒給來源/缺 --rubric/--effort 值不合法/一次給兩份來源/--strict 與 --soft-fail 併用 |
1 |
兩個退出碼開關,方向相反、都是你主動要求才生效:
--strict:把skipped_*變成 3,讓 CI 能把「沒有二審」當成失敗擋下來。--soft-fail:把failed_*也變成 0。當二審是加分項、絕不能擋住主流程時用。 ⚠️ 用了它就等於放棄「靠退出碼判斷」——呼叫端必須自己解析 stdout 最後一行的狀態, 否則你會得到一個「看起來成功、其實沒審到」的靜默結果。 (兩個開關方向相反,不能同時用,同時給會直接報錯。)
預設值(skipped=0、failed=2)的取捨:「沒有後端」是預期中的降級,不該吵; 「後端拒絕了你」是真的有事發生,預設吵一下比較誠實。哪種對你比較好,你自己決定。
模型:刻意不釘死
腳本不指定模型,吃後端 CLI 自己的預設 —— 釘死會過期,而且猜不到你的方案有哪些模型。
代價是:若後端的預設模型不在你的方案內,你會撞到 failed_quota(後端各家訊息不同,
也可能落在 failed_policy/failed_unknown)。這時用 --model 指定你有的模型即可。
⚠️ 免費方案的可用模型與額度,官方文件並未逐項載明 —— 本專案沒有在免費帳號上實測過,
不保證開箱即用。
⚠️ 狀態分類是比對後端 stderr 文字的啟發式,不是後端官方保證的介面 —— CLI 升版就可能失準。所以失敗時後端的 stderr 與 stdout 各印尾 20 行,別只信標籤。 ⚠️ 那是尾段不是全文(原因若在開頭會被截掉),而且後端回顯可能含 token 或你送審的片段 —— 別把它無腦貼進公開的 CI log。 「沒裝」與「沒登入」刻意分成兩種:新手最常卡在第二種,而若訊息說「找不到 codex」, 他會再裝一次然後更困惑。
成本與前提(誠實版)
- 不是零依賴:需要一個二審後端(預設 Codex CLI)+ POSIX shell +
mktemp/date+可連外的網路。誠實說法是「除後端 CLI 與 POSIX shell 外,無額外套件依賴」—— 不需 npm 套件、不需 brew formula、不需自備 API key。 - 每次要花時間與額度:一次審閱約 1–3 分鐘,吃的是你自己的後端帳號額度。
- 官方方案表把 Codex 列在各方案內(含免費方案),但官方的用量限制表並未列出免費方案的 可用模型與額度,且能不能跑起來還要看地區、帳號狀態與組織政策 —— 「方案表上有」不等於「人人都能用」。查證原文與日期見 docs/AI_REVIEW_SOURCES.md,引用前自己重查。
🚦 鐵則
- 🔒 資料界線自己把關:送出去就是給第三方模型看,憑證/個資/客戶資料不要送。
- ✅ 消化,不轉述:意見要併進你的回報並說明採納與否,不是貼一段「它說……」。
- 🚫 沒審到就明講:
skipped_*時回報寫「本次僅自審」,絕不可靜默略過。 - ⚠️ 這是 best-effort,不是強制機制:觸發器只是文字 —— 忘記跑不會有人發現。 三個已知漏洞照實講:① 無收據(沒有機制證明某次工作真的送審過) ② TOCTOU(送審後又改東西,審的是舊版)③ 「本次不送」是無限制 bypass。 想要強制,得在 CI/hook 這種工具層做,光靠 skill 文字辦不到。
- 📝 二審在寫回報之前跑,不是回報寫完再補一段。
進階:換掉後端(不綁單一廠商)
AI_REVIEW_CMD 收 stdin 的 prompt、吐 stdout 的意見,設了就不走 codex:
AI_REVIEW_CMD='ollama run llama3' ./scripts/ai-review.sh draft.md --rubric copy
後端跑不起來(找不到命令、沒有執行權限)或它自己說沒登入時,一樣走 skipped_*+exit 0,
不會中斷你的流程。
⚠️ 三個代價講在前面:
① 自帶後端的品質不可控,而 rubric 的措辭是為「另一個模型家族」寫的;
② AI_REVIEW_CMD 是整條 shell 命令(用 sh -c 執行),不是單純的執行檔路徑 ——
別讓不可信的來源(外部 .env、CI 變數)決定它的值;
③ 若你的後端把錯誤訊息印到 stdout 而且回 exit 0,本工具分不出那是意見還是錯誤頁,
只會用長度給你一個「偏短」的警告 —— 自訂後端時自己看一眼輸出。
(後端回非零時不受此限:stderr 與 stdout 都會納入分類並照印。)
另外兩個環境變數:AI_REVIEW_DIR(落檔目錄,預設 ./.ai-reviews)、
AI_REVIEW_RUBRICS(自訂 rubric 目錄)。
⚠️ 落檔會把送審內容的審閱結果留在磁碟上。檔案以 600 建立(只有你讀得到),
但目錄本身仍受你的 umask 影響,而且 .gitignore 只擋 git、不擋本機其他工具。
不想留就加 --no-save。
進階:自己的 rubric
--rubric 除了三個內建名稱,也吃檔案路徑。rubric 就是純文字提問清單 ——
照 rubrics/*.md 的樣子寫:結論先行、逐項編號、要求具體到可直接動手,
最後一行寫明用什麼語言回答。
實測範圍(過期請重驗)
⚠️ 「POSIX shell」是寫法上的目標,不是可移植性的保證:腳本仍用到 trap … EXIT、
dirname --/basename --/cp -- 這類規格沒有硬性保證的行為。
真正的依據是下面實測過的組合,不是規格推論。
你可以自己驗一次,別只信這段文字:
sh <本skill目錄>/tests/matrix.sh # 加 SH=bash 可指定用哪個 shell 跑受測腳本
41 項行為測試,不燒任何額度(後端全用 stub 模擬)、不弄髒你的目錄(產出寫在暫存區、
跑完自動清掉),全過回 exit 0,可直接放進 CI。缺 python3+pyyaml 時只會略過其中一項。
矩陣開頭會自動 unset 外層可能 export 過的 AI_REVIEW_CMD 等變數——你平常把後端指到別處
也不會污染測試結果。
腳本本體在 macOS 上以 sh/dash/bash/ksh/zsh 各跑過這份矩陣
(狀態分類、--strict/--soft-fail、可插拔後端、set -e+$(…)+wrapper 呼叫鏈、
路徑含空白、落檔目錄不可寫、stdin 來源、用法錯誤、同秒並發落檔、特殊檔名),
並以真實 Codex CLI 驗過 ok 路徑。
Linux 由 CI(ubuntu-latest)跑同一份矩陣;Windows 未實測,免費方案帳號也未實測 —— 沒驗過的一律別當保證。