原典: Orchestrate subagents at scale with dynamic workflows / 日本語版

一行要約

dynamic workflow の本質は「計画を Claude の context ではなくコードに移すこと」で、そのおかげで中間結果はスクリプト変数に留まり、Claude の context には最終回答だけが残る。代償はトークンで、1 run あたり最大 1,000 エージェントまで走りうる。

要点

何が他と違うのか — 「誰が計画を保持するか」

SubagentsSkillsAgent teamsWorkflows
正体Claude が起こすワーカーClaude が従う指示peer セッションを監督するリードエージェントランタイムが実行するスクリプト
次に何を走らせるか決めるのはClaude、ターンごとClaude、プロンプトに従ってリードエージェント、ターンごとスクリプト
中間結果の置き場Claude の context windowClaude の context window共有タスクリストスクリプト変数
再利用できるものワーカー定義指示チーム定義オーケストレーション自体
規模1ターンに数個同上少数の長時間 peer1 run に数十〜数百
中断されたらターンをやり直すターンをやり直すteammate は走り続ける同一セッション内で再開可能

A workflow script holds the loop, the branching, and the intermediate results itself, so Claude’s context holds only the final answer.

workflow のスクリプト自体がループ・分岐・中間結果を保持するので、Claude の context には最終的な答えだけが残る。

計画をコードに移すことのもう1つの効用は、繰り返し可能な品質パターンを適用できること。独立したエージェントに互いの発見を敵対的にレビューさせてから報告させる、複数の角度から計画を起草して互いに比較させる、といったことができる。

起動の3経路

経路やり方
プロンプトで頼むultracode キーワードを含める、または「use a workflow」と自然文で書く
Claude に任せる/effort ultracode を設定すると、セッション中のすべての実質的なタスクで Claude が workflow を計画する
既存のコマンドを走らせるbundled の /deep-research、または自分が保存したもの

キーワードが効くのは「自分がタイプしたプロンプト」だけ(対話プロンプト、IDE 拡張のパネル、Remote Control、origin を { kind: "human" } と刻む Agent SDK アプリ)。次の経路では workflow を起動しない。

  • -p で渡したプロンプト
  • human と刻まずに Agent SDK が送ったプロンプト
  • scheduled task のプロンプト
  • webhook のペイロードや pull request のコメントが会話に中継された場合

キーワードを取り消す: 意図せず起動しかけたら Option+W(macOS)/ Alt+W(Windows・Linux)でハイライトを消す。カーソルがハイライト直後にあるならバックスペースでもよい。そもそも発火させたくなければ /config の Ultracode keyword trigger をオフにする。

ultracode は、セッションの effort レベルがどれであっても、そのセッションで自動 workflow オーケストレーションをオンにする設定(claude --effort ultracode で起動したときは effort も xhigh になる)。1つのリクエストが連続した複数の workflow(理解する用、変更する用、検証する用)になりうる。/effort ultracode はそのセッション限りで、毎回オンにしたいなら ultracode 設定を書く。v2.1.203 以降が必要で、xhigh に対応するモデルでしか /effort スライダにトグルが出ない(スライダでは Tab で切り替え)。戻すときは /effort ultracode off。サブスクリプションでは、同じ作業を ultracode なしでやるより早くセッションや週の使用上限に達する。 オンにしている間は、Large workflow 警告・セッションの同時 subagent 上限・auto mode での最初の workflow 起動の承認が、どれもかからない(大きな run に同意済みとみなす)

提供範囲: 有料プラン全般、Anthropic API、Amazon Bedrock、Google Cloud の Agent Platform、Microsoft Foundry。Pro では /config の Dynamic workflows 行から自分で有効にする。

承認と権限(重要な落とし穴)

permission modeプロンプトが出るタイミング
Manual / accept edits毎回(「この workflow は今後聞かない」を選んだ場合を除く)
Auto初回のみ。Yes を選ぶと user settings に記録される。ultracode がオンならスキップされる
Bypass permissions出ない。即座に走る
claude -p / Agent SDKプロンプトは出ないが、素通りでもない(下記)

