GEMINI LABEN
FLASH GA — Gemini 3.5 Flashが一般提供(GA)に。エージェント・コーディングで持続的なフロンティア性能を発揮する最も賢いモデルと位置づけられていますTOGGLE — Global・US・EUマルチリージョンでは6/16以降、Gemini 3.5 Flashの機能管理トグルが廃止されます。設定を参照している場合は確認が必要ですAGENTS — Managed Agentsが公開プレビューで登場。Googleホストの隔離Linuxサンドボックス内で動く自律的・ステートフルなエージェントを構築・デプロイできますIMAGE — 画像プレビュー2モデル(gemini-3.1-flash-image-preview・gemini-3-pro-image-preview)が6/25に廃止。後継モデルへの移行が必要ですSEARCH — File Searchがマルチモーダル対応。gemini-embedding-2により画像をネイティブに埋め込み・検索できるようになりましたCLI — Gemini CLIとCode Assistが6/18で個人向け提供終了。無料ユーザーとAI Pro/Ultra加入者はAntigravity CLIへ誘導されますFLASH GA — Gemini 3.5 Flashが一般提供(GA)に。エージェント・コーディングで持続的なフロンティア性能を発揮する最も賢いモデルと位置づけられていますTOGGLE — Global・US・EUマルチリージョンでは6/16以降、Gemini 3.5 Flashの機能管理トグルが廃止されます。設定を参照している場合は確認が必要ですAGENTS — Managed Agentsが公開プレビューで登場。Googleホストの隔離Linuxサンドボックス内で動く自律的・ステートフルなエージェントを構築・デプロイできますIMAGE — 画像プレビュー2モデル(gemini-3.1-flash-image-preview・gemini-3-pro-image-preview)が6/25に廃止。後継モデルへの移行が必要ですSEARCH — File Searchがマルチモーダル対応。gemini-embedding-2により画像をネイティブに埋め込み・検索できるようになりましたCLI — Gemini CLIとCode Assistが6/18で個人向け提供終了。無料ユーザーとAI Pro/Ultra加入者はAntigravity CLIへ誘導されます
記事一覧/API / SDK
API / SDK/2026-06-15中級

ヘルプ記事とスクリーンショットを1つの File Search に入れて、画像も引用できる回答を返す

テキストのヘルプ記事と画面スクリーンショットを別々のストアで管理していて、回答に手順画像を添えられない。gemini-embedding-2 のマルチモーダル対応で両者を同じ File Search に入れ、引用元の画像まで返すまでを実装で整理しました。

Gemini API135File Search2gemini-embedding-22マルチモーダル20RAG11

プレミアム記事

個人開発でアプリを運営していると、サポート用の知識は自然と二つに分かれていきます。手順を文章で書いたヘルプ記事と、設定画面を撮ったスクリーンショットです。私自身、壁紙アプリの問い合わせ対応で「課金の復元はどこから?」と聞かれるたびに、文章の手順を返したあとに別フォルダからスクショを探して貼る、という二度手間を続けていました。

困るのは、テキストとスクショを別々の検索基盤に置いていると、ユーザーの一つの質問に対して「文章だけ」か「画像だけ」しか引けないことです。本当は「この手順です(文章)+この画面です(画像)」をひとまとめで返したい。これまでは画像側を OCR してテキスト化し、無理やり同じ土俵に乗せていましたが、ボタンのアイコンや位置といった視覚情報は OCR では拾えませんでした。

gemini-embedding-2 が File Search でマルチモーダル埋め込みに対応したことで、この前提が変わりました。テキストの文書と画像の文書を同じストアに入れ、同じベクトル空間で検索できます。今回は、ヘルプ記事とスクショを一つの File Search ストアに混在させ、回答に「引用元の画像」まで添えて返すところまでを、実際に手を動かした順に整理します。

なぜ「テキストと画像が別ストア」だと回答が片手落ちになるのか

技術的な理由は単純で、別々の埋め込みモデルで作ったベクトルは比較できないからです。テキストを文章用の埋め込み、画像を画像用の埋め込みで別々にインデックスすると、二つのベクトル空間ができてしまい、「質問ベクトルに近いものを上位から取る」という検索が空間をまたげません。結果として、テキスト検索と画像検索を別々に叩き、後段で順位を無理にマージすることになります。

