目次
ブログ記事生成のフローを、/write-post スキルを実行する writer サブエージェントと、レビュー指摘を直す rewriter サブエージェントに分けて組んでいた。両者は中で /write-post を呼び、その内側でさらに planner や researcher といった専門サブエージェントを順に動かす想定だった。ところが writer を起動した瞬間、内側の呼び出しがすべて「そんなツールはない」で止まる。原因を追っていくと、サブエージェントの中からサブエージェントを呼ぶこと自体が公式に塞がれていた。
サブエージェントから別のサブエージェントは呼べない
結論から書くと、サブエージェントの内部から別のサブエージェントを起動する手段は用意されていない。Task(現在の表記では Agent)というツールはメインスレッドにだけ露出していて、サブエージェントが受け取るツール一覧からは黙って消える。tools: の指定で書き足しても結果は変わらない。
公式ドキュメントはこの制約を少なくとも3箇所で明示している。組み込みの Plan サブエージェントの説明では、メインから委譲する形を採る理由として「This prevents infinite nesting (subagents cannot spawn other subagents)」と書かれている[1]。tools: フィールドの解説では「This restriction only applies to agents running as the main thread with claude --agent. Subagents cannot spawn other subagents」とあり、Patterns セクションにも「Subagents cannot spawn other subagents. If your workflow requires nested delegation, use Skills or chain subagents from the main conversation」と再掲されている[1:1]。SDK 側のドキュメントも AgentDefinition の Note で「Subagents cannot spawn their own subagents. Don't include Agent in a subagent's tools array」と釘を刺している[2]。
設計意図は無限のネストを防ぐことだとはっきり書かれている。サブエージェントが孫サブエージェントを起こせると、再帰的にプロセスが膨らんで実行階層の見通しが悪くなる。指揮系統をメインスレッド1つに固定することで、誰がいつ何を起動したかをログから追える状態を保っている。
tools で明示しても黙って消される
ここで一番厄介なのは、サブエージェントの定義に tools: Task や tools: All tools と書いてもエラーが出ないことだ。実行時にランタイムが Agent ツールを静かに取り除くだけで、起動自体は成功する。サブエージェントは自分のツール一覧に Agent が無いとは思っていないので、いざ呼び出して初めて「そんなツールは無い」と返してくる。GitHub の Issue #61993 はこの挙動を「コントラクト不一致」と表現していて、フロントマターで宣言したツールセットと、実行時に渡されるツールセットがずれていることをバグとして報告している[3]。
実際にサブエージェントに渡るツール一覧はこんな顔をしている。Bash、Glob、Grep、LS、Read、Edit、Write、WebFetch、WebSearch 等は揃っているのに、Task/Agent だけがいない[4]。Issue #4182 で最初の報告者がぶつかった挙動も同じで、サブエージェントは「I don't have access to a 'Task' tool that would allow me to spawn sub-agents」と返してくる[4:1]。
Task と Agent は同じものを指す
検索すると Task と Agent が混在していて少し戸惑うが、これは Claude Code v2.1.63 でツール名がリネームされた名残だ。現行 SDK の tool_use ブロックは Agent を返すが、system:init の tools 配列や permission_denials の tool_name は今も Task が出てくる。仕様を調べるときは両方をマッチさせる必要があるが、指している中身は同じ「サブエージェント起動プリミティブ」だと考えていい。
ラッパーサブエージェントを作ろうとして詰む流れ
このネスト不可の制約は、複数のサブエージェントを連携させようとした瞬間に表面化する。自分のリポジトリでは、新規記事を1本仕上げるための writer と、レビュー指摘を反映する rewriter という2種類のラッパーサブエージェントを置いていた。writer の中で /write-post スキルを呼び、スキルが内部で planner・researcher・outliner・drafter・reviewer を Agent ツール経由で順番に起動する設計だった。
---
name: writer
description: 新規記事を1本書き上げるための subagent。/write-post スキルを実行する役割を担い、ネタ選定から執筆・commit・push までを subagent 側で完結させる。
tools: Read, Edit, Write, Bash, WebSearch, WebFetch
---
意図としては、メインスレッドからは「ブログ記事を書いて」「指摘を反映して」の2種類だけを叩けば済むようにしたかった。生成系の長い対話履歴をメインに残さず、ラッパー側に閉じ込めたい狙いもあった。
スキル単体は動くがサブエージェント呼び出しが詰む
サブエージェントの中でもスキル(SKILL.md)を読み込んで実行すること自体はできる。ところがスキルの定義の中で subagent_type: planner を指定して Agent ツールを呼ぼうとした瞬間、ツールが存在しないとして全部止まる。スキルは単なるマークダウン文書なので、内部で何のツールを使うかは実行コンテキスト側のツールセットに依存する。サブエージェントのコンテキストには Agent ツールが無いので、スキルがいくら呼び出しを書いていても物理的に発火しない。
GitHub の Issue #19077 にも同じ構造の minimal reproducer が載っている。.claude/agents/parent.md で tools: Write, Task と明示し、/test-nested-task 経由で parent サブエージェントを起動した上で child サブエージェントの起動を試みているが、parent が「Task ツールが無い」と報告するか、無理に進めて OOM でクラッシュするか、parent が委譲を諦めて自分で実行するかのいずれかになる[5]。
description で促しても呼べないものは呼べない
サブエージェントの description は、メインスレッドがどのサブエージェントに委譲するかを判断するために使われる。「他のサブエージェントを順番に呼び出す」と書いておけば気を利かせて呼んでくれるのではないか、と試したくなるが、これは効かない。委譲判断に使われるのは外側のメインスレッドだけで、サブエージェント内部のツール集合とは別系統だからだ。description で促しても、内側のコンテキストには Agent ツールが居ない以上、呼び出しコマンドを生成しても実行できない。
メインに集約してチェーン実行に組み替える
回避策ははっきりしている。指揮系統をメインスレッドに戻し、スキル自体をメインから直接実行する形に組み替えればいい。ラッパーサブエージェントを介さず、/write-post をメインで叩くと、スキルはメインのツールセット(Agent を含む)を使えるので、planner から reviewer までを順に呼び出せる。これが自分のリポジトリで採用した形で、コミット 4fab026 では writer と rewriter のラッパーを廃止して、メインがスキルを直接実行する設計に切り替えた。
スキルの内部はこういう書き方になる。
### Step 1: planner subagent を呼ぶ
Agent ツールで `subagent_type: planner` を指定して呼ぶ。
スキルから見れば、Agent ツールが手元にあるかどうかが全てで、誰がスキルを実行したかは関係ない。メインから直接呼ばれているうちは Agent が使えるので、planner / researcher / outliner / drafter / reviewer を順番に呼んで、各サブエージェントの出力を _posts/<permalink>.md のような中間ファイル経由で受け渡せばいい。
公式が示す回避策は3択
公式ドキュメントは「ネストしたい場合の選択肢」を3つ示している。1つ目は Skills を使う方法で、サブエージェントの代わりにスキルで段階を区切る。2つ目はメインから複数のサブエージェントをチェーンで呼ぶ方法で、メインが各段階の入出力を仲介する。3つ目は将来的なオーケストレーター用サブエージェントタイプの提案で、Issue #46424 で議論されているが、現時点では実装されていない[6]。実用に使えるのは前者2つで、自分のケースではスキルとメインチェーンを組み合わせて回している。
TeamCreate や SendMessage は代替にならない
サブエージェントには TeamCreate や SendMessage、TaskOutput、TaskStop といった team 系のツールが渡っている。一見すると別のサブエージェントを起こせそうに見えるが、これは別物だ。Issue #61993 の議論でも触れられているとおり、team 系は永続的な「teammate」を作って複数ターンにまたがるコンテキストを共有する仕組みで、Agent ツールが提供する「呼び出すたびに使い捨てのコンテキストで起動する」エフェメラルな spawn とは性質が違う。worker のステートレス性が前提のワークフローに team 系を持ち込むと、ターン間で文脈が漏れ込んで不安定になる。
ネスト制限に当たって team 系に飛びつきたくなる気持ちは分かるが、エフェメラルな子サブエージェントの代替としては機能しない。スキルとメインチェーンに素直に戻したほうが結果的に短い距離で動く。
サブエージェントは並列に動く手足であって、入れ子になった指揮系統を持たない。この前提さえ掴んでおけば、似たエラーに当たったときに「指揮系統をどこに置くか」を最初に確認すれば原因がほぼ自動的に絞り込める。スキルとメインスレッドこそが指揮を執れる側で、サブエージェントは1階層分の専門作業を任される側、という役割分担に落とすのが Claude Code の現状に一番素直な設計になる。
Create custom subagents - Claude Code Docs (2026-05-27 アクセス) ↩︎ ↩︎
Subagents in the SDK - Claude API Docs (2026-05-27 アクセス) ↩︎
Sub-agents cannot spawn other sub-agents: Task/Agent primitive not exposed in nested contexts #61993 (2026-05-27 アクセス) ↩︎
Sub-Agent Task Tool Not Exposed When Launching Nested Agents #4182 (2026-05-27 アクセス) ↩︎ ↩︎
[BUG] Sub-agents can't create sub-sub-agents, even with Task tool access #19077 (2026-05-27 アクセス) ↩︎
[BUG] Agent tool not available to sub-agents — prevents orchestrator pattern #46424 (2026-05-27 アクセス) ↩︎
