大規模言語モデル(LLM)への呼び出しは、そのたびに予算を消費し、ユーザーの忍耐を試します。50人がほぼ同じ質問をしたとしても、従来のインフラでは50件の個別のAPIリクエストを処理することになります。これは、従来のキャッシュが「完全一致する文字列」を基準に考えているためです。「フランスの首都は何ですか?」と「フランスの首都都市を教えてください」を、全く無関係な2つの質問として扱います。セマンティック・キャッシュ(Semantic caching)は、文字ではなく意図を読み取ります。両方のユーザーが「パリ」を求めていることを認識し、回答を一度だけ保存して、モデルを呼び出すことなく再度提供します。

なぜ完全一致では不十分なのか

Redis、Memcached、あるいは単純なインメモリマップであっても、キーが予測可能な場合には標準的なキャッシュは非常にうまく機能します。製品ID、ユーザー名、あるいはURLスラッグの綴りが変わることはありません。しかし、言語は混沌としています。ユーザーは言い換えたり、誤字をしたり、丁寧な表現を加えたり、あるいは単語を省略したりします。サポートボットが「パスワードをリセットするにはどうすればいいですか?」という質問を受け、その10分後に「パスワードを忘れました、助けて」という質問を受けたとします。完全一致レイヤーは、これらを2つの異なるバイト列として認識し、料金を2回請求します。これを毎日の数千件のやり取りに当てはめると、その浪費は深刻なものになります。セマンティック・キャッシュは、マッチングのロジックを生のテキストから「意味空間(meaning space)」へと移行させることで、この問題を解決します。

実際の仕組み

パイプラインは、数学の教科書が説明するよりもずっとシンプルです。

質問のエンコーディング。 クエリが届くと、埋め込みモデル(embedding model)がその意味をベクトルに圧縮します。これは実質的に、浮動小数点数の長いリストに過ぎません。言語におけるGPS座標のようなものだと考えてください。「フランスの首都」と「フランスの首都都市」のように、同じ方向を指している質問は、この空間内でほぼ重なり合います。無関係なトピックに関する質問は、遠く離れた場所に配置されます。

ベクトル検索。 キャッシュには、過去に受け取った質問とその回答が保持されており、各ペアは独自のベクトルによってインデックス化されています。システムは、コサイン距離(cosine distance)などの類似性指標を使用して、入力されたベクトルをこのデータベースと比較します。最新のベクトルストアは、数百万件のエントリをミリ秒単位で検索できます。

キャッシュヒット。 距離が調整済みの閾値を下回った場合、システムは保存された回答を有効なものとして扱います。そのレスポンスを直接返します。APIキーは使用されず、トークン消費も発生せず、ユーザーは数秒ではなく数ミリ秒で回答を得られます。

キャッシュミス。 十分に近いものがない場合、クエリはLLMへと流れます。モデルが回答すると、システムは新しい「ベクトルと回答のペア」をキャッシュに保存し、次に似たような訪問者が来たときに恩恵を受けられるようにします。

この4つのステップのループが、繰り返される意図を「無料のパフォーマンス」へと変えるのです。

アプリケーションにとっての意味

メリットは、請求額が安くなることだけにとどまりません。

トークン消費の削減。 カスタマー向けアシスタントや社内ナレッジボットを運用しているチームでは、トークン費用が70%以上削減されることも珍しくありません。特にサポートやFAQのユースケースでは、繰り返される質問がトラフィックの大部分を占めています。インターセプト(遮断)されたリクエストの一つひとつが、アカウントに残るお金となります。

レスポンスの高速化。 ローカルでのベクトル検索とキャッシュ取得は、50ミリ秒未満で実行できます。一方、ホストされたLLMへのAPI呼び出しは、モデルのサイズや混雑状況に応じて、0.5秒から数秒かかる場合があります。ユーザーはこの違いを即座に感じ取ります。

レート制限の悩みの軽減。 プロバイダーは1分あたりのリクエスト数を制限しています。ローカルで解決できるクエリはすべて、429エラーを発生させたり、高コストなリトライループを強制したりすることのないクエリです。トラフィックの急増時でも、システムは安定を保てます。

真のスケーラビリティ。 キャッシュが繰り返される負荷を吸収するため、LLMのクォータ(割り当て)をアップグレードしたり、より大きなモデルインスタンスをプロビジョニングしたりすることなく、より多くの同時ユーザーに対応できます。モデルが固定費のまま、キャッシュは水平方向にスケールします。

重労働を担うツール

ベクトルパイプラインをゼロから構築する必要はありません。すでに埋め込み、保存、検索のロジックを使いやすいレイヤーとしてラップしているプロジェクトがいくつか存在します。

