0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Claude Codeの「壊れたループ防止」、実装まで覗いたら効いていた

0
Last updated at Posted at 2026-07-19

はじめに

Claude Codeにサブエージェントを何個も並列で投げたら、いつの間にか止まらなくなった——そんな経験がある人は少なくないはずだ。委任が委任を呼ぶループや、答えが出ないまま検索を繰り返すWebSearchは、エージェント型ツールが避けて通れない設計課題である。

Claude Codeの週次ダイジェスト「Week 29」(2026年7月13日〜17日)に、この課題への対策と読める一文が載っていた。WebSearchとsubagentの生成数にセッション単位の上限を設ける、というものだ。ただし、ダイジェストの一文はあくまで説明文であり、それが実際にインストール済みのバイナリへどう実装されているかまでは読み取れない。この記事では、Claude Codeが実際に動いているクラウド実行環境の中から、公式ドキュメントの記述とインストール済みCLIバイナリの中身の両方を確認する。

TL;DR

  • Week 29(v2.1.207〜v2.1.212)で、WebSearch呼び出し回数とsubagent生成数にセッション単位の上限(デフォルト各200)が追加された
  • claude auto-mode reset という新規サブコマンドが実機に存在し、--yes で確認プロンプトを省略できることを --help で確認した
  • --forward-subagent-text フラグと対応する環境変数も実機の --help に存在した
  • インストール済みCLIバイナリ(/opt/claude-code/bin/claude)を strings で覗くと、上限到達時にモデルへ実際に渡される警告文まで文字列として埋め込まれていた
  • MCPツールコールの自動バックグラウンド化(2分超で自動移行)は CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS としてバイナリ内に実在を確認した

前提環境

  • 実行環境: Claude Code on the web(クラウド実行環境・コンテナ)
  • CLI: Claude Code CLI 2.1.214(claude --version で確認)
  • バイナリ: /opt/claude-code/bin/claude(ELF 64-bit LSB executable, x86-64, 265,210,864 バイト)

Week 29で追加された暴走防止ガードレール

公式の週次ダイジェストには、以下の記述がある。

Session-wide caps stop runaway loops: WebSearch calls and subagent spawns each default to 200, tunable with CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION and CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION
Week 29 · July 13–17, 2026

同じダイジェストには、MCPツールコールの扱いについても記載がある。

MCP tool calls that run longer than two minutes now move to the background automatically so the session stays usable; tune or disable the threshold with CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS
— 同上

さらに、--forward-subagent-text フラグと claude auto-mode reset コマンドも同じ週に追加されたと書かれている。

--forward-subagent-text and CLAUDE_CODE_FORWARD_SUBAGENT_TEXT include subagent text and thinking blocks in stream-json output

New claude auto-mode reset restores the default auto-mode configuration, and --yes skips the confirmation prompt
— 同上

ダイジェストは1文ずつの短い紹介にとどまり、上限に達したときに実際に何が起きるのか、モデルにはどう伝わるのかまでは書かれていない。ここから先は、この文書の記述がインストール済みのバイナリの中でどう形になっているかを実機で確認する。

実機検証1: バージョンとサブコマンドの存在確認

まず、このクラウド環境にインストールされているCLIのバージョンを確認する。

$ claude --version
2.1.214 (Claude Code)

Week 29の対象バージョン範囲(v2.1.207〜v2.1.212)より新しく、この機能追加を含んでいる。次に claude auto-mode のサブコマンド一覧を見る。

$ claude auto-mode --help
Usage: claude auto-mode [options] [command]

Inspect or reset auto mode classifier configuration

Commands:
  config              Print the effective auto mode config as JSON
  critique [options]  Get AI feedback on your custom auto mode rules
  defaults [options]  Print the default auto mode environment, allow,
                       soft_deny, and hard_deny rules as JSON
  reset [options]     Reset auto mode configuration to the shipped
                       defaults by removing the autoMode section from
                       your user settings file

reset サブコマンドが実在する。さらに1段掘って確認する。

$ claude auto-mode reset --help
Usage: claude auto-mode reset [options]

Reset auto mode configuration to the shipped defaults by removing the
autoMode section from your user settings file

Options:
  -h, --help  Display help for command
  -y, --yes   Skip the confirmation prompt

ダイジェストが書いていた --yes フラグ(短縮形 -y)もそのまま存在した。同様に claude --helpforward-subagent で絞り込むと、--forward-subagent-text フラグも見つかる。

$ claude --help | grep -i forward
  --forward-subagent-text               Forward subagent text and thinking

ここまでは、ダイジェストの記述とCLIの --help 出力が一致することの確認にとどまる。--help は開発者が「ユーザーに見せたい説明」を書く場所であり、実際の制御ロジックが同じ文言で動いているとは限らない。次の段階として、動作の実体であるバイナリそのものを見る。

実機検証2: バイナリを strings で覗く

CLIの実体は /opt/claude-code/bin/claude という単一のELFバイナリだ(Node.jsをバンドルしたスタンドアロン実行ファイル)。

