Claude Media
CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHとは — 入れ子の段数を変える環境変数

CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHとは — 入れ子の段数を変える環境変数

CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHはサブエージェントが孫エージェントを持てる段数を変える環境変数です。既定値3の由来、上限到達時の挙動、フォークとの違いをまとめます。

CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHは、サブエージェントがさらに自分のサブエージェント(孫エージェント)を起動できる段数を制御する環境変数です。既定ではメイン会話の下に3階層まで入れ子にでき、1を指定すると入れ子そのものを無効化できます。v2.1.217以降のClaude Codeで使えます。

既定の挙動と上限到達時の動き

段数の上限に達したサブエージェントからは、Agentツールだけが自動的に取り上げられます。委譲先を持たないその階層のサブエージェントも、残りのツールで作業を続けます(下の比較を参照)。中間層の細かいやり取りがメイン会話まで上がってこない設計です。

入れ子は「調査役のサブエージェントが、見つけた指摘ごとに検証役のサブエージェントをさらに束ねる」ような、委任先で作業がもう一段分岐するタスクに向いています。

対話セッションでは、起動したサブエージェントがバックグラウンドで起動した子の結果を待ってから終わります。そのため、メイン会話に戻るのは最上位のサブエージェントの要約1件だけで、途中の階層の出力は表に出ません。非対話モード(-p)やAgent SDKでは、起動したサブエージェントは待たずに終わります。起動元が終わったあとに完了した子は、結果をメイン会話へ直接報告します。

CIやSDKで入れ子を使うときは、この違いで中間層の出力が見える形が変わります。非対話モードで--append-subagent-system-promptを渡すと、入れ子のサブエージェントを含む全員のシステムプロンプトの末尾に文章を足せます。フォークだけは会話のプロンプトをそのまま使うため対象外で、v2.1.205以降が必要です。

くらべる

段数の上限に達したときの扱い

Agentツールを取り上げ

通常のサブエージェント

Agentツールだけが外されます。ReadやBashは残るので、その階層は任された作業を自力でこなし、要約を1件返します。

Agentは残る

フォーク(`/subtask`)

Agentはツール一覧に残りますが、呼ぶとエラーが返り、新しいサブエージェントは起動しません。フォークから別のフォークを起動することもできません。

ツール一覧を見るとフォークだけ制限されていないように映りますが、新しい子が起動しない点はどちらも同じです。

フォークは、起動した時点の会話をそのまま引き継ぎます。システムプロンプトとツール定義が親と同一なので、最初のリクエストは親のプロンプトキャッシュを再利用します。同じ文脈が要る作業では、新しいサブエージェントを起こすより安く済みます。ClaudeがAgentツールでフォークを起動するときはisolation: "worktree"を渡せて、その場合の編集は別のgit worktreeに書かれます。

段数はメイン会話そのものを含めず、その下に伸びるサブエージェントの層だけを数えます。既定値3であれば、メイン会話が起動したサブエージェントを1階層目として、そこからさらに2階層分の孫・ひ孫エージェントまでを許すという数え方です。

サブエージェント定義のtoolsにAgentを含めると、そのサブエージェントは段数の上限まで自分の子を起動できるようになります。ただしAgent(reviewer, tester)のようにカッコ内へ起動してよい種類を書く絞り込み構文が効くのは、claude --agentでメインスレッドとして動く場合だけです。サブエージェント定義の内側ではカッコ内の型リストが無視されるため、定義側ではAgentを許可するか外すかの二択になります。

既定値は3段階の歴史を経ている

この変数が今の形になるまでに、既定の段数は3回変わっています。バージョンごとの違いを知らずに設定すると、手元のバージョンでは効かない指定をしてしまうことがあります。

経緯

入れ子の既定の段数の移り変わり

  1. v2.1.172〜v2.1.2165段階で固定

    入れ子が既定で有効で、最大5階層まで。上限は変更できませんでした。

  2. v2.1.217〜v2.1.218既定は1段階

    入れ子は事実上オフになり、環境変数で上げられるようになりました。同じv2.1.217で、同時実行数の上限(既定20)も初めて入っています。

  3. v2.1.219以降既定は3段階

    今の既定値です。環境変数で増減できます。

v2.1.217の変更履歴には、同時実行数の上限について「1回のメッセージから制限なくバックグラウンドのエージェントが広がらないようにする」とあります。同じバージョンで、横方向と縦方向の2つの広がりを同時に絞った形です。

段数(縦方向)とは別に、セッション全体で起動できるサブエージェントの総数を絞る仕組みも一時期存在しました。v2.1.212で導入されたCLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION(既定200件)がそれですが、v2.1.224で撤廃されて現在はno-opです。今も有効に残っているのは、段数とこのあと触れる同時実行数の2つだけです。

設定のしかた

シェルの環境変数として渡す方法が最も手早く試せます。

export CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH=2
claude

プロジェクト全体で固定したい場合はsettings.jsonのenvキーに書きます。次の例はメイン会話の下を2階層までに制限する設定です。

{
  "env": {
    "CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "2"
  }
}

受け付けるのは、数字だけで書いた正の整数です。小数・負の数・文字列のような値は無視されます。そのため、この変数で上限を外すことはできず、増減だけができます。入れ子を完全に止めたいなら1を指定します。

