powered by TechFeed
表示モード
ハウツー

AIエージェントが毎ターン同じ文脈を読み直すコスト問題 — プロンプトキャッシングで入力コストを約62%削減する実践パターン

10月27日、AWSが「Groundhog Day for AI agents: Prompt caching patterns for using OpenAI models on Amazon Bedrock」と題した記事を公開した。AIエージェントが20ターンの会話をこなすとき、モデルはターン19の時点でターン1〜18の全履歴を毎回読み直している。そのトークンコストはすべて開発者の負担だ。Amazon BedrockのOpenAIモデル向けプロンプトキャッシング機能は、この繰り返しコストを最大約62%削減できると記事は報告している。本稿ではその実装パターンと落とし穴を紹介する。

10月27日、AWSが「Groundhog Day for AI agents: Prompt caching patterns for using OpenAI models on Amazon Bedrock」と題した記事を公開した。AIエージェントが20ターンの会話をこなすとき、モデルはターン19の時点でターン1〜18の全履歴を毎回読み直している。そのトークンコストはすべて開発者の負担だ。Amazon BedrockのOpenAIモデル向けプロンプトキャッシング機能は、この繰り返しコストを最大約62%削減できると記事は報告している。本稿ではその実装パターンと落とし穴を紹介する。


AIエージェントが毎ターン同じ文脈を読み直す問題

AIエージェントはツールを呼び出し、結果を読み、次の行動を決定するたびに、モデルへその時点までの全履歴を送信する必要がある。ツール定義、指示、過去の全ツール呼び出し、その結果——これらをすべて毎回送り直す。コーディングセッションの20ターン目には、モデルはターン1〜19を読み返しており、そのトークンコストはすべて開発者の負担だ。

記事はこの状況を映画「Groundhog Day(邦題:恋はデジャ・ブ)」になぞらえる。ビル・マーレー演じる主人公が毎朝同じ2月2日を繰り返すように、エージェントも毎ターン「自分の人生の全記録」を読み直してから行動する。プロンプトキャッシングはこのループを断ち切る仕組みだ。


なぜBedrockでOpenAIモデルが使えるのか

本記事を読む上でまず押さえておきたい背景がある。Amazon BedrockでOpenAIのモデルが利用できるのは、2025年にAWSとOpenAIが発表したパートナーシップに基づく。このパートナーシップにより、OpenAIのモデル群がAmazon Bedrock上のサードパーティモデルとして提供されるようになった。開発者はAWSの統合認証・ネットワーク・コスト管理の仕組みをそのまま使いながら、OpenAIのモデルをAPI呼び出しで利用できる。本記事で紹介されるプロンプトキャッシングも、このBedrock統合レイヤーで実装された機能だ。

なお、記事中のコードサンプルに登場するgpt-6-astra、gpt-6.1-sol、gpt-5.6-lunaといったモデル名は、元記事公開時点(2025年10月)における名称であり、現在の提供状況や正式名称はAWSのサポートモデル一覧で確認されたい。


プロンプトキャッシングの仕組み

モデルがプロンプトを処理する際、まず「プリフィル」と呼ばれる書き込みフェーズを実行する。入力トークンをすべて処理し、KV(Key-Value)ベクトルと呼ばれるモデルの作業状態——各トークンのアテンション計算に使われる中間表現——を構築する。プロンプトキャッシングはこの状態を保存し、次のリクエストが同じ入力トークンで始まる場合にその保存済み状態を再利用する。新しい部分だけを追加処理すればよいため、コストが大幅に削減される。

キャッシングの方式は2種類ある。

  • 暗黙的(Implicit): Amazon Bedrockが再利用可能なプレフィックスの終端を自動で判断する
  • 明示的(Explicit): コードがprompt_cache_breakpointでその終端を明示的に指定する

両方を組み合わせることも可能で、記事ではその併用を推奨している。なお、キャッシングが機能するには最低1,024トークンのプレフィックスが必要だ。


実装パターン:まず静的コンテンツをキャッシュする

最初の実装として、ターンをまたいで変化しないツール定義と指示をキャッシュする方法が紹介されている。

KEY = "support-agent:v7:gpt-6-astra"
INSTRUCTIONS = "Your full support policies and examples..."