claude -p と Agent SDK では起動プロンプトが出ない代わりに、Workflow ツール呼び出しが他のツール呼び出しと同じ権限評価を通る。 deny ルール・ask ルール・dontAsk モードが起動にもそのまま効く。走らせたいなら次のいずれかが要る。

  • permission rule —— allow に Workflow を書けば全 workflow、Workflow(<name>) なら保存済みの1本だけ
  • auto permission mode —— 分類器が呼び出しをレビューして承認しうる
  • bypass permissions mode
  • PreToolUse hook が allow を返す
  • ホスト側 —— --permission-prompt-tool、Agent SDK なら canUseTool コールバック

Desktop アプリでは、workflow 名・フェーズ一覧・トークン使用量の注意を出した承認カードが Once / Always / Deny で出る。進捗は Background tasks サイドペインに出る。

subagent の権限(以前の記述から変わっている):

The subagents the workflow spawns use your permission rules, and Claude Code picks their permission mode by the rules under which permission mode a subagent runs in.

workflow が立てる subagent はあなたの permission ルールを使う。permission mode は「subagent がどの permission mode で走るか」の規則に従って Claude Code が選ぶ。

かつてこの原典は「subagent は常に acceptEdits で動き、ファイル編集は自動承認される」と書いていたが、その記述は無くなった。長い run で確認を挟みたくないなら、エージェントが必要とするツールを開始前に allow ルールへ入れておく。

スクリプトの読み取り権限: Claude が workflow を起動できるのは、そのセッションが既に読める場所にあるスクリプトファイルからだけ。作業ディレクトリの外に置いたスクリプトを走らせるなら、先に /add-dir か Read の allow ルールでそのディレクトリを足す。

スクリプトの形

保存されたスクリプトは meta ブロックとスクリプト本体からなる。本体は top-level await を使えるプレーンな JavaScript。

  • agent() — subagent を1つ起こす
  • pipeline() — リストの各要素に対して1つずつ走らせる
  • parallel() — エージェントタスクの集合を同時に走らせ、全部を待つ
  • phase() — 以降のエージェントを進捗ビュー上で1つの見出しにまとめる
  • log() — フェーズ群の上にメッセージを出す

agent() は、途中で止めた場合や回復不能な API エラーの場合に null を返す。auto mode では、分類器が subagent の起動前に agent() を止めることがあり、これも null になる(進捗ビューに理由が出る)。pipeline() はその null を結果配列に残すので、.filter(Boolean) で落とすのが定型。

schema を渡すと、その subagent は散文ではなく JSON を返す。 Claude Code は起動前にスキーマを検査し、自己矛盾を証明できたときはsubagent を起動せずに矛盾を挙げて失敗する(additionalProperties: false が required のキーを排除している場合など)。検証に5回失敗すると、最後の検証エラーを添えて失敗する(回数は MAX_STRUCTURED_OUTPUT_RETRIES で変える)。

保存済みスクリプトを編集するとき(Claude Code がロード時に課す規則):

  • meta ブロック —— export const meta をファイルの最初の文に置き、name と description を持つ素のオブジェクトリテラルのままにする。変数・関数呼び出し・スプレッドが混ざると、/<name> が / 補完から黙って消える
  • phases —— meta に列挙するなら、phase() に渡すタイトルと完全に一致させる。対応する項目の無い phase() タイトルは独立した進捗グループになる
  • 時刻と乱数 —— Date.now()・Math.random()・引数なしの new Date() はスクリプト内で例外を投げる。 再実行した run が同じ agent() 呼び出しを再現できるようにするため。時刻が要るなら args で渡す
  • 本体に構文エラーがあれば、workflow を走らせたときに報告される

編集の前に /workflow-authoring(bundled skill、v2.1.248 以降)を走らせて、Claude が参照するスクリプト作法のリファレンスを読ませる。編集版を同一セッションで走らせるには /reload-skills で workflow ディレクトリを読み直してから /<name> を叩く。

ランタイムの制約

