跳到主要內容

【2026 最新】Claude Code 子代理為何不派工?Opus 5 委派契約、驗收檔與成本控制

最後更新: ·
Claude Code 子代理為何不派工?用委派契約、驗收檔與成本控制建立可靠工作流

你以為自己剛剛派了一位 reviewer,實際上卻可能是主代理在同一個 context 裡,把自己的答案再看一遍,然後回你一句「審查通過」。這不是小瑕疵:如果工作流的價值正是獨立檢查,那麼「看起來有 review」和「真的有另一個 Claude Code 子代理」是兩件完全不同的事。

這波困惑在 Claude Opus 5 上線後特別明顯。官方 changelog 顯示 Claude Code 2.1.219 於 2026 年 7 月 24 日把 Claude Opus 5 設為預設 Opus 模型;隨後社群有人回報子代理被省略或審查被就地完成。但社群對內部提示詞的推論不是官方定論,所以本文不試圖猜二進位檔裡藏了什麼,而是教你把「有派工」變成可重播、可驗收、缺件就失敗的工程契約。

這是一篇給會用 Claude Code、卻不想把品質交給運氣的實作教學。你不需要先懂多代理理論;跟著放入兩個小檔案、跑一次 smoke test,就能分清楚:這次真的是另一位 worker 做的,還是主代理把流程靜默降級了。

先說結論:可靠委派=指名啟動+獨立證據+缺件即失敗

請先記住這句公式:可靠委派=@ 指名的 Agent 啟動+Start/Stop 事件+帶 nonce 的驗收檔+merge 前檢查。

把它想成寄掛號信。你不能只在工作說明裡寫「有人幫我檢查一下」;你要指定收件人、拿到寄件與簽收紀錄,再檢查信封裡是否真的有你要的內容。Claude Code 官方子代理文件也把三種方式分得很清楚:自然語言點名 agent 時,Claude 通常會決定是否委派;@-mention 則保證該子代理會為這一項工作啟動。這正是從「描述工作」升級成「委派契約」的分水嶺。

Claude Code 子代理可靠委派流程圖:指名啟動、SubagentStart、驗收檔、SubagentStop 與 fail loud 驗收
一個 review 不是一句「請審查」:要同時看見啟動事件、獨立產物與驗收結果。

先別急著怪 Opus 5:你看到的「不派工」有三種版本

  1. 柔性描述被主代理吸收。「這一步由 reviewer 檢查」很像流程旁白,不是明確指令;主代理可能自己完成它。這種情況最難察覺,因為輸出仍然看起來完整。
  2. 角色存在,但沒有被明確選中。子代理的 description 是讓 Claude 判斷何時適合委派的線索,不是排程器。官方文件建議在 description 寫入「use proactively」來鼓勵自動委派;鼓勵不是保證。
  3. 真的啟動了,但卡在權限、工具或預算。background 子代理的工具集合可能較小,模型、permission mode、maxTurns、巢狀深度和同時執行上限也都會影響結果。這些是可量測的執行問題,不該被包裝成「已完成獨立 review」。

所以,社群的「hardcoded」說法可以提醒你要測試,卻不能直接拿來當根因。更可靠的觀察是:本次 run 有沒有一筆你指定角色的 SubagentStart、相對應的 SubagentStop,還有一份含本次 nonce 的驗收檔?沒有其中任何一項,就把 review 視為未發生。

第一步:把「請幫忙」改成可執行的委派契約

先建立一個只負責審查、不碰原始碼的角色。Claude Code 的子代理檔放在 .claude/agents/;官方文件支援在 frontmatter 指定模型、工具、權限、最大回合數與 effort。下列例子讓 reviewer 唯一可寫的東西,就是一份 evidence report。

---
name: evidence-reviewer
description: Independently audit a completed change when explicitly requested.
model: sonnet
tools: Read, Glob, Grep, Write
permissionMode: acceptEdits
maxTurns: 12
effort: medium
---

