10分で200万トークンが消えた:Claude Code「サブエージェント無限増殖」の正体と3つの対策

10分で200万トークンが消えた:Claude Code「サブエージェント無限増殖」の正体と3つの対策 AI

あなたの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でサブエージェントを活用している方は、一度エージェントの起動ログを確認してみてください。
あなたの知らないところで、中間管理職が増殖しているかもしれません。
トークンの請求書が届く前に、停止条件を設計しておきましょう。

タイトルとURLをコピーしました