制約理由
実行中のユーザー入力を受け付けない中断できるのはエージェントの権限プロンプトのみ。段階ごとの承認が要るなら各段階を別の workflow にする
スクリプト自身にファイルシステム・シェルへの直接アクセスがない読み書きとコマンド実行はエージェントの仕事。スクリプトは統率するだけ
モジュールをロードできない(import() を含むスクリプトは開始前に失敗する)本体はプレーン JavaScript。ライブラリが要る作業はエージェントのタスクに入れる
同時実行は既定で最大 16 エージェント(CPU が少ない環境ではより少ない。CPU 制限のかかったコンテナ内も含む)。CLAUDE_CODE_WORKFLOW_MAX_CONCURRENT_AGENTS で 1〜256 に変えられる(v2.1.269 以降)ローカル資源の消費を抑える
fan-out では、先頭エージェントと prompt-cache の接頭辞を共有するエージェントは既定で最大5秒遅れて開始する2本目以降が接頭辞を各自で処理せず、先頭がキャッシュしたものを読むため
1回の parallel() / pipeline() に渡せるのは 4,096 件まで(超えるとエラーで拒否)黙って打ち切ると、作業の一部が知らぬ間に落ちるから
1 run あたり合計 1,000 エージェント暴走ループの防止

fan-out での prompt cache

同一 run のエージェントは互いの prompt cache を読める。モデル・effort・エージェント型・ツール・出力スキーマ・作業ディレクトリが同じなら同じ接頭辞になるので、先に走った兄弟の応答が始まった後に開始したエージェントは、初回リクエストでそのキャッシュを読む。

  • workflow エージェントのリクエストは本会話の cache TTL バケットの外にあるので、サブスクリプションでも既定は5分。1時間にしたいなら subagentPromptCacheTtl を 1h にする(API は1時間キャッシュの書き込みを高い単価で課金する)
  • 一致するエージェントが同時に始まるとき、Claude Code は先頭以外を保留し、先頭の応答が始まってからまとめて解放する。保留の上限は CLAUDE_CODE_WORKFLOW_PREFIX_STAGGER_MS(既定 5000 ミリ秒)。0 で無効化できる

実行のされ方と再開

  • ランタイムは会話とは別の隔離環境でスクリプトを実行する
  • 各 run はスクリプトを ~/.claude/projects/ 配下のセッションディレクトリに書き出す。Claude は開始時にそのパスを受け取るので、読ませたり、前回の run と diff したり、編集して再実行させたりできる

走っている workflow を開かずに止めるなら、/workflows の一覧で選んで x。 一時停止した run は /workflows で選んで p で再開する。停止した run は「同じスクリプトで起動し直して」と Claude に頼む。リプレイはエージェントの開始順に従い、各エージェントは保存結果を返すか、走り直すかのどちらかになる。

前回の状態再開時
完了保存結果を返す。ただしプロンプトが前回と変わった最初のエージェント(スクリプトを編集した、あるいは前段のエージェントが違う結果を返した)は走り直し、それより後の全エージェントも、完了していたかどうかによらず走り直す
停止時にまだ走っていた最初からやり直す。run 全体を止めた場合、どのエージェントも「失敗」には数えない
失敗走り直す。それより後に開始した全エージェントも、完了していたかどうかによらず走り直す。/workflows で x を押してエージェント1つだけを止めた場合は「失敗」に数える

If a script starts A, B, C, and D in that order and B fails, relaunching returns A from cache and runs B, C, and D again.

スクリプトが A・B・C・D をこの順で起動し、B が失敗したとする。起動し直すと A はキャッシュから返り、B・C・D は走り直す。

セッションを離れたときにどうなるかは、離れ方で変わる。

  • セッションをバックグラウンドに送る —— バックグラウンドのセッションで同じようにリプレイされ、そのまま続く
  • workflow 実行中に Claude Code を終了する —— agent view がオンなら終了ダイアログに Move to background and exit が出て、同じように引き継がれる。Exit and stop tasks を選んだ場合、またはその選択肢が出ない場合、run はセッションと一緒に止まる
  • 止まっても保存済みの結果は ~/.claude/projects/ のセッションディレクトリに残るので、claude --resume で戻ったセッションなら「起動し直して」でリプレイできる。新しく始めたセッションにはリプレイするものが無く、最初からになる

