GitLab Duo CLI 進階篇:批次自動化、多模型比較與降噪技巧
保留 2026 年 6 月的 Duo CLI 批次 review 經驗,更新 2026-10-08 的模型識別碼、headless 自動核准與 Credits 計費。附可重試的完成標記、timeout 腳本,以及單次實測的限制。
本文目錄
這篇是上一篇入門文的延續,保留 2026 年 6 月的批次 review 經驗。2026-10-08 補查版本、模型識別碼、計費與 headless 行為;腳本的本機流程有離線測試,這次沒有實跑消耗 Credits 的任務。
為什麼要批次跑
在原文裡,我記下一次接手 review 一個跨了十幾個模組的重構 MR。在網頁上一個模組一個模組問 Duo Chat,問到第五個的時候我已經忘記第一個的結論了。而且每次都要重新給 context,因為 Duo Chat 不知道我之前問了什麼(那時候還沒有 session 同步)。
那次之後我就開始寫腳本了。把十幾個模組的 review 任務排成佇列,一口氣跑完,結果存成檔案。我泡杯咖啡回來,所有結果都在那裡等我。
批次跑的好處是:等待 AI 回答時,不用一直盯著畫面,可以先去做別的事。
最小可行的批次架構
2026-10-08 更新:批次前的設定與執行邊界
先完成入門篇的版本、認證與 namespace 設定。官方安裝頁目前要求 glab 1.107.0 以上;GitLab 19.2 起是正式版,18.11 到 19.1 需要 beta 與實驗功能。還要符合 Agent Platform 前置條件,並設定 default Duo namespace,或在有 Duo 存取權的專案啟動。席次與群組權限不是腳本能繞過的。
官方 headless 說明現在寫得很清楚:glab duo cli run 自動核准工具,不需要額外加 --dangerously-skip-permissions。下面拿掉這個 flag,不代表腳本變成唯讀。批次分析要用可丟棄的工作副本與受控沙盒,隔開正式憑證,結束後檢查差異;prompt 寫「只做 review」不是安全限制。
任務資料與完成標記
不需要搞得很複雜。我的做法是三個資料夾:
my-review/
├── cells/ # 每個任務一個 JSON 檔
├── state/ # 完成標記(.done 檔)
└── results/ # AI 回覆存在這
一個 cell 長這樣:
{
"id": "auth-module-error-handling",
"target": "/path/to/repo",
"model": "claude_opus_4_6_20260205",
"goal": "Review auth 模組的錯誤處理,特別注意 token 過期的 edge case"
}
跑的腳本:
#!/bin/bash
for cell_file in cells/*.json; do
cell_id=$(jq -r '.id' "$cell_file")
# 已經跑過就跳過
[ -f "state/${cell_id}.done" ] && continue
goal=$(jq -r '.goal' "$cell_file")
target=$(jq -r '.target' "$cell_file")
model=$(jq -r '.model' "$cell_file")
echo "⏳ Running: $cell_id"
if glab duo cli run \
-C "$target" \
--goal "$goal" \
--model "$model" \
> "results/${cell_id}.md" 2>&1; then
touch "state/${cell_id}.done"
echo "Done: $cell_id"
else
status=$?
echo "Failed: $cell_id (exit $status); retry on the next run" >&2
fi
sleep 30 # 避免打太快
done
echo "這輪處理結束。"
重點是那個 .done 檔:只有指令成功結束才建立。失敗的輸出留在 results/,不標記完成;下次重跑會再試一次,已成功的任務則會跳過。
我通常在 cell 之間 sleep 30 秒。不是技術上一定要,但實測打太快偶爾會被限流,30 秒是穩定的間隔。
別忘了加 timeout
這是我學到的教訓:有些任務 AI 會想超級久,特別是你給它一個很大的 repo 加一個很模糊的問題。有一次我睡前開始跑 10 個 cell,醒來發現它卡在第 3 個已經跑了 6 小時。
後來我加了 timeout 機制:
# 背景執行 + 計時
glab duo cli run -C "$target" --goal "$goal" \
--model "$model" \
> "results/${cell_id}.md" 2>&1 &
PID=$!
TIMED_OUT=0
ELAPSED=0
while kill -0 "$PID" 2>/dev/null; do
sleep 10
ELAPSED=$((ELAPSED + 10))
if [ "$ELAPSED" -ge 900 ]; then # 15 分鐘上限
TIMED_OUT=1
kill "$PID" 2>/dev/null || true
break
fi
done
if wait "$PID"; then
status=0
else
status=$?
fi
# 等待指令結束後再追加,避免它的輸出覆寫逾時紀錄。
if [ "$TIMED_OUT" -eq 1 ]; then
echo "TIMEOUT after 15min" >> "results/${cell_id}.md"
fi
if [ "$TIMED_OUT" -eq 0 ] && [ "$status" -eq 0 ]; then
touch "state/${cell_id}.done"
else
echo "Failed: $cell_id (exit $status, timed_out=$TIMED_OUT); retry on the next run" >&2
fi
15 分鐘是我目前覺得合理的上限。正常的 review 任務大概 2-5 分鐘會跑完,超過 15 分鐘通常代表它陷入某種迴圈了。逾時紀錄會接在原本的輸出後面,不建立 .done;這輪先處理下一個任務,下次重跑還能再試。這個簡例只對單一 PID 送出 TERM,未涵蓋子程序或忽略 TERM 的情況。
多模型比較的正確姿勢
上一篇提過我會用多模型交叉比對。這篇來分享具體數據。
原文的比較紀錄
原文記下我拿同一個 code review 任務跑過 9 個模型,表格保留以下 7 筆摘要。原文沒有註明測試日期、完整 prompt、每個模型版本與逐輪輸出,這些數字只能當作那次使用紀錄,不能用來排現在的模型名次:
| 模型 | 輸出大小 | 我的評價 |
|---|---|---|
| Claude Opus 4.6 | 10.2 KB | 面面俱到,什麼都講到了,適合第一次看不熟的 code |
| Claude Opus 4.8 | 7.9 KB | 直接告訴你該改什麼 |
| Claude Opus 4.7 | 5.9 KB | 極簡,只講結論,適合你只想快速確認 |
| GPT 5.5 | 7.4 KB | 偶爾切入角度完全不同,有驚喜 |
| Gemini 3.1 Pro | 7.1 KB | 結構清晰,範圍切得很精準 |
| Gemini 3.5 Flash | 4.4 KB | 最快,但深度不夠,當快篩用 |
| GPT 5.4 | 0.3 KB | 那一輪拒絕回答,原因沒有另外驗證 |
幾個實用的心得:
依任務選模型。 我當時的組合是:
- 快速初篩:Gemini 3.5 Flash(那輪回覆最快)
- 全面分析:Claude Opus 4.6(什麼都不想漏掉的時候)
- 第二意見:GPT 5.5(思路跟 Claude 很不一樣)
交叉比對後,還是要查證。 兩個模型都指出同一個問題,可以優先看,但也可能共享相同誤解。只有一個模型提到的發現,也不能只因為少數就刪掉;最後還是看程式碼、重現條件與測試。
2026-10-08 更新:用 GitLab 的模型識別碼
--model 和 GITLAB_DUO_MODEL 接受的是 gitlab_identifier,不是供應商 API 的模型名稱。下面按官方 model registry的 2026-10-08 內容更新;實際可選模型仍看你的實例與群組設定,也可以在互動模式用 /model 查看。
寫成腳本就是多跑幾次:
MODELS=("claude_opus_4_6_20260205" "claude_opus_4_7" "gemini_3_5_flash_vertex")
for model in "${MODELS[@]}"; do
glab duo cli run -C "$TARGET" \
--goal "$GOAL" \
--model "$model" \
> "results/${CELL_ID}-${model}.md" 2>&1
sleep 30
done
縮小 review 範圍,再查證發現
git log 錨點:給 AI 一張地圖
這是我從實戰中摸出來的,效果提升非常明顯。
問題是這樣的:你叫 AI「review 這個 repo」,它不知道從哪裡開始。一個幾千個檔案的 repo,它要自己決定看什麼、跳過什麼。結果常常是:花了很多時間在不重要的地方,真正有問題的地方反而沒看到。
解法:先給它一張地圖。
# 撈出特定主題的 commit 歷史
git log --all \
--grep='error\|exception\|retry\|timeout\|fallback' \
--regexp-ignore-case \
--name-only \
--format='%h %cs %s' \
> error-handling-anchors.txt
這份檔案告訴 AI:「這些是最近跟錯誤處理相關的改動,專注看這些。」
glab duo cli run -C ~/project \
--goal "以下是近期跟錯誤處理相關的 commit:
$(head -50 error-handling-anchors.txt)
根據這些 commit:
1. 錯誤處理的 pattern 是否一致?
2. 有沒有某些模組做了 retry 但類似的模組忘了做?
3. 有沒有 exception 被吞掉(catch 了但沒處理)的跡象?"
為什麼效果好?因為 git log --grep 撈出來的是真正被改過的地方。開發者花時間修的東西,代表那裡曾經有問題。AI 從這些點出發去分析「還有沒有類似的問題」,可以先把調查範圍縮小;「精準十倍」沒有對照測試,不能當作測量結果。
我常用的幾組 keyword:
- 錯誤處理:
error|exception|retry|timeout|fallback - 重構:
refactor|extract|rename|move|split - 效能:
perf|slow|cache|optimize|batch - 技術債:
TODO|FIXME|HACK|workaround|temporary
prompt 驗證條件:降噪 90% 的密技
我用了一陣子才發現,最麻煩的是「AI 找到太多問題,大部分是假的」。
一個 code review 任務回報 20 幾個 finding,你一個一個看,結果 18 個是「嗯理論上是個問題但實際上不會發生」或「已經有其他機制處理了」。浪費的時間比不跑 AI 還多。
轉捩點是我開始在 prompt 尾端加驗證條件:
glab duo cli run -C ~/project \
--goal "Review 這個模組的錯誤處理 pattern。
回報前,每個發現都要通過以下檢查:
1. 在預設設定下這個問題真的存在嗎?(不是只有特殊設定才觸發)
2. 有沒有現有的防護機制已經處理了?(看上下文有沒有 catch / retry / guard)
3. 影響範圍是否超出一般使用?(不是要極端操作才碰到的)
4. 這個問題是真的會造成影響的,不是 style 偏好?
不通過的標為「不適用 — 原因:___」。
只詳細報告通過全部四項的發現。"
當時的結果:某次跑出 21 個結果,加上驗證條件後剩 2 個,回報數少了約 90%。這是單次任務的數量變化,不是誤報率或正確率;被刪掉的 19 個仍可能有漏判,留下的 2 個也要人工查證。
這個做法是:讓 AI 做兩次判斷。 第一次找問題,第二次驗證問題是否真的成立。兩次判斷之間的落差,就是你省下的人工篩選時間。
驗證條件可以根據場景客製化。做 code review 和做技術債盤點的條件不一樣,但結構相同:給 AI 一組「這個 finding 值得回報」的判斷標準。
跟其他工具的搭配
我也會把 Duo CLI 和其他工具搭配使用。
| 階段 | 工具 | 為什麼 |
|---|---|---|
| 廣度掃描 | Duo CLI | 多模型、可批次,當時的使用額度適合初篩 |
| 深度分析 | Claude Code | 有記憶、有工具鏈、適合來回多輪 |
| 機械性驗證 | Codex CLI | 沙盒執行、適合跑確認腳本 |
流程大概是:
- Duo CLI 把 repo 的模組批次掃一遍(廣度),用 2-3 個模型交叉看
- 結果裡標記「需要深入看」的部分,丟給 Claude Code 逐一挖(深度)
- 最後整理成結論,確認修正方向
Duo CLI 在這裡的角色是「第一道濾網」。它不需要做得完美,它需要做得快、做得廣。下一輪的深度分析仍需要明確範圍與驗證,不能保證補回所有漏掉的問題。
2026-10-08 更新:比較成本要看呼叫與額度
六月的流程用到了我當時取得的貢獻者使用額度,並不代表 Enterprise seat 自動附帶同樣額度。官方計費文件把 Agent Platform usage billing 與 Duo Pro/Enterprise 的席次型功能分開,community subscriptions 不附 included credits。不同模型的 credit multiplier 不同,一個任務可能有多次 LLM 呼叫;重跑三個模型,成本也會增加。
批次前先查 namespace 的可用 Credits、用量上限與 on-demand 設定。要比較其他工具,就記下同一任務的實際消耗與驗證後的有效結果,不能只看「都是 Credits」。
一些零散但實用的小提醒
- 結果存 .md 比 .txt 好。 AI 的回覆通常有 markdown 格式,存成 .md 之後用任何 markdown viewer 打開就很好讀。
- 用
GITLAB_DUO_MODEL環境變數設預設模型。 不用每次都打--model。 - 大 repo 拆模組跑。 一次丟整個 repo 效果通常不好。指定子目錄或用
--ai-context-items只注入相關檔案,分析會更集中。 - prompt 越具體越好。 「review 這段 code」不如「review 這段 code 的錯誤處理,特別注意 timeout 的 edge case」。
- 留一份 prompt 模板。 好的 prompt 值得重複用。我有一個資料夾專門放常用的 prompt 模板,不同任務類型套不同模板。
結語
Duo CLI 的進階玩法核心就三件事:批次化、多模型、降噪。把這三個搞定,你就從「一次問一個問題」變成「一次掃一整個 codebase」。
CLI 工具本來就能互相組合,Duo CLI 也一樣。把 AI 接進命令列,就能用 shell script 串起這些工作。
如果你有更好的做法,歡迎在社群分享,我也還在調整自己的流程。