GEMINI LABEN
FLASH35 — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestが指す実体になりました。日常的な生成を速く安価にこなせますAGENTS — Gemini APIのManaged Agentsがpublic previewに。Google管理の隔離Linuxサンドボックスで自律的なエージェントを構築できますMEDIA — Nano Banana 2 Lite(画像)とGemini Omni Flash(動画・会話的編集)がAI Studio・API・Enterprise Agent Platformで利用可能にTTS — gemini-3.1-flash-tts-previewの音声生成がstreamGenerateContent経由でストリーミング対応になりましたTRANSLATE — 新しい音声モデルが70以上の言語を自動判別し、話者の自然な抑揚を保ったままライブ音声翻訳を行いますSPENDCAP — AI Studioにプロジェクト単位の費用上限が導入され、支出を安全側に抑えられるようになりましたFLASH35 — Gemini 3.5 Flashが一般提供となり、gemini-flash-latestが指す実体になりました。日常的な生成を速く安価にこなせますAGENTS — Gemini APIのManaged Agentsがpublic previewに。Google管理の隔離Linuxサンドボックスで自律的なエージェントを構築できますMEDIA — Nano Banana 2 Lite(画像)とGemini Omni Flash(動画・会話的編集)がAI Studio・API・Enterprise Agent Platformで利用可能にTTS — gemini-3.1-flash-tts-previewの音声生成がstreamGenerateContent経由でストリーミング対応になりましたTRANSLATE — 新しい音声モデルが70以上の言語を自動判別し、話者の自然な抑揚を保ったままライブ音声翻訳を行いますSPENDCAP — AI Studioにプロジェクト単位の費用上限が導入され、支出を安全側に抑えられるようになりました
記事一覧/API / SDK
API / SDK/2026-06-13上級

Gemini 3.5 Flash 移行で組み直した RAG の3層キャッシュ — レスポンス・検索・埋め込みを段階的に節約する

Gemini 2.0 Flash の廃止を機に、RAG のキャッシュ設計を 3.5 Flash 前提で組み直しました。レスポンス・セマンティック・埋め込みの3層それぞれの実装コードと実測ヒット率、API 側 Context Caching との役割分担までを整理します。

gemini-3-5-flash3rag21cost-optimization21caching2gemini-embedding-25

プレミアム記事

6月1日に Gemini 2.0 Flash が廃止され、個人開発で運用している私の RAG パイプラインも 3.5 Flash への移行を済ませました。モデル ID を書き換えて動作確認をして終わり、にできればよかったのですが、実際にはここからが本番でした。単価とトークン処理の前提が変わると、以前のキャッシュ設計が「最適」ではなくなるからです。

移行作業のついでに、キャッシュ層を一度すべて剥がして組み直しました。私自身、剥がす前は構成が大きく変わるだろうと予想していたのですが、結論から言うと、最終的には以前と同じ「3層」に落ち着きました。ただし各層の優先度と、API 側の Context Caching との役割分担は移行前と変わっています。以下、組み直し後の設計を実装コードと実測値つきで共有します。

コストの発生点ごとにキャッシュを切る

RAG の1リクエストがお金を使う場所は、分解すると3箇所です。

  1. クエリの埋め込み計算 — 質問文をベクトル化する API コール
  2. ベクトル検索 — ベクトル DB への問い合わせ(マネージドなら検索回数課金)
  3. 回答生成 — 文脈と質問を生成モデルに渡す呼び出し

請求書の大半は 2 と 3 が占めます。だからこそ、キャッシュは「どの発生点を消すか」で層を分けるのが筋がよいと考えています。

  • L1(レスポンスキャッシュ): 同じ質問への回答を保存し、ヒットすれば 1〜3 を全部スキップする
  • L2(セマンティックキャッシュ): 意味的に近い過去クエリの検索結果を再利用し、2 をスキップする
  • L3(埋め込みキャッシュ): 同一文字列の埋め込み再計算をやめ、1 をスキップする