使用上限に当たったとき

run は自分では止まらず、条件が全部そろったときだけ待つ。 1つでも欠けると、そのエージェントは待たずに失敗する。

  • 対話セッションで、claude.ai のサブスクリプションでサインインしていること(claude -p・Agent SDK・バックグラウンドセッション・Remote Control・agent team の teammate では待たない)
  • autoContinueAtUsageLimit がオンであること。待っている最中に切ると、待ちが終わって待機中のエージェントが失敗する
  • 上限が24時間以内にリセットされること(週次の上限はもっと先になりうる)
  • その run がまだ2回しか待っていないこと。3回目は失敗する

コスト管理

  • 大きなタスクに踏み込む前に、小さなスライスで試す(リポジトリ全体ではなく1ディレクトリ、広い問いではなく狭い問い)
  • Large workflow 警告: 25 エージェントを超えて予定される、または予測トークン合計が 150万を超えると、タスクパネルの進捗行に警告が出る。これは助言であって、run を止めたり制限したりはしない。size guideline を自分で選んでいればその値が 25 の閾値を置き換える。ultracode がオンのセッションでは警告は出ない
  • モデルの選び方は subagent と同じ順序(スクリプトが段階ごとに指定したモデルは「呼び出しごとの model」として効く)。何も指定が無ければセッションのモデル。CLAUDE_CODE_SUBAGENT_MODEL は既定値でしかなく、上書きしたいなら CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 を併せて設定する(sub-agents)
  • 組織の availableModels allowlist がスクリプトの要求したモデルを塞いでいる場合、そのエージェントは代替モデルで走る(subagent と同じ代替規則)。/workflows の進捗ビューに要求されたモデルと代替されたモデルの両方を挙げた警告が出る
  • small の size guideline を選ぶと、run あたりのエージェント数を減らせる

size guideline(Claude への助言であって上限ではない):

値Claude が目指すエージェント数
unrestricted指定なし。タスクに応じて Claude が決める
small5 未満
medium15 未満(既定)
large50 未満

既定が medium になったのは v2.1.219 以降(それ以前は unrestricted)。/config の Dynamic workflow size 行、または /config workflowSizeGuideline=small で変える。v2.1.219 以降は設定ファイルの workflowSizeGuideline キーが /config より優先され、設定ファイルが値を持つ間 /config の行は隠される。変更は次のプロンプトから効く。ランタイムの上限は設定によらず適用される。

保存と配布

/workflows で run を選んで s で保存。Tab で保存先を切り替える。

保存先共有範囲
.claude/workflows/(プロジェクト)リポジトリを clone した全員
~/.claude/workflows/(ホーム)全プロジェクトで使えるが自分だけ
  • 同名ならプロジェクト側が走る
  • monorepo では、作業ディレクトリからリポジトリルートまでの間で既に存在する最も近い .claude/workflows/ に書かれる。読み込みもその経路上すべてから行われ、同名なら作業ディレクトリに最も近いものが走る
  • symlink 越しの書き込みは拒否される(プロジェクト側は .claude / .claude/workflows / 対象ファイルのいずれかが symlink なら拒否、個人側は対象ファイル自体が symlink のときだけ拒否)
  • plugin で配布する場合は plugin ルートの workflows/ に置く。plugin 名で namespace される(/acme-tools:release-audit)

引数を渡す: 保存した workflow は args パラメータで入力を受け取る。スクリプトは args というグローバルとして読む。Claude が構造化データとして渡すので、パースなしに配列・オブジェクトのメソッドを呼べる。省略時は undefined。

bundled workflow

/deep-research <question> — 問いを複数の角度から web 検索でファンアウトし、見つけた情報源を取得して相互検証し、各主張に投票して、相互検証を通らなかった主張を除いた出典付きレポートを返す。WebSearch ツールが必要。自分で呼んだときだけ走る。