resp = client.responses.create(
    model="us.openai.gpt-6-astra",
    store=False,
    include=["reasoning.encrypted_content"],
    prompt_cache_key=KEY,
    prompt_cache_options={"mode": "explicit", "ttl": "30m"},
    tools=TOOLS,
    input=[
        {
            "role": "developer",
            "content": [{
                "type": "input_text",
                "text": INSTRUCTIONS,
                "prompt_cache_breakpoint": {"mode": "explicit"},
            }],
        },
        {"role": "user", "content": task},
    ],
)

prompt_cache_keyは、どのリクエストがキャッシュを共有するかをサービスに伝えるキーだ。実際のテストでは、約4,000トークンのツール+指示プレフィックスが初回リクエストで4,120トークンを書き込み、以降のリクエストでその4,120トークンを読み込む形で動作した。

一方、会話が進んで履歴が変化していく場合は暗黙的モードが有効だ。

def ask_with_implicit_cache(history):
    return client.responses.create(
        model="us.openai.gpt-6-astra",
        store=False,
        include=["reasoning.encrypted_content"],
        prompt_cache_key=KEY,
        prompt_cache_options={"mode": "implicit", "ttl": "30m"},
        tools=TOOLS,
        input=history,
    )

store=Falseは会話履歴をアプリケーション側で管理する設定であり、キャッシングを無効化するものではない点に注意が必要だ。


効果:6ターンのワークロードで入力コスト約62%削減

記事が報告している測定結果は具体的だ。GPT-6 Astraを使った6ターンのワークロードで、暗黙的キャッシングはキャッシュなしと比較して入力コストを約62%削減した。明示的なローリングブレークポイント方式では同モデルで約61%の削減を達成している。会話が長くなるほど再利用される履歴が増えるため、削減率はさらに上がる傾向にある。

ただし記事は「これはあくまでこのワークロードの結果。自分のエージェントで計測せよ」と明示している。


よくある落とし穴

記事が警告している注意点を整理する。

  • 明示的モードで静的なブレークポイントだけを設置した場合、ツールと指示はキャッシュされるが、増え続ける会話履歴は毎ターン再処理される
  • ブレークポイントを移動させると、以前のキャッシュが再利用できなくなり繰り返し書き込みが発生する。前のターンのマーカーも残しておくこと
  • 変化するタスクに対して暗黙的キャッシングだけを使うと、タスクが変わるたびにキャッシュが効かなくなる。異なるタスク間で共有したいプレフィックスがある場合は、明示的マーカーを指示の後に追加すること

また、プロンプトキャッシングが機能するにはテキストが完全に同一である必要がある。日付、ユーザー名、リクエストIDなど変化する値はキャッシュ境界の後に配置すること。MCP(Model Context Protocol)サーバーなど外部のツール定義を使う場合も、シリアライズの一貫性を確保する必要がある。


ツール追加・サブエージェントへの応用

記事はさらに、セッション中に新しいツールを動的に追加するパターンと、サブエージェントが親エージェントのキャッシュ済みプレフィックスを共有するパターンも紹介している。

ツールの動的追加では、additional_toolsという入力アイテムタイプを使う。既存のTOOLSリストを変更してしまうとキャッシュ境界が崩れるため、新ツールは必ずadditional_toolsとして末尾に追加する。これにより、元のツール+指示プレフィックスのキャッシュを維持したまま、セッション途中で機能を拡張できる。

サブエージェントのキャッシュ共有では、親エージェントと同一のprompt_cache_keyとTOOLS・指示を使ってサブエージェントを起動することで、親がすでに書き込んだKVキャッシュをそのまま読み込める。並列で複数のサブエージェントが同じタスクを分担する構成では、この共有によってサブエージェント群全体の入力コストを大幅に圧縮できる。

なお、additional_toolsはGPT-6 Astra、GPT-6.1 Sol、GPT-5.6 Lunaで利用可能であり、対応リージョンはAWSのサポートモデル一覧で確認できる(前述の通り、これらのモデル名は元記事公開時点のものである)。

詳細はGroundhog Day for AI agents: Prompt caching patterns for using OpenAI models on Amazon Bedrockを参照していただきたい。