Subagent effort 調成 low:token 少 72%,植入的 bug 照樣抓到
同一個 code review 任務,Claude Code 的 review subagent 從預設繼承的 high 改成 CLAUDE_CODE_SUBAGENT_EFFORT=low,總 token 中位數少 72%、耗時少 73%;寬鬆計分兩組都抓到 6 個植入 bug 的全部,但 low 的 review 比較精簡,偶爾會漏。只測了一個任務、一個模型、每組 5 次。
- 測試日期
- 2026-11-01~02(台北時間)
- Claude Code
- 2.1.316
- 模型
- claude-sonnet-5
- 樣本
- 每組 5 次(另 1 次暖機不計)
659k → 183kp = 0.048
140 秒 → 38 秒p = 0.048
$0.33 → $0.16p = 0.119,不顯著
TL;DR:要設之前先知道這 3 件事
- 先查版本:
claude --version。我們原本裝的 2.1.197 根本沒有CLAUDE_CODE_SUBAGENT_EFFORT,設了也不會生效;2.1.316 才有。 - 設了有用,但不是每一層都保證 low:low 組有 2 次 subagent 自己轉交給內建的 code-review skill,其中一次那個巢狀 agent 以 medium 執行,花費回到 high 的水準。
- 別信只跑一次的對比:同一個設定跑 6 次,總 token 從 302k 到 643k,差了 2.1 倍。每組至少跑 5 次再比中位數。
背景
Claude Code 的 Boris Cherny 檢查使用者回報的 session 後表示,沒有找到單一根因或 regression,用量偏高多半來自一兩個重度 session。他提醒要留意自己的 effort 等級,原文:
Subagents inherit it by default and it can add up fast.
Boris Cherny,X
之後他在回覆中宣布新增 CLAUDE_CODE_SUBAGENT_EFFORT。這份實驗想知道的是:把 review subagent 的 effort 調低,實際省多少,品質掉多少。以下的數字和解讀都是我們自己的測試,不代表上述任何人的說法。
實驗設定
- 問題
- review subagent 用預設繼承的 high effort,跟設成 low 相比,token、時間、花費和審查品質差多少?
- 工具
- Claude Code 2.1.316(npm 最新版),headless 模式
claude -p,輸出 stream-json - 模型
- 固定
--model claude-sonnet-5;subagent 是內建的 general-purpose,也解析為 claude-sonnet-5 - Session effort
- 預設,對 claude-sonnet-5 解析為 high(兩組相同)
- 任務
- review 小型 Python 專案 ledgerlite 的
main...feature/review-mediff(commit4f95831),diff 裡事先植入 6 個已知 bug,現有測試都抓不到 - 條件
- A:不設環境變數(subagent 繼承 high)。B:
CLAUDE_CODE_SUBAGENT_EFFORT=low。其他完全相同。 - 流程
- 先跑 1 次暖機(A,不計),再依 A1、B1、A2、B2…A5、B5 交錯執行。每次都
git reset --hard && git clean -fd,同一份提示詞,主 agent 必須把整個 review 交給恰好一個 subagent(11 次都只呼叫了 1 次)。 - 權限
- 唯讀:只允許 Read/Grep/Glob/Agent、git diff/log/show/status 和 unittest;Edit、Write、網路都禁止,也禁止讀答案和紀錄資料夾。沒有任何一次修改到檔案。
- 量測
- token 和花費取自 CLI 輸出的 usage 與
total_cost_usd(牌價估算);耗時是牆上時間 - 評分
- 事先寫好的答案表,人工對照。嚴格:位置(檔案+行號或函式)和原因都對;寬鬆:原因對、位置大致對
結果
low 組的總 token、耗時、subagent 輸出都明顯比較少,而且差距遠大於同設定重跑的雜訊;花費的中位數也少一半,但因為 B1 那次特別貴,統計上不顯著。A 組最少的一次(399k)仍然比 B 組 5 次裡的 4 次多。
表格可左右滑動 →
| 指標 | A 預設 high:中位數(最小–最大) | B low:中位數(最小–最大) | B 對 A | 排列檢定 p | Mann-Whitney p |
|---|---|---|---|---|---|
| 總 token(含快取) | 658,683 (399,319–723,151) | 182,527 (150,403–547,826) | -72% | 0.048 | 0.016 |
| 耗時(秒) | 140.1 (119.5–151.1) | 37.9 (30.0–109.8) | -73% | 0.048 | 0.008 |
| 估算花費(USD) | $0.334 ($0.264–$0.360) | $0.158 ($0.110–$0.392) | -53% | 0.119 | 0.151 |
| subagent token(含巢狀) | 592,646 (333,342–657,001) | 117,888 (84,652–482,540) | -80% | 0.048 | 0.016 |
| subagent 輸出 token | 10,388 (8,580–11,862) | 1,628 (1,045–7,884) | -84% | 0.048 | 0.008 |
| subagent 工具呼叫數 | 16 (12–19) | 5 (3–15) | -69% | 0.048 | 0.032 |
| 回報問題數 | 9 (7–11) | 6 (4–9) | -33% | 0.119 | 0.111 |
| 植入 bug 抓到(嚴格,滿分 6) | 6 (5–6) | 5 (3–5) | -17% | 0.524 | 0.040 |
| 植入 bug 抓到(寬鬆,滿分 6) | 6 (6–6) | 6 (4–6) | +0% | 1.000 | 1.000 |
p 值:中位數差的精確排列檢定(252 種分組全列)與精確雙尾 Mann-Whitney U。5 對 5 的情況下,排列檢定最小只能到 0.048,Mann-Whitney 最小 0.008。粗體表示排列檢定 p < 0.05。
每一次執行
表格可左右滑動 →
| 執行 | 條件 | 總 token | 花費 $ | 耗時 s | subagent 輸出 | 工具呼叫 | subagent 請求的 effort | code-review skill | 嚴格 | 寬鬆 | 問題數 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| W | 暖機(A,不計) | 787,721 | 0.579 | 202.0 | 16,582 | 18 | high×19 | — | 6 | 6 | 9 |
| A1 | A high | 658,683 | 0.317 | 119.5 | 8,580 | 19 | high×16 | — | 6 | 6 | 7 |
| B1 | B low | 547,826 | 0.392 | 109.8 | 7,884 | 15 | medium×13 · low×2 | 是 | 5 | 6 | 7 |
| A2 | A high | 723,151 | 0.349 | 140.1 | 10,388 | 16 | high×17 | — | 6 | 6 | 7 |
| B2 | B low | 150,403 | 0.110 | 34.2 | 1,242 | 3 | low×3 | — | 5 | 6 | 6 |
| A3 | A high | 694,350 | 0.360 | 151.1 | 11,862 | 19 | high×16 | — | 6 | 6 | 9 |
| B3 | B low | 182,527 | 0.121 | 30.0 | 1,045 | 3 | low×5 | 是 | 3 | 4 | 4 |
| A4 | A high | 612,097 | 0.334 | 143.1 | 10,648 | 13 | high×14 | — | 5 | 6 | 11 |
| B4 | B low | 292,425 | 0.194 | 55.1 | 3,253 | 6 | low×7 | — | 5 | 6 | 9 |
| A5 | A high | 399,319 | 0.264 | 122.9 | 9,329 | 12 | high×9 | — | 6 | 6 | 9 |
| B5 | B low | 154,850 | 0.158 | 37.9 | 1,628 | 5 | low×3 | — | 5 | 6 | 6 |
「subagent 請求的 effort」是 subagent transcript 裡每個 API 請求記錄的 effort 參數與次數(含巢狀 agent)。B4 的 subagent 在背景執行,token 和花費是累計值,時間以牆上時間為準。每次的評分備註都在 results.csv。
環境變數真的有生效嗎?
有,而且是直接看到的,不是推論:
- API 請求參數:每個 subagent transcript 都記錄了請求的
"output_config":{"effort":…}。A 組每個 subagent 請求都是high,B 組是low(B1 的巢狀 skill 除外,見下方)。 - Hook 記錄:我們加了一個 PreToolUse hook,記下每次工具呼叫的
effort.level和$CLAUDE_EFFORT。主 session 在所有執行都是 high;subagent 在 A 組是 high,在 B 組是 low。 - 沒有被覆寫:主 agent 呼叫 subagent 時沒有指定 effort,所以結果只來自環境變數。
hook 會在每次工具呼叫多跑一個小 python 程序,兩組都一樣。CLI 的 --debug 和 stream-json 輸出都沒有 effort 欄位,所以只看那些看不出來有沒有生效。
三個發現
1. 舊版沒有這個設定,設了也不會報錯
第一輪我們用的是 Claude Code 2.1.197,它的執行檔裡找不到 CLAUDE_CODE_SUBAGENT_EFFORT 這個字串,所以「low」那組其實跟預設一模一樣,而且不會有任何提示。升到 2.1.316 之後才有作用。設定前請先跑 claude --version。
2. 同一個設定跑兩次,token 可以差到 2 倍
那 6 次舊版執行等於同一個條件跑了 6 遍(模型 claude-sonnet-5),總 token 從 302,087 到 643,134。第二輪 A 組自己的 5 次也從 399k 到 723k。只各跑一次就說「省了 X%」的對比,基本上沒辦法分辨是設定的效果還是運氣。
3. 設了 low,不代表底下每一層都是 low
B1 和 B3 兩次,low 的 subagent 自己把 review 轉交給內建的 code-review skill,由一個巢狀 agent 執行。B1 那個巢狀 agent 用 medium 跑了 13 個請求,結果 B1 花了 $0.392,比每一次 A 都貴。B3 的巢狀 agent 是 low,但那次 review 最弱,只抓到 4 個 bug、回報 4 個問題。A 組沒有任何一次走這條路。
限制
- 只有一個任務、一個模型(claude-sonnet-5,session effort high)、每組 5 次、一台機器、一個晚上。專案更大時,比例可能會不同。
- 花費是 CLI 依牌價估算的
total_cost_usd,不是帳單;訂閱制下它反映的是額度,不是實際付費金額。 - token 包含快取讀取,占每次總 token 的 72–93%(中位數約 88%)。
- 嚴格計分是人工判斷。A4 和 B4 都把折扣百分比的 bug 標在 coupons.py:16(欄位宣告,離答案的 :23 有 7 行),兩者都算嚴格未中、寬鬆命中。
- 品質只有 n=5:嚴格分數的 Mann-Whitney p 為 0.040,但排列檢定 p 為 0.524,而且 B 組的嚴格失分有 3 次只是位置不準。這組數字不足以下品質的定論。
- 所有執行都沒有誤報。
重跑步驟
- 下載實驗 repo(subagent-kit.zip),解壓後
git checkout feature/review-me。不含答案表。 - 把我們用的提示詞 prompt.txt 放在 repo 根目錄。
- 照下面的指令跑,A、B 交錯,每組至少 5 次,每次前都重設 repo:
claude --version # 2.1.316 (Claude Code)
git checkout feature/review-me && git reset --hard && git clean -fd
# A:預設(不設環境變數,subagent 繼承 session 的 high)
env -u CLAUDE_CODE_SUBAGENT_EFFORT claude -p "$(cat prompt.txt)" \
--model claude-sonnet-5 --output-format stream-json --verbose \
--allowedTools "Read" "Grep" "Glob" "Task" "Agent" \
"Bash(git diff:*)" "Bash(git log:*)" "Bash(git show:*)" "Bash(git status:*)" \
"Bash(python -m unittest:*)" "Bash(python3 -m unittest:*)" \
--disallowedTools "Edit" "Write" "NotebookEdit" "WebFetch" "WebSearch" > A1.stream.jsonl
# B:只差這一個環境變數
CLAUDE_CODE_SUBAGENT_EFFORT=low claude -p "$(cat prompt.txt)" ...(其餘參數同上) > B1.stream.jsonl
想驗證 effort 有沒有生效,可以加上 --settings 載入我們的 hook 設定,或直接看 ~/.claude/projects/…/subagents/agent-*.jsonl 裡的 output_config.effort。kit 裡的 RUNBOOK 是互動模式的版本,用 /usage 看數字也可以,只是沒有 headless 精確。
原始數據下載
- results.csv:第二輪每次執行的 token、花費、時間、effort 參數、評分與備註(含暖機,標示不計)
- stats.json:每個指標的逐次數值、中位數、變化百分比和 p 值
- phase1-results.csv:第一輪(2.1.197 的 6 次同條件執行,以及 2.1.316 各 1 次)
- prompt.txt、hook_settings.json、subagent-kit.zip
下一步
- 繼承 context 對比全新 context:這次沒有測。Matt Pocock 發現 Codex 讓多數 subagent 繼承父 agent 的 context,他已在 mattpocock/skills 改成每個 subagent 從全新 context 開始(#1341)。Claude Code 沒有正式的開關,我們要先設計一個可以重現的做法。
- Codex 對照:同一個任務在 Codex 跑一次,兩邊計量方式不同,只並排不直接比。
- 換任務、換模型:更大的 diff、不同模型,看 −72% 這個比例會不會變。
出處
測試日期與版本
2026-11-01 23:56 到 2026-11-02 00:15(台北時間),Claude Code 2.1.316,claude-sonnet-5,session effort high。各家預設改得很快,這份結果只代表上述版本,建議每個月重查一次。