AIの請求額が一晩で3倍になりました。モデル、トラフィック量、プロンプトのテキストさえも同じでした。原因は、OpenAIのプロンプトキャッシュを壊してしまった、たった一行のコードでした。
なぜキャッシュが重要なのか
プロバイダーのプロンプトキャッシュは、バイト単位で完全に一致するプレフィックス(接頭辞)で始まるリクエストの再処理をスキップすることで、コストを削減します。最初のトークンが以前の呼び出しと一致する場合、プロバイダーはそれらのトークンの計算済み表現を再利用し、新しいサフィックス(接尾辞)分のみを課金します。ルールは厳格です。単に似ているだけでなく、完全に一致している必要があります。先頭のトークンが一つでも異なれば、キャッシュヒットは完全に失われます。
ヒット率を台無しにしたミス
私たちのエージェントでは、モデルに「今」という感覚を与えるために、システムプロンプトの最上部に現在のタイムスタンプを配置していました。タイムスタンプは毎秒変化するため、最初のトークンシーケンスがリクエストごとに一意になってしまいました。キャッシュは一致するものを見つけられず、そのため、各呼び出しにおいて、その後に続く18,000個の静的なトークン(ツールのスキーマ、ドキュメントの断片、few-shotの例、固定の指示など)に対してフル料金が発生しました。その結果、キャッシュヒット率は0%となり、請求額は3倍に膨れ上がりました。
キャッシュ効率を高めるための並べ替え
解決策は簡単です。決して変わらないものはすべてプロンプトの先頭に置き、変動するデータは後ろに回します。
静的なプレフィックス(キャッシュ可能)
- ツールの定義
- 検索ドキュメント
- Few-shotの例
- 固定のシステム指示
変動するサフィックス(キャッシュ不可)
- 現在時刻
- セッション識別子
- ユーザーメッセージ
- ライブコンテキスト
モデルに時間が必要な場合は、先頭に追加するのではなく、静的なブロックの後に追記してください。そうすることで、キャッシュは重い静的な部分を再利用しつつ、最後に最新のコンテキストを提供できます。
スタック内に潜む隠れた要因
テンプレートが正しく見えても、ミドルウェアやSDKが、ペイロードがAPIに届く前に、リクエストID、タイムスタンプ、その他のヘッダーなどのメタデータを密かに先頭に追加してしまうことがあります。また、一部のデプロイメントパイプラインでは、ロールアウトのたびにツールの定義をシャッフルすることもあります。これらの目に見えない変更は、独自のプロンプトビルダーにコード変更がなくても、バイトシーケンスを変化させ、キャッシュを台無しにします。
キャッシュヒット率を監視する
キャッシュヒット率を、AIエージェントの主要なヘルス指標として扱ってください。急激な低下は、リクエストの先頭バイトのいずれかが可変になったことを示しています。ヒット率を公開するモニタリングツールを使用すれば、コストの異常が爆発する前に特定できます。
まとめ
プロンプトキャッシュは、不変のプレフィックスにかかっています。リクエストの開始時に変化するものは、たとえ単一のタイムスタンプであっても、キャッシュを無効にし、請求額を3倍にする可能性があります。静的なコンテンツを最初に、変動するコンテンツを最後に配置し、ツールチェーンに隠れた追加要素がないか監査し、キャッシュヒット率を監視してください。規律あるプロンプトのレイアウトは、パフォーマンスと収益の両方を守ります。
