原典: Prompt caching / 日本語版
一行要約
キャッシュは tools → system → messages の順に prefix として作られ、breakpoint は「リクエスト間で内容が同一である最後のブロック」に置く。ここを間違える(タイムスタンプなど変わるものに置く)と、prefix のハッシュが一致せずヒットしない。
要点
仕組み
- 指定した cache breakpoint までの prefix が最近のクエリでキャッシュ済みか確認する
- あればそれを使う
- なければ全体を処理し、応答の開始時に prefix をキャッシュする
既定のキャッシュ寿命は5分。書き込みまたは読み取りを行うリクエストの開始時点から測る(応答の終了時点ではない)。
価格
| 項目 | 倍率 |
|---|---|
| 5分キャッシュの書き込み | base input の 1.25倍 |
| 1時間キャッシュの書き込み | base input の 2倍 |
| キャッシュ読み取り(両方とも) | base input の 0.1倍。例外は Opus 5.5 の 0.05倍と、Fable 5.1 / Mythos 5.1 の 0.025倍(価格表の脚注) |
→ 2回目のヒットで元が取れる。
breakpoint のルール
- 明示的な breakpoint は1リクエストあたり最大4つ
- キャッシュ階層の順序は
tools→system→messages。各段は前段の上に積み上がるので、ある段の変更はその段以降をすべて無効化する - breakpoint ごとに 20 ブロックの lookback window — 一致するキャッシュエントリを探して最大20位置まで遡る
Key takeaway: Place
cache_controlon the last block whose prefix is identical across the requests you want to share a cache. In a growing conversation the final block works as long as each turn adds fewer than 20 blocks: earlier content never changes, so the next request’s lookback finds the prior write. For a prompt with a varying suffix (timestamps, per-request context, the incoming message), place the breakpoint at the end of the static prefix, not on the varying block.要点:
cache_controlは、キャッシュを共有させたいリクエストの間で prefix が同一である最後のブロックに置け。伸びていく会話では、1ターンで足されるブロックが20未満である限り最後のブロックで足りる。それ以前の内容は変わらないので、次のリクエストの lookback が前回の書き込みを見つける。末尾が変化するプロンプト(タイムスタンプ、リクエストごとの context、届いたメッセージ)では、breakpoint は変化するブロックの上ではなく、静的な prefix の末尾に置く。
Cache writes happen only at the breakpoint, and if that block changes (timestamps, per-request context, the incoming message), the prefix hash never matches. The lookback does not find stable content behind the breakpoint; it only finds entries that earlier requests wrote at their own breakpoints
キャッシュへの書き込みは breakpoint でしか起きない。そのブロックが変化すると(タイムスタンプ、リクエストごとの context、届いたメッセージ)、prefix のハッシュは決して一致しない。lookback は breakpoint の後ろにある安定した内容を見つけてはくれない。見つけるのは、以前のリクエストが自分の breakpoint で書いたエントリだけである。
何がキャッシュを壊すか
| 変更 | tools | system | messages | 補足 |
|---|---|---|---|---|
| ツール定義 | ✘ | ✘ | ✘ | 全キャッシュが無効化される |
| web search のオン/オフ | ✓ | ✘ | ✘ | |
| citations のオン/オフ | ✓ | ✘ | ✘ | |
| speed 設定 | ✓ | ✘ | ✘ | |
| tool choice | ✓ | ✓ | ✘ | |
| 画像 | ✓ | ✓ | ✘ | |
| thinking パラメータ | モデル依存 | モデル依存 | ✘ | 常に messages を無効化 |
| effort 設定 | モデル依存 | モデル依存 | ✘ | 常に messages を無効化。ただしモデルの既定値を明示的に書くのは省略と同じで無効化しない。per-message effort に対応したモデルでは、role: "system" メッセージで運ぶ effort 変更はキャッシュ済みの接頭辞を壊さない |
| 落とされた thinking ブロック | ✓ | ✓ | ✘ | Fable 5.1 / Mythos 5.1 / Opus 5.5 / Sonnet 5.5 の thinking ブロックが、そのリクエストで preserved でないために API に落とされると、そのブロックの位置から後ろのキャッシュが変わる。受け取る側のモデルが読めるブロックをそのまま返すなら壊れない |
(✓ = 保たれる、✘ = 無効化される)
会話の途中で足しても壊れないものが2つある。
- system 指示: Fable 5.1 / Mythos 5.1 / Fable 5 / Mythos 5 / Opus 5.5 / Opus 4.8 / Opus 5 / Sonnet 5.5 では、トップレベルの
systemを編集する代わりに{"role": "system"}のメッセージをmessagesに足せば、system も messages もキャッシュが無効化されない。Sonnet 5 では使えない(トップレベルのsystemを使う) - ツール定義:
inline-tools-2026-09-15beta を付け、toolsは最初に送ったままにして、会話途中の system メッセージのtool_additionブロックで定義を送る。キャッシュ済みの接頭辞は一致したままで、足したメッセージだけが新規入力として処理される(例外は、toolsに非 deferred のツールが1つも無い場合。その最初の1本はそのリクエストで丸ごとキャッシュミスになる。これは tool search の beta とは別の beta の話 —— tool-search-tool のほうでは非 deferred が最低1つ要る)
キャッシュ可能な最小プロンプト長(モデル別)
| モデル | 最小トークン数 |
|---|---|
| Fable 5.1 / Mythos 5.1 / Opus 5.5 / Opus 5 / Sonnet 5.5 / Fable 5 / Mythos 5 | 512 |
| Mythos Preview / Opus 4.7 | 2,048 |
| Opus 4.6 / 4.5 | 4,096 |
| Opus 4.8 / Sonnet 5 / Sonnet 4.6 / Sonnet 4.5 / Opus 4.1 / Sonnet 4 | 1,024 |
| Haiku 4.5 | 4,096 |
| Haiku 3.5 | 2,048 |
usage の読み方
total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokenscache_creation_input_tokens— 新規エントリ作成時に書き込まれたトークンcache_read_input_tokens— このリクエストでキャッシュから読まれたトークンinput_tokens— 最後の breakpoint より後の、キャッシュされていないトークン
ベストプラクティス
- 多ターンの会話はまず automatic caching から始める
- 変更頻度の違うセクションを別々にキャッシュしたいときに明示的 breakpoint を使う
- 安定した内容(system 指示、例、大きな context、ツール)をキャッシュする
- キャッシュ対象はプロンプトの先頭に置く
- breakpoint は「リクエスト間で同一の最後のブロック」に置く
- ヒット率を監視する
- レイテンシに敏感なアプリでは pre-warming を使う(初回のキャッシュミスのペナルティを消す)
そのまま使える具体例
automatic caching(トップレベルの cache_control):
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
cache_control={"type": "ephemeral"},
system="You are an AI assistant tasked with analyzing literary works.",
messages=[{"role": "user", "content": "Analyze the major themes in 'Pride and Prejudice'."}],
)
print(response.usage.model_dump_json())明示的 breakpoint(変わらない大きな文書の末尾に置く):
response = client.messages.create(
model="claude-opus-5",
max_tokens=1024,
system=[
{"type": "text", "text": "You are an AI assistant tasked with analyzing legal documents."},
{
"type": "text",
"text": "Here is the full text of a complex legal agreement: [50 pages]",
"cache_control": {"type": "ephemeral"},
},
],
messages=[{"role": "user", "content": "What are the key terms and conditions in this agreement?"}],
)1時間キャッシュ:
cache_control={"type": "ephemeral", "ttl": "1h"}ツール定義のキャッシュ(最後のツールに置く):
tools=[
{"name": "get_weather", "description": "...", "input_schema": {}},
{
"name": "get_time",
"description": "...",
"input_schema": {},
"cache_control": {"type": "ephemeral"},
},
]pre-warming(max_tokens=0 で書き込みだけ行う):
# Fire this before users arrive to warm the shared system-prompt cache.
prewarm = client.messages.create(
model="claude-opus-5",
max_tokens=0,
system=[
{
"type": "text",
"text": "You are an expert software engineer with deep knowledge of distributed systems...",
"cache_control": {"type": "ephemeral"},
}
],
messages=[{"role": "user", "content": "warmup"}],
)
print(prewarm.stop_reason) # "max_tokens"
print(prewarm.content) # []原典で言及されている関連文書
- manage-tool-context — 「初日から prompt caching を有効にする」の出所
- effort — effort 変更がキャッシュを無効化すること
- context-editing — tool result clearing はキャッシュを壊し、thinking clearing は保つ
- tool-search-tool —
defer_loadingがキャッシュを保つ仕組み - costs — Claude Code 側でのキャッシュ寿命(サブスクは1時間、usage credits 使用中は5分)
- contextual-retrieval — prompt caching による前処理コストの削減