自動プロンプトキャッシュは多ターン会話でどう動くか
cache_controlをブロックごとに置かなくても、会話が伸びるたびにキャッシュ境界が自動で前進する仕組みと、20ブロックの遡及窓に引っかかる条件を整理する。
自動プロンプトキャッシュとは何か
自動プロンプトキャッシュは、個々のコンテンツブロックへ cache_control を置かずに済むキャッシュ設定です。リクエストのトップレベルに cache_control: {"type": "ephemeral"} を1つ加えるだけで、システムがキャッシュ可能な最後のブロックへ自動的にブレークポイントを割り当てます。明示的ブレークポイントとの違いは1点だけです。どこをキャッシュするかをシステムが選ぶか、開発者がブロック単位で選ぶか。
会話が伸びるチャットアプリでは、ターンが増えるたびに cache_control を打ち直す運用は現実的ではありません。自動プロンプトキャッシュはこの手間を消すために用意されています。仕組みの全体像はClaudeのプロンプトキャッシュの仕組みで扱いましたが、本稿は多ターン会話に絞って動きを追います。
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"cache_control": {"type": "ephemeral"},
"system": "You are a helpful assistant.",
"messages": [
{"role": "user", "content": "My name is Alex."},
{"role": "assistant", "content": "Nice to meet you, Alex."},
{"role": "user", "content": "What did I say my name was?"}
]
}'トップレベルの cache_control は tools / system / messages を通しで見て、最後にキャッシュ可能なブロックへ境界を置きます。個別のブロックを見て回る必要はありません。
会話が伸びるとキャッシュ境界はどう動くか
自動プロンプトキャッシュの核心は、リクエストのたびに境界が前へ進むことです。1ターン前までの内容はキャッシュから読み、新しく増えた分だけを書き込みます。
| リクエスト | 内容 | キャッシュの動き |
|---|---|---|
| 1回目 | 内容System + User(1) + Asst(1) + User(2) | キャッシュの動きすべて書き込み |
| 2回目 | 内容〜User(2) + Asst(2) + User(3) | キャッシュの動きUser(2)までを読み込み、Asst(2)+User(3)を書き込み |
| 3回目 | 内容〜User(3) + Asst(3) + User(4) | キャッシュの動きUser(3)までを読み込み、Asst(3)+User(4)を書き込み |
開発者側が毎ターン cache_control の位置を更新する必要はありません。ブレークポイントは常に送信するメッセージ配列の末尾に自動で付きます。
課金体系や最小トークン数の閾値、コンテキストの並び順の制約は、明示的ブレークポイントとまったく同じです。自動プロンプトキャッシュは既存のキャッシュ基盤をそのまま使うだけで、新しい課金ルールを持ち込みません。5分TTLのキャッシュ書き込みは基本入力価格の1.25倍、キャッシュ読み込みは0.1倍(Claude Fable 5.1とClaude Mythos 5.1のみ0.025倍)という単価も、明示的ブレークポイントと共通です。
20ブロックの遡及窓とTTLをどう使い分けるか
自動プロンプトキャッシュにも、明示的ブレークポイントと同じ20ブロックの遡及窓が適用されます。システムはブレークポイント位置から最大20ブロックだけ過去へ遡り、一致するキャッシュエントリを探します。見つからなければ新規に書き込むだけで、読み込みは発生しません。
会話が1ターンで20ブロック以上伸びる構成では、直前ターンのエントリが窓の外に出てしまい、毎回書き込みだけが発生するコスト増に気づきにくい落とし穴があります。並列ツール呼び出しは連続する tool_use や tool_result をまとめて1ブロックとして数えるため、通常の会話でこの窓を超えることは多くありません。ただし大きな出力を複数返すエージェント用途では、1ターンで20ブロックを超えるケースが実際に起こります。
TTL(キャッシュの生存時間)も選べます。既定は5分ですが、1時間TTLを使う場合は次のように指定します。
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"cache_control": {"type": "ephemeral", "ttl": "1h"},
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "..."}]
}'1時間TTLのキャッシュ書き込みは基本入力価格の2倍です。会話の間隔が数分から十数分空くチャットボットでは、既定の5分TTLだとターンの合間にキャッシュが失効し、書き込みだけが繰り返されます。1時間TTLの具体的な損益分岐はClaude APIの1時間キャッシュはいつ使うべきかで扱っています。
明示的ブレークポイントと自動キャッシュの使い分け
自動プロンプトキャッシュは明示的ブレークポイントと併用できます。システム全体で最大4つのブレークポイント枠があり、自動キャッシュはそのうち1枠を使います。システムプロンプトだけを明示的に固定し、会話部分は自動キャッシュに任せる構成が典型です。
| 用途 | 自動キャッシュ | 明示的ブレークポイント |
|---|---|---|
| 素早く導入したい | 自動キャッシュ◎ 設定1行で完結 | 明示的ブレークポイント△ ブロック単位の設計が要る |
| 更新頻度が違う区画を分けたい | 自動キャッシュ△ | 明示的ブレークポイント◎ ツール定義は固定・文脈は日次更新のように分離できる |
| リクエストの末尾が毎回変わる | 自動キャッシュ△ 末尾がキャッシュ対象になり毎回外れる | 明示的ブレークポイント◎ 変化しない直前のブロックを狙って置ける |
| 1ターンで20ブロックを大きく超える | 自動キャッシュ△ 遡及窓から外れやすい | 明示的ブレークポイント◎ 別のブレークポイントを追加できる |
末尾に毎回変わるブロック(タイムスタンプや動的な補足情報)を置く構成では、自動プロンプトキャッシュはその変わるブロックへ境界を置いてしまい、キャッシュが常に外れます。この構成では、変化しない直前のブロックを狙って明示的ブレークポイントを置くほうが確実です。区画ごとに更新頻度を分けたいケースの具体的な置き方はClaude APIの明示的キャッシュブレークポイントの置き方にまとめています。
併用時にはまり込みやすい境界条件が4つあります。自動キャッシュが割り当てる末尾ブロックに、同じTTLの明示的 cache_control がすでに付いている場合、自動キャッシュはno-opになり何も起きません。逆にTTLが食い違っていると400エラーになります。明示的ブレークポイントが4枠を使い切っていて自動キャッシュに割り当てる枠が残っていない場合も400エラーです。自動キャッシュの対象ブロックがキャッシュ不適格(サイズが最小トークン数の閾値未満など)なときは、システムは手前のブロックへ黙って遡り、適格なブロックが見つからなければキャッシュ自体をスキップします。エラーにならず静かにキャッシュが効かなくなるため、ヒット率が想定より低いときはこの遡り・スキップも疑ってください。
自動キャッシュが効かない・壊れる条件
自動プロンプトキャッシュも、明示的ブレークポイントと同じキャッシュ基盤の上で動くため、同じ条件で無効化されます。ツール定義(名前・説明・パラメータ)を変更すると、tools / system / messages のキャッシュが全体で無効になります。画像の追加・削除や tool_choice の変更はメッセージ部分のキャッシュだけを壊し、ツールとシステムのキャッシュは残ります。thinkingの設定(モードや budget_tokens)を変えると常にメッセージのキャッシュが無効になり、モデルによってはツールとシステムのキャッシュも道連れになります。thinking設定の変更でキャッシュヒット率が落ちる具体的な挙動はClaude Thinkingでキャッシュヒット率が落ちる原因で詳しく扱っています。
多ターン会話でとくに見落としやすいのが、途中でシステム指示を追加するケースです。トップレベルの system フィールドを直接書き換えると、そこから下のキャッシュがすべて無効になります。Claude Fable 5.1・Claude Mythos 5.1・Claude Mythos 5・Claude Fable 5・Claude Opus 4.8・Claude Opus 5では、messages 配列へ {"role": "system"} のメッセージを追記する形にすると、既存のキャッシュを壊さずに指示を追加できます。Claude Sonnet 5はこの方式に対応していないため、通常どおりトップレベルの system を書き換える形になります。
thinkingブロックを含む会話でどう動くか
thinkingを有効にしたモデルとの多ターン会話では、もう1つ知っておくべき挙動があります。thinkingブロックは cache_control を直接付けてキャッシュすることはできませんが、ツール結果を含む後続のリクエストを送るときに、他のコンテンツと一緒に自動でキャッシュされます。ツール呼び出しのあとにthinkingブロックを会話へ渡し戻す構成では、この自動キャッシュが日常的に発生します。キャッシュから読み込まれたthinkingブロックは、通常のコンテンツと同じく入力トークンとして計上されます。
ここで前版との差が出ます。Claude Opus 4.5以降・Claude Sonnet 4.6以降では、ツール結果以外のユーザーコンテンツを追加してもthinkingブロックは既定で保持され、キャッシュは有効なままです。それより前のOpus・Sonnetモデルと全てのHaikuモデルでは、ツール結果以外のユーザーコンテンツが挟まった時点で過去のthinkingブロックがすべて取り除かれ、そこから先のキャッシュが無効になります。エージェント用途で複数ターンにわたりthinkingを引き継ぐ構成を組むときは、使っているモデル世代でこの挙動が変わる点を前提に設計します。
キャッシュが実際に効いているかを確認する
自動プロンプトキャッシュは条件を満たさなくてもエラーを返さず、静かにキャッシュなしで処理を続けます。もっとも典型的な条件がプロンプトの長さです。Claude Sonnet 5は1,024トークン、Claude Opus 5は512トークンがキャッシュ可能な最小長で、これを下回るプロンプトはキャッシュされません。会話の序盤はメッセージ数が少なく、この最小長に届かないことがあります。
キャッシュが効いたかどうかは、レスポンスの usage フィールドで確認します。cache_creation_input_tokens と cache_read_input_tokens の両方が0であれば、そのリクエストはキャッシュされていません。会話の序盤でこの値がゼロのままなら、エラーではなく、まだ最小トークン数に届いていないだけの可能性を先に疑います。
同時に複数のリクエストを送る場合も注意が必要です。キャッシュエントリは最初のレスポンスが返り始めてから初めて使えるようになります。並列リクエストでキャッシュヒットを狙うなら、最初のレスポンスの開始を待ってから後続のリクエストを送る設計にします。
想定どおりヒットしないときに確認すること
自動プロンプトキャッシュがヒットしない原因の多くは、ここまでに挙げた条件のどれかに当てはまります。ワークスペースを複数使っている構成では、キャッシュはワークスペースごとに分離されるため、同じ会話でもワークスペースをまたぐとキャッシュは共有されません(Claude API・Claude Platform on AWS・Microsoft Foundryが対象。BedrockとGoogle Cloudは組織単位の分離です)。また、キャッシュヒットには対象範囲の完全一致が必要で、テキストや画像が1文字でも異なれば別のキャッシュ扱いになります。原因の切り分けを手作業で進める代わりに、連続するリクエストのどこでプレフィックスが分岐したかを自動で報告するCache diagnosticsという仕組みもあります。使い方はCache diagnosticsでキャッシュミスの原因を特定するにまとめました。
まとめ
自動プロンプトキャッシュは、会話が伸びるたびにブレークポイントが自動で前進する仕組みです。キャッシュ境界の管理コストを消す一方、20ブロックの遡及窓とリクエスト末尾が変わる構成という2つの制約は明示的ブレークポイントと共通です。数分おきに続く会話には既定の5分TTLで足り、間隔が空くやり取りには1時間TTLへの切り替えを検討する価値があります。システムプロンプトなど更新頻度が違う区画を持つアプリケーションは、自動キャッシュと明示的ブレークポイントを併用する構成から見直すとよいでしょう。