v2.1.196 以降、検証エージェントがレート制限や API エラーで主張を確認できなかった場合、「反証された」ではなく「未検証」として列挙される。

進捗の見方(/workflows のキー操作)

キー動作
↑ / ↓フェーズまたはエージェントを選択
Enter / →掘り下げる(フェーズ → エージェント → プロンプト・直近のツール呼び出し・結果)
Esc / ←1階層戻る
j / kエージェント詳細内のスクロール
f状態でフィルタ(押すたびに巡回)
p一時停止 / 再開
x選択中のエージェントを停止(run にフォーカスがあれば全体を停止)
r選択中の実行エージェントを再起動
srun のスクリプトをコマンドとして保存

無効化

範囲方法
自分/config で Dynamic workflows をオフ / ~/.claude/settings.json に "disableWorkflows": true / CLAUDE_CODE_DISABLE_WORKFLOWS=1
組織全体managed settings に "disableWorkflows": true、または Claude Code admin settings のトグル

workflow が使えるのは CLI・Desktop アプリ・IDE 拡張・claude -p の非対話モード・Agent SDK。無効化の設定はどの経路にも同じように効く。

無効化すると bundled workflow コマンドと /workflow-authoring skill が使えなくなり、ultracode キーワードも発火せず、/effort から Ultracode のトグルが消える(走っている run は続く)。ultracode だけを禁じる managed 設定は無い —— 使える環境ならユーザーは /effort ultracode でオンにできる。effort の上限は ultracode でのレベルを下げるが、ultracode 自体は切らない。

そのまま使える具体例

保存されたスクリプトの形:

export const meta = {
  name: 'audit-routes',
  description: 'Audit every route handler for missing auth checks',
}
 
const found = await agent('List every .ts file under src/routes/.', {
  schema: { type: 'object', required: ['files'], properties: { files: { type: 'array', items: { type: 'string' } } } },
})
 
const audits = await pipeline(found.files, file =>
  agent(`Audit ${file} for missing authentication checks.`, { label: file }),
)
 
return audits.filter(Boolean)

タスクの形ごとのプロンプト例(スクリプトは自分で書かない):

use a workflow to audit every route handler under src/routes/ for missing authentication checks, and adversarially verify each finding before reporting it
use a workflow to run npx tsc --noEmit and keep fixing the reported errors until the type check passes or two rounds in a row make no progress
use a workflow to migrate every component under src/components/ from JavaScript to TypeScript, working on each file in its own isolated copy
use a workflow to review every file changed in this PR for correctness issues, then merge the per-file findings into one ranked summary
use a workflow to find flaky tests in this repo: run the suite repeatedly, record which tests fail intermittently, and stop once two rounds in a row find nothing new

キーワードで単発起動する:

ultracode: audit every API endpoint under src/routes/ for missing auth checks

セッション全体を workflow 前提にする:

/effort ultracode
claude --effort ultracode

サイズの指針を変える:

/config workflowSizeGuideline=small

保存した workflow に引数を渡す:

Run /triage-issues on issues 1024, 1025, and 1030

原典で言及されている関連文書

  • a-harness-for-every-task — この機能の設計意図(agentic laziness / self-preferential bias / goal drift)
  • sub-agents — workflow が統率するワーカーの本体
  • features-overview — subagent / agent teams / workflow の使い分け
  • multi-agent-research-system — fan-out と統合の実運用例
  • building-effective-agents — orchestrator-workers パターン
  • costs — multi-agent 実行と利用上限
  • permission-modes — permission mode。auto mode の分類器が Workflow 呼び出しを承認しうる
  • prompt-caching — fan-out でエージェント同士がキャッシュを共有する条件、subagentPromptCacheTtl
  • hooks — PreToolUse hook で Workflow 呼び出しを allow する
  • skills — bundled skill の /workflow-authoring
  • plugins — plugin に同梱すると plugin 名:meta.name の名前で走る(plugin の作り方と名前の接頭辞は plugins-create)