Prompt Cache の最小値:ドキュメントは実測より 1.4〜2.4 倍過小申告している
あるお客様から、モデル自身のドキュメントが約束するトークン数では、我々のゲートウェイ上で prompt caching が効かないという報告があった。まず自分たちで再現し、次に全モデルを 2 つ目の独立した配信経路、大手 AI ゲートウェイの一つでも走らせた。すると同じズレがトークン単位で再現した。楽観的だったのはどれか一つのゲートウェイではなく、ドキュメントの方だった。公開されている最小値はキャッシュ対象になる下限であって、キャッシュヒットを得られる長さではない。auto-cache 系のファミリーでは、この 2 つの値が 1.4〜2.4 倍ずれる。OpenAI の実効的な初回ヒット閾値はドキュメント記載の 1,024 に対して約 1,456 トークンだった。Gemini 2.5 Flash はドキュメントの 2,048 に対し、初めてキャッシュから読んだのは約 5,000 トークン付近だった。明示的なマーカーを置いた箇所だけをキャッシュする Claude は、ドキュメント記載のモデルごとの最小値に数パーセント以内で一致した。
TL;DR
- OpenAI のドキュメント記載値である 1,024 トークンのキャッシュ最小値は、実効閾値である約 1,456 トークンを過小申告している(2 経路で実測)。
- Gemini 2.5 Flash はドキュメントで 2,048 だが、初めて読んだのは約 5,000 トークン付近で、約 2.4 倍高い。
- Claude の明示的な
cache_controlはドキュメント記載の最小値に数パーセント以内で一致した(Opus は 1,024 に対し 1,073)。 - GLM 5.2 と DeepSeek V4 は最小値を公開しておらず、約 800 トークンから読み始める。MiniMax M3 は長さによらず約 114 キャッシュトークンを報告する。
- automatic cache は初回読み込みの前に 2〜8 回のウォームアップも必要とする。
すべての計測は 2 つの配信経路、我々自身のゲートウェイと大手独立 AI ゲートウェイの一つを通して行い、両経路が一致した場合のみモデルの挙動として扱った。2 つ目の経路の狙いは切り分けだ。無関係なベンダーのスタックで再現するズレなら、原因は我々ではなくモデルにある。このクロスチェックは OpenAI、Gemini、GLM ではきれいに機能し、いずれも両経路で同じ実効閾値でキャッシュした。ただし全モデルで機能するわけではない。2 つ目のゲートウェイでは、open-weight モデルの大半がベンダーの prompt cache を実装していない GPU ホストで配信されており、これはゲートウェイ自身のエンドポイントメタデータがプロバイダーごとに裏付けている。加えて pin されていないルーティングがそれらのホスト間を移動するため、キャッシュのアフィニティが失われる。2 つ目の経路で裏付けが取れなかった箇所については、以下の数値は各ベンダー自身のキャッシュ API に到達する経路のものだ。長さはいずれも各モデル自身のトークン数で、文字数ではなく返却された usage から較正した。各アームは新しい prefix を使い、単発のヒット/ミスではなく、キャッシュ読み込みが発生した最初の呼び出しインデックスを記録した。
ドキュメントの値と実効値のズレ
ドキュメントに書かれた最小値が示すのは、そのプロンプトがキャッシュ「可能」になる条件だ。一方、実効しきい値は、同じプロンプトを繰り返し送ったときに実際に read として返ってくる長さを指す。自動キャッシュ系のモデルでは、この2つの数字は一致しない。
| ファミリー | キャッシュ種別 | ドキュメント上の最小値 | 計測した初回ヒット | ズレ |
|---|---|---|---|---|
| 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 で偽陰性が出て、より深く回すとそれが覆った。
キャッシュされた token 数は固定ブロック単位に丸められる点も、請求を突き合わせるときに知っておくとよい。OpenAI は 128 token ブロック、DeepSeek は 64 token ブロックだ。5,014 token のプロンプトで 4,073 token がキャッシュ read されたのは、部分プレフィックスのヒットがブロック境界に丸められた結果であって、バグではない。
自分で制御するキャッシュは正確
Claude は cache_control でタグ付けしたセグメントだけをキャッシュし、その制御には正確な仕様が伴う。Anthropic の主張はテストしたものすべてが成り立った。
- モデルごとの最小値が token 単位で正確。 Opus 4.8 と Sonnet 5 はドキュメント上の 1,024 に対して 1,073 token で初回 read、Haiku 4.5 は 4,096 に対して 4,206 だった。わずかな超過はブロック丸めであって、ズレではない。
- read レートは入力の 0.1x。 各モデルの入力価格をそのモデル自身の cold 行から算出し、ヒット行からキャッシュレートを逆算した。Opus 4.8 も Haiku 4.5 も 0.10 となり、ドキュメントの倍率と一致した。
- 5分ごとにリフレッシュ、read のたびに無料。 プレフィックスを仕込んで2分後・4分後・6分後に再 read すると、いずれもヒットした。5分ウィンドウ内の read はエントリを生かし続け、追加の write は発生しない。
- カスケード無効化。 安定した system プレフィックスとツール1つを定義した状態で、そのツールの description だけを変更すると、その下の system キャッシュ全体が書き直された。ツール定義の変更は system と message のキャッシュを無効化し、ドキュメントの階層構造どおりに動く。
この過程でドキュメント同士の食い違いも1つ出てきた。あるサードパーティの表では Claude Opus の最小値を 4,096 token としていたが、計測では 1,073 で read され、正しいのは Anthropic 自身が示す 1,024 だった。
オープンウェイト系はたいてい何も書いていない
上に挙げたファミリーは、少なくとも「間違いようのある数字」を公開している。一方、オープンウェイト系と中国系ラボのモデルは、そもそも最小トークン数を一切公開していないものがほとんどで、実測するしかない。ヒットしたあとに公開レートがどう一致するかは プロバイダーのキャッシュ比較 で扱っている。ここで問うのは、最初の read が現れる長さだけだ。
| ファミリー | 公開されている最小値 | 実測の初回ヒット | 粒度 |
|---|---|---|---|
| GLM 5.2 (Z.ai) | なし | 両経路で約 800 から read | 64 トークンブロック |
| DeepSeek V4 | なし | ベンダー API に対して約 800 から read | 64 トークンブロック |
| MiniMax M3 | 512 | どの長さでも一律に約 114 がキャッシュ済みと報告 | 非標準 |
GLM 5.2 は最小長を公開しておらず、両経路とも約 800 トークンから 64 トークンブロック粒度でキャッシュされた。これは文書化されているどのファミリーよりも低い下限だ。DeepSeek V4 も最小値を公開しておらず、同じ 64 トークン粒度で約 800 トークンから read したが、これは自前のキャッシュ API に対してのみだった。DeepSeek のドキュメントはキャッシュを best-effort でヒット率の保証なしと明記していて、中継の挙動もまさにそのとおりだ。もう一方のゲートウェイは複数の GPU ホスト経由で DeepSeek を配信していて、キャッシュを実装しているのは DeepSeek 自身のエンドポイントだけなので、そのエンドポイントにピン留めされないルーティングでは read が一切返らない。
MiniMax M3 は、報告された数字そのものが誤解を招くケースだ。ドキュメントには 512 トークンの最小値と書かれているが、実際には 200 から 5,000 トークンまでどの長さでも、初回呼び出しから約 114 という一定のキャッシュ済みトークン数を報告する。この数字は prompt の長さに連動せず、キャッシュを一切行わない経路でも現れる。つまり、これは何が再利用されたかを示すシグナルではなく、モデル自身の記帳にすぎない。これは新しめの OpenAI モデルが逆方向から教えてくれる教訓と同じだ。usage のトークンフィールドと実際のキャッシュは食い違うことがあるので、節約額が重要なときはトークン数ではなく usage.cost と突き合わせること。
最新モデルはルールが動きつつある
古い挙動がそのまま続くと決めつける前に、ドキュメントレベルで注目すべき変更が 2 つある。GPT-5.6 ファミリーでは、OpenAI のガイドがキャッシュ書き込みのコストを非キャッシュの input レートの 1.25 倍としている。以前のファミリーは書き込みが無料だった。同じガイドでは、暗黙的なキャッシュを最新メッセージにブレークポイントを置くものとして説明していて、ターンをまたいで安定した system ブロックを prefix キャッシュするのとは形が違う。これらのモデルで、異なるユーザーターンをまたいで安定した prefix を再利用したいなら、暗黙の経路に頼らず明示的なブレークポイントでマークすること。書き込みの倍率と最小値はモデルごとに確認すること。1 枚のドキュメントページでは均されてしまうが、いまはどちらもファミリーによって変わる。
この結果をどう使うか
- 自分の実効しきい値を測る。 自前のトークン数で prompt 長を振ってみて、キャッシュ読み取りが返ってくる最初の長さを記録する。ドキュメントに書かれた最小値からヒットが始まると思い込まないこと。
- ウォームアップを見込んでおく。 自動キャッシュ方式のプロバイダーでは、新しい prefix に対する最初の 2〜8 回の呼び出しは、コストモデル上ではキャッシュなしとして扱う。
- 明示マーカーがあるなら優先する。 Claude の cache_control は、テスト可能で正確な仕様を提供していた。最小値、読み取りレート、TTL、無効化ルールがすべて既知だ。この予測可能性は、当てにならないドキュメント上の低い下限値よりも価値がある。
- 新しいモデルファミリーでは基準を取り直す。 今回の調査でも、同じベンダーのラインナップ内で最小値、書き込み料金、ブレークポイントの挙動が変わっていた。
これらのしきい値の裏にある読み取りレート、TTL、キー生成ルールについては、prompt caching ガイドでプロバイダーごとの仕組みを解説している。
要点はこうだ。ドキュメントの最小値は利用資格の下限であって、ヒットのしきい値ではない。自動キャッシュではこの 2 つが 1.4〜2.4 倍ずれる。請求額を左右する数字は、自前のトークン数で、自分のトラフィックに対して検証すること。