このマージが曲者でした。テキスト側のスコアと画像側のスコアはスケールが違うので、しきい値をどう揃えても「文章は的確なのに添える画像がずれる」「画像は合っているのに説明文が古い」という非対称が残ります。私の場合、サポート文面の体感精度は悪くないのに、添付スクショの的中率だけが低い、という状態が長く続きました。

マルチモーダル埋め込みは、テキストと画像を同じ空間に写像します。「課金を復元する」という質問の埋め込みと、復元ボタンが写ったスクショの埋め込みが近くに来るので、一回の検索で両方が上位に並びます。スコアのスケールも揃うため、後段のしきい値設計が一本化できるのが実務上いちばん効きました。

gemini-embedding-2 でテキストと画像の混在ストアを作る

まずストアを作り、埋め込みモデルにマルチモーダル対応の gemini-embedding-2 を指定します。ポイントは、ストア作成時に埋め込みモデルを固定しておくことです。あとからモデルだけ差し替えると既存ベクトルと新規ベクトルが別空間になり、検索結果が静かに劣化します。

# pip install google-genai
from google import genai
from google.genai import types
 
client = genai.Client()  # GEMINI_API_KEY を環境変数から読む
 
# (1) マルチモーダル埋め込みでストアを作成
store = client.file_search_stores.create(
    config={
        "display_name": "app-support-kb",
        # テキストと画像を同じ空間に埋め込むモデルを固定する
        "embedding_model": "gemini-embedding-2",
    }
)
print(store.name)  # → fileSearchStores/app-support-kb-xxxxxxxx

続いて文書を投入します。テキストのヘルプ記事も、スクリーンショットの画像も、同じストアに upload するだけです。ここで効いてくるのが custom_metadata で、あとで「どのモダリティか」「どの画面か」を回答側で使うため、登録時に必ず付けておきます。

# (2) テキストのヘルプ記事を投入
client.file_search_stores.upload_to_file_search_store(
    file_search_store_name=store.name,
    file="docs/restore-purchase.md",
    config={
        "custom_metadata": [
            {"key": "modality", "string_value": "text"},
            {"key": "screen", "string_value": "settings"},
            {"key": "locale", "string_value": "ja"},
        ]
    },
)
 
# (3) スクリーンショットを同じストアに投入
client.file_search_stores.upload_to_file_search_store(
    file_search_store_name=store.name,
    file="shots/settings-restore.png",
    config={
        "custom_metadata": [
            {"key": "modality", "string_value": "image"},
            {"key": "screen", "string_value": "settings"},
            {"key": "locale", "string_value": "ja"},
        ]
    },
)

screen のような業務的なキーを揃えておくと、「文章とスクショが同じ画面を指しているか」を後段で照合できます。私は最初これを省いて投入し、復元手順の文章にホーム画面のスクショが付く、という珍事に遭遇しました。メタデータは検索のためというより、回答の整合性チェックのために入れておく、という感覚です。

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

この記事の続きを読む

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

この記事で得られること
テキストと画像を1つの File Search ストアに混在させ、質問に応じて両モダリティを横断検索できるようになります
grounding メタデータから「引用元がテキストか画像か」を判定し、回答に該当スクショを添えて返す実装が手に入ります
画像アップロード前のリサイズ・対応形式・mediaResolution など、本番で詰まった落とし穴と回避策を持ち帰れます
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API / SDK2026-06-12
壁紙アセットの画像探しを File Search のマルチモーダル検索に任せてみた記録
数千枚の壁紙アセットから目当ての一枚を探す作業を、File Search のマルチモーダル検索(gemini-embedding-2)に置き換えられるか300枚で検証しました。カテゴリタグ運用との比較、つまずいた点、使い分けの結論を実装コードとともに残します。
API / SDK2026-05-15
Gemini API Embedding で踏んだ3つの地雷 — 壁紙アプリのカテゴリ自動分類で遭遇したエラーと対処法
Gemini API Embedding を壁紙アプリのカテゴリ自動分類に組み込んだ際に踏んだ3つのエラー(INVALID_ARGUMENT・RESOURCE_EXHAUSTED 429・RAG精度低下)と実際の修正コードを紹介します。
API / SDK2026-05-05
Gemini RAGの選び方 2026 — シンプル・Advanced・Agenticの3パターンを実装で比べた
Gemini APIを使ったRAG実装の3パターン(シンプル・Advanced・Agentic)を実際のコードで比較。ユースケース別の選択基準と、最初にどこから始めるべきかを解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →