Amazon Bedrockのプロンプトキャッシュは、毎回同じ長い前置き(システムプロンプト、参照ドキュメント、ツール定義)の処理結果を使い回し、入力トークン料金と応答待ちを減らす機能です。2026年10月時点の仕様は、2025年の解説記事から大きく変わっています。Claude Opus 5.5・Sonnet 5.5・Haiku 5.5などの最小トークン数は512に下がり(Sonnet 5は1,024)、AWSのドキュメントはキャッシュを「暗黙(Implicit)」と「明示(Explicit)」の2種類に分けて説明しています。この記事では、対応モデルと制限値、Price List APIの実単価から出した損益分岐、Converse・InvokeModelでの書き方、CloudWatchでのヒット率確認までを、AWS公式ドキュメントで確かめた内容で説明します。
まとめ:Bedrockのプロンプトキャッシュの要点
- 仕組み:プロンプトの先頭部分(プレフィックス)が前回と完全に一致したとき、その部分の再計算を省きます。出力の内容は変わりません。
- 2種類:暗黙キャッシュは指定なしで働きますがベストエフォートで、ヒットは保証されません。キャッシュする範囲を自分で指定するなら、
cachePoint(Converse)やcache_control(InvokeModel)で区切りを置く明示キャッシュを使います。 - 最小トークン:Claude Opus 5.5・Sonnet 5.5・Haiku 5.5・Fable 5.1は512、Opus 4.8・Sonnet 5・Sonnet 4.6・Sonnet 4.5は1,024、Opus 4.7・4.6・4.5とHaiku 4.5は4,096です。足りないと推論は成功してもキャッシュされません。
- 料金:Claude 5.5世代は書き込みが入力の1.25倍(1時間TTLは2倍)、読み取りは0.05倍(Haiku 5.5は0.1倍)です。5分TTLは1回、1時間TTLは2回再利用すれば元が取れます。
- 使えない場面:バッチ推論APIでは使えません。プレフィックスに日時やユーザー名が入っている、または呼び出し間隔がTTLより長いと、書き込み料金だけがかかります。
Bedrockのプロンプトキャッシュの仕組み
AWSのユーザーガイドは、プロンプトキャッシュを暗黙と明示の2種類に分けて説明しています。どちらも「先頭からの完全一致」で判定する点は同じです。違うのは、どこまでを再利用候補にするかを誰が決めるかです。
暗黙キャッシュと明示キャッシュの違い
暗黙キャッシュは、リクエストに何も書かなくてもBedrockとモデルが再利用できる先頭部分を探します。ただし公式は「同じプロンプトを繰り返してもヒットは保証されない」と明記しています。明示キャッシュは、キャッシュチェックポイント(区切り)を置いて「ここまでを再利用したい」と指定する方式です。Anthropicのモデルは両方に対応し、Amazon Novaはテキストプロンプト全体に暗黙キャッシュが効きます。コストを見積もって設計するなら、明示キャッシュを前提にしてください。
チェックポイントとTTLの規則
チェックポイントより前のプレフィックスが1文字でも変わるとキャッシュミスになり、書き込みからやり直しになります。処理はtools → system → messagesの順に連鎖するため、ツール定義を変えるとsystemとmessagesのキャッシュも無効になります。最小トークン数は区切りまでの累積で判定され、区切り同士の間隔に下限はありません。1リクエストに置ける区切りは最大4個です。
有効期限(TTL)は多くのモデルで5分で、ヒットするたびに延長されます。1時間TTLに対応するモデルでは"ttl": "1h"を指定でき、1つのリクエストに5分と1時間を混ぜるときは1時間の区切りを前に置く決まりがあります。5分TTLしか持たないモデル(Claude 3.7 Sonnet、Nova)にttlを付けるとValidationExceptionになることがあります。
対応モデルと最小トークン数(2026年10月)
明示キャッシュの対応表から主要なモデルを抜き出しました。対応モデルが提供されている全リージョンで使えます。最新の値は各モデルのモデルカードで確認してください。
| モデル | 最小トークン | 区切りの上限 | TTL | 置ける場所 |
|---|---|---|---|---|
| Claude Opus 5.5 / Sonnet 5.5 / Haiku 5.5 | 512 | 4 | 5分・1時間 | system / messages / tools |
| Claude Fable 5.1 / Fable 5 / Opus 5 | 512 | 4 | 5分・1時間 | system / messages / tools |
| Claude Opus 4.8 | 1,024 | 4 | 5分・1時間 | system / messages / tools |
| Claude Sonnet 5 / 4.6 / 4.5 | 1,024 | 4 | 5分・1時間 | system / messages / tools |
| Claude Opus 4.7 / 4.6 / 4.5 | 4,096 | 4 | 5分・1時間 | system / messages / tools |
| Claude Haiku 4.5 | 4,096 | 4 | 5分・1時間 | system / messages / tools |
| Claude 3.7 Sonnet | 1,024 | 4 | 5分 | system / messages / tools |
| GPT-6.1 Sol / GPT-6 Astra / GPT-5.6 | 1,024 | 書き込み4 | 30分 | prompt_cache_breakpoint |
| Nova 2 Lite / Nova Pro・Lite・Micro | 1K | 4 | 5分 | system / messages |
同じClaudeでも世代で最小値が8倍違います。Opus 4.7やHaiku 4.5で2,000トークンほどのシステムプロンプトに区切りを置いても、推論は成功しますがキャッシュはされません。Opus 5.5・Sonnet 5.5・Haiku 5.5へ移るなら、512トークン程度の短い指示でもキャッシュ対象になります(Sonnet 5は1,024のままです)。
OpenAIモデルとNovaの制約
BedrockのGPT-5.6以降(GPT-6 Astra、GPT-6.1 Solを含む)は、Responses API・Chat Completions・InvokeModelでprompt_cache_breakpointを使います。Converse APIでは明示キャッシュを使えません。TTLは既定30分で、書き込みは入力の1.25倍です。GPT-5.5以前は暗黙キャッシュのみ(1,024トークン以上)で、書き込みの追加料金はかかりません。Novaはtoolsに区切りを置けず、キャッシュできる量は最大2万トークンです。
東京リージョンから使う推論プロファイル
Claude 5.5世代には、東京リージョンでベアのモデルIDを直接呼べるものがありません。Opus 5.5とHaiku 5.5はjp.の推論プロファイルで東京・大阪内に処理を収められます(Haiku 5.5のモデルカードでは、送信元が東京なら振り分け先は東京・大阪のみ)。Sonnet 5.5にはjp.がなく、global.を使います。公式は、クロスリージョン推論と組み合わせると混雑時にキャッシュ書き込みが増えることがあると注意しています。どのモデルを国内処理で使えるかはAWSでClaudeを使う方法|BedrockとClaude Platform on AWSの違いと選び方で整理しています。
料金と損益分岐:何回再利用すれば元が取れるか
プロンプトキャッシュは、読み取りが安い代わりに書き込みが高い仕組みです。Amazon Bedrockの料金ページの元データであるPrice List API(us-east-1、2026-10-12公開版を10-29に取得)から抜き出しました。単位は100万トークンあたりのUSDで、Global推論の単価です。jp.などの地域推論は1割高くなります(Opus 5.5の入力ならGlobal $4.00に対して$4.40)。
| モデル | 入力 | 書き込み5分 | 書き込み1時間 | 読み取り |
|---|---|---|---|---|
| Claude Opus 5.5 | $4.00 | $5.00 | $8.00 | $0.20 |
| Claude Sonnet 5.5 | $2.00 | $2.50 | $4.00 | $0.10 |
| Claude Haiku 5.5 | $0.10 | $0.125 | $0.20 | $0.01 |
| Claude Sonnet 4.6 | $3.00 | $3.75 | $6.00 | $0.30 |
入力単価を1とすると、書き込みは5分TTLで1.25、1時間TTLで2.0です。読み取りはOpus 5.5とSonnet 5.5で0.05、Haiku 5.5とSonnet 4.6で0.1です。東京リージョンのPrice List(ap-northeast-1)でも、Opus 5.5とHaiku 5.5は同じ単価でした。Haiku 5.5はプロンプトが10万トークンを超えると、入力・出力・キャッシュとも長文脈用の単価に切り替わります(Globalで入力$0.50、書き込み5分$0.625、読み取り$0.05=約5倍)。
損益分岐の計算
同じプレフィックスを1回書き込み、TTL内にn回読み取る場合で比べます。キャッシュなしの費用は「1+n」、キャッシュありは「書き込み倍率+n×読み取り倍率」です。
| 条件 | n=1 | n=2 | 元が取れる回数 |
|---|---|---|---|
| 5分TTL・読み取り0.05 | 1.30 対 2 | 1.35 対 3 | 1回 |
| 1時間TTL・読み取り0.05 | 2.05 対 2 | 2.10 対 3 | 2回 |
| 5分TTL・読み取り0.1 | 1.35 対 2 | 1.45 対 3 | 1回 |
| 1時間TTL・読み取り0.1 | 2.10 対 2 | 2.20 対 3 | 2回 |
例として、Sonnet 5.5(Global)で1万トークンの固定プレフィックスを5分以内に100回送る場合を計算します。キャッシュなしは100万トークン分で$2.00です。キャッシュありは書き込み1回$0.025と読み取り99回$0.099で、合計$0.124(約94%減)になります。
逆に、10分おきに1時間呼ばれる用途(1時間に6回)で5分TTLを使うと、毎回TTLが切れて6回とも書き込みになります。費用は6×1.25=7.5となり、キャッシュなし(6)より25%高くつきます。この呼び出し間隔なら1時間TTLが正解です。Opus 5.5・Sonnet 5.5(読み取り0.05倍)なら2.0+5×0.05=2.25と、キャッシュなしの約4割で済みます。TTLは呼び出し間隔で選んでください。5分以内に次の呼び出しが来るなら5分TTLのままで十分で、ヒットのたびに追加料金なしで延長されます。月額全体の見積もりやほかの割引との組み合わせは、AWS Bedrockの料金はいくら?課金方式4種と月額試算・費用を下げる順番で扱っています。
inputTokensの数え方とクォータ
キャッシュを使うと、レスポンスのinputTokensはキャッシュに読み書きされなかった分だけになります。送った総入力トークンは次の式で求めます。
総入力トークン = inputTokens + cacheReadInputTokens + cacheWriteInputTokens
CloudWatchのランタイムメトリクスの説明では、キャッシュ読み取りは1分あたりトークン数(TPM)のクォータに数えず、書き込みは数えると明記されています。Reservedティアで容量を見積もるときも、InputTokenCountとCacheWriteInputTokenCount(CloudWatchのメトリクス名)を足して計算するよう指示されています。キャッシュがよく当たる構成なら、同じクォータでさばけるリクエストが増えます。
実装方法:Converse・InvokeModel・Responses APIでの書き方
どのAPIでも、固定の内容を前に置き、その直後に区切りを入れ、毎回変わる質問は区切りの後ろに置くことが条件です。ここでは東京からjp.プロファイルで呼ぶ例を示します。以下のパラメーター名と値は、boto3 1.42.97同梱のサービス定義(CachePointBlockのtypeはdefaultのみ、ttlは5mか1h)と照合しています。
Converse APIのcachePoint配置
system・messages・toolConfig.toolsのどこにでもcachePointを差し込めます。次の例は、固定の業務マニュアルをsystemに置き、2回目の呼び出しでキャッシュが読まれることを確認するものです。Converse APIそのものの使い方はAmazon Bedrock Converse APIの使い方|boto3実装・ConverseStream・Tool Use・IAM権限で解説しています。
import boto3
client = boto3.client("bedrock-runtime", region_name="ap-northeast-1")
MODEL_ID = "jp.anthropic.claude-haiku-5-5" # 東京・大阪で処理する推論プロファイル
# 毎回同じ前置き(Haiku 5.5は512トークン以上でキャッシュ成立)。日時やユーザー名は入れない
with open("manual.md", encoding="utf-8") as f:
STATIC_SYSTEM = f.read()
def ask(question):
resp = client.converse(
modelId=MODEL_ID,
system=[
{"text": STATIC_SYSTEM},
{"cachePoint": {"type": "default"}}, # ここまでがキャッシュ対象(1時間なら "ttl": "1h" を追加)
],
messages=[{"role": "user", "content": [{"text": question}]}], # 毎回変わる部分は区切りの後ろ
inferenceConfig={"maxTokens": 512},
)
u = resp["usage"]
print(u["inputTokens"], u.get("cacheWriteInputTokens", 0),
u.get("cacheReadInputTokens", 0), u.get("cacheDetails"))
return resp["output"]["message"]["content"][0]["text"]
ask("返品の受付期限は?") # 1回目: cacheWriteInputTokens が立つ想定
ask("送料は誰が負担する?") # 2回目: cacheReadInputTokens が立ち、書き込みは0になる想定
cacheDetailsは、書き込んだトークン数をTTL別(5m/1h)に返します。5分と1時間を併用したとき、どちらにいくら書き込んだかがわかります(TokenUsageのAPIリファレンス)。
InvokeModel(Claude)のcache_control指定
InvokeModelでは、Anthropic形式のリクエスト本文のブロックにcache_controlを付けます。Converseの{"type": "default"}に対し、こちらは{"type": "ephemeral"}です。AWS公式の例は質問文を先に、長い参照文を後ろに置いて区切りを付けていますが、そのまま質問文だけを差し替えて使うと、毎回プレフィックスが変わってヒットしません。固定部分を先頭に置いてください。
import json
import boto3
client = boto3.client("bedrock-runtime", region_name="ap-northeast-1")
with open("manual.md", encoding="utf-8") as f:
STATIC_SYSTEM = f.read()
body = {
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": STATIC_SYSTEM, # 固定の前置き(毎回同じ)
"cache_control": {"type": "ephemeral", "ttl": "1h"},
}
],
"messages": [{"role": "user", "content": "返品の受付期限は?"}], # 毎回変わる部分
}
resp = client.invoke_model(modelId="jp.anthropic.claude-opus-5-5", body=json.dumps(body))
usage = json.loads(resp["body"].read())["usage"]
print(usage.get("cache_creation_input_tokens"), usage.get("cache_read_input_tokens"))
InvokeModelのレスポンスはAnthropic形式なので、書き込みはcache_creation_input_tokens、読み取りはcache_read_input_tokensで返ります。Anthropicのドキュメントによると、リクエスト最上位にcache_controlを1つ置く自動キャッシュは、Anthropicが「旧来のAmazon Bedrock連携(Opus 4.6以前)」と呼ぶ経路では400エラーになります。InvokeModelで使う場合は、上の例のようにブロック単位で置いてください。
GPT-5.6以降のprompt_cache_breakpoint指定
OpenAIモデルでは、Responses APIのinput_textブロックに区切りを付けます。次の本文はbedrock-runtimeまたはbedrock-mantleのResponses APIに送ります。prompt_cache_options.modeをexplicitにすると、自動の区切りが無効になり、書き込み枠(1リクエスト4回)を自分で置いた区切りだけに使えます。
{
"model": "global.openai.gpt-5.6-sol",
"prompt_cache_options": {"mode": "explicit"},
"input": [
{"type": "message", "role": "developer",
"content": [{"type": "input_text", "text": "固定のシステム指示(1,024トークン以上)",
"prompt_cache_breakpoint": {"mode": "explicit"}}]},
{"type": "message", "role": "user",
"content": [{"type": "input_text", "text": "毎回変わる質問"}]}
]
}
レスポンスのusage.input_tokens_detailsにcached_tokens(読み取り)とcache_write_tokens(書き込み)が入ります。
ヒット率の確認と監視:usageとCloudWatch
1件ずつの確認はレスポンスのusageで行い、本番の継続監視はCloudWatchで行います。公式も「対応していてもヒットは保証されない」としているので、実際に当たっているかを数字で見るまでは、効果を見積もりに入れないでください。
usageによる1件ごとのヒット確認
同じプレフィックスで2回呼び、2回目にcacheReadInputTokensが0より大きく、cacheWriteInputTokensが0なら完全なヒットです。2回目も書き込みが立つなら、プレフィックスがどこかで変わっている可能性が高いです(jp.などのクロスリージョン推論では、混雑時に書き込みが増えることもあります)。どちらも0なら、最小トークン数に届いていないか、区切りの置き忘れ、非対応モデルを疑ってください。Bedrockコンソールのチャットプレイグラウンドでも、Prompt cachingのトグルを有効にすると、応答ごとの読み書きトークン数を「Caching metrics」で確認できます。
CloudWatchによるヒット率の算出
名前空間AWS/Bedrock(bedrock-runtime経由の呼び出し。bedrock-mantle経由は別のメトリクスページ)に、モデルIDごとのCacheReadInputTokenCountとCacheWriteInputTokenCountが出ます。ヒット率の目安は「読み取り ÷(読み取り+書き込み+InputTokenCount)」です。ダッシュボードでは、m1〜m3に3つのメトリクスを合計(Sum)で割り当て、e1に次の式を入れます。
m1 = CacheReadInputTokenCount(合計)
m2 = CacheWriteInputTokenCount(合計)
m3 = InputTokenCount(合計)
e1 = 100 * m1 / (m1 + m2 + m3)
読み取りに対して書き込みの比率が高止まりしているなら、TTL切れか、プレフィックスに動的な値が入っている可能性が高いです。トークン量で見ると、元が取れなくなる目安は、5分TTLなら書き込みが読み取りの約3.6〜3.8倍、1時間TTLなら約0.9倍を超えたときです(読み取り0.05〜0.1倍、書き込み1.25倍/2倍で計算)。
キャッシュが効かない原因と使わない方がよい場面
cacheReadInputTokensが伸びないときに、確認する順番です。
- プレフィックスに動的な値がある:システムプロンプトの先頭に現在時刻、ユーザー名、リクエストIDを埋め込むと毎回ミスします。動的な値は区切りの後ろへ移してください。
- 最小トークン数に届いていない:Opus 4.7やHaiku 4.5は4,096トークンが必要です。エラーは出ず、キャッシュされないだけです。
- toolsやsystemを毎回組み替えている:tools → system → messagesの順に連鎖するので、前の段を変えると後ろも全部ミスします。ツール一覧の並び順が毎回変わるだけでもミスになります。
- 静的部分が区切りから20ブロック以上前にある:Claudeの簡易キャッシュ管理は、区切りからおよそ20コンテンツブロックまでしか遡って一致を探しません。長い会話履歴を丸ごと固定部分にしているなら、区切りを複数に分けてください。
- バッチ推論で使おうとしている:プロンプトキャッシュはオンデマンド推論専用です。バッチ推論に対応するモデルでは、バッチ単価そのものが通常の半額です(Sonnet 4.6のGlobal入力で$3.00に対し$1.50)。
次の用途ではキャッシュを使わない方が安く済みます。1回で終わる呼び出し、呼び出し間隔が1時間を超える処理、プレフィックスが最小トークン数に届かない短いプロンプトです。いずれも書き込みの割増だけがかかるか、効果がありません。プロンプト自体を短くして入力を減らす方法は、Amazon Bedrockのプロンプト最適化で扱っています。社内文書を参照するチャットボットやRAGで、キャッシュを含むコスト設計から相談したい場合は、生成AI導入支援でも対応しています。
よくある質問
Bedrockのプロンプトキャッシュの最小トークン数はいくつですか?
モデルによって異なります。Claude Opus 5.5・Sonnet 5.5・Haiku 5.5・Fable 5.1は512トークン、Opus 4.8・Sonnet 5・Sonnet 4.6・Sonnet 4.5・Claude 3.7 Sonnetは1,024トークン、Opus 4.7・4.6・4.5とHaiku 4.5は4,096トークンです。区切りまでの累積トークン数で判定されます。
キャッシュチェックポイントの最大値はいくつですか?
Claude・Novaは1リクエストあたり4個です。GPT-5.6以降は「書き込み4回」が上限です。
cacheReadInputTokensが0のままなのはなぜですか?
主な原因は3つです。プレフィックスが前回と一致していない、最小トークン数に届いていない、前回の呼び出しからTTL(多くは5分)が過ぎている、のいずれかを確認してください。2回目の呼び出しでcacheWriteInputTokensが立つなら、プレフィックスの不一致かTTL切れを疑います(クロスリージョン推論では混雑時に書き込みが増えることもあります)。
バッチ推論でもプロンプトキャッシュは使えますか?
使えません。AWSのドキュメントは、プロンプトキャッシュをオンデマンド推論エンドポイント専用としています。
ElastiCacheのようなキャッシュと何が違いますか?
ElastiCacheは、アプリ側で応答やデータを保存する汎用キャッシュです。プロンプトキャッシュは、Bedrockの内部で入力の先頭部分の処理結果を再利用します。毎回同じ答えを返すならアプリ側の応答キャッシュ、同じ前置きに違う質問を投げるならプロンプトキャッシュが向いています。OpenAIやGemini、LangChainでの設定との比較はプロンプトキャッシュとは?にまとめています。
関連記事
- プロンプトキャッシュとは?OpenAIの12時間キャッシュとClaude・Gemini・LangChainの設定・料金
- Amazon Bedrock Converse APIの使い方|boto3実装・ConverseStream・Tool Use・IAM権限【2026年10月】
- AWSでClaudeを使う方法|BedrockとClaude Platform on AWSの違いと選び方【2026年9月】
- Amazon Bedrockの使い方|APIキー発行からPython呼び出し・東京で使えるモデルと料金【2026年10月】
- Amazon Bedrockプロンプト最適化|2方式の違い・対応リージョン・料金【2026年最新】