【ITニュース解説】Claude Code Agent Loop Deep Dive (4): From a Finished Answer to the Seven Meanings of stop_reason
2026年10月13日に「Dev.to」が公開したITニュース「Claude Code Agent Loop Deep Dive (4): From a Finished Answer to the Seven Meanings of stop_reason」について初心者にもわかりやすく解説しています。
ITニュース概要
Claudeエージェントは、LLMの応答にツール使用が含まれるかでループを継続するか判断する。出力制限やコンテキスト超過時は回復を試み、拒否や最大実行回数超過で停止する。停止理由は多様で、応答内容やフックも考慮し安全に動作する。
ITニュース解説
Claude Code Agentは、人工知能が複雑なタスクを実行する際に、一連の処理を繰り返す「ループ」の仕組みを利用する。このループは、ユーザーからの要求に応じて適切なツールを実行したり、情報収集を行ったりすることを目的としている。今回の解説では、このループがどのようにして停止するのか、そしてどのような理由で停止するのかを詳しく説明する。
まず、ループの基本的な形は「ツールを使う必要がある限り続ける」というものである。つまり、人工知能が何らかのツールを使うことを決定すればループは継続し、ツールを使う必要がなければループは停止するという単純な考え方である。しかし、実際のシステムはこれほど単純ではなく、さまざまな停止理由とそれに応じた複雑な処理が存在する。
Claude Codeのモデルからの応答には、必ず「stop_reason」という情報が含まれる。これは、モデルがどのような理由で処理を停止したかを示すもので、全部で7種類ある。具体的には、「end_turn」(モデルが応答を完了し、ユーザーに制御を戻す)、「tool_use」(モデルがツールの使用を要求した)、「max_tokens」(出力トークン数の上限に達した)、「stop_sequence」(特定の停止シーケンスに一致した)、「refusal」(安全上の理由で要求を拒否した)、「pause_turn」(現在のターンを一時停止し、後で再開することを要求した)、「model_context_window_exceeded」(入力がモデルのコンテキストウィンドウの制限を超えた)といった理由がある。
しかし、驚くべきことに、Claude Codeはこの「stop_reason」だけでループの停止を決定しない。直感的には、「stop_reason」が「end_turn」ならループを停止し、「tool_use」ならツールを実行し続けると考えるだろう。しかし、実際にはそうではない。Claude Codeは、モデルの応答内容そのもの、具体的には「応答内容にツールの使用を指示するブロックが含まれているか」を検査することで、ループを継続するか停止するかを判断する。なぜなら、「stop_reason」が「tool_use」と報告されていても実際の応答内容にツールの使用指示がない場合や、逆に「end_turn」と報告されていてもツールの使用指示が含まれている場合があるためである。つまり、応答内容こそが真実の源であり、「stop_reason」は主にエラーや回復時のユーザーへの説明のために使われる。
では、各「stop_reason」がどのように扱われるかを見ていこう。「end_turn」の場合、応答内容にツールの使用指示がなければ、ループは正常に完了し、ユーザーに制御が戻る。「tool_use」の場合も、「stop_reason」だけに依存せず、応答内容にツールの使用指示があればツールが実行され、その結果が追加されてから次のモデル呼び出しが行われる。
特に重要なのは、エラーと見なされる状況からの回復処理である。「max_tokens」(出力トークン数の上限に達した)の場合、システムはすぐにループを停止させない。まず、出力トークン数の上限を増やして再試行を試みる。それでも上限に達するようであれば、「[出力トークン制限に達しました、続行してください]」のようなメッセージをユーザーメッセージとして追加し、モデルに中断された作業を明示的に続行させるように促す。この回復試行は最大3回まで行われ、それでも解決しない場合にのみユーザーに問題が通知される。これは、単なる完了ではなく、未完了の作業として回復可能であれば続行すべきだという考え方に基づいている。
同様に、「model_context_window_exceeded」(入力がモデルのコンテキストウィンドウの制限を超えた)の場合も、すぐに停止せず、履歴を圧縮して再試行する回復パスに入る。これもまた、問題が発生しても可能な限りシステムが自動で修正し、処理を続行しようとする設計思想の表れである。
一方で、「refusal」(安全上の理由での拒否)の場合は異なり、Claude Codeはエラーメッセージを作成し、自動的な再試行は行わずにループを停止する。モデルが意図的に拒否した要求は、同じ要求を再発行しても解決する可能性が低いと判断されるためである。
「stop_sequence」(特定の停止シーケンスに一致した)は、Claude Codeがカスタムの停止シーケンスを通常設定しないため、あまり使用されない。これは応答内容の検査へと流れ込み、通常はツールの使用指示がないためターンが完了する。「pause_turn」(現在のターンを一時停止し、後で再開)については、分析されたバージョンでは専用の処理経路が実装されておらず、未対応の状態である。Claude Codeのループは通常、数回の呼び出しで完了することが多いため、この機能の必要性が低かった可能性がある。
このように、エラーと見なされる状況が単なる終了信号ではなく、回復を促すトリガーとして機能することが、Claude Codeの設計における重要な原則である。トークン制限の超過、コンテキストのオーバーフロー、ネットワーク障害など、システムが修復できるエラーは可能な限り自動で修復し、真に回復不能な障害のみをユーザーに伝えることを目的としている。
しかし、無限に回復処理を繰り返す可能性も考慮されている。例えば、モデルが際限なくツールを要求したり、回復処理が何度も再発したりするケースである。これを防ぐために、Claude Codeには「maxTurns」という強力な安全装置が備わっている。これは、ユーザーからの単一の要求に対するモデル呼び出しの回数をカウントするもので、このカウントが設定された上限を超えると、システムは強制的にループを終了させる。この場合、メッセージ履歴に「[max_turns_reached]」が追加され、ユーザーにはループが安全制限によって停止されたことが明確に示される。これにより、監督がない状態でもエージェントの実行が無限ループに陥ることを防ぐ。
さらに、ループがツールの使用指示がなく、通常の完了経路に進もうとしている場合でも、最後に「Stop hook」という最終的なゲートが存在する。これは、ループが終了する直前に実行されるフック(特定の処理を差し込む仕組み)であり、もし「Stop hook」が「ブロック」を返した場合、ループは終了を許されず、もう一度処理を繰り返す必要がある。これは、「テストが実行されるまで終了しない」とか「関連する変更がコミットされるまで終了しない」といった、特定の条件が満たされるまで処理を継続させるようなポリシーを実現するために使用される。
したがって、Claude Code Agentのループが真に完了し、ユーザーに制御が戻るためには、以下の3つの条件を全てクリアする必要がある。
- 応答内容にツールの使用指示ブロックが含まれていないこと。
- 「stop_reason」が回復を必要とするものでないこと。
- 「Stop hook」が完了をブロックしないこと。
これらの仕組みを総合すると、モデルからの応答ごとに、まずツールの使用指示があるかを確認し、なければ「max_tokens」や「model_context_window_exceeded」などの回復可能な停止理由を処理する。次に「refusal」のような強制終了理由を処理し、最終的に「maxTurns」の安全装置や「Stop hook」の最終チェックを通過して初めて、ループが完了するという複雑な意思決定プロセスで成り立っている。この一連の流れにより、Claude Code Agentは柔軟かつ安全に、与えられたタスクを遂行することが可能になるのである。