プロンプトキャッシングを使うとキャッシュヒット時のトークンコストが約90%削減されます。しかし、意図せずキャッシュが無効化されているケースが実務では多く見られます。
2種類のキャッシング方式
自動キャッシングはリクエストのトップレベルに cache_control フィールドを一つ追加するだけです。会話が進むにつれてキャッシュポイントが自動的に前方に移動するため、マルチターン会話に適しています。
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="あなたは...",
messages=[...],
)
明示的なキャッシュブレークポイントは個々のコンテンツブロックに cache_control を配置し、最大4箇所まで設定できます。「ツール定義はほぼ変わらないがシステムプロンプトは毎日更新する」といったケースで使います。
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system=[
{"type": "text", "text": "あなたは専門家です。"},
{
"type": "text",
"text": "<大量の参照資料...>",
"cache_control": {"type": "ephemeral", "ttl": "1h"}, # 1時間 TTL
},
],
messages=[{"role": "user", "content": "質問..."}],
)
# キャッシュヒットの確認
print(response.usage.cache_read_input_tokens) # > 0 ならヒット
print(response.usage.cache_creation_input_tokens) # キャッシュ書き込みトークン数
TTL はデフォルト5分です。拡張思考のタスクは5分を超えることがあるため、長時間タスクには "ttl": "1h" の1時間キャッシュが有効です。キャッシュ可能な最小サイズは Opus 4.8 / Sonnet 4.6 で 1,024 トークン、Opus 4.6 / 4.5 以前では 4,096 トークンです。
落とし穴1:thinking パラメータの変更でキャッシュが無効になる
thinking の設定を変えるとメッセージのキャッシュブレークポイントが無効化されます。具体的には以下の変更がキャッシュを壊します。
thinking: {type: "enabled"}↔{type: "adaptive"}の切り替えbudget_tokensの値を変えるthinkingを有効化・無効化する
ただしシステムプロンプトとツール定義のキャッシュは維持されます。メッセージ部分だけが無効化されます。
落とし穴2:adaptive ↔ enabled を切り替えるとブレークポイントが無効になる
同じ adaptive を使い続けていればキャッシュは保持されますが、adaptive と enabled/disabled の間を切り替えると、メッセージのキャッシュブレークポイントが無効化されます。会話の途中で思考モードを変更するような実装は避けるべきです。
落とし穴3:高速モードの切り替えでキャッシュが無効になる
speed: "fast" と標準速度を切り替えると、システムとメッセージのキャッシュが無効になります。高速モードと標準モードはキャッシュを共有しません。コスト試算でキャッシュヒット率を前提に置いている場合は、モード切り替え時に再計算が必要です。
落とし穴4:変化するサフィックスにブレークポイントを置く
よくある間違いとして、リクエストごとに変わるブロック(タイムスタンプ入りのメッセージなど)の最後にブレークポイントを置くケースがあります。ルックバック検索は「以前のリクエストがそのブレークポイントで書き込んだエントリ」を探すので、内容が変われば毎回キャッシュミスになります。静的プレフィックスの最後のブロックにブレークポイントを置くのが正しい使い方です。
まとめ
| 変更内容 | ツールキャッシュ | システムキャッシュ | メッセージキャッシュ |
|---|---|---|---|
| thinking パラメータの変更 | ✓ | ✓ | ✗ |
| 高速↔標準速度の切り替え | ✓ | ✗ | ✗ |
| tool_choice の変更 | ✓ | ✓ | ✗ |
| ツール定義の変更 | ✗ | ✗ | ✗ |
- thinking モードはできるだけ変えない運用が基本
- キャッシュヒットは
usage.cache_read_input_tokens > 0で確認できる - システムプロンプトとツール定義は thinking 変更の影響を受けない
- 長時間タスクには1時間 TTL を検討する
- キャッシュ可能な最小サイズはモデルによって異なる(1,024〜4,096 トークン)