同一個 coding-agent 任務,為什麼 OMP 有時做得更久、Token 也更多?真正要拆的不是「OMP 快不快」,而是三筆不同的保險費:Plan Mode 在動工前規劃、Advisor 在施工中旁看、Reviewer 在完工後驗收。這篇 OMP A/B 測試教學會把它們拆成四組,同一題各跑 3 次,讓你用成功率、總時間與每次成功成本決定哪些角色值得開。
截至 2026 年 9 月 21 日,OpenRouter 的 Oh My Pi 頁面顯示 1.35B Token、23 個使用模型;這只能證明有流量,不能證明品質,也看不出 Token 是主代理、Advisor 還是子代理花掉的。截至同日,本文查閱的 OMP 官方文件與公開 benchmark 中,未見四組同題、同模型的可重現消融結果。因此本文交付的是可重跑的實驗方法與判讀規則,不是一組假裝由本站跑出的漂亮數字。
OMP A/B 測試先記住:不要只比總 Token
總成本=主代理+規劃+即時顧問+事後審查+修正重工;每次成功成本=全部重跑成本 ÷ 通過驗收的次數。
- 四組只能改一個流程變因;模型、Provider、thinking、工具、Repo commit、Prompt、整組超時與驗收都固定。
- 每組 3 次只是抓明顯波動的冒煙測試,不是統計證明;要做團隊採購或預算決策,應擴成多任務、多次重跑。
- 先看 Hidden Oracle 是否通過,再看 wall time、角色別 Token 與成本;失敗但便宜,不算省錢。
- Advisor 預設可與主代理部分平行,Reviewer 則包含完成後的頂層審查編排與一個 reviewer 子代理;兩者不能用同一個「額外一次呼叫」概括。
如果你第一次做 Agent 評測,可先讀 SoL-Pi 四機制 A/B 教學理解「一次只改一項」,再用 Coding Agent 測試驗收方法設計不讓模型偷看到答案的 Oracle。
Plan、Advisor、Reviewer 到底多做了什麼?
依 OMP v18.2.6 CLI 文件與 Advisor 文件,三者發生在不同時間:
- Plan Mode:
--plan-yolo先讓 plan 角色只讀探索並產生計畫,自動核准後才切到--plan-yolo-into指定的執行模型。它一定多一段規劃,但可能少走後面的冤枉路。 - Advisor:另一個模型持續閱讀主代理新增的 transcript,必要時注入建議。它有自己的 Token 與成本;
advisor.syncBacklog: off時主代理不等它追上,但結束前仍可能等候最後的 review drain。 - Reviewer:
/review在已有 diff 後啟動唯讀 reviewer。v18.2.6 的 headless prompt固定要求一個 reviewer task;它找問題,不直接改檔,所以若要比較最終品質,還要事先定義最多一次修正回合。
可以把它想成裝潢工程:Plan 是開工前的施工圖,Advisor 是施工中巡場的顧問,Reviewer 是交屋前的驗屋師。三個人都可能提早抓到錯誤,也都可能重複主代理已經做過的檢查。A/B 的目的不是證明「多一個人比較好」,而是確認那張施工圖、那次巡場或那場驗屋,是否真的少掉更昂貴的拆除重做。

