LLMアプリのコストとレイテンシを同時に削減する手段として、近年「プロンプトキャッシュ(Prompt Caching)」が実用段階に入った。Anthropic と OpenAI それぞれに固有の実装があり、正しく設計すると同じ入力トークンに対する課金を最大90%削減できる。長い文脈を繰り返し送り続けるアプリ——サポートチャットボット、RAGシステム、ツールを多用するエージェント——ほど恩恵が大きく、月単位のAPI費用を半分以下に圧縮した事例も報告されている。本記事では両社の仕様を比較しつつ、キャッシュヒット率を最大化するプロンプト設計と、実装時に踏みやすいアンチパターンまで一気通貫で解説する。既に「セマンティックキャッシュ」「レスポンスキャッシュ」を知っている方も、プロンプトキャッシュとの本質的な違いを把握することで設計の選択肢が広がるはずだ。

プロンプトキャッシュとは何か——KVキャッシュ再利用の仕組み
LLMの推論はトランスフォーマーの各レイヤーでキー(K)とバリュー(V)のテンソルを計算する。同じプロンプトプレフィックスを毎回送ると、同じK/Vテンソルが毎回ゼロから計算されてしまう。プロンプトキャッシュはこの K/V テンソルをサーバー側にキャッシュし、次のリクエストで再利用することで、計算量を大幅に削減する仕組みだ。
この仕組みで削減できるのは「同じプレフィックスを再送したときのトークン処理コスト」であり、モデルの出力そのものはリクエストごとに新しく生成される。したがって、同一入力に対してまったく同じ出力を返す「レスポンスキャッシュ(セマンティックキャッシュ)」とは根本的に異なる。
レスポンスキャッシュは「ユーザーが同じ質問をした場合に前回の回答をそのまま返す」ものであり、出力の多様性が必要なチャットや、最新情報を参照させたいRAGには適さない。プロンプトキャッシュはコンテキスト計算のみをスキップするため、出力はつねに新鮮なまま処理コストだけが下がる。この違いを混同したまま設計すると、意図しない品質低下や計算コスト増につながる。詳しくは本サイトのセマンティックキャッシュによるLLMコスト削減ガイドを参照してほしい。
プロンプトキャッシュが効果的な典型的ユースケースは次の3つだ。
- 長大なシステムプロンプト——社内規定・キャラクター設定・ガイドラインなど数千〜数万トークンの固定テキスト
- RAGコンテキスト——毎回同じドキュメントセットをコンテキストに詰め込んで検索させるパターン
- Few-shotサンプル——品質維持のために毎回10〜50例をプロンプトに含める場合
レスポンスキャッシュとの使い分け基準
両者は目的も効果もまったく異なるため、用途に応じて使い分けることが重要だ。以下の判断基準を参考にしてほしい。
| 判断軸 | プロンプトキャッシュ | レスポンスキャッシュ |
|---|---|---|
| 出力の多様性が必要か | 必要でもOK(毎回新しく生成) | 不要な場合のみ(同じ回答を返す) |
| 最新情報への対応 | 常に最新を生成できる | キャッシュ期間中は古い回答が返る |
| 節約できるもの | 入力トークンの処理コスト | 出力生成コスト全体 |
| 向いているシステム | チャットボット・RAG・エージェント | 同一クエリが繰り返すQ&Aボット |
| 実装の複雑さ | プロンプト構造の設計が必要 | キャッシュキーの設計が必要 |
両者を組み合わせることも有効だ。たとえば、よく聞かれるFAQ20問についてはレスポンスキャッシュで完全返答をキャッシュし、それ以外の質問ではプロンプトキャッシュ付きの動的生成に切り替えるハイブリッド構成が、コスト最小化と品質維持を両立する設計として現実的だ。
Anthropic Claude の cache_control 実装詳細
Anthropic のプロンプトキャッシュは、プロンプトの各ブロックに cache_control フィールドを明示することで制御する。2026年6月時点でサポートされている type は "ephemeral" のみだ。
最小トークン数と対応モデル
キャッシュが機能するには、キャッシュ対象プレフィックスが以下の最小トークン数を超えている必要がある。未達の場合はキャッシュが静かに無視されるだけでエラーは発生しない。
| モデル | 最小トークン数 |
|---|---|
| Claude Opus 4.8 / Sonnet 4.6 / Sonnet 4.5 | 1,024 |
| Claude Haiku 3.5 | 2,048 |
| Claude Haiku 4.5 | 4,096 |
TTL とコスト比率
デフォルトの TTL は 5分、オプションで 1時間が選択可能だ(2026年初頭に1時間から5分へ短縮されたため、既存コードを持つプロジェクトはコスト増に注意)。料金比率の概要を以下に示すが、具体的な単価は各社公式料金ページで最新値を必ず確認すること。
| 操作 | 標準入力トークンに対する比率 |
|---|---|
| 通常入力(キャッシュなし) | 1.0× |
| キャッシュ書き込み(5分 TTL) | 約 1.25× |
| キャッシュ書き込み(1時間 TTL) | 約 2.0× |
| キャッシュ読み込み | 約 0.1×(90%削減) |
初回リクエストはキャッシュ書き込みで割高になるが、2回目以降でキャッシュ読み込み(0.1×)が発生する。1時間 TTL を選ぶと書き込みコストが倍になるため、リクエスト頻度が高い場合は5分 TTL のほうがトータルで安くなることが多い。
Python 実装例——システムプロンプトのキャッシュ
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """
あなたは当社の製品サポートAIです。
[...ここに数千トークンの製品仕様・FAQ・対応ポリシーが入る...]
"""
def chat(user_message: str) -> str:
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"} # ← キャッシュ対象を宣言
}
],
messages=[
{"role": "user", "content": user_message}
]
)
usage = response.usage
print(f"cache_creation: {usage.cache_creation_input_tokens}")
print(f"cache_read: {usage.cache_read_input_tokens}")
print(f"input (new): {usage.input_tokens}")
return response.content[0].text
# 1回目: cache_creation_input_tokens に数値が入る(書き込みコスト)
print(chat("返品ポリシーを教えてください"))
# 2回目以降(5分以内): cache_read_input_tokens に数値が入る(読み込みコスト=約90%削減)
print(chat("送料無料の条件は?"))
複数ブレークポイントで細粒度制御する
最大4つのキャッシュブレークポイントを設定できる。更新頻度の異なるコンテンツを別々のブロックに分け、それぞれに cache_control を付与することで、変更があった部分だけキャッシュを更新できる。
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system=[
{
"type": "text",
"text": BASE_INSTRUCTIONS, # 週単位で変わる基本指示
"cache_control": {"type": "ephemeral", "ttl": "1h"} # 1時間 TTL
},
{
"type": "text",
"text": TODAY_NEWS_SUMMARY, # 毎時更新するニュース
"cache_control": {"type": "ephemeral"} # 5分 TTL
},
{
"type": "text",
"text": user_profile # ユーザーごとに変わるプロフィール(キャッシュ外)
}
],
messages=messages
)
TTL の異なるブロックを混在させる場合、長い TTL のブロックを短い TTL のブロックより前に配置するのが原則だ。
OpenAI の自動プロンプトキャッシュ——コード変更ゼロで動く
OpenAI のプロンプトキャッシュは、Anthropic と異なりコードへの変更が一切不要だ。1,024トークン以上のプロンプトを同じ API エンドポイントに送ると自動的にキャッシュが適用される。プレフィックスが一致すれば、追加料金なしでキャッシュ読み込みの割引が受けられる。
仕組みの詳細
- プロンプトの先頭から一致する最長プレフィックスがキャッシュされる
- キャッシュ境界は 1,024トークンから始まり128トークン単位で伸びる
- 完全なプレフィックス一致(exact prefix match)が必要——1文字でも変わるとキャッシュミス
- 対応モデルは
gpt-4o以降の最新モデル - インメモリキャッシュの保持時間は通常5〜10分(最大1時間)
usage フィールドでキャッシュヒットを確認する
from openai import OpenAI
import time
client = OpenAI()
SYSTEM = "..." * 500 # 1024トークン超えの長いシステムプロンプト
def call(user_msg: str):
resp = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM},
{"role": "user", "content": user_msg}
]
)
details = resp.usage.prompt_tokens_details
print(f"prompt_tokens: {resp.usage.prompt_tokens}")
print(f"cached_tokens: {details.cached_tokens}") # ← キャッシュヒット数
return resp.choices[0].message.content
# 1回目: cached_tokens = 0(ミス)
call("天気を教えて")
time.sleep(1)
# 2回目以降(同一プレフィックス・1時間以内): cached_tokens > 0
call("明日の予定は?")
キャッシュヒット時の割引率は最大90%とされているが、具体的な割引単価は OpenAI の公式料金ページで確認すること。追加費用は発生しない。
Anthropic と OpenAI の比較サマリ
| 比較項目 | Anthropic Claude | OpenAI GPT-4o 系 |
|---|---|---|
| 制御方式 | 明示(cache_control フィールド) | 自動(コード変更不要) |
| 最小トークン | 1,024〜4,096(モデル依存) | 1,024 |
| キャッシュ粒度 | 最大4ブレークポイント | 128トークン単位の最長プレフィックス |
| TTL | 5分(デフォルト)/ 1時間(オプション) | 5〜10分(最大1時間、モデルによる) |
| 書き込みコスト | 1.25×(5分)/ 2.0×(1時間) | 追加料金なし |
| 読み込み割引 | 約90%削減(0.1×) | 最大90%削減 |
| ヒット確認フィールド | cache_read_input_tokens | prompt_tokens_details.cached_tokens |
| ワークスペース分離 | あり(2026-02-05〜) | 組織レベル |
キャッシュヒット率を上げるプロンプト設計の鉄則
キャッシュは「先頭から一致するプレフィックス」に対して発動する。したがって、変化しないコンテンツをプロンプトの先頭に固め、変化するコンテンツを末尾に置くことが最重要ルールだ。
プロンプト構造のベストプラクティス
【推奨構造】
[1] システムプロンプト(固定) ← キャッシュ対象の先頭
[2] Few-shot サンプル(固定 or 低頻度変更)← キャッシュ対象に含める
[3] RAG で取得したドキュメント(セッション固定)← キャッシュ対象に含める
[4] 会話履歴(ターンごとに増加) ← ここまでをキャッシュ対象にする
[5] 最新のユーザーメッセージ ← キャッシュ外(毎回変わる)
Anthropic の場合は、cache_control を [3] または [4] の末尾ブロックに付与することで、[1]〜[4] をまとめてキャッシュできる。OpenAI の場合は [5] が末尾に来るよう構造を維持するだけでよい。
この構造を守るためのコード規約として、「システムプロンプトは定数として定義し、ファイル先頭に置く」「ユーザーコンテキスト・タイムスタンプ・セッションIDは必ずメッセージ配列の末尾ターンに入れる」の2つをチームのコーディングガイドラインに明記しておくと、後から合流したメンバーがプロンプトを変更する際の意図せぬキャッシュ破壊を防げる。コードレビューの際に「このプロンプト変更はキャッシュブレークポイントの前か後か」を確認する習慣をつけるだけで、運用コストの予期しない増加をかなりの確率で防げるはずだ。
RAGパイプラインへのプロンプトキャッシュ統合
RAGシステムでのキャッシュ設計は、検索結果がターンごとに変わるという特性上、単純なシステムプロンプトキャッシュより複雑になる。推奨されるアプローチは「コアドキュメントと動的ドキュメントの分離」だ。
たとえば製品サポートボットであれば、製品マニュアルの全文(数万トークン)はほぼ変更されないコアドキュメントとしてプレフィックスに固定し、ユーザーの購入履歴・最新の在庫状況・当日のキャンペーン情報などの動的文書は末尾のユーザーターンに付加する。このように「変更頻度」でドキュメントを分類し、低頻度のものほどプロンプトの先頭に寄せることで、高いキャッシュヒット率を維持しながら最新情報にも対応できる。
チャンキング戦略とも組み合わせられる。コアドキュメントを意味的にまとまったチャンクとして先頭ブロックに配置し、cache_control を付与。動的チャンクはキャッシュ外に置く。この設計により、コアドキュメント部分のキャッシュ書き込みは初回のみ発生し、それ以降のリクエストでは読み込みコスト(0.1×)のみとなる。
マルチターン会話でキャッシュを伸ばす
マルチターンチャットではターンが進むほどプロンプトが長くなる。Anthropic の cache_control をトップレベル(messages.create の引数として渡す形)で指定すると、最後のキャッシュ可能なブロックまで自動的にキャッシュされる。
def chat_turn(messages: list, new_user_msg: str) -> str:
"""マルチターン会話でキャッシュを活用する例"""
messages.append({"role": "user", "content": new_user_msg})
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
cache_control={"type": "ephemeral"}, # ← トップレベルで指定
system=SYSTEM_PROMPT,
messages=messages
)
assistant_msg = response.content[0].text
messages.append({"role": "assistant", "content": assistant_msg})
return assistant_msg
このパターンでは、会話が長くなるほどキャッシュ対象のトークン数が増え、相対的な節約率が上昇する。
コスト試算の考え方——実際どれだけ安くなるか
プロンプトキャッシュの効果は「同一プレフィックスを何回再利用するか」に左右される。以下はあくまで構造的な考え方であり、実際の金額は各社の最新料金ページで確認してほしい。
損益分岐点の計算式
キャッシュを使うと初回は書き込みコスト(1.25×)がかかる。N 回リクエストしたときのトータルコストは以下のように表せる。
キャッシュあり合計コスト
= (書き込みコスト × 1回) + (読み込みコスト × (N-1) 回) + (非キャッシュ部分 × N 回)
キャッシュなし合計コスト
= (全トークン × 1.0× × N 回)
損益分岐は N ≈ 2〜3 回(書き込み1.25倍 vs 読み込み0.1倍の差)
つまり、同じプレフィックスを3回以上送るだけで元が取れる計算だ。本番のチャットボットや RAG システムであれば、ほぼ確実に黒字になる。
具体的なシナリオで試算してみる
以下はあくまで比率を使った構造的な試算であり、実際の金額は各社公式料金ページで確認すること。ここでは「標準入力トークン単価を P とする」という前提で考える。
シナリオ:RAGドキュメント 4,000トークン + ユーザー質問 100トークン を 1,000回送るケース
| 項目 | キャッシュなし | Anthropic キャッシュあり(5分 TTL) |
|---|---|---|
| 初回コスト | 4,100 × P | 4,000 × 1.25P(書き込み)+ 100 × P |
| 2〜1,000回目 | 4,100 × P × 999 | 4,000 × 0.1P(読み込み)× 999 + 100 × P × 999 |
| 合計(比率) | 4,100,000 × P | 約 505,000 × P(≒ 88%削減) |
この試算は、1,000回すべてが5分以内の連続リクエストである理想的なケースだ。実際にはリクエストが5分を超えて散在するため、キャッシュミスが発生し節約率は下がる。しかしそれを考慮しても、頻繁なリクエストが続くユースケースでは劇的なコスト削減が見込める。ProjectDiscovery は本番環境での測定でLLMコストを59%削減できたと報告しており、現実的な削減幅としての参考になる。
TTL とリクエスト間隔のトレードオフ
5分 TTL の場合、リクエスト間隔が5分を超えると毎回書き込みコストが発生する。1時間 TTL は書き込みコストが2倍になるが、セッション間隔が長いユースケース(Cron ジョブ、夜間バッチなど)では有利になる。Anthropic が2026年初頭に TTL を1時間から5分へ短縮したことで影響を受けたプロダクトが多く、中には実効コストが30〜60%増加したケースもあったと報告されている。
ユースケース別に整理すると次のようになる。
- リアルタイムチャットボット——ユーザーが連続して会話するため5分 TTL で十分。書き込みコストも低い。
- バッチ推論(夜間・定期実行)——リクエスト間隔が数十分〜数時間空く。1時間 TTL を検討するか、リクエストを意図的に近い時間帯に集める設計にする。
- エージェントの自律ループ——ツール呼び出しのたびにプロンプトが再送される。ループが5分以内に収まるよう設計し、長いシステムプロンプトをキャッシュに乗せると効果的。
マルチモデル管理や OpenRouter 経由でのモデル切り替えを行っている場合は、キャッシュのプロバイダ依存性にも注意が必要だ。詳しくはOpenRouter を使ったマルチモデルコスト最適化ガイドも参照してほしい。
踏んではいけないアンチパターン7選
プロンプトキャッシュはシンプルな仕組みだが、実装ミスでキャッシュがまったく効かなくなる落とし穴が多い。
アンチパターン 1:先頭に可変コンテンツを置く
# NG: タイムスタンプがプロンプト先頭に入るとキャッシュが毎回ミスする
system = f"現在時刻: {datetime.now().isoformat()}\n\nあなたはサポートAIです..."
# OK: 可変部分は末尾に
system = "あなたはサポートAIです...\n\n(固定の長い指示)"
user_context = f"現在時刻: {datetime.now().isoformat()}"
アンチパターン 2:最小トークン未満でキャッシュを期待する
プロンプトが 1,024 トークン(Haiku は 2,048〜4,096 トークン)を下回っているのに、cache_read_input_tokens が増えないと首をかしげるケースがある。まず usage フィールドをログに出して確認しよう。また、英語テキストの場合は「単語数 × 1.3 ≈ トークン数」、日本語の場合は「文字数 × 1.5〜2.0 ≈ トークン数」という大まかな目安でプロンプトサイズを見積もれる。システムプロンプトが想定より短い場合は、品質向上を兼ねてFew-shotサンプルを追加することでキャッシュ閾値を超えられることが多い。
アンチパターン 3:TTL を無視してリクエスト間隔を設計する
バッチ処理でリクエストを1時間以上空けてしまうと、5分 TTL のキャッシュは毎回書き込みになり、キャッシュを使わない場合と比べてコストが増加する(書き込み比率が 1.25× のため)。この状況に気づかず「キャッシュを有効にしたのにコストが増えた」と報告するケースが後を絶たない。TTL に合わせてリクエスト間隔を調整するか、1時間 TTL に切り替えること。1時間 TTL は書き込みコストが 2.0× と高くなるが、少なくとも毎回のキャッシュミスよりは有利だ。
アンチパターン 4:Few-shot サンプルをランダムにシャッフルする
プロンプトに多様性を持たせるため、Few-shot 例の順序をリクエストごとにランダムに変えるアプローチを取ることがある。しかし、プレフィックス一致でキャッシュが機能するため、順序が変わった時点でキャッシュミスが確定する。ヒット率がゼロになるだけでなく、毎回書き込みコストが発生するため純粋なコスト増だ。Few-shot の多様性が必要な場合は、固定サンプル集合を先頭に置き、ランダムサンプルを末尾のユーザーターンに追加する設計に切り替えること。
アンチパターン 5:OpenAI でユーザーIDをプロンプト冒頭に埋め込む
# NG: ユーザーごとにプレフィックスが変わる
system = f"ユーザー: {user_id}\n\n{COMMON_INSTRUCTIONS}"
# OK: 共通指示を先頭に、ユーザー情報は末尾のユーザーターンへ
system = COMMON_INSTRUCTIONS
messages.append({"role": "user", "content": f"[ユーザーID: {user_id}] {question}"})
アンチパターン 6:cache_control を毎回外したり付けたりする
Anthropic の場合、cache_control 自体もプロンプトのハッシュに影響する。「キャッシュありリクエスト」と「キャッシュなしリクエスト」が混在すると、キャッシュが無駄に書き込まれ続ける。一度 cache_control を使う方針にしたら、同じプレフィックスを送る全リクエストで一貫して使うこと。A/Bテストで一方のバリアントに cache_control を付けて比較するような場合も、キャッシュキーが分岐して双方でキャッシュミスが増えることを頭に入れておこう。
アンチパターン 7:RAG で毎回取得文書を変える
RAG で取得する文書セットがリクエストごとに微妙に変わると、プレフィックスが毎回変化してキャッシュが効かない。ベクトル検索の結果は類似スコアがわずかに変わるだけで文書の順序が変わることがある。対策として、同一ユーザーセッション内では最初に取得した文書セットを固定化し、2回目以降のターンではセッションキャッシュから取り出して使う方法が有効だ。あるいは、高頻度で参照されるコアドキュメントを静的プレフィックスとして先頭に固定し、セッションごとに変わる補足文書のみを末尾に付加する「ハイブリッド RAG」設計も検討する価値がある。
運用監視——キャッシュヒット率をダッシュボードで追う
本番運用では、キャッシュヒット率を定期的にモニタリングすることで、設計ミスや TTL 切れによるコスト増を早期に検知できる。
from dataclasses import dataclass, field
from typing import List
import statistics
@dataclass
class CacheStats:
cache_reads: List[int] = field(default_factory=list)
cache_writes: List[int] = field(default_factory=list)
regular_inputs: List[int] = field(default_factory=list)
def record(self, usage):
"""Anthropic usage を記録する"""
self.cache_reads.append(usage.cache_read_input_tokens or 0)
self.cache_writes.append(usage.cache_creation_input_tokens or 0)
self.regular_inputs.append(usage.input_tokens or 0)
@property
def hit_rate(self) -> float:
total_reads = sum(self.cache_reads)
total_writes = sum(self.cache_writes)
if total_reads + total_writes == 0:
return 0.0
return total_reads / (total_reads + total_writes)
def report(self):
print(f"キャッシュヒット率: {self.hit_rate:.1%}")
print(f"合計キャッシュ読込: {sum(self.cache_reads):,} tokens")
print(f"合計キャッシュ書込: {sum(self.cache_writes):,} tokens")
print(f"合計通常入力: {sum(self.regular_inputs):,} tokens")
stats = CacheStats()
# API コール時に記録
response = client.messages.create(...)
stats.record(response.usage)
# 定期レポート
stats.report()
OpenAI の場合は response.usage.prompt_tokens_details.cached_tokens を同様に集計すればよい。ヒット率が想定より低い場合は、プロンプト先頭の可変コンテンツ混入か、TTL 切れが疑われる。レート制限やスロットリング対策と組み合わせた実装についてはLLM API レート制限・スロットリング対応ガイドも参考にしてほしい。
アラートとコスト異常検知
キャッシュヒット率が突然下落した場合は、次の原因が考えられる。
- プロンプトのリファクタリングで先頭部分が変わった(コードデプロイ後に多い)
- TTL が5分に短縮されているのに、バッチ間隔が延びた
- Anthropic のワークスペース分離設定(2026-02-05〜)による意図しない分離
- OpenAI モデルのバージョンアップでキャッシュがリセットされた
本番では、キャッシュヒット率が7日間移動平均から15%以上下落したらアラートを出す仕組みを入れておくと安心だ。Anthropic のAPIが返す usage を DataDog や Grafana に送るだけで実現できる。
ワークスペース分離とセキュリティ
Anthropic は2026年2月5日からキャッシュの分離単位を「組織レベル」から「ワークスペースレベル」に変更した。これにより、同一組織内の異なるワークスペース間でキャッシュが共有されなくなった。マルチテナント構成でワークスペースをテナントごとに分けている場合は、この分離により意図しないキャッシュミスが増える可能性がある。テナント間のデータ分離としては望ましい変更だが、コスト面ではキャッシュヒット率の低下に注意が必要だ。
まとめ——プロンプトキャッシュで得られる3つの恩恵
プロンプトキャッシュを適切に実装すると、次の3つの恩恵が得られる。
- コスト削減——キャッシュヒット時は最大90%削減。長いシステムプロンプトや RAG コンテキストを繰り返す設計ほど効果が大きい。
- レイテンシ(TTFT)改善——K/V 計算をスキップするため、初回レスポンスが最大80%高速化する場合がある。
- スケーラビリティ向上——同じトークンを何度も再計算せずに済むため、GPU リソースの需要ピークが下がり、レート制限に当たりにくくなる。
Anthropic は cache_control で細粒度に制御し、OpenAI は自動化で手軽に始められる。双方の違いを理解した上で、プロジェクトのリクエストパターンに合った TTL と構造設計を選択してほしい。
導入優先度の判断フロー
「自分のプロジェクトにプロンプトキャッシュが必要か」を判断するための簡単なフローを示す。
- プロンプトの先頭部分は固定されているか?
NO → まずプロンプト構造を見直すことが先決。固定できない理由がある場合はキャッシュの効果が薄い。 - 固定部分は1,024トークン以上あるか?
NO → プロンプトキャッシュの閾値未満。Few-shotを増やすか、システムプロンプトを充実させると閾値を超えられる。 - 1日あたりのリクエスト数は100件以上あるか?
NO → 絶対的なコスト削減額が小さいため、後回しにしてよい。YES → 次の問いへ。 - リクエスト間隔は5分以内が多いか?
YES → デフォルト5分 TTL で十分。NO → リクエストをバーストさせる設計変更、または1時間 TTL を検討する。 - Anthropic を使っているか OpenAI を使っているか?
Anthropic →cache_controlを追加するだけ(設計1〜2時間)。OpenAI → プロンプト先頭構造を確認するだけで自動適用される(設計0時間)。
このフローを経ると、多くのプロダクションLLMアプリはステップ4か5の時点でキャッシュ導入を決断できる。迷ったら OpenAI で自動キャッシュを確認しながら始め、Anthropic 移行時に cache_control を追加するという段階的アプローチが現実的だ。
プロンプトキャッシュは「設定さえすれば勝手に効果が出る」と思われがちだが、実際には設計・計測・チューニングの3サイクルが必要だ。最初の1〜2週間はヒット率をダッシュボードで追い、改善できる余地がないか探ることに時間を割いてほしい。キャッシュヒット率を70%以上に安定させられれば、入力トークンコストの大幅削減は現実のものとなる。そこで生まれた予算を新機能のプロンプト改善やモデルのグレードアップに回すことで、プロダクトの品質向上に好循環をつくることができる。
参考
- Anthropic — Prompt caching(公式ドキュメント)
- OpenAI — Prompt caching(公式ドキュメント)
- ProjectDiscovery — How We Cut LLM Costs by 59% With Prompt Caching
この記事を読んで導入イメージが固まってきた方へ
UravationではAIエージェント導入の研修・コンサルを行っています。
