プロンプトキャッシュの最小値:実測ではドキュメントの 1.4〜2.4 倍
ある顧客から、当社のゲートウェイでプロンプトキャッシュが、モデルのドキュメントに記載された token 数に達しても効かないと報告があった。こちらでも再現したため、最大手クラスの独立系 AI ゲートウェイを第 2 の配信経路として、全モデルを再測定した。結果は、token 単位で同じずれが再現された。楽観的だったのは特定のゲートウェイではなく、ドキュメントのほうだ。公開されている最小値はキャッシュ対象になる下限であり、cache hit が発生する長さではない。自動キャッシュを使うモデルファミリーでは、両者に 1.4〜2.4 倍の差があった。OpenAI は、ドキュメント上の 1,024 token に対し、実際に初回 hit が発生したしきい値は約 1,456 token だった。Gemini 2.5 Flash は、記載値が 2,048 token なのに対し、最初の cache read は約 5,000 token だった。一方、明示的なマーカーを置いた箇所だけをキャッシュする Claude は、モデルごとの記載値から数%以内で hit した。
TL;DR
- OpenAI のキャッシュ最小値は 1,024 token と記載されているが、2 つの経路で測定した実効しきい値は約 1,456 token だった。
- Gemini 2.5 Flash の記載値は 2,048 token だが、最初に cache read が発生したのは約 5,000 token で、約 2.4 倍だった。
- Claude の明示的な
cache_controlは、ドキュメント上の最小値から数%以内で hit した(Opus は 1,024 に対して 1,073)。 - GLM 5.2 と DeepSeek V4 は最小値を公開しておらず、約 800 token から read した。MiniMax M3 は長さに関係なく、約 114 cached token と報告する。
- 自動キャッシュでは、最初の read までに 2〜8 回のウォームアップも必要になる。
すべての測定は、当社のゲートウェイと最大手クラスの独立系 AI ゲートウェイという 2 つの配信経路で実行した。両方の結果が一致した場合に限り、モデルの挙動と判断した。第 2 の経路を使った目的は、原因を切り分けることだ。無関係なベンダーのスタックでも同じずれが再現されれば、問題は当社ではなくモデル側にある。この照合は OpenAI、Gemini、GLM で明確に成立した。いずれも両方の経路で、同じ実効しきい値からキャッシュされた。ただし、すべてのモデルで照合できるわけではない。第 2 のゲートウェイでは、オープンウェイトモデルの多くが、ベンダーのプロンプトキャッシュを実装していない GPU ホストで配信されている。これは、そのゲートウェイの endpoint metadata でもプロバイダーごとに確認できる。また、ルーティング先を固定しないと複数のホスト間を移動し、cache affinity が失われる。第 2 の経路で裏付けられなかった場合、以下の数値には各ベンダー自身のキャッシュ API に接続する経路の結果を使用した。長さは文字数ではなく、返された usage から補正した各モデル固有の token 数である。各条件では毎回新しい prefix を使い、単発の hit または miss ではなく、最初に cache read が発生した呼び出し番号を記録した。
ドキュメント記載値と実効値の差
ドキュメント上の最小値は、プロンプトがキャッシュ対象になり得る長さを示す。実効しきい値は、同じプロンプトを繰り返したときに、実際に cache read が返る長さだ。自動キャッシュを使うモデルファミリーでは、この 2 つは同じ値ではない。
| ファミリー | キャッシュ方式 | ドキュメント上の最小値 | 実測した初回 hit | 差 |
|---|---|---|---|---|
| OpenAI GPT-5.5 / 5.4-mini | 自動 | 1,024 | ≈1,456 | +40% |
| Gemini 2.5 Flash | 自動 | 2,048 | ≈5,000 | 2.4x |
| Gemini 3.5 Flash | 自動 | 4,096 | ≈5,200 | +27% |
| Claude Opus 4.8 / Sonnet 5 | 明示的マーカー | 1,024 | 1,073 | 一致 |
| Claude Haiku 4.5 | 明示的マーカー | 4,096 | 4,206 | 一致 |
OpenAI の数値は、両方の経路で token 単位まで一致した。1,356 token のプロンプトでは一度も read されず、1,456 token では read された。最も差が大きかったのは Gemini だった。3,300 token までのスイープでは read が一度も発生せず、キャッシュが無効に見えた。5,000 token まで延長すると、両方の経路で同じ長さから明確に read された。ドキュメントに記載された 2,048 はキャッシュ対象になり得る下限であり、read が返る下限ではない。
今回の調査では、一貫した傾向が見られた。明示的に指定するキャッシュは仕様どおりで、自動的に適用されるキャッシュはそうではなかった。
最小値以外にも未記載の変数がある
実効しきい値を超えることは必要だが、それだけでは足りない。自動キャッシュを使うモデルファミリーではウォームアップが必要で、最初の read は 2 回目ではなく、それより後の呼び出しで発生する。
- OpenAI:最初の read は 2〜3 回目。
- Gemini:最初の read は 4〜8 回目。
これはコストモデルに影響する。6,000 token のプロンプトは、Gemini のドキュメント上のしきい値と実効しきい値をすべて上回る。しかし、同じプロンプトを 2 回だけ送って次へ進むワークロードでは、2 回とも通常料金になる可能性がある。キャッシュのウォームアップが終わっていないためだ。短時間またはバースト的なトラフィックでは、長さの条件を満たしていても未キャッシュ料金がかかる。「キャッシュされない」と判断したのは、呼び出しの間に安定化時間を置き、少なくとも 12 回繰り返してからだ。回数の少ないスイープでは Gemini が false negative になったが、回数を増やすと結果が覆った。
cached token 数も固定ブロック単位にそろえられる。請求額を照合する際には、この点も把握しておく必要がある。OpenAI は 128 token ブロック、DeepSeek は 64 token ブロックだ。5,014 token のプロンプトに対して 4,073 cached token が read された場合、これはブロック境界で丸められた部分的な prefix hit であり、バグではない。
制御できるキャッシュは仕様どおり
Claude は cache_control を付けたセグメントだけをキャッシュし、その仕様も正確だった。検証した Anthropic の仕様はすべて実測と一致した。
- モデルごとの最小値が token 単位で一致。 Opus 4.8 と Sonnet 5 は、ドキュメント上の 1,024 token に対して 1,073 token で最初に read された。Haiku 4.5 は 4,096 に対して 4,206 だった。わずかな超過はブロック単位の丸めによるもので、しきい値のずれではない。
- read 料金は input の 0.1x。 各モデルの未キャッシュ行から input 単価を求め、hit した行からキャッシュ時の料金を算出した。Opus 4.8 と Haiku 4.5 はどちらも 0.10 で、ドキュメント上の倍率と一致した。
- 5 分間の更新が read ごとに無料。 prefix を登録し、2 分後、4 分後、6 分後に再度 read したところ、すべて hit した。各 5 分間の有効期間内に read すれば、追加の write なしでエントリが維持される。
- 連鎖的な無効化。 system prefix を固定し、tool を 1 つ定義した状態で、tool の description だけを変更すると、その下にある system cache がすべて再 write された。tool 定義を変更すると system cache と message cache が無効になり、ドキュメント上の階層構造と一致した。
ドキュメント同士の矛盾も 1 件見つかった。あるサードパーティーの表では Claude Opus の最小値が 4,096 token とされていたが、実測では 1,073 token で read された。正しいのは Anthropic 自身が記載している 1,024 だ。
オープンウェイト系は最小値をほとんど公開していない
ここまでのモデルファミリーには、少なくとも比較対象になる公開値がある。オープンウェイトモデルや中国の研究所が開発したモデルでは、最小値自体がほとんど公開されていないため、測定するしかない。プロバイダー別キャッシュ比較では、hit 後の公開料金と実測値を比較している。ここで扱うのは、最初の read が発生する長さだけだ。
| ファミリー | ドキュメント上の最小値 | 実測した初回 hit | 粒度 |
|---|---|---|---|
| GLM 5.2 (Z.ai) | なし | 両方の経路で ≈800 から read | 64-token ブロック |
| DeepSeek V4 | なし | ベンダー API で ≈800 から read | 64-token ブロック |
| MiniMax M3 | 512 | 長さに関係なく一定の ≈114 cached を報告 | 非標準 |
GLM 5.2 は最小長を公開していないが、両方の経路で約 800 token からキャッシュされ、粒度は 64 token ブロックだった。これは、最小値が公開されているどのモデルファミリーよりも低い。DeepSeek V4 も最小値を公開しておらず、同じ 64 token 単位で約 800 token から read された。ただし、確認できたのは DeepSeek 自身のキャッシュ API だけだった。DeepSeek のドキュメントでは、キャッシュは best-effort であり、hit 率は保証されないとされている。中間ゲートウェイを経由した結果も、まさにそのとおりだった。もう一方のゲートウェイでは、DeepSeek は複数の GPU ホストから配信されているが、キャッシュを実装しているのは DeepSeek 自身の endpoint だけだ。ルーティング先をその endpoint に固定しなければ、read は一度も返らない。
MiniMax M3 では、報告される数値そのものが誤解を招く。ドキュメント上の最小値は 512 token だが、200〜5,000 token のすべての長さで、初回呼び出しから約 114 cached token という一定値を報告する。この数値はプロンプト長に連動せず、キャッシュを一切行わない経路でも表示される。そのため、再利用された量を示す値ではなく、モデル内部の集計値と考えられる。新しい OpenAI モデルでも、別の形で同じ問題が見られる。usage の token フィールドと実際のキャッシュ状況は一致しないことがあるため、削減額が重要なら token 数ではなく usage.cost と照合すべきだ。
最新モデルではルールが変わりつつある
以前の挙動がそのまま続くと考える前に、ドキュメント上の変更を 2 点押さえておく必要がある。GPT-5.6 ファミリーについて、OpenAI のガイドでは cache write の料金が未キャッシュ input の 1.25x と記載されている。従来のファミリーでは write は無料だった。同じガイドでは、implicit caching は最新 message に breakpoint を置く方式として説明されている。これは、会話の turn が変わっても安定した system block を prefix cache する方式とは異なる。これらのモデルで、user turn が変わっても同じ安定した prefix を再利用したい場合は、implicit な経路に任せず、明示的な breakpoint を付ける必要がある。write の倍率と最小値はモデルごとに確認すべきだ。どちらもファミリーによって異なるようになっており、単一のドキュメントページではその差が見えにくい。
実運用での対応
- 自分の環境で実効しきい値を測定する。 自分の token 基準でプロンプト長を段階的に増やし、最初に cache read が返る長さを記録する。ドキュメント上の最小値から hit が始まるとは考えない。
- ウォームアップをコストに含める。 自動キャッシュを使うプロバイダーでは、新しい prefix に対する最初の 2〜8 回を未キャッシュとしてコストモデルに組み込む。
- プロバイダーが対応しているなら、明示的なマーカーを優先する。 Claude の cache_control は、最小値、read 料金、TTL、無効化ルールが明確で、実測可能な仕様だった。この予測可能性は、実際には当てにできない低い公称しきい値よりも価値がある。
- 新しいモデルファミリーごとに基準を測り直す。 今回の調査期間中にも、同一ベンダーのラインナップ内で最小値、write 料金、breakpoint の挙動が変わった。
これらのしきい値の前提となる read 料金、TTL、keying rule については、プロンプトキャッシュガイドでプロバイダーごとの仕組みを解説している。
要点は単純だ。ドキュメント上の最小値はキャッシュ対象になる下限であり、hit するしきい値ではない。自動キャッシュでは、両者に 1.4〜2.4 倍の差がある。請求額を左右する実際の数値は、自分の token とトラフィックで検証する必要がある。