Bifrost は、アプリケーションとモデルプロバイダーの間に配置するように設計されたオープンソースのAIゲートウェイです。非常に低オーバーヘッドなセマンティック・キャッシュを提供します。これは、キャッシュの運用コストが、それが代替するAPI呼び出しのコストを上回ってはならないという点で重要です。また、20以上のLLMプロバイダーへのアクセスを抽象化しているため、キャッシュのロジックを書き換えることなく、OpenAI、Anthropic、あるいはオープンモデルへとトラフィックをルーティングできます。

LiteLLMは、ユニバーサルAPIとして機能します。一つのインターフェースに書き込むだけで、好みのバックエンドへのリクエストに変換してくれます。そのキャッシングモジュールは、複数のアプリケーションサーバー間でキャッシュを共有するためのRedisや、軽量なシングルノード展開のためのローカルメモリをサポートしています。この柔軟性により、スタックを再設計することなく、プロトタイプから本番環境へと移行しようとしているチームにとって魅力的な選択肢となっています。

LangChainは、フレームワークレベルのアプローチを提供します。すでにLangChainを使用してチェーンやエージェントをオーケストレーションしている場合は、ChromaやFAISSなどのベクトルストアをバックエンドとするカスタムセマンティックキャッシュを組み込むことができます。Chromaはローカルでの実験や小規模なデータセットに適しています。FAISSは、個別のデータベースサービスを稼働させることなく、高速なインメモリ近似検索が必要な場合に真価を発揮します。

PineconeMilvusのようなベクトルデータベースを使用した自己管理型セットアップは、完全な制御を必要とするチーム向けのルートです。Pineconeはスケーリングとレプリケーションを処理するマネージドサービスであり、運用の負担を軽減します。MilvusはオープンソースでKubernetesとの親和性が高く、独自のインフラストラクチャ上でデータを保持したい場合に理想的です。ここでの構築には、エンベディング、閾値、エビクション(削除)ポリシーなどを自前で管理する必要があるため、より多くの仕組み(plumbing)が必要になりますが、その見返りは完全な柔軟性です。

避けるべき設定の罠

セマンティックキャッシュの性能は、そのチューニング次第です。本番環境にリリースする前に、注目すべき3つの調整項目があります。

エンベディングの品質。 すべてのエンベディングモデルが、ニュアンスを等しく捉えられるわけではありません。軽量なモデルは「refund policy(返金ポリシー)」と「return policy(返品ポリシー)」をほぼ同じベクトルに圧縮できるかもしれず、それは素晴らしいことです。しかし、同時に「battery life(バッテリー寿命)」と「battery warranty(バッテリー保証)」を混同させてしまう可能性もあり、その場合は誤った回答を返してしまいます。ログから取得した実際のクエリペアを使用して、モデルをテストしてください。もし衝突(collision)が発生する場合は、エンコーディングに数ミリ秒余計にかかったとしても、より強力なエンベディングモデルにアップグレードしてください。

類似度閾値。 これは「十分に似ている」と判断するための許容度です。閾値を高く設定しすぎると(ベクトルの整合性がほぼ完璧であることを求めすぎると)、明らかな意味的一致を見逃し、コストのかかるミスにつながります。逆に閾値を緩くしすぎると、「cancellation fees(キャンセル料)」について尋ねたユーザーに対して、「cancellation procedures(キャンセル手続き)」に関するキャッシュされた回答を返してしまうことがあり、これは恥ずべき、役に立たない挙動です。コサイン類似度の場合、まずは0.85前後から始め、自身のドメインで観察される精度に基づいて調整してください。

キャッシュの鮮度。 古い回答は信頼を損ないます。製品のリニューアル後も、古い料金プランを提示し続けるテクニカルサポートのキャッシュは、ユーザーを苛立たせます。一定期間が経過した後にエントリを削除するTTL(Time-to-Live)ポリシーを実装してください。変化の激しいトピックについては、TTLを短く設定します。数学の事実や会社の沿革のような静的なドメインであれば、より長い期間を設定しても問題ありません。チームによっては、エントリにトピックのタグを付け、ソースドキュメントが変更された際に、関連する回答を一括で無効化できるようにしている場合もあります。

まとめ

セマンティックキャッシングは特効薬(シルバーブレット)ではありませんが、LLMアプリケーションに追加できる、最も投資対効果の高い最適化の一つです。これは、本番環境でのAI導入における最大の不満点である「コスト」と「レイテンシ」に直接対処します。まずはBifrostやLiteLLMのような既存のツールから始め、実際のトラフィックに対してキャッシュヒット率を測定し、エンベディングモデルと閾値を反復的に改善していきましょう。目標は初日から完璧を目指すことではなく、同じ質問によってトークンが二度消費されるのを防ぐことです。


Source: Semantic Caching for LLMs: How It Works and the Tools That Do It

Community: GyaanSetu AI on Telegram