$ file /opt/claude-code/bin/claude
/opt/claude-code/bin/claude: ELF 64-bit LSB executable, x86-64, version 1
(SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 3.2.0, BuildID[sha1]=788318c9115981678ca1a25f40cdb3b39df71403,
not stripped

strings コマンドでバイナリ中の可読文字列を抜き出し、4つの環境変数名で絞り込むと、いずれも実在した。

$ strings /opt/claude-code/bin/claude | grep -oE \
  "CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION|CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION|CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS|CLAUDE_CODE_FORWARD_SUBAGENT_TEXT" \
  | sort | uniq -c
      3 CLAUDE_CODE_FORWARD_SUBAGENT_TEXT
      5 CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION
      5 CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION
      3 CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS

4つの環境変数名すべてが、合計16箇所の出現として実在した。1つの変数につき複数回出現するのは、環境変数の読み取り箇所と、設定スキーマの定義箇所とで別々にリテラルが埋め込まれているためだと考えられる。

ここで見つかった中身は、環境変数名の存在確認だけでは終わらなかった。上限に到達したとき モデル自身に渡される文言そのもの が、そのままバイナリ内の文字列として見つかったのだ。

Web search was not performed: this session has used its web search
budget (${l} of ${a} WebSearch calls). Continue with the information
already gathered instead of issuing more searches. If more searches
are genuinely needed, ask the user to raise
CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION.
Subagent spawn limit reached (${Ye} of ${qe} agents spawned). Complete
the remaining work directly with your tools instead of spawning more
agents. If more agents are genuinely needed, ask the user to raise
CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION.

${l}${a}${Ye}${qe} はminify後の変数名で、実行時には「現在の使用回数」「上限値」に置き換わるテンプレートリテラルだと分かる。subagent側のコードには subagent_launch / subagent_count_cap というイベント名や、getTotalAgentSpawns() という関数呼び出しも隣接して見つかった。これは、上限判定が単なるドキュメント上の説明ではなく、スポーン数を実際にカウントする関数と、それを超えたら例外を投げる分岐として実装されていることを示している。

ガードレール一覧

実機検証と公式ドキュメントの記述を突き合わせた結果を表にまとめる。

ガードレール 環境変数 デフォルト 実装の確認方法
WebSearch呼び出し上限 CLAUDE_CODE_MAX_WEB_SEARCHES_PER_SESSION 200回/セッション バイナリ内の警告文言を実機確認
subagent生成上限 CLAUDE_CODE_MAX_SUBAGENTS_PER_SESSION 200個/セッション(/clear でリセット) バイナリ内の警告文言・subagent_count_cap を実機確認
MCPツールコール自動バックグラウンド化 CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS 2分超で自動移行 バイナリ内の環境変数名を実機確認(挙動は公式ドキュメント)
subagentのテキスト・思考をstream-json出力に含める CLAUDE_CODE_FORWARD_SUBAGENT_TEXT / --forward-subagent-text オフ --help とバイナリ内の代入式(`we=R

CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS の「2分」というデフォルト値そのものはバイナリの文字列からは特定できておらず、公式ダイジェストの記述に基づく二次情報である。一方で、環境変数名自体がバイナリの型定義(Pe.int() というスキーマバリデータ)と一緒に埋め込まれていることは確認できたので、少なくとも「ドキュメントにだけ書かれていて実装が追いついていない設定」ではないと判断できる。

著者視点の発見ポイント

このバイナリを覗く前は、「ダイジェストの1行はマーケティング的な要約で、実際の制御はもっと粗い実装かもしれない」という予想を持っていた。実際には、上限到達時にモデルへ渡すメッセージが「単に止める」のではなく「すでに集めた情報で続行しろ」「ユーザーに上限を上げてもらうよう頼め」という 次の行動を明示する指示文 として設計されていた点が見つかった。これは、単なるレート制限ではなく、暴走を止めた後にエージェントが立ち往生しないようにする設計判断が入っていることを意味する。

もう1つの発見は、Claude Code CLIが単一の263MB超のELFバイナリとして配布されている点だ。Node.jsランタイムごとバンドルされているため、strings のような素朴なUnixツールだけでソースコードなしに実装の手がかりを取り出せる。ドキュメントの記述を裏取りする手段として、公式ソースの検索だけでなく、手元のバイナリを直接読むという選択肢がある。

まとめ

Week 29のダイジェストにあった「WebSearchとsubagentにセッション単位の上限を追加した」という1文は、実機のCLIバイナリを strings で覗くことで、環境変数名だけでなく上限到達時にモデルへ渡される警告文言・内部イベント名・カウント関数まで裏取りできた。ドキュメントの記述と実装が一致しているかを確かめたいときは、--help の出力を読むだけでなく、インストール済みバイナリの文字列を直接検索するのも有効な手段だ。次にClaude Codeの新機能がダイジェストに載ったときは、同じ方法で実装まで潜ってみるとよい。

関連記事

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?