你是獨立審查員,不可修改產品原始碼。
收到 RUN_ID 與範圍後,必須把報告寫到:
.claude/review-evidence/RUN_ID.md

報告必須包含:
- RUN_ID
- REVIEWED_FILES
- FINDINGS(可為 NONE)
- VERDICT:PASS、FAIL 或 BLOCKED

若無法寫出這份檔案,最後一行只能輸出:
REVIEW-CONTRACT-FAILED

把上面的 RUN_ID 當成每次任務換掉的唯一編號,例如 review-20260729-01。重點不在檔名本身,而是它讓舊報告不能冒充這一次的報告。

接著,主管(主代理)收到的工作說明要寫得像這樣:

本次任務採強制分工。先完成實作;完成後,
@"evidence-reviewer (agent)" 對本次 diff 做獨立審查。

RUN_ID:review-20260729-01
範圍:只檢查 src/auth 與對應測試。
成功條件:產出 .claude/review-evidence/review-20260729-01.md。
若沒有該檔案、沒有獨立子代理事件,或 verdict 不是 PASS,
不得宣稱已完成 review,也不得合併。

關鍵是 @-mention,不是「使用 reviewer」這五個字。官方的子代理文件明確把 @-mention 說成單一任務的保證啟動;自然語言只會讓 Claude 自行決定。若你的介面沒有 typeahead,先確認 agent 檔已被載入,再以官方文件列出的 @agent-角色名 形式提交。

Claude Code 子代理描述工作與委派契約的差異比較圖
左邊是期待,右邊才是可驗收的約定:角色、任務、nonce、產物與失敗條件缺一不可。

第二步:驗收檔不是裝飾,它要能讓靜默降級 fail loud

最危險的不是 Claude 說「我不派」,而是它沒有派卻照樣回你「review 完成」。因此驗收規則要反過來寫:缺少 evidence,不是 warning;就是失敗。

先在專案裡準備目錄並指定本次 nonce:

mkdir -p .claude/review-evidence
RUN_ID=review-20260729-01
: > .claude/review-evidence/events.jsonl
printf 'RUN_ID: %s\nEXPECTED: .claude/review-evidence/%s.md\n' "$RUN_ID" "$RUN_ID" > .claude/review-evidence/request.txt

reviewer 的報告開頭至少要長這樣:

RUN_ID: review-20260729-01
REVIEWED_FILES:
- src/auth/login.ts
- src/auth/login.test.ts
FINDINGS:
- NONE
VERDICT: PASS

只看檔案還不夠,因為同一個工作目錄中的主代理也理論上能寫檔。驗收檔回答的是「有沒有交付物」;子代理生命週期事件才回答「有沒有真的產生另一個 worker」。兩者要一起看,才不是自我感覺良好的 audit。

第三步:用 Hook 留下真正派工的收據

Claude Code 提供 SubagentStartSubagentStop hook。前者會帶來唯一的 agent_idagent_type;後者還會提供子代理自己的 transcript 路徑。這正好是「主代理真的呼叫了 Agent tool」的可觀測證據。

建立 scripts/log-subagent-event.sh

#!/usr/bin/env bash
set -euo pipefail

mkdir -p .claude/review-evidence
jq -c '{
  event: .hook_event_name,
  session_id,
  agent_id,
  agent_type,
  agent_transcript_path: (.agent_transcript_path // null)
}' >> .claude/review-evidence/events.jsonl

再在專案的 .claude/settings.json 加上兩個完全相同的 hook 設定:

{
  "hooks": {
    "SubagentStart": [
      {
        "matcher": "^evidence-reviewer$",
        "hooks": [
          { "type": "command", "command": "./scripts/log-subagent-event.sh" }
        ]
      }
    ],
    "SubagentStop": [
      {
        "matcher": "^evidence-reviewer$",
        "hooks": [
          { "type": "command", "command": "./scripts/log-subagent-event.sh" }
        ]
      }
    ]
  }
}

