Claude Code に指示を出して Enter を押すと、しばらく考えた末に答えが返ってきます。この「待っている間」に内部で何が起きているのか。実は1回のやり取りは、API 呼び出しとツール実行を何度も往復するループになっています。入力から生成完了までの流れを段階ごとに追います。
全体像
ユーザー入力
│
▼
[1] 入力の前処理 /コマンド・スキル・@ファイルを解決 / UserPromptSubmit フック
│
▼
[2] コンテキスト組立 system prompt + 会話履歴 + system-reminder
│
▼
[3] API リクエスト Anthropic API へストリーミング送信(生成待ち)
│
▼
[4] モデルの応答 thinking / text / tool_use を生成
│
▼
[5] ツール実行ループ 権限チェック → PreToolUse → 実行 → PostToolUse
│ 結果を tool_result にして [3] へ戻る(エージェントループ)
│
▼
[6] 停止 tool_use のない応答で終了 / Stop フック → Markdown 描画
核心は [3]→[5]→[3] のループです。ユーザーから見た「1回の応答」は、このループが複数周した結果であることがほとんどです。
[1] 入力の前処理
入力はまず展開・解決されます。/ で始まるスラッシュコマンド、スキル、@ファイル名 の参照がここで実際の内容に置き換わります。
この直前に UserPromptSubmit フックが発火します。フックとは、特定のタイミングで自動実行されるユーザー定義の処理のことです。このフックは additionalContext フィールドを返すことで、モデルに渡す前のプロンプトへ追加情報を差し込めます(例: 現在時刻や社内ルールの注入)。
[2] コンテキストの組み立て
モデルに送る入力一式を組み立てます。順序はおおよそ次の通りです。
- system prompt — 環境情報(OS・作業ディレクトリ)、
CLAUDE.mdのメモリ、利用可能なツール定義 - 会話履歴 — これまでのやり取り
- system-reminder — システムレベルで差し込まれる補足情報
ここで「何をどれだけ積むか」が、後述するコンテキストウィンドウ(扱えるトークン量の上限)の消費を決めます。
[3] API リクエストと生成
組み立てた入力を Anthropic API へストリーミングで送ります。モデルが応答を生成している間が、体感上の「考えている時間」です。スピナーの横で動詞がくるくる変わるのもこの区間です(この演出は公式には文書化されていない UI 実装)。
[4] モデルの応答——thinking・text・tool_use
モデルは 3 種類のブロックを生成し得ます。
- thinking — 拡張思考(extended thinking)による内部推論
- text — ユーザーに見せる本文
- tool_use — ツールを呼ぶ指示(どのツールに何を渡すか)
注意したいのは、これらの順序は固定ではない点です。
| モデルの種類 | thinking の出方 |
|---|---|
| Adaptive reasoning(Opus 4.8 / 4.7) | メッセージ内の任意の位置に複数回現れ、tool_use が思考の合間にも挟まる |
| 固定 thinking budget(Opus 4.6 / Sonnet 4.6) | thinking が最初にまとまり、その後 text + tool_use が続く |
「まず考えてから動く」という単純な直線ではなく、新しいモデルでは考えながら道具を使う挙動になっています。
[5] エージェントループ
応答に tool_use が含まれていれば、各ツールについて次の手順を踏みます。
- 権限チェック —
deny → ask → allowの順で評価し、拒否(deny)が最優先。現在の権限モードも影響します。 - PreToolUse フック — 実行前に発火。
blockで中止したり、modifiedInputで入力を書き換えたりできます。 - ツール実行 — Read / Edit / Bash などを実行。たとえば Bash はデフォルトでタイムアウト 2 分(最大 10 分まで設定可)。
- PostToolUse フック — 実行直後に発火。失敗時用の
PostToolUseFailureもあります。
実行結果は tool_result として履歴に追加され、それを持って [3] に戻り、再びモデルを呼びます。モデルは結果を見て次の手(さらにツールを呼ぶ/本文を書く)を決める——この往復がエージェントループです。独立した複数のツールは並列実行され得ます。
「ファイルを探して直す」という一見単純な指示も、内部では grep → 結果を見る → 該当箇所を読む → 編集する、という何周ものループに展開されている。
権限モードには default / acceptEdits / plan / auto / bypassPermissions / dontAsk があり、[5]-1 の分岐の厳しさを切り替えます。
[6] 停止とフックのライフサイクル
モデルが tool_use を含まない応答を返したら、そのターンは終了です。Stop フックが発火し、最終メッセージが Markdown として描画されます。
フックはこのフロー全体に散りばめられた差し込み口です。ターン単位の UserPromptSubmit / Stop、ツール単位の PreToolUse / PostToolUse、セッション単位の SessionStart / SessionEnd、サブエージェントの SubagentStart / SubagentStop、コンパクション前後の PreCompact / PostCompact など、多数のイベントが定義されています。
コンテキストが埋まったら
ループを重ねるほど履歴は伸び、コンテキストウィンドウを消費します。上限に近づくと 自動コンパクション(これまでのやり取りの要約)が走り、要約後の履歴で [2] の組み立てが続きます。前後で PreCompact / PostCompact フックが発火します。あわせてプロンプトキャッシュが効いており、同じ前半部分を送り直すコストと待ち時間を抑えています。
まとめ
- Claude Code の1ターンは「入力→出力」の直線ではなく、API 呼び出しとツール実行を往復するエージェントループ。
- 各段階(入力前・ツール前後・停止・コンパクション前後など)にフックの差し込み口があり、自動処理を挟める。
- 権限チェックは deny 最優先、新しいモデルは 考えながらツールを使う(thinking の順序は固定でない)。
- 履歴が膨らむと自動コンパクションとキャッシュが効き、ループを続けられるようになっている。