「AI 開発してます」を見極める 10 の質問 — 素人のための解説|2026-08 版
第 3 章Q2

Q2 キャッシングの使い分け

同じ計算を二度しない — プロンプトキャッシュとセマンティックキャッシュは別物

Q2. キャッシングの使い分け

プロンプトキャッシングやセマンティックキャッシングを実際に使ったことはありますか? どんな場面で導入し、効果や注意点をどう感じていますか?

出典: @voidwarriorchan の投稿(2026-08-25)
この章で分かること

この質問は何を聞いているのか

質問文には専門用語が2つ並ぶ。プロンプトキャッシング(prompt caching)とは、リクエストのあいだで共通する「プロンプトの先頭部分」の計算結果を保存しておき、次回以降は計算をやり直さずに使い回す仕組みである。セマンティックキャッシング(semantic cache)とは、LLM が返した「応答そのもの」を保存しておき、新しく来た質問が過去の質問と意味的に近いときに、LLM を呼ばずに保存済みの応答をそのまま返す仕組みである。どちらも名前に「キャッシュ」が付くが、再利用する対象がまったく違う――前者は計算を、後者は応答を使い回す。

つまりこの質問は、「同じ計算を何度もさせていないか」「同じ意味の質問に同じ答えを使い回しているか」という、コストとレイテンシに直結する2種類の使い回しを、実際に扱った経験があるかを尋ねている。「効果や注意点」に答えるには、書き込みコストや誤ヒットのリスクというトレードオフを実測した経験が要る。したがってこの質問は、候補者が両者を混同せず仕組みのレベルまで理解し、実務経験があるかを測ることができる。

プロンプトキャッシュ セマンティックキャッシュ ハッシュが一致 生成へ進む しきい値と比較 判定結果に応じて プロンプトの先頭が前回と完全一致 KVキャッシュを再利用(計算を省く) 応答は毎回新しく生成される 意味が近い質問(表現が違っても可) しきい値で意味の近さを判定 ヒット時:保存済み応答をそのまま返す (LLMを呼ばない=出力トークン0)
図 3-1 プロンプトキャッシュは「計算結果」を、セマンティックキャッシュは「応答そのもの」を再利用する。一致の判定条件も、前方一致としきい値でまったく異なる。

プロンプトキャッシング — 計算結果(KVキャッシュ)を使い回す

LLMはTransformer(= 現在のLLMのほぼすべてが採用している計算方式の名前)という仕組みの中で、トークン(= モデルが文章を扱う最小単位。日本語なら1〜2文字程度)ごとに「キー」と「バリュー」という中間の計算結果、KVキャッシュ(key-value cache)を作る。再利用されるのはトークンの文字列ではなく、この中間テンソル(= 数値をまとめた表のようなデータ。ここでは計算途中の結果の塊)である。

自己注意(self-attention)と呼ばれる計算では、あるトークンのキー・バリューは、そのトークンより前にあるトークンだけから決まる。先頭からある位置まで文字列が完全に同じなら、そこまでの計算結果を使い回せるが、途中の1文字が変わればそこから後ろは全部作り直しになる。これが、プロンプトキャッシングが「前方一致(prefix match)」でしか効かない理由で、途中や末尾だけが同じでも効かない。実際にはシステムは文字列を1文字ずつ比べるのではなく、そこまでの内容から機械的に作ったハッシュ(= 文章の内容から機械的に作る短い識別番号。1文字でも内容が違えば別の番号になる)を比較して一致を判定する。

リクエスト1(初回) ハッシュは先頭から累積 リクエスト2(systemが変化) ここから先はハッシュ不一致→再計算 tools定義 system指示 会話の前半 今回の入力 tools定義 system指示 会話の前半 今回の入力
図 3-2 自己注意の計算は先行トークンだけに依存するため、途中の1ブロック(この例では system 指示)が変わると、それより後ろのブロックはすべて再計算になる。薄い塗りのブロックが再計算される範囲を示す。

