
LLMプロンプトキャッシング:APIコストを90%削減(主要3社対応)
LLMプロンプトキャッシングを利用すると、APIコール間で以前に処理されたトークンを再利用でき、入力コストを最大**90%削減し、初回トークン到達時間(TTFT)を最大85%**短縮できます。もし毎回同じシステムプロンプト、ツール定義、またはFew-shot例を送信しているなら、GPUがすでに完了した作業に対して全額を支払っていることになります。
本ガイドでは、他のガイドでは見られない手法として、OpenAI、Anthropic、Geminiの3つのSDKすべてで実装された同じチャットボットを取り上げます。また、Anthropicの2026年2月の自動キャッシングアップデート、実際のドル金額を用いた本番環境のコストシナリオ、そしてキャッシュヒット率を密かに低下させるアンチパターンについても解説します。
<!-- IMAGE: KV cache reuse flow diagram showing prompt prefix matching, cache hit path (fast, cheap), and cache miss path (standard processing) -->主要3社のクイックサマリー
実装の詳細に入る前に、完全な比較表をご覧ください。使用しているプロバイダーが決まっている場合は、該当セクションへスキップしてください。評価中の場合は、この表ですべてを10秒で把握できます。
| 機能 | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| キャッシングタイプ | 自動 | 自動 + 明示的 | 暗黙的 + 明示的 |
| 最小トークン数 | 1,024 | 1,024(ほとんどのモデル) | 1,024(Flash)/ 4,096(Pro) |
| TTL(有効期限) | 5〜10分(拡張時は最大24時間) | 5分または1時間 | 設定可能(デフォルト1時間) |
| キャッシュ書き込みコスト | 1倍(追加料金なし) | 1.25倍(5分)/ 2倍(1時間) | 1倍(追加料金なし) |
| キャッシュ読み込み割引 | 入力価格の50%オフ | 入力価格の90%オフ | 入力価格の約90%オフ |
| キャッシュ隔離単位 | 組織(Organization) | ワークスペース | プロジェクト |
| ストリーミングサポート | はい | はい | はい |
| キャッシュヒット応答フィールド | cached_tokens | cache_read_input_tokens | cachedContentTokenCount |
| 明示的な制御 | なし | はい(cache_control) | はい(名前付きキャッシュオブジェクト) |
| 最新の主要アップデート | 2024年10月 | 2026年2月(自動キャッシング) | 2026年(暗黙的キャッシング) |
主なポイント: OpenAIは最もシンプルです(設定不要、50%割引)。Anthropicは最も深い割引(90%)と最大の制御性を提供します。Geminiは設定可能なTTLと、2.5以降のモデルでの暗黙的キャッシングを提供し、Anthropicと同様の割引率を実現しています。
LLMプロンプトキャッシングの仕組み
プロンプトキャッシングを効果的に使用するために、トランスフォーマーの内部構造を理解する必要はありません。しかし、プレフィックスマッチングという1つの概念は理解する必要があります。
60秒で理解するKVキャッシュ
LLMがプロンプトを処理するとき、すべてのトークンに対してアテンション状態(キーバリューペア)を計算します。これらのKVキャッシュエントリが高コストな部分であり、GPUメモリと計算時間を消費する要因です。プロンプトキャッシングは、これらの計算済み状態を保存するため、同じプレフィックスを持つ次のリクエストは再計算を完全にスキップします。
重要な単語はプレフィックスです。キャッシュはプロンプトの先頭から前方へ一致させます。最初の2,000トークンがキャッシュエントリと一致し、2,001番目のトークンが異なる場合、最初の2,000トークンはキャッシュから提供されます。分岐点以降のすべては新たに計算されます。
これがプロンプトの順序が重要な理由です。プロンプトは以下のように構成しましょう。
- ツール定義(最も静的)
- システムプロンプト
- 静的なFew-shot例
- 取得コンテキスト(半動的)
- 会話履歴(ターンごとに増加)
- ユーザーのクエリ(常に異なる)
静的コンテンツを先に、動的コンテンツを後に配置します。キャッシュされたプレフィックスと一致するトークンが多いほど、節約効果は大きくなります。
プロンプトキャッシング vs セマンティックキャッシング vs レスポンスキャッシング
これら3つの用語は頻繁に混同されます。プロンプトキャッシング(本ガイドで扱う内容)は、同一のトークンプレフィックスに対してGPUレベルで計算済みのKV状態を再利用し、精度の損失ゼロで、キャッシュされていない場合と同じ出力を得られます。セマンティックキャッシングは埋め込みの類似性を使用して、「十分に似ている」クエリに対して以前生成されたレスポンスを返すため、高速ですが誤った回答を返す可能性があります。レスポンスキャッシングは正確な入出力ペアを保存し、キャッシュされたレスポンスをそのまま返すため、 truly identical(完全に同一)のリクエストにのみ機能します。
プロンプトキャッシングは唯一の「無料の最適化」であり、精度のトレードオフなしでコストとレイテンシを削減します。KVキャッシングの背後にある深いトランスフォーマー数学については、Hugging Faceの技術解説で、T4 GPU上で約5.21倍の速度向上が測定されています。
OpenAIのプロンプトキャッシング処理
OpenAIのプロンプトキャッシングは完全に自動です。 2024年10月以来、1,024トークン以上の入力トークンを持つすべてのAPIコールは自動的にキャッシングの恩恵を受けます。オプトインも、ヘッダーの追加も、コードの変更も必要ありません。
OpenAIの自動キャッシングの仕組み
少なくとも1,024トークンのリクエストを送信すると、OpenAIはそのプレフィックスが組織内の最近のリクエストと一致するか確認します。キャッシュヒットのコストは、標準的な入力トークン価格の50%です。初期の1,024トークンの閾値を超えると、キャッシュは128トークン単位で一致します。
キャッシュは通常の使用中は5〜10分存続し、オフピーク時の拡張保持により最大24時間持続することがあります。これは組織単位でスコープされるため、同じ組織内の異なるプロジェクトが共有キャッシュの恩恵を受けます。
サポートされているモデルには、GPT-4o、GPT-4o-mini、GPT-4.1、o1、o3-mini、およびすべての新しいモデルが含まれます。
OpenAI Python SDKの例
from openai import OpenAI
client = OpenAI()
# This system prompt is ~2,000 tokens -- well above the 1,024 minimum
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
def chat(user_message: str) -> str:
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
# Check if caching kicked in
usage = response.usage
cached = usage.prompt_tokens_details.cached_tokens
total_input = usage.prompt_tokens
print(f"Cached: {cached}/{total_input} tokens ({cached/total_input*100:.0f}%)")
return response.choices[0].message.content
# First call: cache miss (full price)
chat("Review this async function for race conditions...")
# Second call within 5-10 min: cache hit (50% off on cached tokens)
chat("Now optimize the same function for throughput...")最初の呼び出しは全額ですべてを処理し、キャッシュを設定します。2番目の呼び出しは、半額の価格でキャッシュされたシステムプロンプトトークンを再利用します。出力には Cached: 1920/2048 tokens (94%) のような表示が見られるはずです。
結論:OpenAIは開始するのが最も簡単で、設定ゼロ、キャッシングは自動で行われます。 50%の割引は3社の中で最低ですが、その簡便さには敵いません。
Anthropic/Claudeのプロンプトキャッシング処理
Anthropicは2つのモードを提供します:自動キャッシング(2026年2月以降デフォルトで有効)と、cache_controlブレークポイントを使用した明示的キャッシングです。注目すべき数字は無視できません。キャッシュされた読み取りコストは標準的な入力価格のわずか10%、つまり90%の割引です。
自動キャッシング vs 明示的キャッシング(2026年アップデート)
2026年2月5日より、Anthropicは資格のあるすべてのプロンプトに対して自動キャッシングをデフォルトで有効にしました。古いベータヘッダーはもう必要ありません。システムが最適なキャッシュブレークポイントを自動的に決定します。
明示的キャッシングは、きめ細かい制御が必要な場合に引き続き利用可能です。特定のコンテンツブロックに cache_control: {"type": "ephemeral"} を配置して、キャッシュ境界を正確にマークします。これは、プロンプトに特定の構造があり、特定のセクションがキャッシュされることを保証したい場合に便利です。
2つのTTLオプションがあります。
- 5分キャッシュ(デフォルト):書き込みコストは基本入力価格の1.25倍、読み取りコストは0.1倍。1回のキャッシュヒットで元が取れます。
- 1時間キャッシュ:書き込みコストは基本入力価格の2倍、読み取りコストは0.1倍。2回のキャッシュヒットで元が取れます。Claude 4.5以降のモデルで利用可能。
2026年2月5日、キャッシュ隔離は組織レベルからワークスペースレベルに変更されました。これは、同じ組織内の異なるワークスペースが個別のキャッシュを維持することを意味します。
Anthropicのキャッシングを使用する際は、最適なキャッシングのためにプロンプトを構造化することが役立ちます。書き込みプレミアムを支払っているため、静的コンテンツを動的コンテンツの前に配置することがここでさらに重要になります。
Anthropic Python SDKの例
import anthropic
client = anthropic.Anthropic()
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
def chat(user_message: str) -> str:
response = client.messages.create(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[
{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # Explicit breakpoint
}
],
messages=[
{"role": "user", "content": user_message},
],
)
# Read cache metrics from the response
usage = response.usage
created = usage.cache_creation_input_tokens
read = usage.cache_read_input_tokens
standard = usage.input_tokens
print(f"Cache write: {created}, Cache read: {read}, Standard: {standard}")
return response.content[0].text
# First call: cache_creation_input_tokens = ~1920 (write at 1.25x)
chat("Review this async function for race conditions...")
# Second call: cache_read_input_tokens = ~1920 (read at 0.1x -- 90% off!)
chat("Now optimize the same function for throughput...")キャッシュ書き込み vs キャッシュ読み込み価格の理解
ここでAnthropicの価格設定が興味深くなります。Claude Sonnet 4.5(基本入力$3/MTok)を例に挙げます。
- 標準入力: 100万トークンあたり$3.00
- キャッシュ書き込み(5分): 100万トークンあたり$3.75(1.25倍)、初回はより多く支払います
- キャッシュ読み込み: 100万トークンあたり$0.30(0.1倍)-- その後のすべてのヒットで90%安くなります
5分キャッシュはわずか1回の読み取りで元が取れます。1時間キャッシュ(書き込み$6.00/MTok)は2回の読み取りで元が取れます。同じプレフィックスで1分間に数回以上のリクエストを行っている場合、計算上は圧倒的に有利です。
結論:Anthropicは最も深い割引(90%)と最大の制御性を提供します。高ボリュームでコストに敏感なワークロードに最適です。
Google Geminiのプロンプトキャッシング処理
Geminiは2つの異なるキャッシングメカニズムを用いた異なるアプローチを取ります:明示的コンテキストキャッシング(作成して参照する名前付きキャッシュオブジェクト)と、暗黙的キャッシング(自動、設定不要、2026年にGemini 2.5以降のモデルに追加)。
明示的コンテキストキャッシング(名前付きキャッシュ)
キャッシングが透過的なOpenAIやAnthropicとは異なり、Geminiの明示的キャッシングでは、まず名前付きキャッシュオブジェクトを作成し、その後続のリクエストでそれを参照する必要があります。最小トークン閾値は、Gemini Flashモデルで1,024トークン、Proモデルで4,096トークンです。TTLは設定可能で、デフォルトは1時間ですが、必要に応じて設定できます。
Gemini 2.5 Proでのキャッシュされたトークンの価格は**$0.125/MTokで、標準的な$1.25/MTokの入力価格と比較して90%の割引**となります。また、Proでは1時間あたり100万トークンにつき$4.50、Flashでは$1.00のストレージコストがかかります。
Gemini 2.5における暗黙的キャッシング(2026年)
Gemini 2.5 ProおよびFlash以降、GoogleはOpenAIのアプローチのような暗黙的キャッシングを追加しました。設定は不要です。プロンプトの先頭に大きな共通コンテンツを配置し、類似したプレフィックスを持つリクエストを短期間に連続して送信します。システムは自動的にキャッシュ対象のコンテンツを検出し、節約分を適用します。
Gemini Python SDKの例
from google import genai
from google.genai import types
client = genai.Client()
SYSTEM_PROMPT = """You are a senior Python developer specializing in async programming.
You follow PEP 8, use type hints, and write comprehensive docstrings.
When reviewing code, check for: race conditions, resource leaks, error handling,
and performance bottlenecks. Always suggest specific fixes with code examples.
[... imagine 1,800 more tokens of coding guidelines, examples, and rules ...]"""
# Step 1: Create a named cache object
cache = client.caches.create(
model="gemini-2.5-flash",
config=types.CreateCachedContentConfig(
display_name="python-review-guidelines",
system_instruction=SYSTEM_PROMPT,
ttl="3600s", # 1 hour
),
)
print(f"Cache created: {cache.name}, expires: {cache.expire_time}")
# Step 2: Use the cache in requests
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Review this async function for race conditions...",
config=types.GenerateContentConfig(
cached_content=cache.name,
),
)
# Check cache usage in the response
metadata = response.usage_metadata
print(f"Cached tokens: {metadata.cached_content_token_count}")
print(f"Total input tokens: {metadata.prompt_token_count}")明示的なアプローチには大きな利点があります。TTLを正確に制御できることです。バッチジョブが4時間実行されることがわかっている場合、4時間のTTLを設定し、処理途中でキャッシュが期限切れになるのを回避できます。
結論:Geminiの設定可能なTTLと二重のキャッシングモード(明示的+暗黙的)により、汎用性が高いです。最小閾値は現在他のプロバイダーと同等であり、キャッシュされた読み取りの90%割引はAnthropicと匹敵します。
サイドバイサイドコード比較:同じユースケース、3社すべて
ここでは、キャッシュされたシステムプロンプトを持つ同じチャットボットを、3つのSDKすべてで実装しています。開発者体験を直接比較してください。
# --- OpenAI: Zero config, just call the API ---
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": SYSTEM_PROMPT}, # Cached automatically
{"role": "user", "content": user_message},
],
)
cached = response.usage.prompt_tokens_details.cached_tokens# --- Anthropic: Explicit cache_control breakpoint ---
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"}, # Mark cache boundary
}],
messages=[{"role": "user", "content": user_message}],
)
cached = response.usage.cache_read_input_tokens# --- Gemini: Named cache object ---
from google import genai
from google.genai import types
client = genai.Client()
cache = client.caches.create(
model="gemini-2.5-flash",
config=types.CreateCachedContentConfig(
system_instruction=SYSTEM_PROMPT,
ttl="3600s",
),
)
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=user_message,
config=types.GenerateContentConfig(cached_content=cache.name),
)
cached = response.usage_metadata.cached_content_token_count| 側面 | OpenAI | Anthropic | Gemini |
|---|---|---|---|
| 設定の複雑さ | なし | cache_controlブロックを追加 | 最初にキャッシュオブジェクトを作成 |
| キャッシュ制御 | 自動のみ | 自動または明示的 | 暗黙的または明示的 |
| キャッシュ読み込み割引 | 50% | 90% | 約90% |
| 最小トークン数 | 1,024 | 1,024 | 1,024(Flash)/ 4,096(Pro) |
| DX(開発者体験)の評価 | 最もシンプル | 最も制御可能 | 最も柔軟なTTL |
努力ゼロで節約したい場合はOpenAIを選択してください。最も深い割引ときめ細かい制御が必要な場合はAnthropicを選択してください。設定可能なキャッシュ寿命が必要か、すでにGoogle Cloudを利用している場合はGeminiを選択してください。
本番環境コスト計算機:スケールに応じた実際の節約
抽象的なパーセンテージは意思決定を促しません。ドル金額こそが重要です。ここでは、Claude Sonnet 4.5(入力$3/MTok)、GPT-4o(入力$2.50/MTok)、Gemini 2.5 Pro(入力$1.25/MTok)を使用した、実際の費用見積もりを含む3つの本番シナリオを示します。
価格は2026年3月に検証済みです。現在のレートについては、Anthropicの価格、OpenAIの価格、Geminiの価格を確認してください。
前提条件:80%のキャッシュヒット率(適切に構造化されたプロンプトの場合現実的)、出力トークンは除外(キャッシングは入力コストにのみ影響するため)。
| シナリオ | キャッシングなし(月額) | OpenAIキャッシングあり | Anthropicキャッシングあり | Geminiキャッシングあり |
|---|---|---|---|---|
| ホビーチャットボット:100 req/日、2Kシステムプロンプト | OpenAI: $15 / Anthropic: $18 / Gemini: $7.50 | $12($3節約) | $5.40($12.60節約) | $2.25($5.25節約) |
| 成長期API:10K req/日、8Kキャッシュされたプレフィックス | OpenAI: $600 / Anthropic: $720 / Gemini: $300 | $360($240節約) | $144($576節約) | $60($240節約) |
| エンタープライズパイプライン:100K req/日、10Kキャッシュされたプレフィックス | OpenAI: $7,500 / Anthropic: $9,000 / Gemini: $3,750 | $4,500($3,000節約) | $1,800($7,200節約) | $750($3,000節約) |
成長期ティアでは、OpenAIよりも基本価格が高いにもかかわらず、Anthropicキャッシングにより月額$576の節約が可能です。エンタープライズ規模では、Anthropicで月額$7,200、年間$86,400の節約が見込めます。これは設定変更だけでシニアエンジニア一人分の節約に相当します。
パターンは明確です。リクエスト量が多く、静的プレフィックスが長いほど、キャッシングによる節約効果は大きくなります。Anthropicの90%割引は大規模なスケールで支配的ですが、総コストを考慮するとGeminiの低い基本価格も競争力があります。
プロンプトキャッシングのアンチパターン:キャッシングすべきでない場合
キャッシングはシンプルに見えますが、キャッシュヒット率が謎の0%のままになることがあります。ここでは、プロンプトキャッシングを密かに壊すミスとその修正方法を紹介します。
キャッシュを破壊するミス(修正法付き)
システムプロンプト内のタイムスタンプ、最も一般的なミスです。システムプロンプトに datetime.now() が含まれている場合、キャッシュキーは毎秒変化します。
# BAD: Cache misses every single request
system_prompt = f"""You are a helpful assistant.
Current time: {datetime.now().isoformat()}
Always be helpful and accurate."""
# GOOD: Move the timestamp to the user message
system_prompt = """You are a helpful assistant.
Always be helpful and accurate."""
user_message = f"[Current time: {datetime.now().isoformat()}]\n{user_query}"静的コンテンツ前のユーザー固有コンテンツ、session_id やユーザー設定を先頭に配置すると、すべてのユーザーが一意のプレフィックスを持つことになります。
# BAD: Unique prefix per user = zero cache reuse
messages = [
{"role": "system", "content": f"User ID: {user_id}\nPreferences: {prefs}\n{GUIDELINES}"},
{"role": "user", "content": query},
]
# GOOD: Static content first, user context at the end
messages = [
{"role": "system", "content": GUIDELINES}, # Same for all users -> cached
{"role": "user", "content": f"Context: User {user_id}, prefs: {prefs}\n{query}"},
]| アンチパターン | なぜキャッシュが壊れるか | 修正方法 |
|---|---|---|
| システムプロンプト内のタイムスタンプ | プレフィックスが毎秒変化 | タイムスタンプをユーザーメッセージへ移動 |
| プレフィックス内のセッション/ユーザーID | ユーザーごとに一意のプレフィックス | ユーザーコンテキストを静的コンテンツ後に移動 |
| 回転するFew-shot例 | 異なる例 = 異なるプレフィックス | 固定された例のセットを使用 |
| 動的なツール定義 | ツールの変更 = プレフィックス不一致 | ツールスキーマを静的に保つ |
| 短いプロンプト(最小値未満) | キャッシュが単純にトリガーされない | コンテキストを統合して1,024トークンを超えるようにする |
| システムプロンプト内のリクエストごとのパーソナライゼーション | システムプロンプトが毎回変化 | 共有システムプロンプト + ユーザー固有のユーザーメッセージを使用 |
プロンプトキャッシングが本当に役立たない場合
プロンプトを完璧に構造化しても、キャッシングの恩恵を受けないシナリオがあります。
- 単回使用プロンプト:すべてのリクエストが完全にユニークなコンテキストを持ち、共有プレフィックスがない場合、キャッシュするものがありません。
- 非常に短いプロンプト:1,024トークン未満(OpenAI/Anthropic)または4,096トークン未満(Gemini Pro)の場合、キャッシングは活性化しません。
- 稀なリクエスト:リクエスト間隔が数時間ある場合、2番目のリクエストが到着する前にキャッシュの有効期限が切れます。OpenAIの5〜10分のウィンドウとAnthropicのデフォルト5分TTLは、一貫したトラフィックが必要であることを意味します。
プロンプトキャッシングはストリーミングと併用できますか?
はい。プロンプトキャッシングとストリーミングは独立しており、キャッシングは入力トークンで動作し、ストリーミングは出力配信に影響します。 これらはリクエストライフサイクルの異なる段階で異なる問題を解決します。
キャッシュはプリフィルフェーズ(入力プロンプトの処理)を処理します。ストリーミングはデコードフェーズ(出力トークンの生成と増分的な送信)を処理します。両方の恩恵を同時に得られます。キャッシュヒットによる高速なプリフィルと、ストリーミングによる進捗的な出力配信です。
以下は、キャッシングを有効にしたストリーミングの例です。
import anthropic
client = anthropic.Anthropic()
with client.messages.stream(
model="claude-sonnet-4-5-20250514",
max_tokens=1024,
system=[{
"type": "text",
"text": SYSTEM_PROMPT,
"cache_control": {"type": "ephemeral"},
}],
messages=[{"role": "user", "content": "Explain Python's GIL..."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# After streaming completes, check cache metrics
usage = stream.get_final_message().usage
print(f"\nCache read: {usage.cache_read_input_tokens} tokens")キャッシングによるTTFTの改善は、実際にはストリーミングを使用しているときに最も顕著です。キャッシングなしでは、最初のトークンがストリームバックされる前に完全なプリフィルを待つ必要があります。キャッシングありでは、プリフィルがほぼ瞬時であるため、トークンはほぼすぐに流れ始めます。
本番環境でのキャッシュヒット率の監視方法
キャッシングの設定は戦いの半分です。実際に機能しているかどうかを知ることが残りの半分です。キャッシュヒット率が**50%**を下回る場合、プロンプト構造に何らかの変化があり、機会損失が発生しています。
プロバイダー固有のキャッシュメトリクス
| プロバイダー | キャッシュ読み込みフィールド | キャッシュ書き込みフィールド | 総入力フィールド |
|---|---|---|---|
| OpenAI | usage.prompt_tokens_details.cached_tokens | N/A(自動) | usage.prompt_tokens |
| Anthropic | usage.cache_read_input_tokens | usage.cache_creation_input_tokens | usage.input_tokens |
| Gemini | usageMetadata.cachedContentTokenCount | N/A(明示的キャッシュオブジェクト) | usageMetadata.promptTokenCount |
シンプルなキャッシュヒット率ロガー
以下は、任意のプロジェクトに組み込んでAPIレスポンスフィールド経由でキャッシュヒット率を追跡できるユーティリティ関数です。
import logging
logger = logging.getLogger("cache_monitor")
def log_cache_metrics(provider: str, usage: dict) -> float:
"""Extract and log cache metrics from any provider's response. Returns hit rate."""
if provider == "openai":
cached = getattr(usage.prompt_tokens_details, "cached_tokens", 0)
total = usage.prompt_tokens
elif provider == "anthropic":
cached = usage.cache_read_input_tokens
created = usage.cache_creation_input_tokens
total = cached + created + usage.input_tokens
elif provider == "gemini":
cached = getattr(usage, "cached_content_token_count", 0)
total = usage.prompt_token_count
else:
raise ValueError(f"Unknown provider: {provider}")
hit_rate = (cached / total * 100) if total > 0 else 0
logger.info(f"[{provider}] Cache hit rate: {hit_rate:.1f}% ({cached}/{total} tokens)")
if hit_rate < 50:
logger.warning(f"[{provider}] Low cache hit rate! Check prompt structure.")
return hit_rate健全な本番システムは70〜90%のキャッシュヒット率を維持すべきです。50%を下回る場合は、アンチパターンのセクションを見直してください。また、これを自動評価メトリクスと統合して、プロンプトパイプラインの回帰を検出することもできます。
実世界でのユースケースにおけるプロンプトキャッシング
上記のチャットボットの例はメカニズムを示していますが、プロンプトキャッシングは特定のアーキテクチャパターンで真価を発揮します。
RAGパイプライン
RAGセットアップでは、システムプロンプトとFew-shot例はすべてのクエリで静的です。取得されたドキュメントは毎回変化します。キャッシュされたプレフィックスを最大化するようにプロンプトを構造化しましょう。
- システムプロンプト(キャッシュ済み)
- Few-shot例(キャッシュ済み)
- 取得されたドキュメント(動的、最後に配置)
- ユーザークエリ(常にユニーク)
5,000トークンのシステムプロンプトと3,000トークンのFew-shot例がある場合、各リクエストで8,000トークンがキャッシュされます。Anthropicで1日1,000リクエストの場合、キャッシュされたプレフィックスだけで1日約$6.50の節約になります。コンテキストブロックを取得してキャッシュする際は、取得出力が静的プレフィックスの後に来るようにしてください。
マルチターンチャットボット
マルチターン会話はプロンプトキャッシングの絶好のターゲットです。各ターンは会話履歴に追加されますが、以前のターンからの全体の過去の会話はすでにキャッシュされています。キャッシュの恩恵は累積し、10ターン目には、最新のユーザーメッセージからの200の新しいトークンに対して、15,000トークンのキャッシュされた履歴を持つ可能性があります。
エージェントシステムとMCPツール定義
ツール使用のエージェントを構築している場合、ツール定義はすべてのAPIコールで繰り返される静的なJSONスキーマです。典型的なエージェントには、合計3,000〜5,000トークンの定義を持つ20以上のツールがあるかもしれません。これはキャッシングの絶好の材料です。
これは、サーバーツール定義が毎回送信されるMCPベースのアーキテクチャで特に重要です。Anthropicの明示的な cache_control を使用して、tools 配列をキャッシング用にマークし、それらのトークンが再利用されることを保証できます。
どのプロバイダーを選ぶべきか?
| 必要なもの... | ベストチョイス | 理由 |
|---|---|---|
| 設定ゼロ、ただ節約したい | OpenAI | 自動キャッシング、コード変更不要 |
| 最大のコスト削減(90%) | Anthropic | 0.1倍のキャッシュ読み込み価格、最も深い割引 |
| きめ細かいキャッシュ制御 | Anthropic | 明示的なブレークポイント + 設定可能なTTL(5分または1時間) |
| 長文ドキュメント分析 | Gemini | 名前付きキャッシュオブジェクトによる設定可能なTTL |
| マルチターンチャットの簡素化 | OpenAI | 増大する会話履歴に対する自動プレフィックスマッチング |
| ツール定義を持つエージェントシステム | Anthropic | cache_control でツール定義を明示的にキャッシュ |
| マルチプロバイダーの柔軟性 | LiteLLM | すべてのプロバイダー間で統一されたキャッシング構文 |
すでに1つのプロバイダーを使用している場合は、そこから始めてください。プロンプトキャッシングには切り替えは必要ありません。LiteLLMはプロキシ層として機能し、プロバイダー間でキャッシングパラメータを正規化するため、複数のモデルにリクエストをルーティングする場合に役立ちます。
FAQ:LLMプロンプトキャッシング
LLMにおけるプロンプトキャッシングとは何ですか?
プロンプトキャッシングは、以前に処理されたプロンプトプレフィックスから計算されたアテンション状態(KVキャッシュ)を保存します。後続のリクエストが同じトークンシーケンスで始まる場合、プロバイダーはそれらを再計算する代わりに保存された状態を再利用し、出力品質にゼロの影響でコストとレイテンシを削減します。
プロンプトキャッシングはAPIコストをどれだけ節約できますか?
節約額はプロバイダーによって**50%から90%**の範囲です。OpenAIはキャッシュされた入力トークンに対して50%の割引を提供します。Anthropicは最大90%オフ(基本価格の0.1倍でキャッシュ読み込み)を提供します。Geminiはキャッシュされた読み取りで約90%オフを提供します。実際の節約額は、キャッシュヒット率、プロンプトの長さ、リクエスト頻度によって異なります。
OpenAIのプロンプトキャッシングは自動で行われますか?
はい、2024年10月以降そうです。1,024トークン以上の入力トークンを持つあらゆるAPIコールは自動的にキャッシングの恩恵を受けます。オプトイン、ヘッダー、コード変更は不要です。キャッシュはプロンプトの先頭からトークンプレフィックスを一致させます。
プロンプトキャッシングとセマンティックキャッシングの違いは何ですか?
プロンプトキャッシングはGPUレベルで正確なトークンプレフィックスを一致させ、精度の損失はなく、出力はキャッシュされていないリクエストと同一です。セマンティックキャッシングは埋め込みの類似性を使用して「十分に近い」以前のクエリを見つけ、キャッシュされたレスポンスを返すため、高速ですが不正確または古くなった回答を返す可能性があります。これらは根本的に異なる問題を解決します。
プロンプトキャッシュはどのくらい持ちますか?
プロバイダーによって異なります。OpenAI:5〜10分(拡張保持で最大24時間)。Anthropic:5分(デフォルト)または1時間(Claude 4.5以降のモデルで利用可能、書き込みコスト2倍)。Gemini:設定可能、明示的キャッシュではデフォルト1時間。暗黙的キャッシングのTTLはGoogleによって自動的に管理されます。
プロンプトキャッシングの最小トークン長は何ですか?
OpenAI:1,024トークン。Anthropic:ほとんどの最新モデルで1,024トークン。Gemini:Flashモデルで1,024トークン、Proモデルで4,096トークン。これらの閾値未満のプロンプトはキャッシングを活性化せず、これが「動かない」という最も一般的な落とし穴です。
プロンプトキャッシングはストリーミングレスポンスと併用できますか?
はい。キャッシングとストリーミングはリクエストの異なるフェーズで動作します。キャッシングは入力プリフィルフェーズを高速化し、ストリーミングは出力トークンを増分的に配信します。両方は同時に機能し、ストリーミングを有効にするとTTFTの改善がより顕著に気づかれます。
プロンプトキャッシングを使用すべきでないのはいつですか?
プロンプトが最小トークン閾値未満の場合、システムプロンプトにタイムスタンプやセッションIDを含める場合、コール間でFew-shot例を回転させる場合、またはキャッシュが期限切れになる前にリクエストが頻繁すぎない場合(OpenAI/Anthropicの5〜10分ウィンドウ)は、キャッシングへの依存を避けてください。
LangChainやLiteLLMでプロンプトキャッシングを使用できますか?
はい。LangChainはプロバイダー固有のキャッシングパラメータをそのAPIラッパーを通じて渡します。LiteLLMは統一されたキャッシング構文を提供し、Anthropic、OpenAI、Gemini、Vertex AI、Bedrock間で cache_control を正規化するため、マルチプロバイダー設定で特に役立ちます。
キャッシュヒットとキャッシュミスとは何ですか?
キャッシュヒットは、プロバイダーがメモリ内で一致するプレフィックスを見つけ、保存されたKV状態を再利用したことを意味し、割引されたキャッシュトークン料金を支払い、より高速なTTFTを得られます。キャッシュミスは、一致が見つからなかったことを意味し、そのため完全なプロンプトが標準価格で最初から処理されます。APIレスポンスの cached_tokens(OpenAI)、cache_read_input_tokens(Anthropic)、または cachedContentTokenCount(Gemini)フィールドを確認して、どちらが発生したかを確認できます。
最終結論
| カテゴリ | 勝者 | 主な理由 |
|---|---|---|
| 最も簡単なセットアップ | OpenAI | 自動、設定ゼロ |
| 最も深い割引 | Anthropic | キャッシュされた読み取りで90%オフ(基本の0.1倍) |
| 最大の制御性 | Anthropic | 明示的なブレークポイント + 5分または1時間のTTL |
| 長文ドキュメントに最適 | Gemini | 名前付きキャッシュオブジェクトによる設定可能なTTL |
| マルチターンチャットに最適 | OpenAI | 会話履歴に対する自動プレフィックスマッチング |
| エージェント/MCPに最適 | Anthropic | ツール定義を明示的にキャッシュ |
プロンプトキャッシングは、LLM APIスタックにおいて最も低労力で高リターンの最適化です。モデルを変更する必要もなく、品質を犠牲にすることもなく、実装は「何もしない」(OpenAI)から「1フィールド追加」(Anthropic)、「キャッシュオブジェクト作成」(Gemini)までさまざまです。
現在のプロバイダーの自動キャッシングから始めてください。上記のログユーティリティでキャッシュヒット率を測定してください。70%を下回る場合は、プロンプトを再構造化し(静的を先に、動的を後に)、アンチパターンを排除してください。ほとんどのチームは、これらの変更を実装してから1日以内に50〜80%のコスト削減を目撃します。