既定の3より大きい値(たとえば5)も、正の整数なら指定できます。2にすると、サブエージェントは2層目まで起動でき、2層目はそれ以上起動できません。

特定のサブエージェントだけネストを止める

環境変数を動かすと、その設定を読み込むすべてのサブエージェントに影響します。読み取り専用でいてほしいレビュー専任のサブエージェントなど、特定の1つだけ入れ子を禁じたい場合は、変数を触らずそのサブエージェント定義のtoolsからAgentを外すか、disallowedToolsに加える方法が的確です。全体の上限は変えずに、個別の挙動だけをピンポイントで固定できます。

ネストしたサブエージェントの設定方法は、最上位のサブエージェントと同じです。プロジェクト・ユーザーいずれのスコープからも同じ規則で解決されます。用途に応じた設定の目安は次のとおりです。

場面設定の選択肢効く範囲
入れ子を使わない設定の選択肢1を指定効く範囲変数を読む全サブエージェント
入れ子は残しつつ2段目までに絞る設定の選択肢2を指定効く範囲変数を読む全サブエージェント
レビュー専任など、他を呼ばせたくない1つ設定の選択肢その定義のtoolsからAgentを外す効く範囲その定義だけ
調査役がさらに検証役を束ねる設定の選択肢既定の3のまま効く範囲変数を読む全サブエージェント

上限に達すると画面上ではどう見えるか

Claude Codeはネストしたサブエージェントを、プロンプト入力欄の下にあるサブエージェントパネルにツリー表示します。まだ子を持っている行には(+N)という件数が添えられ、開くとその階層のきょうだいと直接の子を、mainまで遡る経路つきで確認できます。

上限に達した階層でtoolsにAgentしか書いていないサブエージェントは、通常は起動が拒否されます。取り上げられたAgentを除くと、使えるツールがゼロになるためです。このエラーへの対処は「spawned with zero tools」の対処にまとめています。ネストの上限を引き上げるか、そのサブエージェントのtoolsに他のツールを最低1つ加えるかで解消します。

並列数の上限とは別の変数

サブエージェントの数に関わる変数は、段数のほかに2つあります。段数(縦方向)を絞っても、同時に動ける本数(横方向)は変わりません。

数字

名前の似た3つの変数と既定値

  • MAX_SUBAGENT_SPAWN_DEPTH

    3段

    入れ子で持てる階層の数

  • MAX_CONCURRENT_SUBAGENTS

    20本

    同時に実行中のサブエージェント数

  • MAX_TOOL_USE_CONCURRENCY

    10

    読み取り専用ツールとサブエージェントを合わせた並列実行数

それぞれ別の軸を制御します

同時実行数の上限は、既定の20本に達するとAgentツールが新しいサブエージェントを起動せず、Concurrent subagent limit reachedというエラーで失敗します。ultracodeが有効なセッションは、この上限の対象外です。/subtaskで自分が始めたフォークは枠を1つ使いますが、この上限では止まりません。終了済みのサブエージェントを再開した場合も新しい枠を使います。ただし上限は確認されないので、実行中の数が上限を超えることがあります。ワークフローのエージェントやエージェントチームのメンバーは、この枠ではなく各機能の別の上限に従います。詳細はCLAUDE_CODE_MAX_CONCURRENT_SUBAGENTSとはにあります。

Agent SDKでも同じ変数が効く

TypeScript・PythonいずれのAgent SDKでも、同じCLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHをenvオプション経由で渡して段数を制御できます。ここで述べるSDKの上限は、Claude Code v2.1.219以降を同梱するTypeScript SDK v0.3.219とPython SDK v0.2.127以降の挙動です。SDK側には支出上限(TypeScriptのmaxBudgetUsd、Pythonのmax_budget_usd)という別の歯止めもあります。上限に達すると新しいサブエージェントの起動が拒否され、動いているバックグラウンドのサブエージェントも止まります。到達時のエラーはBudget limit reached、結果の種別はerror_max_budget_usdです。

Claude Opus 5は以前のモデルよりサブエージェントへ委任しやすいため、深さ・同時実行数・支出の3つの上限は、Opus 5を使うクエリで特に効きます。組み合わせ方はAgent SDKのサブエージェント上限で扱っています。TypeScript SDKはenvで渡した値でサブプロセスの環境を置き換えるので、process.envを展開して渡します。Python SDKは継承した環境に統合します。

/subtaskのフォークがこの深さ制限とどう絡むかはClaude Codeのサブエージェント並列設計に書きました。

よくある質問

既定値の3に戻すにはどうすればよいか

settings.jsonのenvからCLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHの行を削除するか、シェルでunset CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTHを実行します。変数が存在しなければ、Claude Codeはバージョンに応じた既定値(v2.1.219以降なら3)を使います。値を書かずにおけば、既定値が変わったときも設定ファイルを直さず追従できます。

まとめ

入れ子を使う運用なら、まず手元のバージョンがv2.1.219以降かを確かめます。それより古いと、既定の段数も変更できるかどうかも違います。1つのサブエージェントだけ止めたいときは、変数ではなくtools側で絞るほうが他への影響を避けられます。環境変数全体の一覧はClaude Code環境変数リファレンスを参照してください。

この記事を共有:XはてブLinkedIn