Amazon Bedrock、OpenAI GPT-5.6 モデルの明示的プロンプトキャッシュを導入
AWS は OpenAI の最新モデル GPT-5.6 シリーズを Amazon Bedrock で一般提供し、コスト削減と効率化を実現する明示的プロンプトキャッシング機能を追加した。
AI深層分析を開く2026年7月31日 01:14
AI深層分析
キーポイント
GPT-5.6 シリーズの一般提供開始
OpenAI の GPT-5.6 Sol, Terra, Luna が Amazon Bedrock で利用可能となり、複雑な推論から高速処理まで用途別に選べる。
明示的プロンプトキャッシングの導入
AWS は入力の一部をキャッシュして再利用する機能を提供し、システム指示やツール定義の繰り返しコストを大幅に削減する。
コストとパフォーマンスの最適化
キャッシュされた入力は 90% の割引で課金され、30 分間有効となるため、エージェントワークフローでの利用価値が高い。
GPT-5.6 モデルの可用性と ID
利用可能なモデル ID は openai.gpt-5.6-sol、openai.gpt-5.6-terra、openai.gpt-5.6-luna の 3 つであり、リージョンごとの利用可否は異なる。
推論努力レベルの制御と最適化
none から xhigh までの 5 レベルで推論努力を調整でき、GPT-5.6 はトークン効率が高いため低い設定でも品質を維持できる場合がある。
重要な引用
GPT-5.6 Sol, Terra, and Luna are now generally available on Amazon Bedrock.
Cached input is billed at a 90 percent discount and stays available for reuse for 30 minutes.
GPT-5.6 is more token efficient, and many workloads maintain quality at a lower effort setting.
Sampling parameters (temperature and top_p) are supported when reasoning.effort is set to none.
編集コメントを表示
編集コメント
プロンプトキャッシングの明示的制御機能は、実運用におけるコスト管理の観点から極めて重要なアップデートである。特にエージェントシステムのように同じ文脈を繰り返すワークフローでは、導入による効果が見込めるため、開発者は即座に評価を検討すべきだ。
Source Article
元記事を日本語で読む
本文に関係しない購読案内、埋め込み通知、サイト内プロモーションは除いています。
本記事は、OpenAI の Chris Dickens との共著です。
OpenAI の GPT-5.6 Sol、Terra、Luna が、Amazon Bedrock で一般利用可能になりました。Amazon Bedrock 上で GPT-5.6 を利用すれば、最新の OpenAI フロンティアモデルをトークン課金で利用でき、AWS のセキュリティやガバナンス機能もそのまま活用できます。また、既存の AWS コミットメントの利用量にもカウントされます。
このモデルファミリーは、3 つの能力レベルに分かれています。最も複雑な推論やエージェントによるコーディング作業には「GPT-5.6 Sol」を、バランス型の日常業務用ワークロードには「GPT-5.6 Terra」を、分類や要約など高速・大量処理が必要なタスクには「GPT-5.6 Luna」を使用します。
新モデルの導入に併せて、Amazon Bedrock では「明示的なプロンプトキャッシュ(explicit prompt caching)」機能も利用可能になりました。この機能を使えば、どの部分をキャッシュしてリクエスト間で再利用するかを細かく制御できます。キャッシュされた入力は 90% オフで課金され(詳細は Amazon Bedrock の料金ページ を参照)、30 分間再利用可能です。特に、システム指示やツール定義、参照ドキュメントが多数の呼び出しで繰り返されるエージェントワークフローでは、この機能から最大の恩恵を得られます。
Amazon Bedrock で GPT-5.6 モデルが利用可能になりました。本稿では、プロンプトのどの部分をキャッシュし、リクエスト間で再利用するかをユーザー自身が制御できる「明示的プロンプトキャッシング」機能についてご紹介します。
この新機能は、従来からある暗黙的なキャッシングとどう違うのか、それぞれのモードをいつ使い分けるべきか、セットアップ方法や動作確認の方法、そしてエージェントワークフローにおけるパフォーマンスについて解説します。また、Amazon Bedrock 上で現在稼働している GPT モデルのワークロードを GPT-5.6 に移行する方法や、他のプラットフォームから移行する場合の手順についても触れます。
Amazon Bedrock で GPT-5.6 を使い始める
GPT-5.6 モデルは、Amazon Bedrock の bedrock-mantle エンドポイント上で、OpenAI 互換の Responses API を通じて提供されています。
クライアントの設定
認証には、AWS 資格情報から生成された短期間のベアートークを使用するのが推奨されます。トークンジェネレーターを OpenAI SDK とともにインストールしてください。
pip install openai aws-bedrock-token-generator
次にクライアントを作成します。このトークンジェネレーターは標準的な AWS 資格情報のチェーン(IAM ロール、環境変数、または CLI プロファイル)を利用するため、コードに長期有効なシークレットを埋め込む必要がありません。
from openai import OpenAI
from aws_bedrock_token_generator import provide_token
REGION = "us-east-2"
client = OpenAI(
base_url=f"https://bedrock-mantle.{REGION}.api.aws/openai/v1",
api_key=provide_token(region=REGION), # AWS 資格情報から取得した短期トークン
)
最初のリクエストを実行する
GPT-5.6 モデルでは Responses API を使用します。最小限のリクエストは以下のようになります。
以下のコードは、Amazon Bedrock で OpenAI の GPT-5.6 モデルを呼び出す例です。
response = client.responses.create(
model="openai.gpt-5.6-terra",
instructions="You are a concise technical assistant.",
input="What is Amazon Bedrock?",
max_output_tokens=500,
)
print(response.output_text)利用可能なモデル ID は、openai.gpt-5.6-sol、openai.gpt-5.6-terra、openai.gpt-5.6-luna の 3 つです。GPT-5.6 Sol は米国東部(バージニア北部)と米国東部(オハイオ)リージョンで利用可能です。Terra と Luna はさらに米国西部(オレゴン)でも利用できます。リージョン別のモデル利用状況については、Amazon Bedrock の「AWS リージョン別サポート対象モデル」ページをご参照ください。
推論の努力レベルを制御する
GPT-5.6 では、none、low、medium、high、xhigh の 5 つの推論努力レベルを設定できます。デフォルトは medium です。高いレベルに設定すると、複雑な問題に対してより多くの推論リソースが割り当てられます。一方、none を指定すれば、単純なタスクでは最も低遅延で処理を実行できます。
response = client.responses.create(
model="openai.gpt-5.6-luna",
input="Classify this ticket as bug, feature request, or question: 'App crashes on login.'",
reasoning={"effort": "none"},
)GPT-5.5 または GPT-5.4 からアップグレードする際の practical なガイドラインとして、まずは現在の設定レベルで始め、その後一つ下のレベルでテストすることをお勧めします。GPT-5.6 はトークン効率に優れており、多くのワークロードでは低い努力度(effort)の設定でも品質を維持できます。
推論の努力度を「none」に設定した場合は、サンプリングパラメータである temperature と top_p を使用可能です。それ以外の努力度レベルでは、モデルの推論プロセスが出力の変動性を制御します。
Stream responses
ストリーミングは SDK の標準インターフェースを通じて動作し、タイプされたイベントとして出力を配信します:
with client.responses.stream(
model="openai.gpt-5.6-terra",
input="Write a haiku about distributed systems.",
) as stream:
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)
Call tools and get structured output
関数呼び出しと厳密な JSON スキーマ出力は、OpenAI のネイティブ API と同じように動作します。ツールの定義には、Responses API のフラット形式を使用します:
AWS の Amazon Bedrock で OpenAI GPT-5.6 モデルを利用する際、明示的なプロンプトキャッシュ機能を活用できます。以下は、関数呼び出しを実行する例です。
構造化された出力が必要な場合は、厳格な JSON スキーマを指定します。モデルはそれに基づいた有効な JSON を返します。
Amazon Bedrock で GPT-5.6 のプロンプトキャッシュを活用する
GPT-5.6 モデルは、Responses API を通じてプロンプトキャッシュをサポートしています。利用可能なモードは2つあります。
1 つ目は「インプリシット(暗黙的)モード」で、Amazon Bedrock が自動的にキャッシュの境界点を設定します。
2 つ目は「エクスペリット(明示的)モード」で、ユーザー自身がキャッシュの境界を指定し、より精密な制御を実現できます。
ここでは両方のモードについて解説し、キャッシュ動作の確認方法や、ワークロードに最適なモードの選び方をご紹介します。
プロンプトキャッシュを利用すると、Amazon Bedrock はリクエスト間で重複するプロンプト部分を再計算せずに済みます。GPT-5.6 では、キャッシュからの読み取りは非キャッシュ入力トークンと比較して 90% オフで課金され、書き込みは非キャッシュ入力料率の 1.25 倍です。この機能は、「一度書き込んで何度も読む」パターンを想定して設計されています。
読み取りによるコスト削減分が、書き込みによる追加コストを上回るため、キャッシュ経由で処理されるトークンの約 20% が読み取りリクエストになれば、ワークロード全体のネット入力コストは低下します。インプリシットモードでは、Amazon Bedrock が境界点を設定して最適化してくれるため、ユーザー側の手間なくこの効果を得られます。一方、エクスペリットモードでは、安定したプレフィックス部分を自分で指定することで、キャッシュヒット率をさらに高めることが可能です。後続のリクエストでそのプレフィックスがキャッシュから読み出されるためです。
現在の料率については、Amazon Bedrock 料金ページをご確認ください。
暗黙的プロンプトキャッシングから始める
GPT-5.6 では、プロンプトキャッシングはデフォルトで「暗黙的モード」が有効になっています。キャッシングパラメータを指定せずにリクエストを送信すると、Amazon Bedrock が自動的にキャッシュのブレイクポイントを設定し、再利用可能なプレフィックスを検索します。1,024 トークン以上の安定したプレフィックスであれば、コードを変更することなくキャッシュして再利用できます。
キャッシングパラメータ不要な暗黙的キャッシング
response = client.responses.create(
model="openai.gpt-5.6-terra",
instructions=SYSTEM_INSTRUCTIONS, # 安定したプレフィックス、1,024 トークン以上
input=user_question,
)
details = response.usage.input_tokens_details
print(f"cached: {details.cached_tokens}, written: {details.cache_write_tokens}")暗黙的キャッシングを使えば、プロンプト構造の分析を一切行わずとも、既存のコードが初日からキャッシュ読み取りの対象となります。Bedrock がブレイクポイントの設定を代行するため、最初のリクエストでプレフィックスがキャッシュに書き込まれ、その後のリクエストではそれが読み出されます。
ただし、安定したプレフィックスの後に続くコンテンツが、チャットアシスタントやエージェントによるツールループなど、すべてのリクエストで変化するワークロードの場合には、自分で明示的なブレイクポイントを指定する方が予測可能な結果を得られます。この手法については次のセクションで詳しく説明します。
明示的なプロンプトキャッシュの設定
明示モードでは、キャッシュの境界を直接制御できます。再利用可能なプレフィックスの終わりを自分で指定するだけで、キャッシュされたプレフィックスは最低 30 分間利用可能になります。これにより、1 つのエージェント実行で発生する一時的な呼び出しの急増にも十分に対応可能です。
GPT-5.6 モデルにおけるキャッシュ制御には、以下の 3 つのリクエストパラメータがあります。
- prompt_cache_breakpoint: コンテンツブロックに配置し、再利用可能なプロンプトプレフィックスの正確な終わりをマークします。このマークされたブロックまで(含む)の内容がキャッシュされ、その後の内容は自由に変わっても、キャッシュされたプレフィックスの有効性は維持されます。各キャッシュされたプレフィックスには少なくとも 1,024 トークンを含める必要があり、入力テキスト、入力画像、入力ファイルの各ブロックに対して、リクエストあたり最大 4 つのブレイクポイントを設定できます。
- prompt_cache_key: 同じキャッシュにリクエストをルーティングするための安定した ID です。セッション内またはアプリケーション全体でこのキーを一貫して設定することで、繰り返し行われるリクエストがキャッシュされたプレフィックスを検出できるようにします。
- prompt_cache_options: キャッシュモード(明示的または暗黙的)と TTL(有効期限)を制御します。暗黙的モードについては次節で解説します。
以下に完全な例を示します。すべての呼び出しで同じ長いシステム指示を持つサポートアシスタントのケースです。その後、毎回変わるユーザーからの質問が続きます。この場合、ブレイクポイントは静的なコンテンツの最後に設定します。
Amazon Bedrock上でOpenAI GPT-5.6モデルを利用する際、明示的なプロンプトキャッシュ機能を導入しました。
response = client.responses.create(
model="openai.gpt-5.6-terra",
prompt_cache_key="support-app:kb-v1", # same key across all requests
input=[
{
"type": "message",
"role": "developer",
"content": [{
"type": "input_text",
"text": SYSTEM_INSTRUCTIONS, # long, static: guidelines, KB excerpts (>= 1,024 tokens)
"prompt_cache_breakpoint": {"mode": "explicit"},
}],
},
{
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": user_question, # changes on every request
}],
},
],
extra_body={"prompt_cache_options": {"mode": "explicit"}},
)
キャッシュ動作の確認
すべてのレスポンスには、キャッシュがどのように機能したかがusage.input_tokens_detailsオブジェクトに明記されます。ここが設定の検証ポイントです。
- cached_tokens: キャッシュから読み込まれた入力トークン数。請求時には90%割引が適用されます。
- cache_write_tokens: キャッシュへ書き込まれた入力トークン数。未キャッシュ時のレートに対して1.25倍の請求となります。
details = response.usage.input_tokens_details
print(f"cached: {details.cached_tokens}, written: {details.cache_write_tokens}")
*注記:30分以内のキャッシュ内から提供されたトークンは、その後の呼び出しでは課金対象外となります。詳細は以下の説明をご覧ください。
input_tokens = cached_tokens + cache_write_tokens + non-cached remainder
input_tokens はリクエスト全体のトークン数を示します。cached_tokens と cache_write_tokens は、その入力のうちどれがキャッシュから供給されたかを報告するもので、残りの部分は毎回送信される新しいコンテンツ(例:ブレークポイント後のユーザー質問)です。
キャッシュ読み込み数と書き込み数は input_tokens に追加されるのではなく、input_tokens の一部としてカウントされるため、キャッシュから提供されたトークンは 1 回だけカウントされ、キャッシュ読み込みレートで 1 回だけ課金されます。同じトークンに対して 2 重に請求されることはありません。
以下の例では、1 つの prompt_cache_key のもとで、3,626 トークンのシステムプレフィックスが再利用されています。ユーザー質問は毎回変わるため、キャッシュされない input_tokens の残りの部分もそれに伴って変化します:
リクエスト
input_tokens
cached_tokens
cache_write_tokens
新しい(非キャッシュ)入力
初回(コールド)
3,682
0
3,626
56
2 回目
3,671
3,626
0
45
3 回目
3,662
3,626
0
36
最初のリクエストで、3,626 トークンのプレフィックスがキャッシュに書き込まれます。2 回目のリクエスト以降は、このプレフィックスがキャッシュ読み込み割引レートで読み出され、新しいユーザー入力(今回はそれぞれ 45 と 36 トークン)のみが標準レートで処理されます。cached_tokens は高い値を維持し、cache_write_tokens はゼロに低下します。input_tokens の変動は、変化するユーザー質問のサイズ分だけになります。
これらのフィールドは、すべてのレスポンスに含まれています。最も直接的な検証ワークフローとしては、アプリケーションからリクエスト ID や prompt_cache_key とともにこれらをログ出力し、本番トラフィックが依存する前に「書き込み 1 回・読み取り多数」のパターンが正しく機能していることを確認することです。
集計モニタリングについては、bedrock-mantle エンドポイントが AWS/BedrockMantle ネームスペースの下で推論およびトークンメトリクスを Amazon CloudWatch に公開しています(CloudWatch メトリクスを使用した bedrock-mantle 推論の監視 を参照)。これにより、アカウント、プロジェクト、モデルごとの入力および出力トークンの総量を追跡できます。
一方、リクエストごとのキャッシュ内訳は、各レスポンスに含まれる usage オブジェクトから取得可能です。つまり、これらの 2 つのフィールドをアプリケーションレベルでログ記録することが、キャッシュの可観測性を支える基盤となります。
エージェントループでのキャッシング活用
エージェントワークロードこそが、明示的キャッシングの真価を発揮する場です。ツール呼び出しループでは、システムプロンプトやツールの定義が各ターンで繰り返される一方、会話の内容は末尾に蓄積されていきます。これは静的なコンテンツの後にブレークポイントを設けるキャッシュ戦略と完璧に合致します。
以下は、サービスヘルスと直近のデプロイ状況を確認するインシデント対応アシスタントを構築する例です。
import json
SYSTEM_PROMPT = "..." # long runbook and instructions (>= 1,024 tokens)
MAX_TURNS = 10
TOOLS = [
{"type": "function", "name": "get_service_health",
"description": "Get health status for a microservice",
"parameters": {"type": "object",
"properties": {"service": {"type": "string"}},
"required": ["service"]}},
{"type": "function", "name": "get_recent_deploys",
"description": "List deployments in the last N hours",
"parameters": {"type": "object",
"properties": {"hours": {"type": "integer"}},
"required": ["hours"]}},
]
conversation = [
{"type": "message", "role": "developer",
"content": [{"type": "input_text",
"text": SYSTEM_PROMPT,
"prompt_cache_breakpoint": {"mode": "explicit"}}]},
{"type": "message", "role": "user",
"content": [{"type": "input_text",
"text": "Is checkout-service healthy? If not, was there a recent deploy?"}]},
]
for turn in range(MAX_TURNS):
response = client.responses.create(
model="openai.gpt-5.6-sol",
prompt_cache_key="incident-agent:session-42",
input=conversation,
tools=TOOLS,
extra_body={"prompt_cache_options": {"mode": "explicit", "ttl": "30m"}},
)
tool_calls = [o for o in response.output if o.type == "function_call"]
if not tool_calls:
print(response.output_text)
break
for call in tool_calls:
execute_tool は、実際のシステムを呼び出して JSON 直列化可能な結果を返す実装です。
result = execute_tool(call.name, json.loads(call.arguments))
conversation.append({"type": "function_call", "call_id": call.call_id,
"name": call.name, "arguments": call.arguments})
conversation.append({"type": "function_call_output", "call_id": call.call_id,
"output": json.dumps(result)})
このループを動かすのはモデルです。どのツールを呼び出すかを決め、最終的な応答を返してツール呼び出しが止まればループは終了します。このツール呼び出しのループこそが、エージェントの最小限の形態であり、エージェントフレームワークが自動的に管理しているのも同じ仕組みです。
最初のターンでシステムプロンプトのプレフィックスがキャッシュに書き込まれます。その後の各ターンでは、モデルが新たに追加されたツール呼び出しと結果を処理する間に、このプレフィックスをキャッシュから読み出します。30 分の TTL(有効期限)は、数分間続くエージェントセッションを十分にカバーできます。
各ターンで 2 つのユースフィールドをログに記録すると、そのパターンが明確になります。最初のターンで一度だけキャッシュへの書き込みが行われ、その後すべてのターンでキャッシュからの読み出しが続くという流れです。
暗黙的キャッシングと明示的キャッシングの選択
GPT-5.6 では、prompt_cache_options.mode を設定することで、2 つのキャッシングモードから選べます。
暗黙的(デフォルト)
Amazon Bedrock が最新メッセージに自動的にキャッシュブレイクポイントを設け、キャッシュヒット率を最大化しようとします。明示的に設定したブレイクポイントは、この自動処理と競合する可能性があります。
原文を表示
*This post is co-written with Chris Dickens from OpenAI.*
OpenAI GPT-5.6 Sol, Terra, and Luna are now generally available on Amazon Bedrock. With GPT-5.6 on Amazon Bedrock, you get the newest generation of OpenAI frontier models with pay-per-token pricing, AWS security and governance controls, and usage that counts toward your existing AWS commitments. The family covers three capability tiers: GPT-5.6 Sol for the most complex reasoning and agentic coding work, GPT-5.6 Terra for balanced everyday production workloads, and GPT-5.6 Luna for fast, high-volume tasks such as classification and summarization.
Alongside the new models, GPT-5.6 introduces explicit prompt caching on Amazon Bedrock, a new capability that gives you precise control over which portions of your prompt are cached and reused across requests. Cached input is billed at a 90 percent discount (see the Amazon Bedrock pricing page) and stays available for reuse for 30 minutes. You get the most value from this in agentic workflows, where system instructions, tool definitions, and reference documents repeat across many calls.
In this post, we introduce explicit prompt caching for GPT-5.6 on Amazon Bedrock, a new capability that gives you control over which parts of your prompt are cached and reused across requests. We show how it differs from implicit caching and when to use each mode, how to set it up and verify that it is working, and how it performs in an agentic workflow. We also cover how to migrate workloads from earlier GPT models onto GPT-5.6, whether they run on Amazon Bedrock today or on another platform.
Get started with GPT-5.6 on Amazon Bedrock
GPT-5.6 models are served through the OpenAI-compatible Responses API on the Amazon Bedrock bedrock-mantle endpoint.
Set up the client
The recommended way to authenticate is with short-term bearer tokens generated from your AWS credentials. Install the token generator alongside the OpenAI SDK:
pip install openai aws-bedrock-token-generatorThen create a client. The token generator uses the standard AWS credential chain (IAM roles, environment variables, or your CLI profile), so your code stays free of long-lived secrets:
from openai import OpenAI
from aws_bedrock_token_generator import provide_token
REGION = "us-east-2"
client = OpenAI(
base_url=f"https://bedrock-mantle.{REGION}.api.aws/openai/v1",
api_key=provide_token(region=REGION), # short-term token from your AWS credentials
)Make your first request
GPT-5.6 models use the Responses API. A minimal request looks like this:
response = client.responses.create(
model="openai.gpt-5.6-terra",
instructions="You are a concise technical assistant.",
input="What is Amazon Bedrock?",
max_output_tokens=500,
)
print(response.output_text)The three model IDs are openai.gpt-5.6-sol, openai.gpt-5.6-terra, and openai.gpt-5.6-luna. GPT-5.6 Sol is available in US East (N. Virginia) and US East (Ohio). Terra and Luna are additionally available in US West (Oregon). For model availability by Region, refer to Supported models by AWS Region in Amazon Bedrock (https://docs.aws.amazon.com/bedrock/latest/userguide/models-regions.html).
Control reasoning effort
GPT-5.6 supports reasoning effort levels none, low, medium, high, and xhigh, with medium as the default. Higher levels allocate more reasoning to harder problems, and none gives you the lowest-latency path for straightforward tasks:
response = client.responses.create(
model="openai.gpt-5.6-luna",
input="Classify this ticket as bug, feature request, or question: 'App crashes on login.'",
reasoning={"effort": "none"},
)A practical guideline when upgrading from GPT-5.5 or GPT-5.4: start with the effort level you use today, then test one level lower. GPT-5.6 is more token efficient, and many workloads maintain quality at a lower effort setting. Sampling parameters (temperature and top_p) are supported when reasoning.effort is set to none. At other effort levels, the model’s reasoning process controls output variance.
Stream responses
Streaming works through the SDK’s standard interface and delivers output as typed events:
with client.responses.stream(
model="openai.gpt-5.6-terra",
input="Write a haiku about distributed systems.",
) as stream:
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="", flush=True)Call tools and get structured output
Function calling and strict JSON schema output both work as they do with OpenAI’s native API. Tool definitions use the Responses API’s flat format:
response = client.responses.create(
model="openai.gpt-5.6-terra",
input="What's the weather in Seattle?",
tools=[{
"type": "function",
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
}],
)
for item in response.output:
if item.type == "function_call":
print(item.name, item.arguments) # get_weather {"city":"Seattle"}For structured output, pass a strict JSON schema and the model returns valid JSON that conforms to it:
response = client.responses.create(
model="openai.gpt-5.6-luna",
input="Extract: 'Order #1234 shipped to Berlin on May 2.'",
text={
"format": {
"type": "json_schema",
"name": "order",
"strict": True,
"schema": {
"type": "object",
"properties": {
"order_id": {"type": "string"},
"destination": {"type": "string"},
},
"required": ["order_id", "destination"],
"additionalProperties": False,
},
}
},
)
print(response.output_text) # {"destination":"Berlin","order_id":"1234"}Use prompt caching for GPT-5.6 on Amazon Bedrock
GPT-5.6 models support prompt caching through the Responses API, with two modes: implicit, where Amazon Bedrock places cache breakpoints for you automatically, and explicit, where you mark the cache boundary yourself for precise control. This section covers both, along with how to verify caching behavior and choose the right mode for your workload.
Prompt caching lets Amazon Bedrock skip recomputing portions of your prompt that repeat across requests. On GPT-5.6, cache reads are billed at a 90 percent discount compared to uncached input tokens, and cache writes are billed at 1.25 times the uncached input rate, so the feature is designed for write-once, read-many patterns. Because a read saves far more than a write adds, a workload lowers its net input cost once cache reads make up roughly 20 percent of the tokens that flow through the cache. Implicit moves you toward that with no work on your part, because Amazon Bedrock places the breakpoint and tunes it for you. In explicit mode, marking the stable prefix yourself typically pushes the hit rate higher still, because later requests read the prefix back while it stays cached. For current rates, see the Amazon Bedrock pricing page.
Start with implicit prompt caching
On GPT-5.6, prompt caching is on by default in implicit mode. When you send a request without any caching parameters, Amazon Bedrock automatically places a cache breakpoint and looks for a reusable prefix. A stable prefix of at least 1,024 tokens can be cached and reused with no change to your code.
# Implicit caching: no caching parameters needed
response = client.responses.create(
model="openai.gpt-5.6-terra",
instructions=SYSTEM_INSTRUCTIONS, # stable prefix, >= 1,024 tokens
input=user_question,
)
details = response.usage.input_tokens_details
print(f"cached: {details.cached_tokens}, written: {details.cache_write_tokens}")Implicit caching means your existing code starts earning cache reads from day one, with no analysis of your prompt structure required. Because Bedrock chooses the breakpoint for you, the first request writes the prefix to the cache and later requests read it back. For workloads where the content after your stable prefix changes on every request, such as chat assistants and agentic tool loops, you get more predictable results by marking the prefix yourself with an explicit breakpoint. The following section describes this approach.
Set up explicit prompt caching
Explicit mode gives you direct control over the cache boundary. You mark the end of your reusable prefix, and cached prefixes stay available for reuse for at least 30 minutes, long enough to cover the burst of calls a single agent run generates. Three request parameters control caching on GPT-5.6:
- prompt_cache_breakpoint: placed on a content block, marks the exact end of a reusable prompt prefix. Everything up to and including the marked block is cached, and everything after it can change freely while the cached prefix stays valid. Each cached prefix must contain at least 1,024 tokens, and you can set up to 4 breakpoints per request on input_text, input_image, and input_file blocks.
- prompt_cache_key: a stable ID that routes requests to the same cache. Set it consistently across all requests in a session or application so repeat requests find the cached prefix.
- prompt_cache_options: controls the caching mode (implicit or explicit, covered in the next section) and the TTL.
Here is a complete example: a support assistant with a long system instruction that is identical on every call, followed by a user question that changes every time. The breakpoint goes at the end of the static content:
response = client.responses.create(
model="openai.gpt-5.6-terra",
prompt_cache_key="support-app:kb-v1", # same key across all requests
input=[
{
"type": "message",
"role": "developer",
"content": [{
"type": "input_text",
"text": SYSTEM_INSTRUCTIONS, # long, static: guidelines, KB excerpts (>= 1,024 tokens)
"prompt_cache_breakpoint": {"mode": "explicit"},
}],
},
{
"type": "message",
"role": "user",
"content": [{
"type": "input_text",
"text": user_question, # changes on every request
}],
},
],
extra_body={"prompt_cache_options": {"mode": "explicit"}},
)Verify caching behavior
Every response reports exactly what the cache did, in the usage.input_tokens_details object. This is the place to verify your setup:
- cached_tokens: input tokens read from cache, billed at the 90 percent discount.
- cache_write_tokens: input tokens written to cache, billed at 1.25 times the uncached rate.
details = response.usage.input_tokens_details
print(f"cached: {details.cached_tokens}, written: {details.cache_write_tokens}")*Note: Tokens served from the cache within the 30-minute window are excluded from charges on subsequent calls. The following explanation covers this in detail.*
input_tokens = cached_tokens + cache_write_tokens + non-cached remainder
input_tokens is the full input count for the request. cached_tokens and cache_write_tokens report how much of that input came from the cache, and the rest is the new content you send each time, such as the user question after your breakpoint. Because the cached and written counts are part of input_tokens rather than added on top of it, a token served from the cache is counted once and billed once at the cache-read rate. You are never charged twice for the same token. In the following example, the requests reuse the same 3,626-token system prefix under one prompt_cache_key. The user question changes each time, so the non-cached remainder of input_tokens changes with it:
Request
input_tokens
cached_tokens
cache_write_tokens
New (non-cached) input
First (cold)
3,682
0
3,626
56
Second
3,671
3,626
0
45
Third
3,662
3,626
0
36
The first request writes the 3,626-token prefix to the cache. From the second request onward, that prefix is read back at the cache-read discount while only the new user input (45 and 36 tokens here) is processed at the standard rate. cached_tokens stays high, cache_write_tokens drops to zero, and input_tokens moves only by the size of the changing user question.
These two fields arrive with every response. The most direct verification workflow is to log them from your application alongside the request ID and prompt_cache_key. Then confirm the write-once, read-many pattern in your logs before production traffic depends on it. For aggregate monitoring, the bedrock-mantle endpoint publishes inference and token metrics to Amazon CloudWatch under the AWS/BedrockMantle namespace (see Monitor bedrock-mantle inference using CloudWatch metrics). This tracks overall input and output token volume by account, project, and model. The per-request cache breakdown comes from the usage object in each response, which makes application-level logging of these two fields the foundation of your caching observability.
Use caching in an agentic loop
Agentic workloads are where explicit caching shines. In a tool-calling loop, the system prompt and tool definitions repeat on every turn while the conversation grows at the end, a perfect fit for a breakpoint after the static content. This example builds an incident-response assistant that checks service health and recent deployments:
import json
SYSTEM_PROMPT = "..." # long runbook and instructions (>= 1,024 tokens)
MAX_TURNS = 10
TOOLS = [
{"type": "function", "name": "get_service_health",
"description": "Get health status for a microservice",
"parameters": {"type": "object",
"properties": {"service": {"type": "string"}},
"required": ["service"]}},
{"type": "function", "name": "get_recent_deploys",
"description": "List deployments in the last N hours",
"parameters": {"type": "object",
"properties": {"hours": {"type": "integer"}},
"required": ["hours"]}},
]
conversation = [
{"type": "message", "role": "developer",
"content": [{"type": "input_text",
"text": SYSTEM_PROMPT,
"prompt_cache_breakpoint": {"mode": "explicit"}}]},
{"type": "message", "role": "user",
"content": [{"type": "input_text",
"text": "Is checkout-service healthy? If not, was there a recent deploy?"}]},
]
for turn in range(MAX_TURNS):
response = client.responses.create(
model="openai.gpt-5.6-sol",
prompt_cache_key="incident-agent:session-42",
input=conversation,
tools=TOOLS,
extra_body={"prompt_cache_options": {"mode": "explicit", "ttl": "30m"}},
)
tool_calls = [o for o in response.output if o.type == "function_call"]
if not tool_calls:
print(response.output_text)
break
for call in tool_calls:
# execute_tool is your implementation: call the real system
# and return a JSON-serializable result
result = execute_tool(call.name, json.loads(call.arguments))
conversation.append({"type": "function_call", "call_id": call.call_id,
"name": call.name, "arguments": call.arguments})
conversation.append({"type": "function_call_output", "call_id": call.call_id,
"output": json.dumps(result)})The model drives this loop: it decides which tools to call, and the loop ends when the model returns a final response instead of another tool call. This tool loop is the minimal form of an agent, the same loop that agent frameworks manage for you. The first turn writes the system prompt prefix to the cache. Every later turn in the run reads that prefix from the cache while the model processes the newly appended tool calls and results, and the 30-minute TTL comfortably covers multi-minute agent sessions. Logging the two usage fields per turn shows the pattern clearly: a single cache write on the opening turn, followed by cache reads on each turn after it.
Choose between implicit and explicit caching
GPT-5.6 supports two caching modes, controlled by prompt_cache_options.mode:
Implicit (the default). Amazon Bedrock automatically places a cache breakpoint on the latest message and attempts to maximize your cache hit rate. Any explicit breakpoints you
関連記事
News to Guide
ニュースの次に確認する
発表内容を、現在の料金や仕様と照らし合わせられる関連ガイドです。
今日のまとめ
AIデイリーブリーフで今日の重要ニュースをまとめ読み