GEMINI LABEN
MEMORY — Memory Bank の Memory Profiles が GA になりました。静的スキーマの構造化プロファイルにより、セッション中の検索を挟まずに情報へ到達できますSCOPE — プロファイルは取り込み時のスコープごとに分離され、スキーマとスコープの組み合わせに対して単一のプロファイルが維持されますINGEST — IngestEvents API が GA になり、イベントのストリーミング・メモリのリビジョン管理・メタデータの付与が扱えるようになりましたAUDIO — gemini-3.1-flash-tts-preview が streamGenerateContent 経由のストリーミングに対応し、読み上げ開始までの待ち時間が縮みましたCLASSROOM — 8月10日から、既にアクセス権を付与されている K-12 と高等教育の全年齢の学生が Gemini in Classroom を利用できるようになりますSUNSET — 停止日が迫っています。8月17日に画像生成モデル、20日に Grok 4.1 ファミリー、31日に gemini-robotics-er-1.6-preview ですMEMORY — Memory Bank の Memory Profiles が GA になりました。静的スキーマの構造化プロファイルにより、セッション中の検索を挟まずに情報へ到達できますSCOPE — プロファイルは取り込み時のスコープごとに分離され、スキーマとスコープの組み合わせに対して単一のプロファイルが維持されますINGEST — IngestEvents API が GA になり、イベントのストリーミング・メモリのリビジョン管理・メタデータの付与が扱えるようになりましたAUDIO — gemini-3.1-flash-tts-preview が streamGenerateContent 経由のストリーミングに対応し、読み上げ開始までの待ち時間が縮みましたCLASSROOM — 8月10日から、既にアクセス権を付与されている K-12 と高等教育の全年齢の学生が Gemini in Classroom を利用できるようになりますSUNSET — 停止日が迫っています。8月17日に画像生成モデル、20日に Grok 4.1 ファミリー、31日に gemini-robotics-er-1.6-preview です
記事一覧/API / SDK
API / SDK/2026-06-23上級

File Search のストアが本番で静かに陳腐化する — カタログ同期とドリフト検知を実装した運用メモ

File Search に一度カタログを流し込んで終わりにすると、配信を止めたアセットを案内する『古い回答』が本番で返り始めます。ハッシュ差分の増分取り込みと、削除を割り切るブルーグリーン再構築、そして定期ドリフト検知までを実装で整理しました。

gemini102file-search4rag21gemini-embedding-27production105

プレミアム記事

File Search に壁紙カタログを一度流し込んで満足していたら、二週間ほど経った頃に「その壁紙はすでに配信を終了しています」という案内が本番で返ってきて青ざめました。アセット自体は App Store と Google Play の更新で差し替え済みなのに、File Search のストアの中身は最初に取り込んだ日のまま止まっていたのです。

File Search の入門記事は「ファイルを入れればグラウンディングできる」ところで終わります。けれども個人開発で実際に運用してみると、難しいのは最初の取り込みではなく、正本(source of truth)が変わり続けるのにストアだけが古いスナップショットのまま取り残されることでした。この記事は、その「静かな陳腐化」を止めるために私自身が組んだ同期パイプラインの記録です。

ストアは「作った時点のスナップショット」でしかない

まず前提を揃えます。File Search のストア(FileSearchStore)は、取り込んだ瞬間の内容を gemini-embedding-2 で索引化した塊です。便利なのは、自前でベクトルDBを立てたりチャンク分割を設計したりせずに、テキストも画像も同じストアに入れて引用元つきで回答を返せる点です。マルチモーダル対応で、壁紙のような画像アセットをそのまま入れられるようになったのは大きな前進でした。

ただし、ストアは取り込んだ後に放っておくと更新されません。正本のカタログ側で起きる変化は、おおむね次の3種類です。

  • 追加: 新しい壁紙を配信した。ストアにはまだ無い。
  • 更新: 既存アセットのメタ情報(タイトル・カテゴリ・配信状況)を書き換えた。ストアの中身は古い。
  • 削除: 配信を終了した。ストアには「もう無いもの」が残っている。

