什麼是 Workflow?解析 Claude Code 的多代理編排
什麼是 Claude Code 的 Workflow?解析多代理編排:一段確定性的 JavaScript 腳本協調眾多子代理,並附完整實作範例。
如果你在 2026 年看過 Claude Code 處理大型任務,你可能見過它宣告「啟動一個 12 個 agent 的 workflow」——接著 /workflows 指令即時顯示進度,數十個子代理(subagent)向外扇出、互相驗證、最後收斂出一個答案。新使用者每次都會問同樣兩個問題:什麼是 workflow?「編排(orchestration)」到底是什麼意思?
本文從零開始回答這兩個問題。不需要任何多代理的先備知識。
簡短版答案
**Workflow(工作流程)**是一段由 Claude Code 撰寫、由 harness(執行框架)執行的小型 JavaScript 程式。腳本的職責是協調:生成子代理、把它們的輸出互相串接、平行執行多件事、決定接下來發生什麼——用的是普通的迴圈與條件判斷,而不是模型的即興發揮。
**編排(orchestration)**就是字面上的意思:一份樂譜,許多樂手。
- 樂譜是 workflow 腳本。它是確定性(deterministic)的——同一份腳本每次都做同樣的事。它決定誰在何時演奏:哪些 agent 執行、以什麼順序、拿什麼輸入。
- 樂手是子代理。每一個都是完整的 Claude agent,擁有自己的上下文視窗(context window)與工具。它們在樂譜分配的段落內行使判斷——閱讀程式碼、權衡證據、撰寫分析。
這種分工正是整個概念的核心,值得背下來:
控制流程放在程式碼裡,判斷交給模型。
模型在任務進行中決定「我該不該再生成一個 reviewer?」是即興演出——有彈性,但無法重現、也難以控管預算。由腳本來決定——for 迴圈、if 判斷——就是編排。
從單一 Agent 到交響樂團
Workflow 不是憑空出現的。它是一段演進的第四步,你可以沿著 Claude Code 的歷史一路追溯:
Stage 1: Solo agent
┌─────────┐
│ Claude │ one context window does everything:
└─────────┘ read, plan, edit, test
Stage 2: Subagent fan-out (Agent tool)
┌─────────┐
│ Claude │──→ agent: "search the codebase"
│ (main) │──→ agent: "read these 40 files"
└─────────┘ results return to the parent only
Stage 3: Agent teams
┌─────────┐ ┌─────────┐
│ agent A │←──→│ agent B │ named agents that persist,
└─────────┘ └─────────┘ continued via SendMessage
Stage 4: Scripted workflows
┌────────────────────────────┐
│ JavaScript orchestration │
│ loops · phases · fan-out │
└──┬──────┬──────┬──────┬────┘
agent agent agent agent (deterministic score,
judging musicians)
Stage 1 是每個人的起點:一個 agent、一個上下文視窗。在任務超出單一上下文能容納的範圍之前,它都夠用。
Stage 2 加入了 Agent tool:主 agent 把多檔案閱讀與搜尋委派給子代理,自己的上下文只保留結論——而不是整批檔案內容。子代理預設在背景執行,其最終訊息只回傳給呼叫者。(深入說明見 Session 4:子代理與上下文隔離。)
Stage 3 讓 agent 成為可持續合作的夥伴:子代理可以被賦予一個 name,父代理之後可以透過 SendMessage 以信箱(mailbox)的方式繼續與它協作——上下文完整保留——而不是每次重新開始。(見 Session 9:Agent Teams 與通訊。)
Stage 4——Fable 5 世代的 Workflow tool——改變的是由誰決定結構。在 Stage 2 和 3 中,主 agent 是一輪一輪即興委派。在 workflow 中,結構只寫一次、以程式碼的形式寫下,然後被精確執行。Harness 在背景執行腳本、回傳一個 task ID、完成時通知你;整個過程中 /workflows 都會顯示即時進度。
為什麼要用腳本?確定性為何重要
把協調層做成確定性的,聽起來像是個技術細節。但其實大部分的價值正來自這裡。
**1. 可重現性。**腳本徹底禁止非確定性:Date.now()、Math.random()、不帶參數的 new Date() 在 workflow 腳本裡都會直接拋出錯誤。同一份腳本,同樣的行為。沒有「上次明明可以」這回事——樂譜不會在兩次演出之間改變。
**2. 從快取續跑(resume)。**每次 workflow 執行都會保存它的腳本,並由一份 journal.jsonl 記錄每個 agent 實際回傳了什麼。帶著 resumeFromRunId 重新啟動,harness 會直接從快取重播 agent() 呼叫中最長的未變更前綴——只有被修改或新增的呼叫才會真的執行。修好一個 50 agent 執行中第 3 階段的 prompt,你只需要重付第 3 階段的成本,而不是第 1、2 階段。這一切之所以可行,正因為控制流程是確定性的;這也是那些非確定性內建函式被禁用的原因。
**3. 沒有混亂的平行化。**用程式碼扇出(fan-out)才是安全的扇出。一個 workflow 最多同時執行 min(16, CPU 核心數 − 2) 個 agent,超出的排入佇列;單次執行以 1,000 個 agent 為上限,作為失控迴圈的保險;而且如果你對單一 fan-out 呼叫傳入超過 4,096 個項目,它會明確報錯(絕不默默截斷)。
**4. 預算強制執行。**在 prompt 裡寫上「+500k」,這一輪就有了 token 目標,並在腳本內以 budget 物件呈現:budget.total、budget.spent()、budget.remaining()。這個額度池由主迴圈與該輪的每一個 workflow 共享——而且是硬上限:一旦花費達到總額,之後的 agent() 呼叫都會拋出錯誤。腳本可以檢查 budget.remaining() 並優雅收尾;即興的模型沒有等效的煞車。
溫和導覽:agent()、parallel()、pipeline()
你不需要完整的 API 就能掌握概念(深入探討見 Session 27:Workflow 工具)。三個基本元件就能撐起大多數 workflow:
agent(prompt, opts?)——生成一個子代理,取回它的最終文字。透過opts.schema傳入 JSON Schema,你拿到的會是一個經過驗證的物件——子代理會被強制經由結構化輸出工具作答,形狀不符時自動重試。逐 agent 的model與effort(推理強度)選項,讓你把便宜的模型放在機械式工作上、把頂級模型放在判斷上。parallel(thunks)——同時執行多件事,並等待全部完成(一道屏障,barrier)。拋出錯誤的 thunk 會 resolve 成null而不是讓整次執行崩潰,所以你可以用.filter(Boolean)過濾。pipeline(items, stage1, stage2, ...)——每個項目獨立流過每一個階段,階段之間沒有屏障:項目 A 可以在第 3 階段,同時項目 B 還在第 1 階段。總耗時(wall-clock)就是最慢的單一項目走完全程的時間。
這裡是一個完整而簡單的 workflow——平行審查一批變更檔案,然後合併發現:
export const meta = {
name: 'review-changes',
description: 'Review changed files in parallel, then merge findings',
phases: [{ title: 'Review' }, { title: 'Merge' }],
};
phase('Review');
const files = args.files; // passed in when the workflow is invoked
// Fan out: one reviewer per file, all running concurrently.
const reports = (await parallel(
files.map((file) => () =>
agent(`Read ${file} and report any correctness bugs you find.`, {
label: `review ${file}`,
phase: 'Review',
model: 'haiku', // cheap tier for mechanical per-file reading
effort: 'low',
})
)
)).filter(Boolean); // a failed reviewer becomes null — drop it
phase('Merge');
log(`Collected ${reports.length} per-file reports.`);
// One high-effort agent merges and ranks everything.
await agent(
`Merge these review reports. Deduplicate and rank by severity:\n\n` +
reports.join('\n---\n'),
{ phase: 'Merge', effort: 'high' }
);
幾個值得注意的地方:
- 腳本以
export const meta = ...開頭——一個純字面值(不含變數、不含函式呼叫),宣告名稱、描述與階段。每個phase()呼叫都對應那裡宣告的一個標題,這正是即時進度畫面的資料來源。 args是 workflow 取得參數化輸入的方式;log()會寫下敘事行,供你在執行過程中閱讀。- 腳本本身沒有檔案系統存取權,也沒有 Node.js API——agent 才有工具;樂譜不碰樂器。
- 合併步驟刻意利用了
parallel的屏障:它需要每一份報告都到齊,才能跨報告去除重複。這正是經驗法則——只有當下一階段需要來自上一階段所有項目的跨項目上下文時,屏障才是合理的。不需要跨項目比較的逐項處理鏈,應該放進pipeline,那裡什麼都不用等。
想留下來重複使用的 workflow 放在 .claude/workflows/,之後可以用名稱呼叫;一個 workflow 甚至可以透過 workflow() 呼叫另一個 workflow,巢狀一層。
超越扇出:品質模式
扇出只是基本盤。編排真正有趣的部分,是用結構讓答案更可能為真:
- 對抗式驗證(adversarial verify)——針對每個發現,生成獨立的懷疑者 agent,明確要求它們反駁該發現;如果多數反駁成功,這個發現就淘汰。這能在看似合理但其實錯誤的結果到你面前之前把它們濾掉。
- 評審團(judge panel)——從不同角度對同一問題做出多個獨立嘗試,由平行的評審打分,最終答案由勝出者加上其餘方案的最佳想法綜整而成。
- 循環到枯竭(loop-until-dry)——面對規模未知的「找出所有 X」任務,持續生成搜尋者,直到連續好幾輪都找不到新東西為止。
這些模式值得專門一堂課——Session 28:編排品質模式逐一附程式碼講解。目前先記住這個重點:答案品質變成了你如何編排的結構性屬性,而不只是模型本身的屬性。
單打獨鬥、子代理,還是 Workflow?
機制越多不見得越好。這是一張誠實的決策表:
| 情境 | 選擇 | 原因 |
|---|---|---|
| 查單一事實,而且你知道在哪個檔案 | 單打獨鬥(不委派) | 委派的開銷不划算——直接讀就好 |
| 多檔案閱讀、搜尋、探索 | 子代理(Agent tool) | 主上下文只留結論,不留整批檔案內容 |
| 需要記得先前工作的合作者 | 具名 agent + SendMessage | 帶著完整上下文繼續,而不是重新開始 |
| 跨多項目的多階段流程,需要驗證或續跑 | Workflow | 確定性控制流程、平行化、預算、從快取續跑 |
如何啟用
Workflow 是**選擇性啟用(opt-in)**的——單一 workflow 可能生成數十個 agent、消耗可觀的 token 量,所以 harness 要求你明確要求這種規模。不啟用時,Claude Code 會使用個別子代理或獨自工作。三種啟用方式:
- 直接說:在 prompt 中寫上「use a workflow」做一次性啟用。
- Ultracode:在 prompt 中加入關鍵字「ultracode」,或透過
/effort為整個 session 啟用。Ultracode = xhigh 推理強度 + 在每個實質任務上常駐的多代理 workflow 編排。(完整指南:Ultracode 與 Effort 等級。) - 透過 skill:skill 的指示可以指引 Claude Code 為其任務使用 workflow 進行編排。
啟用時加上像「+500k」這樣的 token 指令,整個樂團就會在一個硬預算之內演奏。
重點結論
Workflow 是樂譜,不是獨奏者。Claude Code 撰寫確定性的 JavaScript 來決定什麼執行、何時執行、以什麼順序執行——並把每一次判斷都委派給擅長判斷的子代理。你得到的是程式碼的可靠性(可重現、續跑、平行化、預算)乘上模型的智能,而不必在兩者之間二選一。
下次某個任務對單一上下文視窗來說太大時,別要求一個更大的 agent。請要求一個交響樂團。