エンジニアリングの世界では「Cache Rules Everything Around Me(キャッシュがすべてを制する)」とよく言われますが、この原則は AI エージェントにも同様に当てはまります。
Claude Code のような長時間動作するエージェント型製品を実用可能にしているのは プロンプトキャッシュ です。これにより、以前のやり取りの計算結果を再利用し、レイテンシとコストを大幅に削減できます。
プロンプトキャッシュとは何か、どのように機能し、技術的にはどのように実装するのでしょうか? @RLanceMartin 氏によるプロンプトキャッシュと新しい自動キャッシュ機能の発表に関する記事はこちら をご覧ください。
Claude Code では、すべての基盤をプロンプトキャッシュを中心に構築しています。高いプロンプトキャッシュヒット率はコストを削減し、サブスクリプションプランにおいてより寛大なレート制限を提供するのに役立つため、プロンプトキャッシュヒット率にアラートを設定し、低すぎる場合は SEV(重大インシデント)を宣言しています。
以下は、プロンプトキャッシュを大規模に最適化する過程で学んだ、(しばしば直感に反する)教訓です。
キャッシュを考慮したプロンプトの構成

プロンプトキャッシュはプレフィックス一致によって機能します。API はリクエストの先頭から各 cache_control ブレークポイントまでのすべてをキャッシュします。つまり、要素をどの順序で配置するかが非常に重要であり、できるだけ多くのリクエストがプレフィックスを共有できるようにする必要があります。
これを行う最善の方法は、静的コンテンツを先に、動的コンテンツを後に配置することです。Claude Code では、以下のようになります。
- 静的システムプロンプト & ツール(グローバルにキャッシュ)
- Claude.MD(プロジェクト内でキャッシュ)
- セッションコンテキスト(セッション内でキャッシュ)
- 会話メッセージ
これにより、セッション間でキャッシュヒットを最大限に共有できます。
しかし、これは驚くほど壊れやすいものです!これまでにこの順序を壊したことのある例としては、詳細なタイムスタンプを静的システムプロンプトに入れたり、ツールの順序定義を非決定的にシャッフルしたり、ツールのパラメータ(AgentTool が呼び出せるエージェントなど)を更新したりしたケースがあります。
更新にはメッセージを活用する
プロンプトに含めた情報が古くなる場合があります。例えば、時刻情報が含まれている場合や、ユーザーがファイルを変更した場合などです。プロンプトを更新したくなるかもしれませんが、それはキャッシュミスを引き起こし、ユーザーにとって非常に高コストになる可能性があります。
代わりに、次のターンでメッセージを介してこの情報を渡すことを検討してください。Claude Code では、次のユーザーメッセージまたはツール結果に <system-reminder> タグを追加して、モデルに更新された情報(例:今日は水曜日です)を伝えています。これにより、キャッシュを維持できます。
セッション中にモデルを変更しない
プロンプトキャッシュはモデルごとに固有であり、これによりプロンプトキャッシュの計算は非常に直感に反するものになる可能性があります。
Opus との会話で 10 万トークンまで進んだ状態で、比較的簡単に答えられる質問をしたい場合、Haiku に切り替えるよりも Opus に答えさせた方が実際にはコストが低くなります。なぜなら、Haiku 用にプロンプトキャッシュを再構築する必要があるからです。
モデルを切り替える必要がある場合の最善の方法は、サブエージェントを使用することです。Opus が別のモデルに対して、実行する必要のあるタスクに関する「ハンドオフ」メッセージを準備します。Claude Code の Explore エージェントではこれを頻繁に行っており、Haiku を使用しています。
セッション中にツールを追加または削除しない
会話の途中でツールセットを変更することは、人々がプロンプトキャッシュを壊す最も一般的な方法の 1 つです。直感的には、モデルには今必要なツールだけを与えるべきだと思われるかもしれません。しかし、ツールはキャッシュされたプレフィックスの一部であるため、ツールを追加または削除すると、会話全体のキャッシュが無効になります。
プランモード — キャッシュを中心に設計する
プランモードは、キャッシュの制約を考慮して機能を設計する良い例です。直感的なアプローチは、ユーザーがプランモードに入ったときに、ツールセットを読み取り専用ツールのみに交換することです。しかし、それではキャッシュが壊れてしまいます。
代わりに、私たちはリクエスト内に すべての ツールを常に保持し、EnterPlanMode と ExitPlanMode 自体をツールとして使用します。ユーザーがプランモードをオンに切り替えると、エージェントはプランモードであることとその指示(コードベースを探索する、ファイルを編集しない、計画が完了したら ExitPlanMode を呼び出す)を説明するシステムメッセージを受け取ります。ツール定義は決して変更されません。
これには追加の利点があります。EnterPlanMode はモデル自身が呼び出すことができるツールであるため、複雑な問題を検出したときに、キャッシュを壊すことなく自律的にプランモードに入ることができます。
ツール検索 — 削除ではなく延期する
同じ原理がツール検索機能にも適用されます。Claude Code は数十もの MCP ツールをロードできますが、それらすべてをすべてのリクエストに含めるとコストがかかります。しかし、会話の途中で削除するとキャッシュが壊れてしまいます。
私たちの解決策は defer_loading です。ツールを削除する代わりに、軽量なスタブ(ツール名のみ、defer_loading: true を設定)を送信します。モデルは必要に応じて ToolSearch ツールを介してこれらのツールを「発見」できます。完全なツールスキーマは、モデルが選択した場合にのみロードされます。これにより、キャッシュされたプレフィックスが安定します。同じスタブが同じ順序で常に存在します。
幸い、API を通じて ツール検索 ツールを使用してこれを簡素化できます。
コンテキストのフォーク — コンパクション

