はじめに
「Vertex AI Searchを使ってRAG(検索拡張生成)を構築しているけれど、ユーザーごとに参照するファイルを出し分けたい…」
「不要なデータが混ざって回答の精度が落ちるのを防ぎたい…」
開発を進める中で、このような課題に直面したことはありませんか?
実は、**Vertex AI Searchの「フィルタ機能」**を使えば、データストアを分けずに、1つのデータストア内で参照ファイルを柔軟にコントロールすることが可能です。
この記事では、Vertex AI Searchでのフィルタリングの実装方法から、メタデータ(JSONL)の設定、フィルタ構文の書き方までを実例付きで解説します。
Vertex AI Searchとは?
まずは簡単にVertex AI Searchについておさらいしましょう。
Vertex AI Searchは、Google Cloudが提供するフルマネージドサービスです。Cloud Storageなどに格納した自社の独自データをAIが横断的に検索(グラウンディング)し、その結果をもとにGeminiなどのLLMが回答を生成します。
これを利用することで、社内文書や特定のマニュアルに基づいた、精度の高いAIチャットボットなどを構築できます。
フィルタ機能を使うメリット
Vertex AI Searchにおけるフィルタ機能は、検索対象となるレコード(ドキュメント)を条件に応じて絞り込む機能です。これを利用することで、以下のような大きなメリットがあります。
-
権限管理の効率化:
「部署AにはファイルAだけ」「部署BにはファイルBだけ」といった閲覧制限をかける際、わざわざデータストアを複数作成する必要がありません。1つのデータストアで管理できるため、運用面での管理が楽になったりします。 -
回答精度の向上:
回答に関連のない古いデータや、ノイズになりそうなファイルを検索対象から除外することで、LLMのハルシネーション(嘘の回答)を抑制し、回答品質を高めることができます。
実践!フィルタリングの実装方法
それでは、実際にPythonを使ってGemini API経由でVertex AI Searchを呼び出す際のコード例を見てみましょう。ここでは、 gemini-2.5-flash を使用する想定で記述します。
Pythonコード例
ポイントは、retrieval 設定内の vertex_ai_search パラメータにある filter です。
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=contents,
config=GenerateContentConfig(
system_instruction=system_instruction,
tools=[
types.Tool(
retrieval=types.Retrieval(
vertex_ai_search=types.VertexAISearch(
datastore='<your-datastore-id>',
filter='group: ANY("1")' # ←ここで検索するファイルをフィルタリング
)
)
)
]
),
)
この例では、メタデータの group というキーが"1"であるファイルのみを検索対象とするよう指示しています。この1行を追加するだけで、AIが参照する情報をコントロールできます。
ファイルごとのメタデータ(Key/Value)設定方法
フィルタリングを行うためには、検索対象のファイルに「メタデータ(属性情報)」を付与する必要があります。これには、.jsonl形式のファイルを使用します。
JSONLファイルの記述例
Cloud Storage上のファイルとメタデータを紐付けるためのJSONLファイルを作成し、Vertex AI Searchに取り込みます。
{"id": "doc1", "structData": {"group": "1", "sex": "man", "age":25, "createdAt": "2025-05-08T12:00:00+09:00", "office": {"location": {"address": "1-17-1 Toranomon, Minato-ku, Tokyo"}}}, "content": {"mimeType": "application/pdf", "uri": "gs://<your-bucket>/person_1.pdf"}}
{"id": "doc2", "structData": {"group": "1", "sex": "woman", "age":36, "createdAt": "2025-11-23T12:00:00+09:00", "office": {"location": {"address": "3-28-12 Meieki, Nakamura-ku, Nagoya, Aichi"}}}, "content": {"mimeType": "application/pdf", "uri": "gs://<your-bucket>/person_2.pdf"}}
{"id": "doc3", "structData": {"group": "2", "sex": "man", "age":24, "createdAt": "2025-02-07T12:00:00+09:00", "office": {"location": {"address": "1-17-1 Toranomon, Minato-ku, Tokyo"}}}, "content": {"mimeType": "application/pdf", "uri": "gs://<your-bucket>/person_3.pdf"}}
{"id": "doc4", "structData": {"group": "1", "sex": "woman", "age":43, "createdAt": "2024-06-18T12:00:00+09:00", "office": {"location": {"address": "4-20 Ofukacho, Kita-ku, Osaka"}}}, "content": {"mimeType": "application/pdf", "uri": "gs://<your-bucket>/person_4.pdf"}}
各項目のポイント
-
id: レコードを一意に識別するためのIDです。重複しないように設定します。
-
structData: ここが重要です。管理者が自由にKeyとValueを設定できるオブジェクトです。上記のコード例の
filterは、主にここの値を参照します。 -
content: 実際のファイルの場所(URI)や形式(mimeType)を指定します。
Google Cloud ConsoleからVertex AIを選択し、データストアを作成します。

インポートするファイルは、Cloud Storageなどに格納した.jsonlファイルを指定します。
すぐ使える!フィルタ構文チートシート
structDataに設定した値に対して、どのようなフィルタ条件が書けるかをまとめました。開発時の参考にしてください。
テキストの一致 [ANY]
特定のタグやグループを指定する場合に使用します。
-
'group: ANY("1")': 単体指定 -
'group: ANY("1", "2")': 複数指定("1"または"2"を含む)
否定 [NOT, -]
特定の条件を除外したい場合に使用します。
'NOT group: ANY("1")''-group: ANY("1")'
数値比較 [<, =, >]
年齢や価格、日付などの比較に使用します。
-
数値型(number)
-
'age > 30': 30より大きい -
'age = 30': 30と等しい -
'age <= 30': 30以下
-
-
日付型(datetime)
-
'createdAt <= "2025-12-8T12:00:00+09:00"': YYYY-MM-DDTHH: mm: ss± HH: mm形式 -
'createdAt <= "2025-12-08"': YYYY-MM-DD形式
-
数値範囲 [IN]
特定の範囲内にあるデータを絞り込みます。
i は inclusive(含む)、e は exclusive(含まない)を意味します。
-
'age: IN(20, 40)': 20以上 40未満(デフォルト) -
'age: IN(20i, 40i)': 20以上 40以下 -
'age: IN(20e, 40e)': 20より大きく 40未満 -
'age: IN(20e, 40i)': 20より大きく 40以下 -
'age: IN(*, 40)': 40未満(下限なし)
地理位置情報[GEO_DISTANCE]
上述した例ではaddress(住所)でしたが、緯度・経度でも指定することができます。
住所をメタデータとして記載し、コード実行では緯度経度を指定することも可能です。
"office": {"location": {"address": "1-17-1 Toranomon, Minato-ku, Tokyo"}
// または
"office": {"location": {"latitude": 35.6657, "longitude": 139.7448}
-
'office.location: GEO_DISTANCE("4-2-8 Shibakoen, Minato-ku, Tokyo", 5000)': 住所で指定(5000m以内) -
'office.location:GEO_DISTANCE(35.6585, 139.7454, 5000)': 緯度経度で指定(5000m以内)
複合条件 [AND, OR]
複数の条件を組み合わせる場合に使用します。
-
'(group: ANY("1") AND age = 30)': AND(かつ) -
'(group: ANY("1") OR age = 30)': OR(または)
まとめ
Vertex AI Searchのフィルタ機能を活用することで、RAGシステムの柔軟性と精度は格段に向上します。
特に、組織内でのドキュメント検索システムを構築する場合、「誰にどの情報を見せるか」というセキュリティの観点からもフィルタ機能は必須と言えます。ぜひ今回の記事を参考に、メタデータ設計とフィルタリングを試してみてください。
最後まで読んでいただきありがとうございました。
この記事がフィルタリングの助けになれば幸いです。