第一步:把版本、題目與答案鎖死
本文以 2026 年 9 月 18 日發布的 OMP v18.2.6 為基準,Bun 需 1.3.14 以上。安裝時不要追著 latest 跑:
bun --version
bun install -g @oh-my-pi/pi-coding-agent@18.2.6
omp --version
練習 fixture 可用公開的 p-limit commit a8a6fbe。每次 run 都從同一 commit 建立全新 worktree,先安裝一次相同依賴快照並確認原始測試通過,再交付這張任務卡:
這個 commit 要用 Node.js 20 以上,而且上游 .npmrc 關掉了 package lock。先在一份「fixture 母版」用 npm install --package-lock=true 產生 lockfile、跑完 npm test,再把 package-lock.json 記成自己的 benchmark base commit;12 個 worktree 全從這個本機 commit 分支,並在計時前各自執行 npm ci --package-lock=true。不要讓每個 arm 重新解析不同套件版本,也不要把安裝時間混進 Agent wall time。母版只能放程式與依賴,不能放答案、先前 session 或任何 run 產物。
替 p-limit 新增暫停/恢復能力:
1. pLimit 可接受 paused: boolean,預設 false。
2. limiter 暴露 isPaused、pause()、resume()。
3. pause 不取消執行中的工作,只阻止新的 queued task 啟動;resume 立刻依 concurrency 補滿。
4. limitFunction 也要轉交這些能力。
5. 更新型別、README 與公開測試,不改既有行為。
6. 完成後執行 npm test。
Oracle 由另一個人預先放在 Agent 看不到的目錄,至少測「暫停時 active task 可完成、pending task 不啟動」「多次 pause/resume 不重複執行」「改 concurrency 後 resume 仍守上限」「型別與 limitFunction 介面」以及禁改檔案。公開測試是施工者的尺,Hidden Oracle 才是裁判;這個觀念也適用於 spec-first 工作流比較。
題目難度也要卡在「基準組有機會成功、但不是每次秒過」。若 A 組 3/3 都在幾秒內完成,Plan 與 Advisor 沒有發揮空間;若四組全數 timeout,則只證明題目或預算不合適。先用一個不列入統計的 pilot 檢查安裝、權限、Oracle 與 20 分鐘上限是否可用,正式 12 次才開始記分。
第二步:讓四個角色真的用同一個模型
不要只固定主代理。Reviewer 的 bundled agent 預設走 @slow,Advisor 走 modelRoles.advisor,Plan 走 modelRoles.plan;若三個 role 指向不同模型,你測到的是模型差異,不是角色差異。建立一份只供 benchmark 使用的 overlay,將 MODEL_ID 換成同一個完整 Provider/Model selector 與 reasoning level:
modelRoles:
default: MODEL_ID:medium
plan: MODEL_ID:medium
advisor: MODEL_ID:medium
slow: MODEL_ID:medium
retry:
modelFallback: false
fallbackChains:
default: []
plan: []
advisor: []
slow: []
tier:
subagent: inherit
advisor: inherit
advisor:
enabled: false
syncBacklog: off
immuneTurns: 3
maxNotesPerUpdate: 4
同時固定 service tier、thinking、context/output 上限、approval mode、啟用工具、MCP、LSP、rules 與記憶來源。每次 run 使用新的 session、worktree 與 prompt-cache key;金鑰只放環境變數,不寫進 task、config 或公開 log。想先理解 prompt cache 與重複上下文,可搭配 Claude Token 節省教學。
這裡的「同一模型」還要包含同一個 Provider、同一 reasoning level 與同一 service tier。兩個平台即使顯示相同模型名稱,排隊、快取、價格與限流也可能不同。關掉模型 fallback 後,某次 429 或服務失敗就照原樣記成 infrastructure failure;不要讓 OMP 靜默換模型,再把較快或較慢的結果放進同一欄。
第三步:跑四組 OMP A/B 測試
先為每個 run 準備獨立的 WORKTREE、SESSION_DIR、RUN.jsonl 與唯一 CACHE_KEY,並使用沒有舊 session、rules 或 WATCHDOG roster 的 benchmark profile。將下方 MODEL_ID 換成可用的完整 selector;TASK_FILE 必須是絕對路徑,避免 shell 在切換到 --cwd 前讀錯檔。四組都呼叫同一個 wrapper:
MODEL='MODEL_ID'
SERVICE_TIER='none'
CFG='/absolute/path/benchmark.yml'
TASK_FILE='/absolute/path/task.md'
TASK="$(cat "$TASK_FILE")"
RUN_ROOT='/absolute/path/omp-ab-runs'
IMPL_TOOLS='read,write,edit,bash,grep,glob,find,lsp,ast_grep,ast_edit,todo'
new_run() {
RUN_ID="$1" # 例如 A-1、B-1、C-1、D-1
RUN_DIR="$RUN_ROOT/$RUN_ID"
SESSION_DIR="$RUN_DIR/sessions"
CACHE_KEY="omp-ab-$RUN_ID-$(uuidgen)"
ARM_DEADLINE=$(( $(date +%s) + 1200 ))
mkdir -p "$RUN_DIR" "$SESSION_DIR"
}
run_omp() {
local prompt="$1"
shift
local remaining=$(( ARM_DEADLINE - $(date +%s) ))
(( remaining > 0 )) || return 124
omp -p --mode json --profile omp-ab \
--cwd "$WORKTREE" --config "$CFG" --session-dir "$SESSION_DIR" \
--model "$MODEL" --thinking medium --service-tier "$SERVICE_TIER" \
--approval-mode yolo --no-extensions --no-skills --no-rules \
--tools "$IMPL_TOOLS" --max-time "${remaining}s" \
--prompt-cache-key "$CACHE_KEY" "$@" -- "$prompt"
}
# A:預設;明確排除 task/eval/hub,避免暗中再開代理
new_run A-1
run_omp "$TASK" > "$RUN_DIR/events.jsonl" 2> "$RUN_DIR/stderr.log"
printf '%s\n' "$?" > "$RUN_DIR/exit-code.txt"
# B:Plan only;規劃與執行仍是同一模型
new_run B-1
run_omp "$TASK" --plan-yolo --plan-yolo-into "$MODEL" \
> "$RUN_DIR/events.jsonl" 2> "$RUN_DIR/stderr.log"
printf '%s\n' "$?" > "$RUN_DIR/exit-code.txt"
# C:Advisor only;syncBacklog 維持 off
new_run C-1
run_omp "$TASK" --advisor > "$RUN_DIR/events.jsonl" 2> "$RUN_DIR/stderr.log"
printf '%s\n' "$?" > "$RUN_DIR/exit-code.txt"
# D:Advisor 完成後,直接送入 v18.2.6 官方 headless review 指令
new_run D-1
run_omp "$TASK" --advisor > "$RUN_DIR/main.jsonl" 2> "$RUN_DIR/main-stderr.log"
printf '%s\n' "$?" > "$RUN_DIR/main-exit-code.txt"
SESSION_DIR="$RUN_DIR/review-session"
CACHE_KEY="omp-ab-$RUN_ID-review-$(uuidgen)"
IMPL_TOOLS='task,read,bash,grep,glob,find,lsp,ast_grep'
run_omp 'Use task with agent: "reviewer" and a tasks array; create exactly 1 reviewer task for recent code changes. Return only provable P0-P3 findings and the verdict.' \
> "$RUN_DIR/review.jsonl" 2> "$RUN_DIR/review-stderr.log"
printf '%s\n' "$?" > "$RUN_DIR/review-exit-code.txt"
上面不直接呼叫 /review,是因為 implementation arms 用 --no-extensions 排除環境差異;它等價重現 v18.2.6 headless prompt 的核心要求,明確要求 reviewer agent × 1。D 組若出現可信的 P0–P2,再把 findings 交給主代理修正一次並重跑測試;沒有 findings 就不追加回合。Reviewer 本身是唯讀,不能把「它指出問題」誤記成「成品已修好」;review 成本也包含頂層 orchestrator 與 reviewer 子代理,不是一個 model call。
D 組要合併 implementation session、review session 與修正回合的用量。--max-time 不保證包住最後的 Advisor drain,所以外層 CI/runner 還要在同一個 ARM_DEADLINE 強制結束整組;Plan、Reviewer 與修正都只能使用剩餘秒數。正式跑 3 輪時,先產生 A–D 的隨機順序,再把 RUN_ID 改成對應的 A-1…D-3,不要照範例的固定次序執行。
四組各跑 3 次,共 12 次,並在每個三次小區塊內打亂順序,避免 Provider 尖峰或快取暖機永遠偏向同一組。若第一輪只想做最低成本 smoke test,仍應保留全部失敗與 timeout,不能只挑最快的一次。這是 Agent Harness Token 效率分析最容易被忽略的一步。