上の層でヒットするほど節約幅が大きい。この段階構造は 3.5 Flash になっても変わりませんでした。変わったのは「どこまで自前で持つか」の判断です。後述します。

L1: レスポンスキャッシュ — 移行後も最初に入れるべき層

ユーザーの質問は驚くほど重複します。FAQ 寄りの使われ方をするアプリなら、完全一致だけでも3割前後がヒットします。私の運用データ(直近1週間)では L1 のヒット率は 34% でした。つまり生成呼び出しの3分の1が、API に到達する前に消えています。

import hashlib
import json
import redis
 
from google import genai
 
client = genai.Client()  # API キーは環境変数 GEMINI_API_KEY から
r = redis.Redis(decode_responses=True)
RESP_TTL = 60 * 60 * 24 * 7  # 7日
 
def response_cache_key(tenant: str, query: str, filters: dict) -> str:
    """テナント・正規化済みクエリ・フィルタから決定的にキーを生成します。"""
    payload = json.dumps(
        {"t": tenant, "q": " ".join(query.lower().split()), "f": filters},
        sort_keys=True, ensure_ascii=False,
    )
    return "rag:l1:" + hashlib.sha256(payload.encode()).hexdigest()
 
def answer_with_l1(tenant: str, query: str, filters: dict) -> dict:
    key = response_cache_key(tenant, query, filters)
    if (hit := r.get(key)) is not None:
        return json.loads(hit)
    result = run_rag_pipeline(tenant, query, filters)  # L2/L3 を含む本体
    r.setex(key, RESP_TTL, json.dumps(result, ensure_ascii=False))
    return result

このコードで意図しているのは3点です。まず、正規化を lower().split() の組み合わせにして、大文字小文字と空白揺れを同一視すること。次に、テナント ID をキーの先頭要素に必ず入れること。私は以前、これを忘れかけて別テナントの回答が混ざる寸前までいったことがあります。権限境界はキャッシュキーの段階で切るのが一番確実です。最後に TTL。ドキュメントを更新したのに古い回答が返り続けると、ユーザーからの信頼は静かに削れていきます。

なお、ドキュメント更新時の無効化は TTL 任せにせず、回答キャッシュのメタデータに参照ドキュメント ID を持たせ、更新イベントで該当キーをまとめて破棄する作りにしています。週次更新程度の頻度なら、この仕組みだけで「古い回答事故」はほぼ起きません。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
google-genai SDK と Redis で組む3層キャッシュ(レスポンス・セマンティック・埋め込み)の動作する実装コード
類似度閾値を 0.92 に決めるまでの検証手順と、誤ヒット・テナント混線・古い回答の固定化を防ぐ無効化設計
API 側 Context Caching と自前キャッシュの役割分担、層別ヒット率の観測コードと L2 投資判断の基準
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API / SDK2026-07-06
取り込んだのに一度も引かれない資料 — File Search ストアを引用ログで棚卸しする隔離つき剪定設計
File Search ストアに積んだドキュメントの多くは一度も引用されないまま費用と検索精度を蝕みます。grounding metadata から引用ログを取り、一度も引かれない資料を隔離期間つきで安全に剪定する運用設計を、動くコードとともに解説します。
API / SDK2026-06-23
File Search のストアが本番で静かに陳腐化する — カタログ同期とドリフト検知を実装した運用メモ
File Search に一度カタログを流し込んで終わりにすると、配信を止めたアセットを案内する『古い回答』が本番で返り始めます。ハッシュ差分の増分取り込みと、削除を割り切るブルーグリーン再構築、そして定期ドリフト検知までを実装で整理しました。
API / SDK2026-04-19
Gemini API キャッシュ戦略の運用ノート — Context Caching と Implicit Caching を本番で組み合わせて月額費用を抑える
Context Caching と Implicit Caching を個人開発アプリの本番運用で組み合わせた実装メモ。動くコード・実測コスト・運用で気づいた7つの落とし穴を、AdMob 連携アプリの文脈で整理しています。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →