CLAUDE_CODE_MAX_TURNSとは — セッションのターン数を上限で止める環境変数
CLAUDE_CODE_MAX_TURNSは非対話実行のターン数に上限を設ける環境変数です。--max-turnsとの優先順位、値の検証、金額・時間の上限との使い分けをまとめます。
CLAUDE_CODE_MAX_TURNS は、Claudeが自律的に応答とツール実行を繰り返す「ターン」の回数に上限をかける環境変数です。明示的な上限が渡されなかったときの既定値として働き、CLIフラグの --max-turns と同じ効果を持ちます。上限に達するとClaude Codeはエラーで終了し、暴走した自動実行がAPI呼び出しを無限に重ねる事態を防ぎます。
CLAUDE_CODE_MAX_TURNSが決めるもの
この変数の役割は1つで、Claudeが1回のやり取りのなかで応答・ツール呼び出しを重ねる回数の天井を決めます。数値を指定しなければターン数に上限はなく、Claudeは目的を達成するまで(あるいはコンテキストが尽きるまで)ツールを使い続けます。
--max-turns フラグを毎回のコマンドに付けるかわりに、この環境変数へ既定値を1つ入れておけば、フラグを省略したすべての実行に同じ上限がかかります。両方を指定した場合は --max-turns が優先されます。環境変数はあくまで「フラグを渡さなかったときの既定値」という位置付けです。
上限そのものを外したい場合は、変数を削除するかフラグを付けずに実行します。数値を書き換えて上限を緩めるのではなく、変数の有無で「上限あり/なし」を切り替える設計です。
設定のしかた
シェルの環境変数として渡すのが基本です。
export CLAUDE_CODE_MAX_TURNS=10
claude -p "リポジトリ内のTODOコメントを一覧化して"1回だけ上限を変えたいときは、コマンドの前に置く形でも渡せます。
CLAUDE_CODE_MAX_TURNS=5 claude -p "テストを実行して失敗を修正して"同じ上限を毎回付けたいだけなら、フラグを直接書く方法もあります。挙動は環境変数と同じで、上限に達すればエラー終了します。
claude -p --max-turns 3 "query"チームや実行環境をまたいで固定値を共有したい場合は、settings.json の env キーに書く方法もあります。この形にすると、その設定ファイルを読み込むすべてのセッションに同じ上限が配られます。
{
"env": {
"CLAUDE_CODE_MAX_TURNS": "15"
}
}プロジェクト直下の.claude/settings.jsonに書けば、そのリポジトリでClaude Codeを起動する全員に同じ上限が適用されます。管理設定(managed settings)に書けば、個人設定や実行時のフラグでも上書きできない強制値になります。CI専用のワークフローファイルにだけexportを書くより、プロジェクト設定に既定値を持たせるほうが安全です。必要なジョブだけ--max-turnsで個別に上書きすれば、設定の置き場所が散らばりません。
上限に達するとどうなるか
上限のターン数を使い切ると、Claude Codeはエラーで終了します。作業が途中でも強制的に打ち切られる形で、続きを自動で再開する仕組みはありません。長い作業をターン数で区切りたい場合は、上限を緩めるか、タスクをより小さな単位に分けて複数回実行する構成にします。
適切な上限の値はタスクの粒度で変わります。1ファイルの単純な修正や定型のフォーマット直しなら数ターンで完結することが多く、上限を低めに設定してもエラーで打ち切られる心配は小さくなります。
逆に複数ファイルにまたがるリファクタリングやテスト修正まで含む作業では、ツール呼び出しの往復が増えます。上限を低く絞りすぎると、本来なら完了できたはずのタスクが途中終了になります。初めて自動化に組み込むときは、いったん余裕を持った値で走らせ、実際に消費したターン数をログから確認してから絞り込むほうが失敗が少なくなります。
--input-format stream-json で標準入力からメッセージを流し込む構成では、少し複雑な挙動があります。Claudeが作業中に新しいメッセージを送っても、そのメッセージはいったんキューに積まれ、現在のターンの上限が尽きたところで独立した新しいターンとして実行されます。つまり上限は会話単位ではなく、送られたメッセージごとに新しく数え直されます。
対話セッションでは効かない可能性が高い
置き換え先の --max-turns は、公式ドキュメントで「印刷モード限定(print mode only)」と明記されているフラグです。印刷モードとは -p を付けて起動する非対話実行のことで、対話的に claude と打って開く通常のセッションとは別の実行形態を指します。
CLAUDE_CODE_MAX_TURNS 自体の説明には「印刷モード限定」という言葉は明記されていません。ただし「--max-turns と同じ効果を持つ」とされているため、対話セッションでの挙動は公式には確認できていません。対話中のやり取りには元々「ターンの上限で強制終了する」という概念が馴染まないこともあり、この変数は -p を使った非対話実行を前提に考えるのが安全です。
CI/自動化での使いどころ
自律実行の暴走を止めたい場面では、上限のかけ方が3種類あります。それぞれ止めるものが違うため、目的に合わせて選びます。
| 止めたいもの | 使う変数・フラグ | 備考 |
|---|---|---|
| ターンの回数 | 使う変数・フラグCLAUDE_CODE_MAX_TURNS / --max-turns | 備考印刷モード限定 |
| 使った金額 | 使う変数・フラグ--max-budget-usd | 備考対応する環境変数は無く、フラグ指定のみ |
| 実行時間そのもの | 使う変数・フラグCI側のジョブタイムアウト設定 | 備考GitHub Actionsのtimeout-minutes等 |
--max-budget-usd はサブエージェントの支出も合算して上限を判定します。上限に達するとサブエージェントの新規起動が失敗し、実行中のバックグラウンドサブエージェントも停止します。この上限強制の挙動はv2.1.217以降で有効です。ターン数の上限と違い、こちらには対応する環境変数がなく、CLIフラグでしか指定できません。日次バッチのように毎回同じ設定で回す構成では、CLAUDE_CODE_MAX_TURNSで大まかな暴走防止を効かせつつ、コストの厳密な上限は--max-budget-usdをコマンドに直接書く組み合わせが実務的です。
GitHub ActionsやGitLab CIにClaude Codeを組み込む構成では、ターン数の上限とジョブのタイムアウトを両方効かせておくのが定石です。ターン数だけに頼ると、1ターンが長時間のツール実行を含む場合に時間の予測が難しくなります。逆にタイムアウトだけに頼ると、無駄なターンを繰り返した末に時間切れで打ち切られ、コストだけが積み上がる結果になりかねません。CI組み込みの実践的な設定例はClaude CodeをGitHub Actionsに組み込むとClaude CodeをGitLab CI/CDに組み込むにまとめています。
よくある質問
CLAUDE_CODE_MAX_TURNSと--max-turnsのどちらを使うべきですか
毎回同じ上限を使うならフラグより環境変数のほうが書き漏れを防げます。実行ごとに上限を変えたい場合や、CIの設定ファイルにコマンドとして明示したい場合は--max-turnsをその場で渡す形が向いています。両方を設定した場合はフラグが優先されるため、一時的に上限を変えたいときだけフラグを追加する運用もできます。
上限に達したときにClaudeの作業内容は保存されますか
エラー終了する時点までにClaudeが行ったファイル編集やコミットはそのまま残ります。会話自体は打ち切られるため、続きを行うには新しいセッションを開始するか、claude --resumeのような再開の仕組みを使う必要があります。
既定ではターン数に上限がありますか
ありません。CLAUDE_CODE_MAX_TURNSも--max-turnsも指定しなければ無制限のままで、公式ドキュメントもビルトインの既定上限には触れていません。対話セッションを日常的に使っているだけなら意識する場面は少なく、無人実行を組み込む段階になって初めて、明示的に値を決める必要が出てきます。
「ターン」1回の定義は何ですか
公式ドキュメントは「agentic turn」という言葉で説明しており、Claudeが応答を返す・ツールを呼び出すといった一連の自律的な行動のまとまりを1ターンとして数えます。1ターンの中で複数のツール呼び出しが連続することもあるため、ターン数とツール呼び出し回数は必ずしも一致しません。
対話セッションで上限に近づいたらどうなりますか
対話セッションに--max-turnsのような強制終了は確認されていません。長時間の対話でコンテキストが埋まってきた場合は、ターン数の上限とは別の仕組みである自動コンパクションが働き、古いやり取りを要約して空きを作ります。
まとめ
CLAUDE_CODE_MAX_TURNS は、非対話実行のターン数に上限をかける環境変数です。--max-turnsと同じ効果を持ち、フラグを渡さなかったときの既定値として働きます。正の整数以外を指定すると起動時エラーになる点、stream-json経由の追加メッセージは独立した新しいターンとして数え直される点は、値を決める前に押さえておく価値があります。金額を止めたいなら--max-budget-usd、実行時間そのものを止めたいならCI側のタイムアウトと、目的に応じて上限のかけ方を使い分けるのが実務的です。Claude Codeの環境変数全体を用途別に見渡したい場合はClaude Code環境変数リファレンスを参照してください。