第四步:記錄成功率、時間、Token 與重工
每次 run 完成後,先在 Agent 之外執行相同的公開測試、Hidden Oracle、git diff --check 與禁改範圍檢查。接著遞迴解析 $RUN_ROOT/$RUN_ID 下所有 session JSONL,並用 manifest 標出 implementation、review 與 repair phase;OMP 會把 Advisor 寫到 __advisor*.jsonl。不要用 profile-wide 的 omp stats --json 當單次帳本,因為它不接受任意 --session-dir 作為掃描目標。至少保留:
- 品質:Oracle pass/fail、公開測試回歸、越界改檔、Reviewer 真/假陽性與最後是否修正。
- 時間:主代理完成時間、全流程退出時間。Advisor 的非同步工作可能讓兩者不同。
- 用量:依預先記錄的 phase/session 邊界,彙總 main、plan、advisor、review、repair 的 input、output 與 cache usage;reasoning Token 只有 Provider 有回報才記,缺值標
N/A。 - 重工:重試、失敗 edit、compaction、Advisor 被採納的 note、Reviewer 觸發的修正回合與工具呼叫數。
三次結果用中位數與範圍呈現,不要只報平均;成功率則保留 0/3 到 3/3。成本欄最重要的是「全部三次成本 ÷ 成功次數」:若某組花 6 美元只成功一次,每次成功成本就是 6 美元,而不是把兩次失敗刪掉後假裝很便宜。
若走 OAuth 或訂閱方案,OMP stats 顯示的美元值可能是 API 等值估算,不一定等於帳單;報告時要標成 estimate。真的要比較現金成本,改用同一個按量計費 API,並以 Provider usage/billing 紀錄對帳,不能把月費額度和 API 單價混算。
建議再加兩欄時間:primary settle 是主代理產出完成答覆的時點,process exit 是 OMP 完成 Advisor drain 並真正結束的時點。C、D 組若只記前者,會把最後仍在運作的第二模型藏起來;若只記後者,又看不出使用者何時已經拿到答案。兩欄一起報,才能分辨「等待變慢」與「背景成本增加」。
第五步:便宜模型分工要另開一輪
完成同模型消融後,才做實務上更省錢的 routing:例如主代理維持強模型、Plan 或 Advisor 改用較便宜模型、Reviewer 保留較強的 @slow。這一輪回答的是「怎麼配最划算」,不再回答「角色本身有沒有用」。仍沿用同一批 task、Oracle 與停止條件,並重新記錄錯誤建議率;便宜 Advisor 若頻繁誤判、讓主代理多做修正,低單價也可能換來更高的每次成功成本。
怎麼判讀:哪一種任務值得多付一層角色?
- 低風險、需求清楚、Oracle 很強:先留在 A。基準組若穩定通過,額外角色多半只是在買重複檢查。
- 跨檔案、需求有衝突、常在開工後改方向:看 B 是否降低重工與越界修改;Plan 的價值不是計畫寫得長,而是少返工。
- 長任務容易遺漏限制或中途偏航:看 C 的 Advisor note 是否及時、正確且真的被採納。若多數是噪音,就先關掉。
- 安全、付款、資料遷移或大 diff:看 D 的 Reviewer 是否抓到 Oracle 沒涵蓋的真問題;把修正時間與 Token 一起算進去。
若同一工具呼叫反覆 3 次仍沒有新證據、已用掉總時限 80%、Advisor 連續給出重複/互斥建議,或額外角色已使成本超過預算,立刻停止該 run、保留紀錄,回到 A 組最小配置。先完成這個因果測試,再做「便宜模型當 Advisor、強模型當 Reviewer」的第二階段經濟實驗;兩階段混在一起,就無法知道改善來自角色還是模型。
常見問題
1. Plan Mode 一定比較慢嗎?
它一定增加前置規劃,但總時間不一定增加;若計畫減少探索、錯改與返工,整體可能反而較短,只能靠同題重跑判斷。
2. Advisor 和 Reviewer 是同一個功能嗎?
不是。Advisor 在主代理執行中讀 transcript 並注入建議;Reviewer 在已有 diff 後做唯讀審查。
3. 可以用便宜模型當 Advisor 嗎?
可以,但先用同模型完成機制消融,再另做模型路由測試;否則無法分辨角色與模型品質的影響。
4. 每組跑 3 次夠嗎?
只夠做冒煙檢查。正式決策應增加不同風險與規模的任務,每個 cell 也要更多重跑並報告不確定性。
5. 為什麼不能只看 Token?
因為少做測試、提早放棄或輸出錯誤答案都會變省;品質守門後的每次成功成本才可比較。
6. Advisor 的 syncBacklog 要設多少?
主實驗固定 off,讓它不因等待策略混入額外變因;之後可另跑 1,測接近同步審查的品質/延遲交換。
7. Reviewer 找到問題就算成功嗎?
不算。它不直接改檔;要確認 finding 為真、完成修正並重新通過 Oracle,才可算進最終成功。
8. 什麼時候應回到最小配置?
當 A 組已穩定通過、額外角色沒有提高成功率,或 Advisor/Reviewer 的真陽性價值低於等待與成本時,就關掉它們。可觀測、可回滾的 harness 才是重點;可延伸閱讀 AI Agent Harness 實作指南。
結論:OMP 角色不是越多越安全
OMP A/B 測試真正要回答的不是「哪個角色最好」,而是它在你的任務風險下,有沒有用較少的失敗與重工,補回額外時間和 Token。先鎖定版本與 Oracle,跑 A;只有發現明確失敗型態,才依序加 Plan、Advisor 或完成後 Reviewer。若收益無法重現,就回到最小配置,把複雜度留給真的需要它的任務。
想繼續追蹤工具與方法,可瀏覽 AlphaLab AI 專區;若要把 Agent 評測、工作流與自動化系統化,也可查看 AlphaLab 課程。
接著閱讀
左右滑動查看更多推薦






