あなたのAIエージェントが、勝手に「中間管理職」を量産していたらどうしますか?
先日、Redditの r/ClaudeAI で興味深い投稿が話題になりました。
Claude CodeでSonnet 5を使ったところ、サブエージェントが次々と自分のサブエージェントを生成したというのです。
しかも、同じタスクを延々と委譲し続けていました。
この記事では、何が起きたのかを紹介します。
そして、なぜ起きるのか、どう防ぐのかを解説します。
何が起きたのか
投稿者が報告した状況は、こうです。
ある情報を探すよう依頼しました。
すると、Sonnet 5は自分で処理せず、「Find(探す)」というタスクを持つサブエージェントを起動しました。
ここまでは普通の挙動です。
しかし、問題はその先でした。
そのサブエージェントはタスクを完了させませんでした。
代わりに、「Search(検索する)」というほぼ同じタスクのサブエージェントをさらに生成したのです。
すると、そのサブエージェントもまた「Locate(見つける)」という別のサブエージェントを起動しました。
要するに、サブエージェントがサブエージェントを生み、それがまたサブエージェントを生む。
中身は、ずっと同じタスクの繰り返しです。
投稿者は最終的にすべてを停止しました。
そして、「サブエージェントを一切起動するな」と明示的に指示するしかありませんでした。
コメント欄には、同様の報告が相次ぎました。
中でも強烈だったのが、次の報告です。
10分間放置しただけで66個のエージェントが起動し、200万トークンを消費したというのです。
結果として、5時間分の利用枠を使い切ってしまいました。
別のユーザーからは、こんな報告もありました。
複数のサブエージェントが同じコードを同時に触ってしまい、片方の変更をもう片方が打ち消したそうです。
なぜ委譲の連鎖が起きるのか
コメント欄では、原因についての考察も進みました。
有力な説は2つあります。
引き金はツールの説明文
あるユーザーは、Claude Codeのエージェント起動ツールの説明文に注目しました。
そこには、次のような趣旨の記述があります。
タスクが利用可能なエージェントタイプに合致する場合や、複数ファイルにまたがる調査が必要な場合は、このツールで委譲せよ
Sonnet 5は、この指示に文字通り従っただけなのかもしれません。
「探し物」というタスクは、常にこの条件に合致します。
そのため、階層のどこにいても「委譲すべき」と判断してしまうわけです。
大きなモデルなら、意図を汲んで加減します。
しかし、Sonnetは指示を杓子定規に実行する傾向がある、という指摘もありました。
連鎖する理由は「深さの信号」の欠如
引き金がツール説明文だとして、なぜ止まらずに連鎖するのか。
この点について、技術的に踏み込んだ考察がありました。
サブエージェントには、自分がすでに「入れ子の中」にいることを知らせる信号が渡っていない、というのです。
サブエージェントは、親と同じツールリスト、同じ指示、同じ文脈を受け継ぎます。
そのため、各サブエージェントは親とまったく同じ判断を下すのです。
つまり、「このタスクは委譲すべきだ」と。
さらに、バイナリを解析したというユーザーからの報告もありました。
深さを示す仕組み自体は内部に存在するものの、設定と参照が正しく機能していないそうです。
真偽は公式に確認されていません。
しかし、観測された挙動とは整合する話です。
一方で、外から観測できる手がかりが1つだけあります。
PreToolUseフックに渡される入力の agent_id です。
この値は、親エージェントの中で動いているときにだけ存在します。
そして、これが後述する対策の鍵になります。
コミュニティで共有された3つの対策
コメント欄では、実践的な対策が3つ出そろいました。
強度の順に紹介します。
対策1:フックで物理的にブロックする
最も確実な方法です。
PreToolUseフックで、エージェント起動ツールへの呼び出しを監視します。
そして、入力に agent_id が含まれていたら拒否するのです。
agent_id があるということは、サブエージェントからの呼び出しを意味するからです。
あるユーザーが共有した設定は、次のような仕組みでした。
Node.jsのワンライナーで標準入力のJSONを解析し、agent_id の存在を検出します。
検出したら permissionDecision を deny にして、「入れ子のエージェント生成はブロックされています」という理由を返します。
これなら、モデルがどう判断しようと関係ありません。
2階層目以降は、物理的に起動できなくなります。
対策2:サブエージェントからTaskツールを取り除く
サブエージェントの定義から、エージェント起動用のツール自体を外してしまう方法です。
ツールが手元になければ、委譲しようがありません。
あわせて、こんな助言もありました。
「汎用エージェント」ではなく、目的別のエージェントを定義しておくと良いそうです。
例えば、コーディング用、調査用、ドキュメント用といった具合です。
役割が明確になるため、暴走しにくくなります。
対策3:プロンプトで釘を刺す
一番手軽な方法です。
サブエージェントへの指示に、一文加えるだけです。
「あなたは作業者です。サブエージェントを生成しないでください」と。
関連して、興味深い落とし穴の報告もありました。
ベースの指示に「バックグラウンドでサブエージェントを活用せよ」と書いていたケースです。
この場合、その指示がサブエージェントにもそのまま受け継がれます。
その結果、連鎖の原因になっていたのです。
この指示をメインの文脈にだけ注入するよう変えたところ、問題は解消したそうです。
また、別の解決策もありました。
「入れ子は1階層まで」というルールをCLAUDE.mdに明記して、収束させたという報告です。
フックほどの強制力はありません。
しかし、まず試す価値はあります。
トークンは誰のために燃えているのか
コメント欄で目立ったのは、技術的な考察だけではありません。
「会社は中間管理職を減らそうと苦労しているのに、AIは自ら中間管理職を導入し始めた」という皮肉が飛び交いました。
仕事を丸投げするだけのエージェントの連鎖は、確かに組織の縮図に見えます。
一方で、笑えない指摘もあります。
委譲が1回増えるたびに、トークン消費は膨らみます。
この挙動は課金を増やすため、意図的な仕様ではないかと疑う声も少なくありませんでした。
真相は分かりません。
しかし、前述の200万トークンの事例を見れば、疑いたくなる気持ちも理解できます。
私の見立てでは、これは陰謀ではなく設計の詰めの甘さでしょう。
ツール説明文が委譲を強く推奨している。
そして、深さの信号が機能していない。
この2つが揃えば、連鎖は必然です。
停止条件のない委譲ツールを持たせれば、委譲が最適解になってしまいます。
ある指摘の通り、これはモデル固有のバグというより、エージェント設計一般の教訓と捉えるべきです。
まとめ
Redditで報告された「サブエージェントの無限委譲」問題を整理しました。
原因は、2つの要素の組み合わせにあると考えられています。
委譲を促すツール説明文と、自分の階層を知る手段を持たないサブエージェントです。
対策は3段階です。
- フックで agent_id を検出して物理的にブロックする
- サブエージェントからTaskツールを外す
- プロンプトで明示的に禁止する
確実性を求めるならフック、手軽さならプロンプトです。
Claude Codeでサブエージェントを活用している方は、一度エージェントの起動ログを確認してみてください。
あなたの知らないところで、中間管理職が増殖しているかもしれません。
トークンの請求書が届く前に、停止条件を設計しておきましょう。