コンパクションは、コンテキストウィンドウを使い果たしたときに発生します。それまでの会話を要約し、その要約を使用して新しいセッションを続行します。
驚くべきことに、コンパクションにはプロンプトキャッシュに関する多くのエッジケースがあり、直感に反する場合があります。
特に、コンパクションを実行する際には、要約を生成するためにモデルに会話全体を送信する必要があります。これが異なるシステムプロンプトとツールなしの別個の API 呼び出しである場合(単純な実装)、メインの会話からのキャッシュされたプレフィックスはまったく一致しません。これらの入力トークンすべてに全額を支払うことになり、ユーザーのコストが大幅に増加します。
解決策 — キャッシュセーフなフォーク
コンパクションを実行するとき、親の会話と まったく同じ システムプロンプト、ユーザーコンテキスト、システムコンテキスト、ツール定義を使用します。親の会話メッセージを先頭に追加し、その後、最後に新しいユーザーメッセージとしてコンパクションプロンプトを追加します。
API から見ると、このリクエストは親の最後のリクエストとほぼ同じに見えます。同じプレフィックス、同じツール、同じ履歴であるため、キャッシュされたプレフィックスが再利用されます。新しいトークンはコンパクションプロンプト自体のみです。
ただし、これは、コンパクトメッセージとサマリー出力トークンを含めるのに十分な余裕をコンテキストウィンドウに確保するために、「コンパクションバッファ」を保存する必要があることを意味します。
コンパクションは難しいですが、幸いなことに、これらの教訓を自分で学ぶ必要はありません。Claude Code での経験に基づいて、コンパクション を API に直接組み込みました。そのため、これらのパターンを独自のアプリケーションに適用できます。
学んだ教訓
- プロンプトキャッシュはプレフィックス一致です。 プレフィックス内のどこかが変更されると、その後のすべてが無効になります。この制約を中心にシステム全体を設計してください。適切な順序を設定すれば、キャッシュのほとんどは自動的に機能します。
- システムプロンプトの変更ではなくメッセージを使用してください。 プランモードへの移行や日付の変更などのためにシステムプロンプトを編集したくなるかもしれませんが、これらは会話中のメッセージとして挿入する方が適切です。
- 会話の途中でツールやモデルを変更しないでください。 ツールセットを変更するのではなく、ツールを使用して状態遷移(プランモードなど)をモデル化してください。ツールを削除するのではなく、ツールのロードを延期してください。
- キャッシュヒット率をアップタイムと同様に監視してください。 キャッシュ不良に対してアラートを発報し、インシデントとして扱っています。数パーセントのキャッシュミス率でも、コストとレイテンシに劇的な影響を与える可能性があります。
- フォーク操作は親のプレフィックスを共有する必要があります。 サイド計算(コンパクション、要約、スキル実行)を実行する必要がある場合は、同一のキャッシュセーフなパラメータを使用して、親のプレフィックスでキャッシュヒットを得られるようにしてください。
Claude Code は初日からプロンプトキャッシュを中心に構築されています。エージェントを構築するのであれば、あなたも同じようにすべきです。