最後執行 chmod +x scripts/log-subagent-event.sh。想了解 payload 的完整欄位,可以直接看官方的 Hooks reference;它也說明了 Start 與 Stop 都能按 agent 名稱做 matcher。這一筆 JSONL 不是漂亮的 log,而是你升級後 smoke test 的對照基線。

第四步:把驗收寫成一個合併前的閘門

下面這個最小檢查不判斷程式碼好不好;它只回答一件事:你所稱的獨立 review,有沒有留下完整證據鏈。把它放成 scripts/verify-review-contract.sh

#!/usr/bin/env bash
set -euo pipefail

RUN_ID="$1"
REPORT=".claude/review-evidence/$RUN_ID.md"
EVENTS=".claude/review-evidence/events.jsonl"

test -s "$REPORT" || { echo "FAIL: missing reviewer report"; exit 1; }
test -s "$EVENTS" || { echo "FAIL: no reviewer event log"; exit 1; }
rg -q "^RUN_ID: $RUN_ID$" "$REPORT" || { echo "FAIL: wrong RUN_ID"; exit 1; }
rg -q "^VERDICT: (PASS|FAIL|BLOCKED)$" "$REPORT" || { echo "FAIL: missing verdict"; exit 1; }
START_ID="$(jq -r 'select(.event == "SubagentStart" and .agent_type == "evidence-reviewer") | .agent_id' "$EVENTS" | tail -n 1)"
test -n "$START_ID" && test "$START_ID" != "null" || { echo "FAIL: no reviewer start event"; exit 1; }
jq -e --arg id "$START_ID" 'select(.event == "SubagentStop" and .agent_type == "evidence-reviewer" and .agent_id == $id)' "$EVENTS" >/dev/null || { echo "FAIL: no matching reviewer stop event"; exit 1; }

echo "PASS: reviewer was observable and left an acceptance artifact"

這裡故意沒有「自動幫你修掉」的分支。沒有檔案、沒有 Start/Stop、沒有 verdict,命令就非零結束;CI、release checklist 或主代理都應把它視為沒有 review。這就是 fail loud:寧可阻塞你五分鐘,也不要讓同一個 agent 假裝成兩個人。

第五步:Explorer、reviewer 怎麼分模型與 token 預算?

多開子代理不是免費的「平行宇宙」;每個 worker 都會讀任務、思考、呼叫工具、回傳摘要。最實用的成本控制不是把每個人都降成最弱模型,而是把昂貴思考留給真的需要判斷的步驟

  • Explorer:haikumaxTurns: 8、read-only。只負責列出檔案、找入口、回傳短清單。問題要窄,例如「列出 auth flow 的檔案與測試」,不要叫它「理解整個 repo」。
  • Reviewer:sonnetmaxTurns: 12讀 diff、對照需求、產出 findings 與 verdict。它的價值是第二個 context,不是重寫主代理的所有工作。
  • Escalation:opus、有限回合。只在 reviewer 找到架構、安全或規格歧義時啟動;不要預設每個 TODO 都派 Opus 5 重新想一次。

官方文件把 maxTurnseffort 列為子代理可設定欄位;把它們當成你的「熔斷器」,而不是假裝有一個萬用的精準 token 上限。更要注意優先序:CLAUDE_CODE_SUBAGENT_MODEL 的環境變數高於每個 agent 檔的 model。如果你把它全域鎖成 Opus,原本省錢的 explorer 也會一起升級,成本策略就失效了。

Claude Code 子代理成本控制圖:Haiku explorer、Sonnet reviewer、Opus escalation 的回合預算
把模型與回合數分配給角色,而不是讓每一個小任務都繼承最昂貴的主模型。

更新後 5 分鐘 smoke test:不要只看「看起來正常」

