AIコーディングとエージェント

[AIコンテキスト #7] プロンプトキャッシュでAPIコストを削減

シリーズ最終回はお金の話です。エージェントをAPIで動かしたことがあれば、請求書の違和感に気づいたでしょう。出力より入力トークン料金が圧倒的に高いのです。第1回の構造を思い出せば当然です。毎ターン、システムプロンプトから会話履歴全体まで再送するため、50ターンのエージェントセッションでは同じシステムプロンプトに50回課金されます…

読了 5 分
[AIコンテキスト #7] プロンプトキャッシュでAPIコストを削減のカバー画像

シリーズ最終回はお金の話です。エージェントをAPIで動かしたことがあれば、請求書の違和感に気づいたでしょう。出力より入力トークン料金が圧倒的に高いのです。第1回の構造を思い出せば当然です。毎ターン、システムプロンプトから会話履歴全体まで再送するため、50ターンのエージェントセッションでは同じシステムプロンプトに50回課金されることになります。

この反復コストを削る仕組みがプロンプトキャッシュ(prompt caching)です。うまく使えば入力コストは10分の1になり、応答も速くなります。ただし条件が一つあります。コンテキストをキャッシュに適した形で積み上げる必要があります。今回はその原理と、知らないうちにキャッシュを全消去するミスを見ていきます。

同じプレフィックスは再計算しない

原理は第1回ですでに半分説明しました。モデルが入力を処理すると、トークンごとにアテンションの中間結果が生成され、KVキャッシュとしてGPUメモリに蓄積されます。プロンプトキャッシュは、このKVキャッシュをリクエスト終了後も保持し、次のリクエストが同じ内容で始まれば、その部分の計算を丸ごと再利用する機能です。

エージェントの会話にどれほど適しているか見てみましょう。10ターン目の入力は「システムプロンプト+ターン1〜9+新しいメッセージ」です。11ターン目は「システムプロンプト+ターン1〜10+新しいメッセージ」です。前半は完全に同じです。キャッシュがあれば、サーバーはターン10までの計算済み結果を取り出し、新しく追加された末尾だけ計算すれば済みます。

料金もこの構造に従います。Anthropic APIでは、キャッシュから読み出した入力トークンは通常料金の10%です。キャッシュへの新規書き込みには25%の割増がありますが、1回書いて何度も読むエージェントではすぐ相殺されます。数百ターンのセッションでは、キャッシュの有無でコストが数倍変わります。キャッシュ部分を処理しないため、最初のトークンまでの遅延も大幅に短くなります。

条件は一つ、プレフィックスを一文字も変えない

ただではありません。キャッシュ再利用の条件はプレフィックスの一致です。入力の先頭から連続する同一部分にだけ適用され、内容が変わった最初の位置以降はすべて再計算されます。

この規則の理由も第1回で説明しました。アテンションでは各トークンのKV値が、それより前にあるすべてのトークンに依存します。前方のトークンが一つでも変われば、その後の全トークンの計算結果が変わるため、キャッシュを使えません。コンテキストの前半ほど変更コストが高い理由です。

したがって、キャッシュに適したコンテキストの原則は一文でまとめられます。安定したものを前に、可変なものを後ろに置き、履歴は変更せず追記だけする(append-only)。

append-onlyならキャッシュヒット、プレフィックスを変更するとその位置から全計算
append-onlyならキャッシュヒット、プレフィックスを変更するとその位置から全計算

キャッシュを全消去する不用意なミス

原則は単純ですが、破り方は巧妙です。

一つ目はシステムプロンプト内の可変値です。現在時刻を秒単位で埋め込むとどうなるでしょう。コンテキストの先頭が毎回変わるため、キャッシュヒット率は0%になります。入れるなら日付程度に丸めるか、コンテキストの後方に置きましょう。セッションIDや乱数も同じ落とし穴です。

二つ目はツール定義の変更です。ツールスキーマは通常コンテキストの最上部に入るため、セッション途中でツールを追加・削除すると、その後全体のキャッシュが無効になります。第4回ではMCPサーバーの整理を勧めましたが、キャッシュの観点ではもう一言加わります。整理はセッション開始前に行い、途中では触らないことです。

三つ目は履歴の途中編集です。過去のターンを修正したり古いターンを削除してコンテキストを節約しようとすると、プレフィックスが壊れた位置からキャッシュが消えます。数千トークンを節約するつもりが、セッション全体の再計算費用を払う、割に合わない取引になりがちです。履歴から何かを消すなら、区切りを付けてまとめて空にする方がよいでしょう。

最後に、第3回の/compactもキャッシュの観点で見直せます。圧縮すると履歴全体が新しい要約に置き換わるため、キャッシュは完全にリセットされます。もちろん、その後のターンは短い履歴の上に新しいキャッシュを積めるので長期的には得ですが、「compactは無料の掃除ではなく、キャッシュ再構築のコストを伴うイベント」という感覚が必要です。頻繁なcompactより、区切りごとの/clearの方がコスト面で有利な場合が多い理由です。

キャッシュの有無で請求額は数倍変わります
キャッシュの有無で請求額は数倍変わります

シリーズ総まとめ、コンテキストを扱う7つの感覚

7回を貫いた原則を、一行ずつ振り返ります。

  1. コンテキストウィンドウは有限で、その限界はアテンション計算とKVキャッシュという物理に由来します。
  2. 入るからといって有効に使われるわけではありません。長さそのものが品質を下げます。
  3. 作業の境界ごとに/clearを基本とし、文脈を引き継ぐときだけ指示付きの/compactを使います。
  4. システムプロンプト・CLAUDE.md・ツール定義は固定費です。常に真であることだけを短く書きます。
  5. 過程が重く結論が軽い作業は、サブエージェントのコンテキストに隔離します。
  6. セッションをまたぐ知識はファイルに外部化します。計画ファイル、メモリ、大きければRAGです。
  7. コンテキストはappend-onlyで積むとキャッシュが活きます。安定したものを前に、可変なものを後ろに置きます。

一言で言えば、コンテキストはモデルの能力ではなく、ユーザーが設計する予算です。100万トークン時代になっても、この感覚は有効でしょう。ウィンドウが大きくなるほど、何を載せるかを選ぶ目が性能差を生むからです。