生成AIのAPIを業務に組み込むと、請求額の内訳が「入力トークン」に偏っていることに気づきます。
長いシステムプロンプトや、参照させたい社内ドキュメント。
こうした前置きは中身がほとんど変わらないのに、リクエストのたびに丸ごと課金対象になっているのです。
その無駄を削るために各社が用意しているのが、プロンプトキャッシュという仕組み。
料金だけでなく応答速度にも効いてくるので、仕組みと条件を押さえておくと設計の選択肢が広がります。
プロンプトキャッシュとは「プロンプトの先頭を使い回す」仕組み
名前から想像しやすいのは「同じ質問への答えを覚えておく」形かもしれません。
けれど実際は、答えではなく入力の前半部分(プレフィックス)を処理した結果を取っておく仕組みです。
毎回まるごと読み直している
LLM は、送られてきたプロンプトを毎回ゼロから読み込んで内部表現に変換します。
同じシステムプロンプトを1万トークンぶら下げていれば、その1万トークンが毎回きっちり課金される。
しかも読み込みには時間もかかるため、長い前置きは料金と初回応答の遅さの両方に効いてくるわけです。
前から順に一致した分だけ再利用できる
キャッシュが効くのは、プロンプトの先頭から連続して一致している範囲だけ。
Anthropic の公式ドキュメントでは、tools → system → messages の順に組み立てられた内容を前から照合すると説明されています。
Prompt caching(Claude Docs)
つまり前のほうで1バイトでも変わると、そこから後ろは全部キャッシュ対象から外れる。
「毎回変わる日付をシステムプロンプトの冒頭に入れていたせいで、キャッシュが一度も効いていなかった」という事故は、この性質から生まれます。
料金はどう変わるのか
キャッシュは無条件で安くなる魔法ではなく、書き込みと読み出しで単価が分かれる従量課金の一種です。
読み出しは約1割、書き込みは割増
Anthropic のドキュメントによると、キャッシュからの読み出しは通常の入力単価のおよそ0.1倍。
一方でキャッシュへの書き込みには割増が乗り、5分間の保持なら1.25倍、1時間の保持なら2倍とされています。
OpenAI 側も考え方は近く、キャッシュされた入力トークンは通常の0.1倍と案内されていました。
Prompt caching(OpenAI API)
ただし有効期間の扱いには差があり、OpenAI は既定で自動的に有効になる方式を採っています。
何回読み出せば元が取れるか
割増があるということは、1回きりのリクエストではむしろ高くつくということ。
5分保持の場合、書き込み1.25倍+読み出し0.1倍で合計1.35倍となり、キャッシュなしの2回ぶん(2倍)より安くなります。
つまり2回目のリクエストが来た時点で損益分岐を超える計算。
1時間保持は書き込みが2倍なので、少なくとも3回は読み出さないと釣り合いません。
間隔が空きがちなバッチ処理では長い保持、連続して叩くチャットでは短い保持、と使い分けるのが素直でしょう。
効かせるための3つの条件
仕組みを知っていても、置き方を間違えるとキャッシュは静かに空振りします。
変わらないものを前に、変わるものを後ろに
設計の原則は、この一点。
固定のシステムプロンプトや長い参照資料を前に置き、ユーザーの質問やタイムスタンプは後ろに回す。
キャッシュの区切り位置を指定する API では、概念としては次のような形で印を付けます。
system=[
{"type": "text", "text": LONG_MANUAL, # 変わらない前置き
"cache_control": {"type": "ephemeral"}}, # ここまでをキャッシュ
]
messages=[{"role": "user", "content": question}] # 変わる部分は後ろ
# ... 以下略
最低トークン数を下回ると黙って効かない
見落としやすいのが、キャッシュ可能な最小のプレフィックス長という下限です。
Anthropic はモデルによって512〜4096トークンと差があり、OpenAI も1,024トークン(一部の旧モデルは2,048トークン)を下限としています。
厄介なのは、下限を割っていてもエラーにならず、ただ静かにキャッシュされない点。
「指定したのに安くならない」と悩んだら、まず前置きの長さを疑ってみてください。
効いているかは usage で確かめる
推測で終わらせず、レスポンスの利用状況を読むのが確実です。
Anthropic の API なら、キャッシュへ書いた量と読んだ量が別々のフィールドで返ってきます。
- 書き込み:
cache_creation_input_tokens(割増単価を払った分) - 読み出し:
cache_read_input_tokens(0.1倍で済んだ分) - 通常課金:
input_tokens(キャッシュに乗らなかった残り)
読み出しの値がいつまでも0なら、どこかに「毎回変わる何か」が紛れ込んでいるというサインです。
最後に
プロンプトキャッシュは、モデルを賢くする機能ではなく、同じ前置きを何度も読ませないための運用上の工夫でした。
先頭から一致した分だけ効く、下限を割ると黙って効かない、2回目から元が取れる。
この3点を押さえたうえで、料金の内訳を実際の usage で確かめると、削れる無駄がはっきり見えてきます。
トークンという単位そのものや、モデル内部のキャッシュとの違いが気になった方は、こちらもどうぞ。
以上です。












コメントを残す