每次 Claude Code 更新後,照下面跑一次。原生安裝通常會背景更新;Homebrew、WinGet 與 Linux 套件管理器則依官方安裝方式手動升級。先用 claude --version 記下版本;需要時可執行 claude update,然後開一個新的 session。

  1. 設定新的 RUN_ID,清空這次 smoke test 的 events.jsonl,例如 review-20260729-smoke,並清楚指定一個很小、無副作用的審查範圍。
  2. @"evidence-reviewer (agent)" 啟動 reviewer,不接受主代理「我直接看過了」作為替代。
  3. 確認 .claude/review-evidence/events.jsonl 新增一筆 Start 與一筆 Stop;Stop 記錄中的 child transcript 路徑也應存在。
  4. 確認同一個 RUN_ID 的 Markdown 報告存在、列出實際檢查檔案,且有明確 verdict。
  5. 執行 ./scripts/verify-review-contract.sh review-20260729-smoke。只有它回傳 PASS,才把這個版本標成可用於真正 workflow。

若失敗,請把結果分類,而不是立刻歸咎模型:沒有 Start 事件,先檢查 @-mention、agent 名稱與設定載入;有 Start、沒有 Stop,查看子代理 transcript 與權限;有事件、沒有驗收檔,代表 reviewer contract 沒有完成。這三種修法完全不同,但都比「再提示它一次」可靠。

常見問題 FAQ

Q1:在 skill 裡寫「由 reviewer 處理」就夠了嗎?
不夠。那是角色描述,不是每次 run 的啟動證明。對不能靜默降級的步驟,使用 @-mention、RUN_ID 與驗收閘門。

Q2:自然語言「請用 reviewer」完全沒用嗎?
有用,但不是保證。官方說這會讓 Claude 決定是否委派;當你需要確定該角色真的啟動時,改用 @-mention。

Q3:驗收檔本身能證明獨立性嗎?
不能單獨證明。它證明交付物存在;把它和 SubagentStart/Stop 的 agent_id、子代理 transcript 一起保存,才形成可檢查的證據鏈。

Q4:reviewer 為何還能 Write?
只為了寫 report。工具清單刻意沒有 Edit 或 Bash;若你需要更嚴格隔離,可讓實作者使用 worktree,reviewer 只讀該 diff 與指定 evidence 目錄。

Q5:所有 review 都該用 Opus 5 嗎?
不一定。大部分「需求有沒有覆蓋、測試有沒有漏」的工作先用 Sonnet;只有難以判斷的設計、安全或跨系統議題才升級。

Q6:maxTurns 是精準 token 預算嗎?
不是。它限制 agentic 回合,適合防止工作越跑越大;真正節流還要把任務範圍、檔案範圍和回傳格式一起寫窄。

Q7:子代理可以再派子代理嗎?
可以,但有深度限制。官方目前說明預設可往下三層;對單純 review,反而建議不要提供 Agent 工具,避免審查員把責任再轉包出去。

Q8:何時該用 agent team,而不是子代理?
當 workers 需要彼此討論與共享 task list 時。單向回報、單一責任的 explorer/reviewer 適合子代理;需要多個人互相挑戰觀點時才考慮仍屬實驗功能的 agent teams

給新手的 5 個重點

  1. 描述工作,不等於要求委派。要可靠地指定 worker,使用 @-mention。
  2. 一份 report 不是獨立性證明。搭配 Start/Stop hook 才能看見真的有 worker 被啟動。
  3. 每次 run 都要新 RUN_ID。這能阻止舊檔案替新任務背書。
  4. 把缺件寫成失敗。沒有 evidence 就不能 merge,別讓「審查過」只是文字。
  5. 最省錢的子代理,是範圍最小的子代理。Haiku 找檔、Sonnet 審查、Opus 做例外升級。

接著閱讀

左右滑動查看更多推薦

結語:別再把「它說有做」當成「它真的有做」

新版模型、版本更新和提示詞策略都可能改變 Claude Code 的行為;可靠的 workflow 不該依賴猜測它此刻會不會主動派工。把委派看成一份契約:指名 worker、留事件、交驗收檔、缺件就停。做到這四件事,你得到的不只是「多一個 reviewer」,而是一套能在下一次更新後仍自己告訴你「這次沒有真的派工」的系統。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週一封,第一時間收到新文章與投資觀察。

我們不會 spam,隨時可退訂。