Anthropic の Claude API では、tools→system→messagesの順で階層的にキャッシュを作り、上の階層が変わるとそれより下も道連れで無効になる。だから「静的なもの(ツール定義・システム指示)を前、動的なもの(ユーザーの最新入力)を後ろ」に置くのが公式の推奨だ。よくある失敗は、区切り位置(キャッシュブレークポイント)を毎回内容が変わるブロック――タイムスタンプ入りの指示や、会話を共有しない単発リクエストのユーザー入力――に置くことだ。公式は「静的な前置きの末尾に置き、変わるブロックには置くな」と明記し、区切り位置をAPI側が自動で決める方式(automatic caching、自動キャッシュ。詳細は実務の節)も同じ罠にはまり得るとしている。

再利用にはいくつか条件がある。最小トークン数(= プレフィックス(=先頭部分)がこれ未満だとキャッシュされない下限)はモデルによって異なり、未満でもエラーにはならず静かにキャッシュされないだけなので気づきにくい。TTL(time to live、= キャッシュが保持される最短時間)は、Anthropic / OpenAIでは読み取りが起きるたびに延長される。Geminiのexplicit cachingは指定した期限まで保持され、延長は明示的な更新で行う。AnthropicとOpenAI(GPT-5.6以降)では、書き込みは通常入力の1.25倍と割高、読み取りは0.1倍と大幅に割安という料金構造のため、Anthropicの目安では5分キャッシュは1回、1時間キャッシュは2回読み取れば元が取れる。書き込むだけで一度も読み取られなければむしろ損をする(OpenAIのGPT-5.5以前など、書き込みが無料のモデルではこの損は生じない)。具体的な数値は実務の節の表にまとめた。

プロンプトキャッシングが速くするのは「読み込み段階(prefill、= 入力を読み込んで理解する処理)」だけで、「書き出し段階(decode、= 1トークンずつ応答を生成する処理)」は速くならない。応答の中身もキャッシュの有無で変わらず、毎回新しく生成される。

セマンティックキャッシング — 応答そのものを使い回す

セマンティックキャッシュは仕組みが違う。新しい質問を埋め込み(embedding、= 意味の近さが距離として表れる数値のベクトルに変換したもの)に変換し、過去の質問の中から近いものをベクトル検索(= 数値の近さで似たものを探す検索)で探す。類似度のしきい値(threshold)を超えて近ければ「ヒット」として保存済みの応答をそのまま返し、LLMは呼ばない。見つからなければ「ミス」としてLLMを呼び出し、応答と埋め込みを保存する。

質問を渡す 候補と距離 似ている質問が見つかった 見つからなかった 新しい質問 埋め込みに変換してベクトル検索 しきい値で類似度を判定 ヒット:保存済み応答を返す (LLMは呼ばない) ミス:LLMを呼び出す 応答を生成しキャッシュへ保存
図 3-3 質問を埋め込みに変換し、しきい値を超える候補が見つかればLLMを呼ばずに保存済み応答を返す。見つからなければLLMを呼び、結果を保存する。

決定的な違いは一致の判定方法だ。プロンプトキャッシュはハッシュの完全一致しか見ないので誤ヒットは原理的に起きないが、セマンティックキャッシュは「意味が近いか」という確率的な判定なので、誤ヒット(false hit、= 別の質問なのにキャッシュがヒットして誤った答えが返ること)が起こり得る。しきい値を緩めるほどヒット率は上がるが誤ヒットも増え、厳しくすると誤ヒットは減るが本来ヒットすべき言い換えまで取りこぼす。

下の図は、しきい値が適切な場合と緩めすぎた場合を並べたものだ。横軸は埋め込み同士の意味の近さで、しきい値より左(意味が近い側)に入った候補だけがヒットとして扱われる。

しきい値が適切な場合 しきい値 ここより左=ヒット 意味が近い ← → 意味が遠い 似た言い換え 関連する質問 無関係だが似た表現 しきい値を緩めすぎた場合 しきい値 誤ヒット 意味が近い ← → 意味が遠い 似た言い換え 関連する質問 無関係だが似た表現
図 3-4 横軸は意味の近さで、しきい値より左だけがヒットになる。適切なしきい値では言い換えだけがヒットするが、緩めすぎると、関連するだけの質問や無関係だが表現が似ているだけの質問まで、誤ってヒットとして扱われてしまう。

しきい値の表し方は製品によって向きが逆であることに注意が要る。「距離(distance)」で表す製品は数値が低いほど厳しく、「類似度(similarity)」で表す製品は数値が高いほど厳しい。同じ0.8という数字でも、製品によって意味がまったく違う(実務の節の表を参照)。

節約できるものも違う。プロンプトキャッシュが省くのは入力側の処理(prefill)だけで出力トークンは毎回課金されるが、セマンティックキャッシュはヒットすればLLM呼び出し自体を省くので出力コストも節約できる。Redis LangCache(Redis社のマネージド型セマンティックキャッシュ。マネージド型 = サーバーの構築・運用を提供会社に任せ、利用者はAPIを呼ぶだけで使える形態)は節約額を「月間の出力トークン費用 × ヒット率」で見積もる方法を公式に示す一方、入力側の節約は埋め込み生成とDB保存コストで相殺されがちだとも明記している。

危険なのは多ターンの会話やツール呼び出しループ(= AIが外部の機能を呼び、その結果を受けて次の行動を決める、を繰り返す処理)への適用だ。LiteLLM(複数のLLM APIを束ねる中継サーバー製品)は公式に、各ターンが直前ターンへ差分を加えただけの文章になるため、埋め込みの類似度(1が完全一致)が0.99近く、つまりほぼ同一文とみなされるまで上がり、しきい値を調整しても直前ターンの古い応答を返してしまう(=同じツール呼び出しを繰り返す不具合として現れる)と警告している。もう一つの危険はユーザーをまたいだ情報混在で、ユーザーIDでキャッシュを区切らないと別ユーザー宛ての応答(個人情報を含む場合もある)が返ってしまう。

実務では何をするのか

提供会社のAPI(マネージドAPI)を使う場合

Claude APIでは、キャッシュしたいブロックの末尾に cache_control を付ける。リクエスト全体の一番外側(トップレベル)に1つ置けば自動でキャッシュ位置をずらす「automatic caching」と、ブロックごとに個別指定する「explicit breakpoints」(最大4箇所)の2方式があり、ttl: "1h" で1時間まで延ばせる。

{
  "model": "claude-opus-5",
  "max_tokens": 1024,
  "cache_control": { "type": "ephemeral" },
  "system": "……固定のシステムプロンプト……",
  "messages": [ ... ]
}

OpenAIは既定で有効になっており、GPT-5.6以降は prompt_cache_options.ttl で保持時間を管理する。Google Geminiは「implicit caching(自動・コスト保証なし)」と「explicit caching(cachedContents を明示的に作成・コスト保証あり)」の2方式に分かれる。主要な数値は次の表のとおり(2026-08時点、モデルによって変わる代表値)。

提供元最小トークン数TTL書き込み倍率読み取り倍率
Anthropic Claude API512〜4,096(モデルによる)既定5分・指定で1時間1.25倍(5分)/2倍(1時間)0.1倍
OpenAI(GPT-5.6以降)1,02430分(既定かつ唯一の値)1.25倍0.1倍
Google Gemini(explicit)2,048〜4,096(モデルによる)既定1時間・自由に設定可公式に倍率の記載なし。別途、保存時間課金(storage price、例: Gemini 3.5 Flashは1Mトークン・1時間あたり1.00 USD、2026-08時点)0.1倍相当(2026-08時点の料金表からの換算)
vLLM(自前ホスティング)完全ブロック単位(端数は対象外)TTLの指定は不要(メモリが足りなくなると、使われていない古い順に捨てる = LRU)課金概念なし(GPUメモリを消費)課金概念なし(計算を省略)

効いているかは使用量フィールドで確認する。Anthropicは usage.cache_read_input_tokens(読み取り分)と usage.cache_creation_input_tokens(書き込み分)、OpenAIは usage.input_tokens_details.cached_tokens を見る。両方0ならキャッシュされていない(最小トークン数未満が典型原因)。

自前でホスティングする場合

vLLM(オープンソースのLLM推論サーバー)のような自前ホスティング(=提供会社側で運用されるAPIに頼らず、自社でサーバーを構築・運用する形態)では、料金の代わりにGPUメモリという有限資源を奪い合う。enable_prefix_caching=True(既定で有効)でKVキャッシュをブロック単位でハッシュ化し、先頭から同じ内容のブロックだけを再利用する(端数ブロックは対象外)。マルチテナント(= 1台のサーバーを複数の顧客企業で共用する構成)では、テナント(利用企業)ごとに違う値(cache_salt)をハッシュの材料に混ぜないと、応答時間の差から他人のプロンプト内容を推測されるタイミング攻撃のリスクがある。

