Agent SDKのサブエージェント上限 — 深さ・並列数・支出をキャップする
Agent SDKにはサブエージェントの深さ・同時実行数・支出をコードから制限する3つの仕組みがあります。既定値と上限到達時の挙動を解説します。
サブエージェントはなぜ上限が必要か
allowedToolsにAgentを含めた瞬間から、いつ・何個のサブエージェントを立てるかはClaude自身の判断に委ねられます。サブエージェントはそれぞれ独立してAPIリクエストを送るため、その費用はクエリ全体のtotal_cost_usdにすべて合算されます。しかもサブエージェントは自分自身がさらにサブエージェントを起動できるので、1つのプロンプトから木構造にエージェントが枝分かれし、放っておくと際限なく広がる可能性があります。
Agent SDKはこの広がり方を3つの軸——ネストの深さ、同時実行数、クエリ全体の支出——でキャップする仕組みを持ちます。深さと同時実行数は環境変数で、支出はクエリのオプションで設定します。公式ドキュメントはこの仕組みをTypeScript SDK v0.3.219 / Python SDK v0.2.127以降(Claude Code v2.1.219以降を同梱するリリース)の説明としており、それより前のSDKでは一部の上限が欠けているか既定値が異なるため、本番運用でこれらの上限に頼る前にアップグレードを確認する必要があります。
深さ・同時実行数・支出はどう設定するか
| 上限 | 設定方法 | 既定値 | 上限に達したときの挙動 |
|---|---|---|---|
| 深さ | 設定方法CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH | 既定値3層(メイン下)。1で子エージェントの起動自体を止める | 上限に達したときの挙動最下層のサブエージェントは自分では起動できず、委任された作業を自力でこなす |
| 同時実行数 | 設定方法CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS | 既定値20(Agentツールで起動した全サブエージェントを数える) | 上限に達したときの挙動新規起動を拒否しConcurrent subagent limit reachedを返す |
| 支出 | 設定方法TypeScriptはmaxBudgetUsd、Pythonはmax_budget_usd | 既定値上限なし(total_cost_usdと比較、サブエージェントの分も合算) | 上限に達したときの挙動新規起動を拒否しBudget limit reachedを返し、バックグラウンドの実行中エージェントも停止 |
深さと同時実行数はどちらも環境変数としてenvオプション経由で渡し、この2つの環境変数を使うにはClaude Code v2.1.217以降が必要です。深さの既定値には変遷があり、v2.1.217からv2.1.218までは既定1(=子エージェントは起動できない)、v2.1.219で既定3に引き上げられました。もう一つ、v2.1.212で導入されたセッション単位の起動総数の上限(CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION、既定200)は、v2.1.224で削除されて現在はno-opです。深さと同時実行数の2つの上限だけが今は有効に残っています。
env変数の渡し方はSDKで挙動が違う
深さと同時実行数を設定するenvオプションは、TypeScriptとPythonで意味が異なります。TypeScript SDKはenvに渡した内容でサブプロセスの環境変数を丸ごと置き換えるため、PATHのような既存の環境変数を残したいならprocess.envを展開してから上書きする必要があります。Python SDKは逆に、渡した内容を継承済みの環境変数へマージします。同じオプション名でも片方は置換、片方は合成という違いがあり、TypeScript側でこれを忘れるとPATHが消えてコマンド実行系のツールが軒並み失敗します。
次の例は、ネストを完全に止め、同時実行を最大5に絞り、推定支出が5ドルに達したらクエリを止める設定です。
const result = query({
prompt: "Audit every service in this repo for unhandled promise rejections",
options: {
allowedTools: ["Read", "Grep", "Glob", "Agent"],
// envはサブプロセスの環境変数を置き換えるのでprocess.envを展開してPATHを残す
env: {
...process.env,
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH: "1",
CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS: "5",
},
maxBudgetUsd: 5,
},
});options = ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
# envは継承済みの環境変数にマージされる
env={
"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1",
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "5",
},
max_budget_usd=5.0,
)支出上限の下で見える結果は3通りです。上限未満で終わればsuccessと実際のコストが返ります。上限に達するとerror_max_budget_usdというサブタイプとともに上限以上のコストが返り、エラーハンドラーに処理が移ります。同時実行数の上限に達した場合は、クエリのメッセージストリームにConcurrent subagent limit reachedというtool_resultブロックが現れます。これはClaudeがAgentツールの結果として直接受け取るのと同じ内容です。
Opus5のサブエージェント上限はなぜ従来以上に重要か
Claude Opus5は従来のモデルよりもサブエージェントへの委任を積極的に行います。そのため深さ・同時実行数・支出の上限は、Opus5を使うクエリでこそ効いてきます。Claude Codeのclaude_codeシステムプロンプトプリセットを使っている場合、モデルがOpus5であればシステムプロンプトに「求められない限りAgentツールを呼ばない」という一文が自動的に足されます。ただしAgentツール自体は使える状態のままです。カスタムのシステムプロンプトを使う、あるいはsystemPromptを指定しない構成では、Claude Code側はシステムプロンプトを組み立てないため、この一文は入りません。その場合はOpus5のプロンプトガイドが挙げる委任抑制の指示を自分のプロンプトに追加する必要があります。
どちらの指示も、あくまでClaudeの振る舞いを誘導するだけです。実際にどれだけ委任するかはClaudeの判断に委ねられているため、指示を入れたかどうかにかかわらず、深さ・同時実行数・支出の上限は別途設定しておく必要があります。
数十から数百規模のサブエージェントを毎ターン束ねたい場合、上限を緩めて力業で対応するより、オーケストレーションをスクリプト側に移すWorkflowツールに切り替えるほうが実質的です。ターンごとの委任ではなくスクリプトが会話の外でエージェントを束ねる仕組みはダイナミックワークフローとはで扱っています。個々のサブエージェントを並列に使う実践パターンはClaude Codeのサブエージェント完全活用にまとめています。
深さの既定引き上げは何を示す動きか
深さの上限は2つの引き上げを経ています。v2.1.217からv2.1.218までの既定値は1で、サブエージェントは自分の子を起動できませんでした。v2.1.219で既定が3に引き上げられ、サブエージェントは自身の下にさらに2層まで子を持てるようになりました。深さの上限機能自体が導入された直後にいったん最も厳しい値(1)から始まり、その後まもなく緩められたという順序です。
この順序は、際限ない入れ子を先に止めてから、実運用で問題が出ない範囲を確認して緩めるという進め方を示しています。同時実行数の上限(既定20)がv2.1.217の導入時から変わっていないのとは対照的で、深さと同時実行数を別々の慎重さでチューニングしていることがうかがえます。深さを大きくすると1つのプロンプトから広がるエージェントの木が指数的に膨らみやすいため、同時実行数より小さく刻んで調整する軸だと考えられます。
用途に応じてどう組み合わせるか
無人で動かすCI/CDパイプラインと、対話的に使うローカル開発では、適切な上限の組み合わせが異なります。
| 用途 | 深さ | 同時実行数 | 支出上限 | 狙い |
|---|---|---|---|---|
| CI/CDでの自動レビュー | 深さ1(既定を下げる) | 同時実行数既定20のまま、または絞る | 支出上限明示的に設定 | 狙い1回の実行コストを予測可能にする |
| ローカルでの探索的な調査 | 深さ既定3のまま | 同時実行数既定20のまま | 支出上限設定しない、または高めに | 狙い委任の自由度を確保しつつ暴走だけ防ぐ |
| マルチテナントのSDKアプリ | 深さテナントの信頼度で分岐 | 同時実行数テナントごとに調整 | 支出上限テナントの契約枠に合わせて必須設定 | 狙いテナント間でコストを分離する |
無人稼働ほど3つの上限すべてを明示するのが安全側です。特に支出上限は既定で無効なので、CI/CDやマルチテナント運用では設定を忘れると歯止めなくコストが積み上がります。逆にローカルでの探索的な調査では、上限を絞りすぎるとサブエージェントが委任のたびに壁に当たり、かえって手動介入が増えます。既定値をいったん信頼し、実際のコストや実行時間を見てから絞るほうが手戻りが少なくなります。
まとめ — 上限は既定のままにしない
Agent SDKのサブエージェント上限は、深さ(既定3)・同時実行数(既定20)・支出(既定は上限なし)という性質の異なる3つの軸で構成されています。支出だけは既定で無制限なので、無人で回す構成ではmaxBudgetUsdを明示するのが実質的な必須設定です。個々のサブエージェントの設計はAgent SDKのサブエージェント定義、権限モードとの組み合わせはAgent SDKのパーミッション制御にまとめています。
よくある質問
支出上限に達すると実行中のバックグラウンドサブエージェントはどうなりますか
新規のサブエージェント起動を拒否するだけでなく、その時点でバックグラウンド実行中のサブエージェントも停止し、クエリ全体がerror_max_budget_usdで終わります。
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSIONはまだ使えますか
使えません。Claude Code v2.1.224で削除されno-opになりました。現在は同時実行数の上限と深さの上限の2つだけが有効です。
深さを1に設定するとどうなりますか
サブエージェントが自分自身の子サブエージェントを起動できなくなります。メインエージェントの直下1層だけが動く構成です。
ultracodeを有効にしたセッションでも同時実行数の上限は効きますか
効きません。ultracodeが有効なセッションは同時実行数の上限による拒否の対象外です。
同時実行数の上限に達すると何が返りますか
新しいサブエージェントの起動が拒否され、メッセージストリームにConcurrent subagent limit reachedというtool_resultブロックが現れます。Claude自身もAgentツールの結果として同じ内容を受け取ります。
サブエージェント自身のAPI費用はどこにカウントされますか
サブエージェントが送るすべてのAPIリクエストの費用は、クエリ全体のtotal_cost_usdに合算されます。支出上限はこの合計値と比較されるため、メインエージェントの費用だけを見ていると上限到達を見落とします。
同時実行数の上限は入れ子の階層を区別しますか
区別しません。Agentツールで起動されたすべてのサブエージェントを、階層に関わらず合計した数で数えます。深い階層のサブエージェントも浅い階層のサブエージェントも同じカウントに含まれます。
深さの上限に達したサブエージェントはエラーになりますか
エラーにはなりません。その階層のサブエージェントは自分でさらに委任することができなくなり、渡された作業を自力でこなすだけです。
支出上限を設定しない場合、何を目安にすればよいですか
目安となる既定値は用意されていません。想定するサブエージェントの数と1回あたりの平均コストから逆算して見積もり、無人で回す構成では必ず明示的なmaxBudgetUsdを設定するのが安全です。