第13章 KVキャッシュ/プロンプトキャッシュ — 同じ前文を安く・速く

📖 この章のゴール:「プロンプトキャッシュ(KVキャッシュ)」で、同じ前置きの再送を安く・速くする考え方と、効かせる書き方が分かる。

← 目次・はじめにへもどる


📱 ChatGPTではこう見える

長い会話を続けていると、毎回これまでのやりとりを全部おさらいしているはずなのに、返事はサッと返ってきます。しかも「会話が長くなったら料金が一気にふくらんだ」という感じも、思ったほどありません。

実はこの裏で「同じ前置きの計算結果を、こっそり使い回す」しくみがはたらいています。それがこの章のテーマです。

🤔 なぜ「同じ前文の再送」が起きるの?(🟢 基礎)

第4章でやったとおり、LLM(大規模言語モデル=かしこい文章予測エンジン)には記憶がありません。だから毎回「全部送る」必要があります。

つまり毎回、同じ前置きを何度も送っているのです。

  • system(最初に決めた「あなたは親切なアシスタントです」などの設定)
  • これまでの会話(だんだん積み上がっていく長い文脈)

ここで登場するのがプロンプトキャッシュ(prompt cache=「前置きの計算結果を一時保存しておくしくみ」)です。LLMは送られてきた文章の前半を計算します。前半がまったく同じなら、その計算結果を取っておいて、2回目以降は使い回せます。だから2回目以降は安く・速くなります。

🔧 この内部で動いている技術が「KVキャッシュ」(Key-Value cache)と呼ばれるものです。名前は気にしなくて大丈夫。「前半の計算結果のメモ書き」くらいに思ってください。詳しくは付録C。

たとえ話:分厚い本を読むとき、毎回1ページ目から読み直すのは大変ですよね。しおりをはさんでおいて、続きから再開するイメージです。前半が変わらなければ、しおりの位置から始められます。

提供元による違いも知っておきましょう。

  • OpenAIのGPT:長い共通の前置き(プレフィックス)があれば、自動的にキャッシュが効きます。こちらが何か書く必要はありません。
  • Anthropic(Claude):「ここまでをキャッシュして」と明示的に指定します(やり方は付録C)。

🛠 こう作る(🟢 基礎)

ポイントはたった1つ。変わらない前半を安定させ、変わる部分を後ろに置くことです。

まずは「効きにくい」悪い例から見てみましょう。

const messages = [
  { role: "system", content: `現在時刻: ${new Date().toISOString()}\nあなたは親切なアシスタントです。` },
  { role: "user", content: userInput },
];

1行ずつ読むと:

  • const messages = [ … LLMに送るメッセージの配列を作り始めます。
  • { role: "system", content: ... } … 一番先頭に設定文(system)を置いています。
  • 現在時刻: ${new Date().toISOString()} … ここが問題。毎回ちがう時刻が先頭に入ってしまいます。
  • あなたは親切なアシスタントです。 … 本来は固定したい文なのに、上の時刻のせいで前半全体が毎回変わります。
  • { role: "user", content: userInput } … ユーザーの入力。これは毎回変わって当然です。
  • ]; … 配列を閉じます。

前半に毎回ちがう値(時刻)が入ると、「前半が同じ」という条件がくずれ、キャッシュが効きません。

次に「効きやすい」良い例です。

const messages = [
  { role: "system", content: "あなたは親切なアシスタントです。" },
  ...history,
  { role: "user", content: `現在時刻: ${now}\n${userInput}` },
];

1行ずつ読むと:

  • { role: "system", content: "あなたは親切なアシスタントです。" } … 先頭をずっと同じ文に固定しました。
  • ...history … これまでの会話。前のほうほど内容が固まっているので、ここも安定した前半になります。
  • { role: "user", content: ... } … 毎回変わる部分はこの一番後ろにまとめます。
  • 現在時刻: ${now}\n${userInput} … 時刻のような「毎回変わる値」は、先頭ではなく後ろ側に置くのがコツです。

こうすると前半(system+これまでの会話)が安定し、キャッシュが効きやすくなります。具体的な料金やどれくらい安くなるかは付録Dを見てください。

⚠️ ハマりどころ

  • 前半を毎回ちょっとでも変えると効かない:タイムスタンプ・乱数・ユーザー名などを先頭に入れない。1文字でもちがえば「別の前置き」とみなされます。
  • キャッシュは入力(こちらが送る文)の話:LLMの出力(返事)は別に課金されます。キャッシュは入力側を安くするしくみで、出力代までは安くなりません。
  • 万能ではない:短い文や、毎回まったく違う内容には効果が薄いです。「長くて同じ前置きを繰り返す」ときに一番効きます。

🤖 AIに頼むなら(Vibe codingのコツ)

🗣 プロンプト例:「TypeScript + OpenAI SDKのチャットで、systemと固定の長い文脈を先頭に固定して、毎回変わる部分(時刻やユーザー入力)を後ろに置く形に直して。プロンプトキャッシュが効きやすい並びにしてください。」

チェックリスト:

  • systemが毎回まったく同じ文になっている
  • タイムスタンプ・乱数・IDなど「毎回変わる値」を先頭に置いていない
  • 変わる部分は配列の後ろ(最新のuserメッセージ側)にまとめている
  • 出力は別課金だと理解している(入力だけが安くなる)

📝 ことばメモ

  • プロンプトキャッシュ(prompt cache):同じ前置きの計算結果を一時保存して、2回目以降を安く・速くするしくみ。
  • KVキャッシュ(Key-Value cache):プロンプトキャッシュを内部で支えている技術。名前だけ覚えればOK。
  • プレフィックス(prefix):送る文章の「前半・先頭部分」のこと。ここが同じだとキャッシュが効く。

➡️ 次の章へ

次は第14章「本番で待ち受けるもの=スケールとコストの物語」。たくさんの人が同時に使い始めたとき、何が起きてどう向き合うかを物語として見ていきます。

← 目次・はじめにへもどる