このうち一番こわいのは削除です。追加や更新は「新しい回答が出ない」だけで済みますが、削除されたアセットがストアに残っていると、AIは実在しないものを自信たっぷりに案内します。冒頭の事故がまさにこれでした。

正本とストアのズレを「マニフェスト」で可視化する

ズレを止める前に、まず「いま何がどうズレているか」を機械的に分かる形にします。私はストアを直接のぞきにいくのではなく、正本側からマニフェストを作る方針にしました。各アセットの内容ハッシュを取り、前回同期したマニフェストと比べれば、差分は単純な集合演算で出ます。

# build_manifest.py
# 正本カタログ(DBやファイル一覧)から「ID → 内容ハッシュ」の辞書を作る。
# ストアの中身に依存せず、正本だけを根拠にするのがポイント。
import hashlib
import json
from pathlib import Path
 
 
def asset_fingerprint(asset: dict) -> str:
    """配信状況・タイトル・カテゴリ・本体ファイルのハッシュをまとめて1つの指紋にする。
    どれか1つでも変われば指紋が変わり、更新として検出できる。"""
    h = hashlib.sha256()
    h.update(asset["status"].encode())          # active / retired
    h.update(asset["title"].encode())
    h.update(asset["category"].encode())
    # 画像本体はファイルのバイト列をそのままハッシュ(メタだけでなく中身も見る)
    h.update(Path(asset["image_path"]).read_bytes())
    return h.hexdigest()
 
 
def build_manifest(catalog: list[dict]) -> dict[str, str]:
    # 配信中のものだけを索引対象にする。retired はそもそも入れない。
    return {
        a["id"]: asset_fingerprint(a)
        for a in catalog
        if a["status"] == "active"
    }
 
 
if __name__ == "__main__":
    catalog = json.loads(Path("catalog.json").read_text())
    manifest = build_manifest(catalog)
    Path("manifest.current.json").write_text(json.dumps(manifest, indent=2))
    print(f"manifest entries: {len(manifest)}")
    # 期待する出力例: manifest entries: 3127

ここで「メタ情報だけでなく画像本体のバイト列もハッシュに含める」のが地味に効きます。タイトルは同じまま画像だけ差し替えるリリースが意外と多く、メタだけ見ていると更新を取りこぼすからです。

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

この記事の続きを読む

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

この記事で得られること
File Search のストアが元カタログとズレて『もう無いものを案内する』問題を、ハッシュ差分の増分取り込みで止められるようになります
数千件規模のアセットを毎リリース入れ替えても、ブルーグリーンでストアを作り直してポインタを切り替えれば、クエリを止めずに新しい索引へ移せます
正本とストアがどれだけズレているかを毎晩はかるドリフト検知スクリプトを、そのまま自分のパイプラインに組み込めます
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API / SDK2026-07-06
取り込んだのに一度も引かれない資料 — File Search ストアを引用ログで棚卸しする隔離つき剪定設計
File Search ストアに積んだドキュメントの多くは一度も引用されないまま費用と検索精度を蝕みます。grounding metadata から引用ログを取り、一度も引かれない資料を隔離期間つきで安全に剪定する運用設計を、動くコードとともに解説します。
API / SDK2026-06-24
File Searchの回答に「何ページの、どの図か」まで添える ― 視覚引用メタデータで出典を検証可能にする
File Search の grounding metadata に media_id と page_numbers が加わり、回答のどの一文がどのページ・どの図に基づくのかを辿れるようになりました。PDFと画像を混ぜた参照データで、検証可能な引用UIを組み立てるまでを実装で整理します。
API / SDK2026-04-14
Gemini API Embedding × ベクトルDB完全比較: Pinecone・Qdrant・pgvector・Cloud Spannerを本番で使い分けるガイド
Gemini text-embedding-004でPinecone・Qdrant・pgvector・Cloud Spanner Vectorを実測比較。コスト・レイテンシ・実装難易度を完全網羅した本番ベクトルDB選択ガイド。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →