◉GEMINI LABEN
●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●COMPUTER — Computer Use が Interactions / GenerateContent API で GA になりました(10/30)●LIVE — Live と TTS のプレビュー版は最短 11/17 に停止します(残り16日)。移行先は gemini-3.8-live と 3.8 系 TTS です●CLI — Gemini API CLI(gemini-api)がベータで登場(10/27)。エージェントやCI向けのゼロ依存クライアントです●STORE — 新規の有料プロジェクトでは生成リクエストの保存(store)が既定でオンになります(10/26)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…●ARGON — gemini-4-argon が 10/13 に GA。複雑なコーディング・エージェント・数学・科学向けです●COMPUTER — Computer Use が Interactions / GenerateContent API で GA になりました(10/30)●LIVE — Live と TTS のプレビュー版は最短 11/17 に停止します(残り16日)。移行先は gemini-3.8-live と 3.8 系 TTS です●CLI — Gemini API CLI(gemini-api)がベータで登場(10/27)。エージェントやCI向けのゼロ依存クライアントです●STORE — 新規の有料プロジェクトでは生成リクエストの保存(store)が既定でオンになります(10/26)●NEW — クラッシュ報告を毎回ゼロから読ませない — 既知バグ早見表を先に grep し…
記事一覧/API / SDK
◈ API / SDK/2026-06-12中級

壁紙アセットの画像探しを File Search のマルチモーダル検索に任せてみた記録

数千枚の壁紙アセットから目当ての一枚を探す作業を、File Search のマルチモーダル検索(gemini-embedding-2)に置き換えられるか300枚で検証しました。カテゴリタグ運用との比較、つまずいた点、使い分けの結論を実装コードとともに残します。

Gemini API254File Search7マルチモーダル25画像検索個人開発121

「夕暮れの海を紫がかったトーンで仕上げた壁紙、あれはどのフォルダだったか」。先週、運営中の壁紙アプリの特集ページを組んでいて、この一枚を探すのに10分以上かけてしまいました。カテゴリは合っている。タグも辿った。それでも見つからない。原因は単純で、その画像は「海」カテゴリではなく「空」カテゴリに入っていたのです。

私の手元には、個人開発で運営しているアプリ群の壁紙アセットが数千枚あります。これまでは Gemini Vision による30カテゴリの自動分類で整理しており、その経緯はGemini Vision で壁紙アプリのカテゴリ自動分類を試した記録に書きました。分類の精度には満足しております。ただ、分類とは「画像を一つの箱に入れる」ことです。箱をまたぐニュアンス――「夕暮れ」で「海」で「紫」――は、箱の構造ではすくえません。

そこに、File Search が gemini-embedding-2 で画像のネイティブ埋め込み・検索に対応したという知らせが届きました。自然言語のクエリで画像そのものを意味検索できるなら、この「箱をまたぐ探しもの」が解決するかもしれない。まずは300枚で検証した記録です。

カテゴリ分類で困っていなかったのに、なぜ検索が欲しくなったか

正直に書くと、エンドユーザー向けの機能としてはカテゴリ分類で十分に回っております。困っていたのは運営側の作業です。

特集ページの編成、App Store 用スクリーンショットの素材選び、季節キャンペーンの差し替え。こうした作業では「カテゴリ」ではなく「印象」で画像を探します。「静かで寒色系の朝」「視線が抜ける構図の都市夜景」。この語彙はカテゴリ30個では表現できず、結局サムネイル一覧を目視で流すことになります。1回あたり5〜15分。月に何度も発生します。

タグを増やせば解決する、とは考えませんでした。タグ体系を細かくするほど付与の一貫性が崩れ、メンテナンスコストが検索の便益を食いつぶす。これは数千枚を管理してきた中での実感です。欲しいのは「タグを設計しない検索」でした。

300枚をストアに入れて検索できるようにするまで

検証には Python SDK(google-genai)を使いました。やることは三つだけです。ストアを作る、画像を入れる、検索する。

まずストアの作成と画像のアップロードです。後で手元の資産管理と突き合わせられるよう、custom_metadata にアセットIDを必ず入れておきます。

import pathlib
from google import genai
 
client = genai.Client()  # 環境変数 GEMINI_API_KEY を参照
 
# 検証用の File Search ストアを作成
store = client.file_search_stores.create(
    config={"display_name": "wallpaper-assets-trial"}
)
 
# 2026年6月入庫分の300枚をインポート
for path in sorted(pathlib.Path("./assets/2026-06").glob("*.jpg")):
    client.file_search_stores.upload_to_file_search_store(
        file_search_store_name=store.name,
        file=str(path),
        config={
            "display_name": path.stem,
            "custom_metadata": [
                {"key": "asset_id", "string_value": path.stem},
            ],
        },
    )

このコードのポイントは custom_metadata です。検索結果はチャンク(取得元)として返ってくるため、メタデータにIDがないと「どのファイルがヒットしたのか」をアプリ側の資産DBと照合する手段がなくなります。最初の数十枚をID無しで入れてしまい、入れ直す羽目になりました。

検索は、通常の generate_content に File Search をツールとして渡すだけです。

from google.genai import types
 
response = client.models.generate_content(
    model="gemini-3.5-flash",
    contents="夕暮れの海を写した、紫がかったトーンの壁紙を探してください",
    config=types.GenerateContentConfig(
        tools=[
            types.Tool(
                file_search=types.FileSearch(
                    file_search_store_names=[store.name]
                )
            )
        ]
    ),
)
 
# 回答本文より、根拠として返るチャンクの方が本命
meta = response.candidates[0].grounding_metadata
for chunk in meta.grounding_chunks:
    print(chunk.retrieved_context.title)  # → custom_metadata と照合

運営ツールとして使う場合、欲しいのはモデルの文章ではなくヒットした画像の一覧です。なので grounding_metadata 側を主役として扱い、回答テキストは添え物にする。この割り切りで実装がだいぶ素直になりました。

ぶつかった壁は三つ

一つ目は、インデックス反映のラグです。アップロード直後に検索しても、その画像はヒットしません。300枚の検証では、全件が検索に乗るまで体感で数分、長いときで7分ほどかかりました。バッチで入庫して翌朝使う運用なら問題ありませんが、「入れた直後に確認」という手作業の流れには合いません。入庫スクリプトの最後に、代表クエリを投げて新規分がヒットするか確かめる待ち合わせ処理を足しました。

二つ目は、厳密な条件との混在です。意味検索は「紫っぽい夕暮れの海」には強いのですが、「アスペクト比 19.5:9 以上」「2024年以前に入庫」のような確定条件は埋め込み検索の守備範囲ではありません。ここは無理をさせず、File Search で意味の候補を出し、解像度や入庫日は手元の資産DBで絞る二段構えにしました。メタデータフィルタも併用できますが、数値レンジの絞り込みは自前DBの方が確実です。

三つ目は、コストの考え方です。File Search は検索クエリ時の埋め込み生成には課金されず、インデックス作成時の埋め込み処理に課金される設計です。つまり「入庫時に一度払い、検索は何度でも軽い」。300枚の検証ではインデックス費用は誤差の範囲でしたが、数千枚を全量投入するなら、二度と検索しない死蔵アセットまで入れるかは考えどころです。私は「現役アセットのみ投入、引退分はストアから削除」という運用に倒すつもりです。

カテゴリ分類は捨てない ― 役割が違った

検証前は「意味検索が使えるならカテゴリ分類は引退かもしれない」と内心思っておりました。20本のクエリで試した結果、17本で意図した画像が上位に入り、精度には確かな手応えがあります。それでも結論は「両方残す」です。役割が違いました。

  • カテゴリ分類が向くもの: エンドユーザー向けの一覧導線。「箱」が安定していること自体に価値があり、毎日開く画面では予測可能性が信頼になります
  • マルチモーダル検索が向くもの: 運営側の探しもの。語彙が毎回変わる、一回性の高いクエリ。タグ設計のメンテナンスコストをゼロにできるのが効きます
  • 両者の接続点: 検索でよくヒットする語彙(「夕暮れ」「寒色」など)は、次のカテゴリ再編やアプリ内検索機能の語彙設計のヒントになります

冒頭の「紫がかった夕暮れの海」は、File Search では最初のクエリで1位に返ってきました。10分の目視が数秒になった瞬間で、静かに胸が熱くなりました。

次のステップ

全量投入はまだ行いません。まず新規入庫分だけをストアに流すパイプラインを組み、月次で「検索が実作業を何分置き換えたか」を記録してから判断します。私自身、意味検索の便利さは体感的なぶん、効果を数字にしておかないと、ただの維持費になりかねないからです。

もし手元に「タグでは表現しきれない画像資産」をお持ちでしたら、まずは数百枚の小さなストアで試すことをおすすめします。インデックスのラグとメタデータ設計さえ押さえれば、検証自体は半日で終わります。同じ課題に取り組んでいる方の参考になれば幸いです。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

◈ API / SDK2026-05-02
個人開発者のための Gemini API 収益化ロードマップ — マルチモーダルを軸にしたアプリ設計と課金導線
Gemini API のマルチモーダル機能を個人開発の収益化へ直結させるロードマップです。Gemini × Firebase × Stripe のアーキテクチャ、動画・音声解析の課金パターン、無料から有料への導線設計、サブスクと単発購入のハイブリッドまで実装コードで示します。
◈ API / SDK2026-04-27
Gemini APIで副業を始める90日ロードマップ — マルチモーダルの強みを生かした個人収益化の実装ガイド
Gemini API を使って副業として月数万円を作る90日のロードマップ。マルチモーダル対応・コンテキストキャッシング・Free Tier活用といったGeminiの強みを最大限活かしながら、個人事業者が無理なく続けられる収益化構造をフェーズ分けで解説します。
◈ API / SDK2026-09-29
『F6号』と『A4くらい』が同じ列に並ぶ作品台帳を、Gemini の読み取りと号数表の換算で cm に揃えるまで
作家さんの作品台帳に『F6号』『41×31.8cm』『A4くらい』が混ざっていました。Gemini API には読み取りだけを頼み、換算は号数表、向きは画像で決める小さな道具を、動くコードとともに一本ずつ組み立てます。