セマンティックキャッシュを組み込む場合

セマンティックキャッシュはLLM提供者側の機能ではなく、アプリ側かゲートウェイ(= アプリとLLMの間に置く中継サーバー)側に自分で組み込む。代表的な実装は「検索→(ミスなら)LLM呼び出し→保存」の2回の呼び出しで統合する。マネージド型のRedis LangCacheは similarityThreshold や、ユーザー・テナントを区切る attributes(最大5個)を指定できる。Azure API Management・Kong(ともにAPIゲートウェイ製品)のうち、Azure API Managementでは前段の検索ポリシーと後段の保存ポリシーの対で構成し、KongやLiteLLM Proxyはプラグイン/設定1つで検索と保存の両方を担う。しきい値に正解値はなく、Azureは0.05から、Redis LangCacheは0.8〜0.9から始めることが公式に推奨されている(向きは製品ごとに逆なので要注意)。

製品パラメータ名厳しくする向き既定値
GPTCachesimilarity_threshold公式の説明と実装コードで向きの記述が一致せず(要実測)0.8
RedisVL SemanticCachedistance_threshold距離・低いほど厳しい0.1
Redis LangCachesimilarityThreshold類似度・高いほど厳しい0.85
Azure API Managementscore-thresholdスコア・低いほど厳しい既定なし(0.05から開始を推奨)

実務の工夫として、システムメッセージを埋め込み対象から外す(Azureの ignore-system-messages)、直近1メッセージだけを対象にする(Kongの message_countback)、ユーザー単位で空間を分けること、TTLを明示設定することが公式ドキュメントで繰り返し推奨されている。

回答を見極めるポイント

良い回答に含まれる要素
弱い回答のサイン

深掘り質問の例

つまずきポイント

「キャッシュがあれば何でも速くなる」と思い込んでいる。実際に速くなるのは前方一致した部分の読み込み段階(prefill)だけで、応答の生成(decode)や、意味が近いだけの質問には効かない。

短いプロンプトでも自動的にキャッシュされると思っている。最小トークン数未満はエラーにならず静かにキャッシュされないだけなので、コストが下がらない原因として見落としやすい。

セマンティックキャッシュで「ヒット率が高いほど良い」と誤解している。しきい値が緩すぎて誤ヒットが増えているだけの可能性があり、公式もヒット率だけを目標にしないよう明記している。

理解度チェック

Q1. プロンプトキャッシングが再利用しているのは、プロンプトの文字列そのものですか?

いいえ。再利用しているのは、Transformerの自己注意機構が計算する中間結果(KVテンソル = キーとバリューという2種類の数値の塊)である。トークンの文字列そのものは保存されない。

Q2. プロンプトキャッシュが「前方一致」でしか効かないのはなぜですか?

自己注意の計算では、あるトークンのキー・バリューはそれより前のトークンだけから決まるため。先頭から同じ文字列である範囲までは計算結果を使い回せるが、途中の1文字でも変わるとそこから後ろは全部作り直しになる。

Q3. セマンティックキャッシュのしきい値を緩めると何が起きますか?

LLMを呼ばずに済むヒット率は上がるが、実際には別の質問なのに誤って過去の答えを返してしまう「誤ヒット」のリスクも増える。

Q4. 多ターンのチャットボットやツール呼び出しループにセマンティックキャッシュをそのまま使うと、なぜ問題が起きやすいですか?

各ターンが直前のターンにわずかな差分を加えただけの文章になるため、埋め込み同士の類似度(1が完全一致)が0.99近くまで上がってしまう。しきい値を厳しくしても直前のターンの古い応答を返してしまい、エージェントが同じツール呼び出しを繰り返す不具合として現れる。

Q5. プロンプトキャッシュがヒットしても、削減されないコストは何ですか?

出力トークンのコスト。プロンプトキャッシュが省くのは入力側の処理(prefill)だけで、応答の生成は毎回行われ出力トークンは毎回課金される。出力トークンまで含めて省けるのは、セマンティックキャッシュがヒットした場合だけである。

まとめ

次章のQ5「コンテキストウィンドウの調整」では、キャッシュだけでは足りずコンテキストそのものを削る場面――トークン上限に近づいたときに何を切り詰め、何を要約するか――を見る。

参考リンク