大きなシステムプロンプトや長いドキュメントを何度も送るアプリケーションでは、同じ内容を毎回フルで処理させるのは無駄です。Claude APIのプロンプトキャッシュを使うと、変化しない前半部分をキャッシュから読み出し、入力コストとレイテンシを大きく下げられます。この記事では仕組みと cache_control の付け方、キャッシュが効いているかの確認方法までを解説します。
プロンプトキャッシュとは
プロンプトキャッシュはプレフィックス(先頭からの一致)でのキャッシュです。リクエストは tools → system → messages の順にレンダリングされ、その先頭部分がバイト単位で一致していれば、キャッシュ済みの内容を安価に読み出せます。逆に、プレフィックスのどこか1バイトでも変わると、それ以降のキャッシュはすべて無効になります。この一点がプロンプトキャッシュのすべての挙動の元になっています。
したがって、頻繁に使う大きなシステムプロンプトや共有コンテキスト(数千トークン規模のドキュメントやfew-shot例)を先頭に固定し、質問など毎回変わる部分を後ろに置くのが基本設計です。
cache_controlの付け方
最も簡単なのは、リクエスト本体のトップレベルに cache_control を付ける自動キャッシュです。キャッシュ可能な最後のブロックが自動的にキャッシュされます。
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=16000,
cache_control={"type": "ephemeral"}, # 最後のキャッシュ可能ブロックを自動キャッシュ
system="あなたはこの大きなドキュメントの専門家です...",
messages=[{"role": "user", "content": "要点を要約してください"}],
)
細かく制御したい場合は、キャッシュしたいプレフィックスの最後のブロックに cache_control を付けます。system をテキストブロックの配列で渡し、末尾ブロックに付与すると、tools と system をまとめてキャッシュできます(レンダリング順が tools → system のため)。
system=[{
"type": "text",
"text": "大きな共有プロンプト...",
"cache_control": {"type": "ephemeral"}, # 既定のTTLは5分
}]
1時間のTTLにしたい場合は {"type": "ephemeral", "ttl": "1h"} を指定します。ブレークポイント(cache_control)は1リクエストにつき最大4個までです。
キャッシュヒットの確認
レスポンスの usage にキャッシュの状況が返ります。同じプレフィックスで繰り返しリクエストしているのに cache_read_input_tokens がゼロのままなら、どこかにキャッシュを壊す要因(後述)があります。
print(response.usage.cache_creation_input_tokens) # キャッシュに書き込んだトークン(約1.25倍のコスト)
print(response.usage.cache_read_input_tokens) # キャッシュから読んだトークン(約0.1倍のコスト)
print(response.usage.input_tokens) # キャッシュされなかったトークン(通常コスト)
注意点として、input_tokens はキャッシュされなかった残りの分だけを表します。プロンプト全体のサイズは input_tokens + cache_creation_input_tokens + cache_read_input_tokens の合計です。
キャッシュが効かない原因
キャッシュはプレフィックスの完全一致で成立するため、先頭付近に「毎回変わるもの」が入っていると成立しません。よくある無効化の原因は次のとおりです。
- システムプロンプトに
datetime.now()やUUID・リクエストIDを埋め込んでいる - JSONを
sort_keys=Trueなしでシリアライズしている(キー順が非決定的になる) - ユーザーIDやセッションIDをシステムプロンプトに差し込んでいる(ユーザーごとに別プレフィックスになる)
- 会話の途中で
toolsの内容やモデルを切り替えている(tools は位置0でレンダリングされ、変えると全体が無効化される。モデルもキャッシュはモデル単位)
現在時刻・モード・ユーザー名などをシステムプロンプトに差し込むと、その後ろがすべてキャッシュ対象外になります。動的な内容はブレークポイントより後の messages 側に置きましょう。
料金と使いどころ
キャッシュ読み出しは基本の入力価格の約0.1倍と安価ですが、キャッシュ書き込みは5分TTLで約1.25倍、1時間TTLで約2倍です。したがって損益分岐は、5分TTLなら同一プレフィックスで2回以上、1時間TTLなら3回以上使う場合です。逆に、先頭から毎回内容が変わるプロンプトはキャッシュしても書き込み料だけ払って読み出しが発生せず、損になります。その場合は付けないのが正解です。
本記事は非公式翻訳です。最新のパラメータ・価格は公式ドキュメントを必ずご確認ください。