プロンプトキャッシュ(Prompt Caching、プロンプトキャッシング)は、LLMに送るプロンプトのうち毎回同じ先頭部分について、モデルが計算した中間状態を一時保存し、次のリクエストで使い回す仕組みです。長いシステムプロンプトや参照文書を毎回送るチャットボットやエージェントでは、入力料金が基本単価の0.025〜0.1倍まで下がり、最初の文字が返るまでの時間も短くなります。OpenAIは2026年10月20日に、Responses APIで保持を12時間に延ばす選択肢(書き込みは入力単価の2.5倍)を追加しました。この記事では仕組みと応答キャッシュとの違いを押さえたうえで、OpenAIの30分・12時間の使い分け、Claude・Azure OpenAI・Gemini・Bedrock・Grokの設定と料金、LangChainからの使い方、キャッシュされたデータの扱い、ローカルLLM(llama.cpp)での実測までを、2026年10月時点の公式ドキュメントに沿って整理します。
まとめ:プロンプトキャッシュの要点と入力料金が下がる条件
- 保存されるのは入力の計算結果(KV)で、応答ではありません。回答は毎回生成されるので、同じ質問に同じ答えを返す仕組みとは別物です。
- 先頭からの完全一致が条件です。途中が1文字変わると、そこから後ろは再計算になります。時刻やIDなど毎回変わる値は末尾へ置きます。
- 入口は各社で違います。OpenAI・Gemini・Grokは既定で自動、Claudeは
cache_controlを1つ付けると有効になります。最低長はClaudeの5.5世代・Fable 5.1が512トークン(Sonnet 5は1,024)、OpenAIのGPT-5.6以降が1,024トークン、Gemini 4 Argon・3.8 Flashなどが4,096トークンです。 - 書き込みが割増になるモデルでは、再利用されない先頭にキャッシュを付けると損をします。ClaudeとGPT-5.6以降は書き込みが1.25倍(Claudeの1時間TTLは2倍、OpenAIの12時間保持は2.5倍)、読み取りは0.025〜0.1倍です。5分・30分の保持なら2回目の利用で元が取れます。
- OpenAIの12時間キャッシュは、30分を超える間隔で同じ先頭を3回以上使うときに得をします。Responses APIで
prompt_cache_options.ttlか区切りごとのttlに"12h"を指定します。数分おきに使う会話文脈は既定の"30m"のままが安上がりです。 - LangChainの
set_llm_cacheは応答キャッシュです。プロバイダのプロンプトキャッシュを使うなら、ChatAnthropicにcache_controlを渡します。 - 効いたかどうかは、応答の
usageにある読み取りトークン数で確かめます。ゼロが続くなら、先頭側に変わる値が混ざっています。
以下、仕組み→各社の設定(OpenAIの12時間キャッシュを含む)→LangChain→データの扱い→ローカルLLM→実測と設計の順に説明します。
プロンプトキャッシュの仕組み:先頭KVの再利用と入力処理の省略
プロバイダ側で保持する入力の中間状態(KV)と入力処理の再利用
LLMはプロンプトを先頭のトークンから順に処理し、トークンごとにKey・Valueと呼ばれる中間状態を計算します。OpenAIの公式ガイドは、プロンプトキャッシュが保存するのはこのKVテンソルでありトークンそのものではない、と明記している内容です。次のリクエストが同じ先頭で始まれば、その区間の計算を飛ばして続きだけを処理するため、入力料金の割引と最初のトークンまでの時間(TTFT)の短縮が同時に起きます。推論エンジン内部でKVを使い回す土台の仕組みはKVキャッシュの仕組みと推論高速化・メモリ削減の解説で詳しく扱っています。
ヒットの条件:先頭から連続して一致する区間と変更箇所による影響
一致判定は先頭からの完全一致です。Claudeでは公式ドキュメントのとおり、内部の並びがtools→system→messagesの順に固定されており、ツール定義を変えると後ろのsystemとmessagesも含めて再計算になります。OpenAIも同様で、model・tools・reasoning.effort・構造化出力のスキーマなどを変えると先頭が変わる扱いです。システムプロンプトに現在時刻を埋め込む、ツール一覧を毎回並べ替える、といった作りではキャッシュはほぼ効きません。
毎回生成される応答の性質と同じ回答を固定して返す用途への不向き
キャッシュされるのは入力側の計算だけで、モデルは毎回あらためて回答を生成します。同じプロンプトを再送しても、temperature次第で応答が変わる可能性もありますが、回答を固定する機能ではありません。llama.cppのサーバーREADMEも、cache_promptを有効にするとバッチサイズの違いで出力のlogitsがビット単位では一致しない場合があると注記しています。
応答キャッシュ・セマンティックキャッシュとの違いと回答生成の範囲
「LLMのキャッシュ」には、目的も置き場所も違う3種類があります。下げたいのが入力料金と待ち時間なのか、モデルの呼び出し回数そのものなのかで選びます。
| 種類 | 保存するもの | ヒット条件 | モデル呼び出し | 実装場所 |
|---|---|---|---|---|
| プロンプトキャッシュ | 入力先頭のKV | 先頭の完全一致 | 毎回する | プロバイダ・推論エンジン |
| 応答キャッシュ | 生成済みの応答 | プロンプト全体の完全一致 | しない | アプリ側(LangChain・Redis等) |
| セマンティックキャッシュ | 生成済みの応答 | 意味の近さ(ベクトル類似度) | しない | アプリ側(GPTCache等) |
プロンプトキャッシュは回答を毎回生成するので、品質を落とさずにコストと遅延を下げられます。応答キャッシュとセマンティックキャッシュはモデルを呼ばないぶん節約幅は大きいものの、古い回答を返す鮮度の問題と、似て非なる質問に誤った回答を返す問題をアプリ側での管理が必要です。両者は排他ではなく、応答キャッシュで拾えなかった質問だけをLLMへ送り、その送信部分にプロンプトキャッシュを効かせる併用も成り立ちます。
主要プロバイダのプロンプトキャッシュ比較(2026年10月)
各社の公式ドキュメントから、設定方法・最低長・保持時間・料金倍率を並べます。倍率は通常の入力単価に対する値です。
| 提供先 | 有効化 | 最低長(トークン) | 保持 | 読み取り | 書き込み |
|---|---|---|---|---|---|
| Claude(Anthropic) | cache_control | 512〜4,096 | 5分/1時間 | 0.025〜0.1倍 | 1.25倍/2倍 |
| OpenAI GPT-5.6以降 | 既定で自動 | 1,024 | 最低30分/12時間 | 0.1倍(6.1 Solは0.05倍) | 1.25倍/12時間は2.5倍 |
| OpenAI GPT-5.5以前 | 既定で自動 | 設定で変動 | 5〜10分〜24時間 | モデルごと(多くは0.1倍) | 追加料金なし |
| Azure OpenAI | 既定で自動 | 1,024 | 5.4以前の既定はin_memory | Standardは割引・PTUは最大100%割引 | GPT-5.6以降のみ課金 |
| Gemini API | 暗黙は既定で自動 | 2,048〜4,096 | 明示は既定1時間 | Gemini 4 Argonは0.05倍 | 明示のみ保存料金 |
| Amazon Bedrock | 暗黙/cachePoint | モデルごと(Claude 5.5世代は512) | 5分/1時間 | モデルごと | モデルごと |
| xAI Grok | 既定で自動 | 公式に記載なし | 公式に記載なし | 割引単価 | – |
実務でまず見るのは、書き込みに割増があるか(Claude・GPT-5.6以降)と、最低長に届くか(Gemini 4 Argon・3.8/3.6 Flash、Haiku 4.5、Opus 4.6/4.5は4,096トークン)です。最低長に届かないプロンプトはエラーにならず、黙ってキャッシュされずに処理されます。OpenAIの12時間保持はResponses APIだけの選択肢で、読み取りの倍率は30分保持と同じです。
OpenAIのプロンプトキャッシュ:GPT-5.6で変わった課金と設定
OpenAI APIのキャッシュは、対応モデルなら設定なしで有効です。ただし公式ガイドのとおり、GPT-5.6を境に方式と課金が分かれています。
GPT-5.6以降:書き込み1.25倍とprompt_cache_options
GPT-5.6以降は、キャッシュの書き込みに通常入力の1.25倍、読み取りに0.1倍(GPT-6.1 Solは0.05倍)がかかります。料金表のStandard(短いコンテキスト)では、GPT-6.1 Solが入力2.00ドル・キャッシュ入力0.10ドル・30分の書き込み2.50ドル・12時間の書き込み5.00ドル(100万トークンあたり)です。prompt_cache_options.modeが既定のimplicitなら最新メッセージの末尾に自動で区切りが置かれ、explicitにすると入力ブロックに付けた"prompt_cache_breakpoint": {"mode": "explicit"}だけを使います。1リクエストで作れる書き込みは4つまでです。保持はprompt_cache_options.ttlで選び、既定の"30m"(最低30分)に加えて、2026年10月20日からResponses APIで"12h"(最低12時間)を指定できます。12時間の使い方は次の章で扱います。prompt_cache_keyはルーティングの調整には不要になり、顧客やユーザーごとにキャッシュの集計を分けたいときに使う任意項目になりました。毎回変わる内容にまで書き込みが発生する設計だと、旧世代の感覚より割高になります。
GPT-5.5以前:書き込み無料とprompt_cache_retention
GPT-5.5以前は書き込みに追加料金がかかりません。保持はprompt_cache_retentionで選び、"in_memory"は非アクティブ5〜10分程度で消え最長1時間、"24h"は通常30分程度から最長24時間です。GPT-5.5とGPT-5.5 Proは"24h"のみ、両方に対応する旧モデルでは指定を省くと、Zero Data Retention(ZDR)が無効の組織は24h、有効の組織はin_memoryが既定になります。12時間のttlはこのprompt_cache_retentionの挙動を変えません。このGPT-5.5以前では、共通の先頭を持つリクエストに同じprompt_cache_keyを付けると同じマシンへ寄りやすくなります。1つのキーあたり、すべての先頭を合計して毎分15リクエスト程度が目安で、超えると別マシンへあふれてミスが出やすくなるため、量が多い場合は決まった規則でキーを分けます。
OpenAIの12時間プロンプトキャッシュ:ttlの指定方法と30分保持との損益分岐
30分の保持では、昼休みや会議をはさんで1時間後に同じシステムプロンプトを送ると、もう一度書き込み料金がかかります。12時間キャッシュは、この「数時間おきに同じ先頭を使う」処理の書き込みを1日1回程度に抑えるための選択肢です。
2026年10月20日の追加内容:Responses APIで選べる12時間の最低保持
OpenAI APIのchangelogは、2026年10月20日付でv1/responsesに12時間のプロンプトキャッシュを追加したと告知しています。共有の指示・ツール定義・文脈を長く保持し、リクエストの間隔が数時間空いてもキャッシュ入力の単価で読めるようにするもので、12時間の書き込みは入力単価の2.5倍です。公式ガイドの記載で押さえる点は次の4つです。
- 2.5倍は通常入力への上乗せではなく、書き込みにかかる総額の倍率です(30分の1.25倍も同じ扱い)。
- 読み取りの倍率は30分・12時間で同じです(多くのモデルで0.1倍、GPT-6.1 Solは0.05倍)。
- 12時間は「キャッシュ入力の単価で読める資格」の最低期間です。保存したKVが毎回使われることや、待ち時間が必ず短くなることは保証されません。
"12h"は削除期限を設定するものではなく、データ保持の上限ポリシーも変えません。OpenAIが指定より長く保持する場合もあります。
Responses APIの基本と、Chat Completions APIから移すときの判断はOpenAI Responses APIとChat Completions APIの違いと移行手順で扱っています。なお、Azure OpenAIのプロンプトキャッシュ解説(2026-08-11更新、2026-10-24に確認)はttlの値を30mのみと記載しており、12時間は本家OpenAI APIの選択肢として扱うのが現時点では安全です。
区切り単位のttlで12時間を指定するResponses APIのcurl例
指定できる場所は次の2か所です。prompt_cache_options.ttlはリクエスト全体の既定値で、暗黙の区切りと、ttlを持たない明示の区切りに効きます。prompt_cache_breakpoint.ttlは個々の明示の区切りだけを上書きする指定です。どちらも省けば従来どおり30分で、対応しない値は400 invalid_request_errorになります。一日中使う社内規程は12時間、数分おきに変わる会話の文脈は30分、という混在が公式の推奨パターンです。
curl https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6.1-sol",
"prompt_cache_options": { "mode": "explicit", "ttl": "30m" },
"input": [
{ "role": "developer", "content": [ {
"type": "input_text",
"text": "社内規程に基づいて回答してください。(1,024トークン以上の規程本文)",
"prompt_cache_breakpoint": { "mode": "explicit", "ttl": "12h" }
} ] },
{ "role": "user", "content": [
{ "type": "input_text",
"text": "この案件の経緯(数分おきに追記される会話文脈)",
"prompt_cache_breakpoint": { "mode": "explicit" } },
{ "type": "input_text",
"text": "顧客情報の持ち出しは誰の許可が要りますか。" }
] }
]
}'
1つ目の区切りは区切り単位の"12h"で、2つ目は区切りにttlが無いのでリクエスト既定の"30m"になります。explicitモードなので、最後の区切りより後ろにある今回の質問には書き込み料金がかかりません。区切りの手前までの各先頭が、モデルの最低長(GPT-5.6以降は1,024トークン)に届いている必要があります。Pythonから同じリクエストを組み立てるときのクライアントの初期化はOpenAI Python SDKの使い方を参照してください。
課金の規則:重なる区間は長い保持で1回課金、30分から12時間は再書き込み
区切りは、その手前の先頭全体を覆います。1つのリクエストの中で同じトークンを複数の書き込みが覆う場合、そのトークンは覆っている中で最も長い保持の単価で1回だけ課金されます。公式ガイドの例をまとめると次のとおりです。
| 送信前の状態 | 指定した区切り | 読み取り | 30分書き込み | 12時間書き込み |
|---|---|---|---|---|
| キャッシュなし | 2,000で12h→5,000で30m | 0 | 3,000 | 2,000 |
| キャッシュなし | 2,000で30m→5,000で12h | 0 | 0 | 5,000 |
| 2,000まで30分の保持あり | 5,000で12h | 0 | 0 | 5,000 |
| 2,000まで12時間の保持あり | 5,000で30m | 2,000 | 3,000 | 0 |
3行目のとおり、30分で保持している区間を12時間へ格上げすると、前回の書き込み分は差し引かれず、その区間にも12時間の書き込み料金がかかります。最初から12時間で書くか、30分のまま使うかを決めておき、途中で切り替えない設計が安上がりです。逆に、12時間の保持がある区間を30分の区切りで読んだ場合は読み取りとして課金され、12時間の期限が延びることも、書き込みが再び発生することもありません。
30分と12時間の損益分岐:30分超の間隔で3回以上使う先頭は12時間
同じ先頭を、毎回30分以上空けてK回使う場合を、通常入力1回分を1として比べます。読み取りの倍率をrとすると、キャッシュなしはK、30分保持は毎回書き直しになるので1.25×K、12時間保持は「2.5+r×(K−1)」です。r=0.1ならK=2で2.6対2(キャッシュなし)・2.5(30分)と12時間が最も高く、K=3で2.7対3・3.75となり12時間が逆転します。GPT-6.1 Sol(r=0.05)でも同じくK=3からです。一方、30分以内に何度も使う会話や連続したエージェントの手順では、書き込みが1回で済む30分保持(1.25倍)のほうが12時間(2.5倍)より安くなります。
具体額では、GPT-6.1 Solで1万トークンの社内規程を先頭に置き、9時から18時まで1時間おきに10回使う場合、キャッシュなしは0.20ドル、30分保持は毎回書き込みになって0.25ドル、12時間保持は書き込み0.05ドル+読み取り9回0.009ドルの約0.059ドルで、キャッシュなしより約70%少なくなります(いずれも料金表の100万トークン単価から計算、2026年10月時点)。12時間を選ぶ前に、ログから同じ先頭の利用間隔を集計し、30分を超える間隔での再利用が1日3回以上あるかを確かめてください。
効果の確認では、usage.input_tokens_details.cache_write_tokens_detailsのttl_30m_tokensとttl_12h_tokensを見ます。2つは重複せず、合計がcache_write_tokensに相当する内訳です。入力の費用は「通常入力×入力単価+cached_tokens×キャッシュ入力単価+ttl_30m_tokens×1.25倍の単価+ttl_12h_tokens×2.5倍の単価」で、cache_write_tokensを重ねて足さないよう注意します。通常入力はinput_tokensから読み取りと書き込みを引いた残りです。
Azure OpenAIのプロンプトキャッシュ:保持期間とデプロイ種別の違い
Microsoft Learnのプロンプトキャッシュ解説(2026-08-11更新)によると、Azure OpenAIのリクエスト形式はOpenAIと同じで、modelにデプロイ名を入れる点だけが違います。条件は1,024トークン以上で、先頭1,024トークンが一致することです。呼び出し側の実装手順はAzure OpenAI APIの使い方(Python・REST呼び出し)で扱っています。
OpenAI本家と異なるのは既定値とデプロイ種別です。GPT-5.4以前はprompt_cache_retentionを省くとin_memory、GPT-5.5は拡張保持(最長24時間)を既定値としています。読み取りの割引はStandardで入力単価の割引、Provisioned(PTU)では最大100%割引です。GPT-5.6以降の明示的な区切り(breakpoint)とcache_write_tokensはStandardの従量課金デプロイだけが対応し、PTU-Mは対応しません。prompt_cache_options.ttlは同解説の時点で30mが唯一の値で、本家の"12h"をそのまま送る共通コードは事前に検証が要ります。GPT-5.5以前のモデルにprompt_cache_optionsを送ると400エラーになるので、モデルを混在させる共通コードでは分岐が要ります。
Claudeのプロンプトキャッシュ:cache_controlの2方式と料金倍率
最上位に1つ付ける自動方式と、固定ブロック単位で区切る明示方式
Claudeはcache_control(typeはephemeral)で有効にします。自動方式はリクエストの最上位に"cache_control": {"type": "ephemeral"}を1つ置くだけで、最後のキャッシュ可能なブロックに区切りが付き、会話が伸びると区切りも後ろへずれる仕組みです。ただし最後のブロックが毎回変わる構成(固定の指示に毎回違う質問を付ける、末尾に時刻を付けるなど)では、書き込みが変わるブロックの位置でしか起きないため、自動方式は1回もヒットせず書き込み料金だけがかかります。この場合は固定部分の末尾に明示の区切りを置きます。明示方式はシステムプロンプトやツール定義など個々のブロックにcache_controlを付ける書き方で、区切りは1リクエスト最大4つです。自動方式も4つの枠を1つ使います。各区切りからさかのぼって既存のキャッシュを探すのは20ブロックまでなので、1ターンで20ブロック以上増える会話では手前にもう1つ区切りを置きます。
TTLは5分と1時間、読み取りはモデルで0.025〜0.1倍
TTLは既定5分で、"ttl": "1h"で1時間になります。5分以内に再利用されるたびに、追加料金なしで延長される仕組みです。書き込みは5分TTLが1.25倍、1時間TTLが2倍で全モデル共通ですが、読み取りの倍率はモデルで違います。
| モデル | 入力 | 5分書き込み | 1時間書き込み | 読み取り | 最低長 |
|---|---|---|---|---|---|
| Fable 5.1 | 10ドル | 12.50ドル | 20ドル | 0.25ドル(0.025倍) | 512 |
| Opus 5.5 | 4ドル | 5ドル | 8ドル | 0.20ドル(0.05倍) | 512 |
| Sonnet 5.5 | 2ドル | 2.50ドル | 4ドル | 0.10ドル(0.05倍) | 512 |
| Sonnet 5 | 2ドル | 2.50ドル | 4ドル | 0.20ドル(0.1倍) | 1,024 |
| Haiku 4.5 | 1ドル | 1.25ドル | 2ドル | 0.10ドル(0.1倍) | 4,096 |
単価は100万トークンあたりで、Anthropicのプロンプトキャッシュ解説の料金表によります。Haiku 5.5はプロンプト10万トークン以下が入力0.10ドル・読み取り0.01ドル、超えると入力0.50ドル・読み取り0.05ドルの2段階で、キャッシュの読み書きもプロンプト長に数えられます。Opus 4.6・Opus 4.5も最低長が4,096トークンなので、短めのシステムプロンプトをHaiku 4.5や旧Opusへ移すとキャッシュが効かなくなる点に注意してください。モデル別の基本単価やAPIキーの取得はAnthropic API(Claude API)の料金とAPIキー取得方法で確認できます。数時間おきに使う先頭について、Claudeの最長は1時間TTLなので、OpenAIの12時間保持に相当する選択肢はありません。間隔が1時間を超える処理では、毎回書き直す前提で損益を計算します。
キャッシュのウォームアップ:max_tokens:0による事前書き込み
利用者の最初のリクエストだけはキャッシュミスで遅くなります。Claudeではmax_tokens: 0のリクエストを先に送ると、出力を生成せずにcache_controlの位置までキャッシュを書き込み、空のcontentとstop_reason: "max_tokens"を返します。出力トークンは課金されず、課金は書き込みと区切り以降の通常入力だけです。区切りはダミーの質問ではなく、後続リクエストと共有するシステムプロンプトやツール定義の末尾に明示で置き(自動方式は使わない)、thinkingとoutput_config.effortは本番リクエストと揃えます。stream: true・拡張思考のthinking.type: "enabled"・構造化出力・tool_choiceのtool・any指定と組み合わせるとinvalid_request_errorになり、Message Batchesの中でも使えません。以前のmax_tokens: 1で温める回避策は、この方式に置き換えられます。
Gemini・Amazon Bedrock・xAI Grokのキャッシュ設定
Gemini API:暗黙キャッシュと明示のコンテキストキャッシュ
Geminiでは「コンテキストキャッシュ」と呼びます。公式ガイド(2026-10-13更新)によると、暗黙キャッシュはGemini 2.5以降の全モデルで既定オンで、最低長はGemini 4 Argon・3.8 Flash・3.6 Flash・3.1 Pro Previewが4,096、2.5 Flash・2.5 Proが2,048トークンです。キャッシュを作成してTTLを決める明示キャッシュは、generateContent APIの対応するGemini 3・2.5モデルだけで使え、Gemini 4 ArgonとInteractions APIは暗黙のみです。料金表では、Gemini 4 Argonの入力2.00ドルに対しキャッシュ入力は0.10ドル(2026年11月30日まで)で、12月1日からはそれぞれ4.00ドルと0.20ドルになります。明示キャッシュには保存料金がかかるため、1時間に何十回も参照する大きな固定文脈があるときだけ使い、それ以外は暗黙キャッシュに任せます。
Amazon Bedrock:cachePointとバッチ非対応
Bedrockのユーザーガイドでは、自動で先頭一致を試みる暗黙キャッシュと、Converse APIのcachePointやInvokeModel APIのcache_controlで区切る明示キャッシュが並んでいます。Claude Opus 5.5・Sonnet 5.5・Haiku 5.5は最低512トークン・チェックポイント最大4つ・TTL 5分または1時間です。オンデマンド推論専用で、バッチ推論APIでは使えません。対応モデル表と料金はAmazon Bedrockのプロンプトキャッシュの仕組み・対応モデル・料金で、Converse APIの呼び出し方はAmazon Bedrock Converse APIの使い方で扱っています。
xAI Grok:自動キャッシュとx-grok-conv-id
xAI(現SpaceXAI)のドキュメントによると、Grokは連続するリクエストの先頭メッセージが一致すると自動でキャッシュします。ヒット率を上げるにはx-grok-conv-idヘッダー(Responses APIではprompt_cache_key)に会話IDを入れ、同じサーバーへ寄せる指定が有効です。過去のメッセージを編集・削除・並べ替えると一致が崩れるので、履歴は追記だけにします。
LangChainのプロンプトキャッシュと応答キャッシュの設定・使い分け
「LangChain キャッシュ」で出てくる情報の多くはset_llm_cacheの解説ですが、これはプロバイダのプロンプトキャッシュではありません。LangChainでは2つを分けて考えます。
set_llm_cacheの正体:完全一致で呼び出しを省く応答キャッシュ
langchain_core.cachesのBaseCacheは、プロンプトの文字列とモデル設定の組をキーにして生成結果を保存する層です。langchain-core 1.6.12でモデル呼び出し回数を数えるテスト用モデルにInMemoryCacheを設定し、3回呼び出して確かめました。
from langchain_core.globals import set_llm_cache
from langchain_core.caches import InMemoryCache
# model は呼び出し回数を数えるテスト用モデル(GenericFakeChatModel の派生)
set_llm_cache(InMemoryCache())
r1 = model.invoke("社内規程を要約して") # モデルを呼ぶ → 応答A
r2 = model.invoke("社内規程を要約して") # 呼ばない → 応答Aをそのまま返す
r3 = model.invoke("社内規程を要約してください") # 末尾だけ違う → モデルを呼ぶ → 応答B
# 実行結果: r1=応答A r2=応答A r3=応答B model_calls=2
完全一致の2回目はモデルを呼ばずに1回目の応答を返し、末尾が少し違うだけの3回目は普通に呼び出しました。応答キャッシュは「先頭が同じなら後ろが違ってもよい」プロンプトキャッシュとは一致条件が逆で、回答も固定されます。社内規程が改訂されても古い回答が返り続けるので、使うなら保存期間と消去の手順を決めておきます。
ChatAnthropicのcache_control指定とsystemブロックの区切り
Claudeのプロンプトキャッシュは、LangChainのAnthropic連携ドキュメントのとおり2通りで使えます。langchain-anthropic 1.4.0以降ならinvokeにcache_controlを渡すと自動方式になり、langchain-anthropic 1.7.6で送信内容を組み立てさせると、リクエスト最上位に'cache_control': {'type': 'ephemeral'}が載ることを確認しました。ただし自動方式の区切りは最後のブロック(ユーザーの質問)に付くので、会話を追記していくマルチターン向けです。固定の規程に毎回違う質問を付ける用途では、次のようにsystemブロックへ区切りを付けます。
from langchain_anthropic import ChatAnthropic
model = ChatAnthropic(model="claude-sonnet-5-5")
messages = [
{"role": "system", "content": [{
"type": "text",
"text": "社内規程に基づいて回答してください。\n" + manual,
"cache_control": {"type": "ephemeral"}, # 1時間なら "ttl": "1h" を追加
}]},
{"role": "user", "content": "顧客情報の持ち出しは誰の許可が要りますか。"},
]
res = model.invoke(messages)
print(res.usage_metadata["input_token_details"]) # {'cache_read': ..., 'cache_creation': ...}
会話を伸ばしていくチャットボットなら、model.invoke(messages, cache_control={"type": "ephemeral"})の自動方式で区切りの管理を任せられます。create_agentで作るエージェントにはlangchain_anthropic.middleware.AnthropicPromptCachingMiddleware(引数ttlは"5m"か"1h")を挟むと、システムプロンプトとツール定義のキャッシュはLangChain側で管理が可能です。OpenAIはChatOpenAIのままで自動キャッシュが効き、必要ならprompt_cache_keyを渡します。BedrockにはBedrockPromptCachingMiddlewareがあります。JavaScript版の導入はLangChain.jsの導入と使い方を参照してください。
キャッシュされたデータの保持・分離・暗号化と提供元ごとの確認事項
社内文書をキャッシュに載せる前に、どこにどれだけ残るかを確認しておきます。3社とも組織をまたいでキャッシュを共有しない点は共通ですが、保存場所の書き方が違います。
| 提供先 | 保存場所 | 分離の単位 | 保持期間 | ZDR |
|---|---|---|---|---|
| Anthropic | メモリのみ(保存しない) | 組織・ワークスペース | 最低5分/1時間、利用で延長、期限後に削除 | 対象 |
| OpenAI | 暗号化したKVをGPUローカルに置く場合あり | 組織・処理リージョン | 5.5以前24時間、5.6以降30分/12時間 | 有効なら既定in_memory |
| Azure OpenAI | メモリ、拡張保持はGPUローカル | Azureサブスクリプション | in_memoryは最終利用から1時間以内 | – |
Anthropicは公式ドキュメントのデータ保持の項で、プロンプトの原文と応答を保存せず、KV表現とキャッシュ内容の暗号学的ハッシュはメモリ上だけに置き、保存(at rest)しないと書いています。分離の単位は組織とワークスペースで、Bedrock・Google Cloud経由では組織単位です。OpenAIは、キャッシュが暗号化したKVテンソルをアプリケーションの状態としてGPUローカルのストレージに置く場合があると明記し、ZDRの有無で保持の既定値を変えています。12時間キャッシュについても、指定するのは最低期間であって削除期限ではない、と公式ガイドが断っています。「12時間後に確実に消える」前提で社内規程や個人情報を載せる設計にはしないでください。Azure OpenAIの解説は、キャッシュをサブスクリプション間で共有しないこと、拡張保持ではメモリが満杯になるとKVテンソルをGPUローカルのストレージへ退避すること、Data Zoneのデプロイではデータゾーン、Regionalのデプロイではリージョンの境界内にデータがとどまることを示していますが、キャッシュ自体の暗号化方式(鍵の種類やカスタマーマネージドキーの適用可否)は記載していません。Azureで暗号化方式を監査要件として示す必要があるなら、プロンプトキャッシュの記述だけで判断せず、Microsoftのデータプライバシー文書かサポート窓口で確認してから、拡張保持を避けてin_memoryを明示する運用が安全です。
ローカルLLMのプロンプトキャッシュ:llama.cppのcache_promptを実測
ローカル実行には従量課金がないので、狙いは料金ではなくプロンプト処理時間の短縮です。llama.cppのサーバーREADMEでは、--cache-prompt(リクエスト単位ではcache_prompt)は既定で有効で、前回と共通する先頭のKVを再利用し、違う後半だけを処理します。--cache-reuse Nは、先頭以外の一致チャンクをKVシフトで再利用する最小サイズで、既定0(無効)です。
同じ先頭での処理量:2,100トークンから13トークンへの削減
llama.cpp v0.7.0(コミット620d222)のllama-serverに、Qwen2.5-0.5B-InstructのQ4_K_M量子化GGUFを読み込み、Intel Core i9-9880HのCPUだけで計測しました。約2,100トークンの社内規程を先頭に置き、末尾の質問だけを変えて/completionへ送り、応答のtimingsを比べた結果です。
| リクエスト | cache_n | prompt_n | プロンプト処理 |
|---|---|---|---|
| 1回目(初回) | 0 | 2,100 | 20.4秒 |
| 2回目(質問だけ変更) | 2,082 | 13 | 0.33秒 |
| 先頭に現在時刻を1行追加 | 0 | 2,119 | 19.8秒 |
| cache_prompt: false | 0 | 2,100 | 20.8秒 |
cache_nは再利用したトークン数、prompt_nは新たに処理したトークン数です。質問だけを変えた2回目は処理が13トークンに減り、プロンプト処理は20.4秒から0.33秒になりました。一方、先頭に時刻を1行足しただけで再利用は0になり、初回と同じ時間がかかります。クラウドAPIで「先頭に時刻を入れるとキャッシュが効かない」と言われる理由が、そのまま数字に出ています。
別の文書を挟んだ後の再利用と–cache-ramによるKVの保持
スロットが1つのサーバーで「社内規程→経費規程→社内規程」の順に送ると、--cache-ram 0では3回目の再利用が2トークンだけで19.8秒かかりました。既定の--cache-ram 8192(MiB)では、3回目が2,082トークンを再利用して0.19秒で済みました。READMEのとおり、空いたスロットのKVをRAM上のプロンプトキャッシュへ退避しておき、後で同じ先頭が来たときに戻す仕組みです。複数の文書を切り替えて使うなら、メモリに余裕がある限り--cache-ramを0にしないでください。
Ollamaではモデルがメモリから外れると、保持していたKVも失われます。OllamaのFAQによると、モデルは既定で5分間使われないとアンロードされるので、長いシステムプロンプトを使う場合はAPIのkeep_alive(例:"24h"、-1で無期限)で常駐させる設定が可能です。複数の利用者でサーバーを共有するなら、先頭一致のKVをリクエスト間で共有できるvLLMの自動プレフィックスキャッシュが適した選択肢です。仕組みはvLLMのPagedAttentionの仕組みと使い方で扱っています。
キャッシュの効果確認:usageの読み取りトークン数と書き込みの内訳
先頭に変わる値が混ざっていれば、設定が正しく見えても1回もヒットしません。確かめる方法は応答の使用量を見ることだけなので、同じ先頭のリクエストを2回送って数字を比べる手順を最初に組み込みます。
Claude APIの2回送信による読み取り・書き込みトークンの確認
Anthropic公式SDK(anthropic 1.15.0)で、長い社内規程をシステムプロンプトに入れ、質問だけを変えて2回呼び出す例です。質問が毎回変わるので、自動方式ではなくsystemブロックに明示の区切りを付けます。1回目はcache_creation_input_tokensに書き込み量が、5分以内の2回目はcache_read_input_tokensに読み取り量が出れば成功です。
import anthropic
client = anthropic.Anthropic()
manual = open("rules.txt", encoding="utf-8").read() # 512トークン以上の固定文書
def ask(question):
r = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=512,
system=[{
"type": "text",
"text": "社内規程に基づいて回答してください。\n" + manual,
"cache_control": {"type": "ephemeral"}, # 明示方式:固定部分の末尾に区切り
}],
messages=[{"role": "user", "content": question}],
)
u = r.usage
print("write", u.cache_creation_input_tokens, "read", u.cache_read_input_tokens, "other", u.input_tokens)
ask("顧客情報の持ち出しは誰の許可が要りますか。") # 1回目: writeに数値
ask("違反時は何条で処分されますか。") # 2回目: readに数値
Claudeの総入力は「読み取り+書き込み+input_tokens」の合計なので、input_tokensだけを見て減っていないと判断しないでください。2回目も読み取りがゼロなら、rules.txtに更新日時などが埋め込まれていないか、最低長に届いているかを確かめます。
各社のusageフィールド対応表と読み取り・書き込みトークンの集計範囲
読み取りと書き込みのトークン数が返るフィールドは、提供先ごとに次のとおりです。
- Claude:読み取りは
usage.cache_read_input_tokens、書き込みはusage.cache_creation_input_tokens - OpenAI(Responses API):読み取りは
usage.input_tokens_details.cached_tokens、書き込みはusage.input_tokens_details.cache_write_tokens - OpenAI・Azure(Chat Completions):読み取りは
usage.prompt_tokens_details.cached_tokens、書き込みはusage.prompt_tokens_details.cache_write_tokens - Bedrock(Converse API):読み取りは
cacheReadInputTokens、書き込みはcacheWriteInputTokens - Gemini(Interactions API):読み取りは
usage.total_cached_tokens(書き込みの項目なし) - Gemini(generateContent):読み取りは
usageMetadata.cachedContentTokenCount(書き込みの項目なし) - xAI Grok(Chat Completions):読み取りは
usage.prompt_tokens_details.cached_tokens(書き込みの項目なし) - LangChain:読み取りは
usage_metadata.input_token_details.cache_read、書き込みは同じ場所のcache_creation
書き込みトークンが出るのはOpenAI・AzureではGPT-5.6以降だけです。OpenAIのResponses APIでは、書き込みの内訳がcache_write_tokens_detailsのttl_30m_tokensとttl_12h_tokensに分かれて返り、片方がゼロでも両方のフィールドが出ます。cached_tokensは課金された読み取りだけを数え、30分から12時間への格上げで書き込みとして課金された分は含みません。監視ダッシュボードには読み取りトークン÷総入力トークンの「キャッシュ率」を出しておくと、プロンプトを改修してキャッシュが壊れたときにすぐ気づけます。OpenAIにはPrompt Caching Dashboardもあります。
ヒット率を上げるプロンプト設計と再利用回数・保持期間別の損益分岐
先頭に固定の指示とツール定義を置き、末尾に時刻やIDを回す構成
プロンプトの先頭に置くのは固定の内容だけです。システムプロンプト、ツール定義、few-shotの例、参照文書を前半に固め、ユーザーの質問・現在時刻・リクエストIDは末尾へ回し、Claudeではその手前(固定部分の末尾)に明示の区切りを置きます。OpenAIで12時間と30分を混在させるときも同じ順で、一日中変わらない部分を最前列に置き、そこへ12時間の区切りを付ける構成です。JSONを差し込むならキー順を固定し、同じバイト列にします。会話が続くエージェントでは、途中でツール定義やモデルを入れ替えると全体が無効になるので、モードの切り替えはメッセージで表現する方法が有効です。OpenAIのGPT-6系なら、推論の強さを変えるときもreasoning.effortを書き換えずconfiguration_updateを追記すれば先頭を保てます。文脈の組み立て全体はコンテキストエンジニアリングとプロンプトエンジニアリングの違いも参考になります。
損益分岐の比較:5分TTLは2回目、1時間TTLは3回目から得になる条件
Sonnet 5.5やGPT-6.1 Solのように書き込み1.25倍・読み取り0.05倍のモデルで、同じ先頭をN回使う場合を比べます。キャッシュなしはN、5分TTL(OpenAIなら30分保持)は「1.25+0.05×(N−1)」なので、N=2で1.30対2となり2回目から得です。1時間TTLは「2+0.05×(N−1)」で、N=2は2.05対2でわずかに損、3回目(2.10対3)から得になります。OpenAIの12時間保持は「2.5+0.05×(N−1)」で、同じく3回目(2.60対3)から得です。具体額では、Sonnet 5.5で1万トークンのシステムプロンプトを5分以内に100回送ると、キャッシュなしは2.00ドル、キャッシュありは書き込み0.025ドル+読み取り0.099ドルの約0.12ドルで、約94%の削減です。書き込みが無料のGPT-5.5以前は、ヒットしなくても損をしません。
書き込み料金と再利用の見込みからキャッシュを付けないほうがよい3つの条件
次のどれかに当てはまるなら、書き込みが割増のモデルではキャッシュを付けません。いちばん多いのは先頭が毎回変わり、共有できる部分がない処理で、書き込み料金だけを払って読み取りが起きません。次がリクエスト間隔がTTLより長い処理で、1日数回のバッチ的な要約などです。1時間TTLやOpenAIの12時間保持・24h保持に切り替える前に、保持期間の中での再利用が2〜3回に届くかを計算します。12時間保持でも、1日1〜2回しか使わない先頭なら2.5倍の書き込み分だけ損になります。最後が最低長に届かない短いプロンプトで、付けても何も起きません。逆に、数千トークンの固定指示を持つ社内チャットボット、同じリポジトリ文脈で何十回もツールを呼ぶコーディングエージェント、長いPDFへの連続質問は、迷わず採用してよい典型です。トークン消費を減らすもう1つの手段はauto-compactによる自動コンテキスト圧縮で扱っています。社内チャットボットや業務エージェントにキャッシュ前提のプロンプト構成と費用見積りを組み込みたい場合は、一創の生成AI導入支援でモデル選定から実装・運用監視まで支援しています。
よくある質問
OpenAIの12時間プロンプトキャッシュはどんなときに使いますか?
同じシステムプロンプトや参照文書を、30分を超える間隔で1日3回以上使う処理に向きます。書き込みは入力単価の2.5倍で、読み取りの倍率は30分保持と同じです。数分おきに続く会話やエージェントの手順は、既定の30分保持のほうが安くなります。指定はResponses APIのprompt_cache_options.ttlか、明示の区切りのttlに"12h"を入れます。
プロンプトキャッシュを使うと毎回同じ回答が返りますか?
いいえ。キャッシュされるのは入力側の計算だけで、応答は毎回モデルが生成します。同じ入力に同じ回答を返したい場合は、LangChainのset_llm_cacheなどの応答キャッシュが選択肢です。なお、プロンプトキャッシングとプロンプトキャッシュは同じ機能の呼び方の違いで、Geminiは「コンテキストキャッシュ」と呼んでいます。
LangChainでClaudeのプロンプトキャッシュを使うにはどうしますか?
固定のシステムプロンプトに毎回違う質問を付けるなら、systemのコンテンツブロックに"cache_control": {"type": "ephemeral"}を付けます。会話を追記していくマルチターンなら、langchain-anthropic 1.4.0以降でinvokeにcache_controlを渡す自動方式が利用可能です。エージェントならAnthropicPromptCachingMiddlewareを使います。効果の確認先はusage_metadataのcache_readです。
Azure OpenAIのプロンプトキャッシュは暗号化されていますか?
Azure OpenAIのプロンプトキャッシュ解説には、キャッシュ自体の暗号化方式の記載がありません。書かれているのはサブスクリプション間で共有しないことと保持期間・保存場所です。監査で方式の根拠が要るなら、Microsoftの公式窓口で確認してください。また同解説(2026-08-11更新)ではttlの値は30mのみで、本家OpenAIの12時間保持は記載されていません。
キャッシュがヒットしない主な原因は何ですか?
先頭側に毎回変わる値が入っているのが最も多い原因です。現在時刻、UUID、キー順が不定なJSON、会話途中でのツール定義の差し替えが該当します。Claudeの自動方式で、最後のブロック(質問)が毎回変わる構成もヒットしません。次に多いのが、最低長(Claudeの5.5世代は512、Haiku 4.5は4,096、OpenAIのGPT-5.6以降は1,024トークン)に届いていないケースと、リクエスト間隔がTTLを超えているケースです。OpenAIでは間隔が30分を超えるなら12時間保持を検討します。
関連記事
- Amazon Bedrockのプロンプトキャッシュとは|仕組み・対応モデル・料金・実装方法【2026年最新】
- OpenAI Responses APIとChat Completions APIの違い|移行手順と見送る条件【2026年10月】
- KVキャッシュとは?LLM推論を高速化する仕組みとメモリ削減・実装判断を実装者向けに解説【2026年版】
- Anthropic API(Claude API)の料金とAPIキー取得方法|モデル別単価・無料枠・月額上限【2026年9月】
- vLLMとは?PagedAttentionの仕組み・使い方とOllama・TensorRT-LLMとの違いを実装者目線で解説
- コンテキストエンジニアリングとは?プロンプトエンジニアリングとの違いと4つの実装手法