🍺

実践 Vertex AI Search:フィルタを使ってみる(基本)

2024/11/15に公開

1. はじめに

株式会社 Hogetic Lab のエンジニア 古川です。

皆さん、Google Cloud の Vertex AI Search を使ったことはありますか?

生成 AI は、そのモデルの学習に使ったインターネット上のデータのみを情報として持つため、その学習データ以降の情報や、インターネットに公開されていない企業内の情報に関する質問をすると、正しい情報を回答することができません。

この問題を解決するための一つの方法が RAG (Retrieval-Augmented Generation) という技術で、Vertex AI Search は、この RAG を手軽に構築できるフルマネージド プラットフォームです。

今回は、RAG の精度を上げる実用性の高い「フィルタ」について解説します。

※ 本記事は「一度は Google Cloud のコンソールで Vertex AI Search を触って実際にアプリを作った経験があること」を前提としており、詳細な手順や用語は説明しません。Vertex AI Search をまだ試したことのない方は、以下のチュートリアルを試してみることをお勧めします。

2. フィルタとは

フィルタは構造化データのカラムまたは非構造化データのメタデータで、検索対象を絞り込む機能です。

どの種類のデータセットでも使用できますが、今回は、効果のわかりやすい構造化データを例にして解説します。

実用性のある RAG を作るのに最も重要なのは、生成 AI の回答時に参照する情報をデータセットから取り出す時の精度です。

データセットとして構造化データを使用すると、複数のカラムで構成されたテーブル形式のデータに対して、自然言語で質問することで、関連度の高い情報を取り出すことができます。

データセットはスキーマ設定を持ち、取り込み時に各項目で「インデックスを作るか」「検索可能にするか」などの設定ができます。(設定の種類はスキーマの設定を参照してください。)
この設定を適切に行うことで、検索の精度を上げることができます。

しかし、自然言語での検索なので、この設定だけでは精度には限界があります。
テーブルに入っている構造化データをデータセットに使う場合、カラムには作成日などの日付や価格などの数値が入っているため、その値を直接指定して検索対象を絞り込んだ方が検索精度が上がることが期待できます。

この検索の絞り込みを実現するのがフィルタです。

3. フィルタを設定して効果を確認する

フィルタの設定方法とその効果について解説します。

データセットとスキーマ

今回の解説で使用するデータセットを紹介します。

これは個人的な趣味の話になりますが、私はクラフトビールが大好きで、飲んだビールの名前や場所、印象等の情報を記録しており、それを使って「あの時、どんなビールを飲んだっけ?」「こんな特徴のビール、どこで飲んだっけ?」という質問に答えてくれるエージェントを目標に個人的に開発しています。今回紹介するのは、その技術調査をまとめたものです。

余談ですが、皆さんの中にも、Excel や Google Sheets でこのような趣味の記録をつけている方がいらっしゃるのではないでしょうか?
Vertex AI に限らず、生成 AI の技術は、具体的なデータを使って試すことでより理解が深まります。いや、使いこなすには試すしかありません。そして、試すことでまた次のアイデアが生まれます。ですので、個人でデータを持っている方は、そのデータを使って試してみることをお勧めします。

データセット
コンソールからBigQueryのテーブルを指定して取り込みました。
取り込んだデータ(BQテーブル)の一部

元データのデータベースとしては Firestore を使用しており、現在はデータストアの元データとして直接指定することもできるのですが、分析用に少し加工する必要があるので BigQuery にしています。

スキーマ
自動検出で取り込んだ結果のスキーマはこちらです。
スキーマ(一部)

ポイント

  • スキーマの設定はデータセット作成時に指定しますが、後からもこの画面から編集可能です。
  • 一部のフィールド名(title, description など) はキープロパティが自動で設定され、スキーマ設定を変更できません。(Google の Web 検索技術をベースにしているためと想像します。)
  • データセットへの取り込み時に型(種類)が自動で決まります。なお、「検索可能」なのは string のみですが、フィルタはどの型にも適用できます。
  • JSONファイルを用意することで、自動検出ではなく、明示的にスキーマと各種設定を指定することもできます。

詳細はこちらを参照ください。

フィルタ設定と実行結果

フィルタは、コンソール UI では設定できないので、curl コマンドやちょっとしたコーディングが必要です。
こちらのサンプルコードを参考に、filterを設定して結果を確認します。

    request = discoveryengine.SearchRequest(
        serving_config=serving_config,
        query=search_query,
        page_size=10,
        content_search_spec=content_search_spec,
        query_expansion_spec=discoveryengine.SearchRequest.QueryExpansionSpec(
            condition=discoveryengine.SearchRequest.QueryExpansionSpec.Condition.AUTO,
        ),
        spell_correction_spec=discoveryengine.SearchRequest.SpellCorrectionSpec(
            mode=discoveryengine.SearchRequest.SpellCorrectionSpec.Mode.AUTO
        ),
        filter="{{ここに条件を指定する}}", 
    )

search リクエスト部分抜粋

去年の同時期(2023年11月)に飲んで美味しかったビールを挙げてもらいましょう。

  • 質問:「2023年11月に飲んだビールの中でまた飲みたいと感じたビールを異なるスタイルで3つ挙げて」

フィルタ設定しない時の結果

フィルタ設定なしでの実行結果はこちらです。

  • 検索結果数: 1215件
  • 要約

    質問の情報からは、2023年11月に飲んだビールで「また飲みたい」と感じたビールは、湘南ビールのバーレーワインのみです。 異なるスタイルのビールを3つ挙げるには、情報が不足しています。 記録にあるのはバーレーワインのみで、他のスタイルのビールは2023年11月以外に飲んだもの、または「また飲みたい」と感じなかったものしかありません。

ほぼ全てのレコードが検索対象になってしまいました。自然言語での日にち指定はうまく検索に反映されていないようです。
また、要約には10件使っていますが、適切なデータが含まれなかったためか、要約の精度も低いものになりました。

フィルタ設定した時の結果

フィルタに日付を期間で指定したフィルタで同じ質問を投げてみます。

    filter="record_date >= \"2023-11-01\" AND record_date <= \"2023-11-30\"",

※ record_date の型は datetime

  • 検索結果数: 36件
  • 要約

    2023年11月に飲んだビールで、また飲みたいと感じたビールを異なるスタイルで3つ挙げます。
    1つ目は、湘南ビールの「バーレーワイン」です。これはバーレーワインスタイルのビールで、モルティでフレッシュな香りに、カラメルを思わせる甘い香りと味噌や醤油を思わせる醸造感が特徴的でした。マイルドな口当たりで、苦味が強く、スッキリとした後味も印象的でした。甘みと苦みのバランスが良く、クセになる味わいです。
    2つ目は、ヤッホーブルーイングの「僕ビール君ビールジョーカーくん」です。これはセッションIPAスタイルのビールで、爽やかな柑橘系の香りと、軽くマンゴーや桃を思わせるトロピカルな香りが特徴です。マイルドな口当たりで、ややクリスプな飲み口、程よい柑橘感が楽しめました。
    3つ目は、サッポロビールの「プレミアム生ビール」です。これはピルスナースタイルのビールで、甘い麦芽とラガーらしい芳醇な香りが特徴です。マイルドな口当たりで、強い苦味とクリアな麦芽の甘味を感じました。ヱビスを思わせるような、バランスの良い味わいです。

    異なるスタイルのビールを3つ選んで紹介しました。

このように指定した範囲でフィルタされたデータを取得して要約を作成できました。(BQテーブルで検索すると 37 レコードだったので、検索で 1 件だけ外れたようです)

なお、filter="record_date = \"2023-11\"" と月で止めて実行すると、2023-11-01 でフィルタされた結果が返ってきました。
公式ドキュメントの Examples には年でフィルタする例があり、月でも同様に動作することを期待したのですが。想定した範囲でフィルタできているか事前の検証が必要です。

ちなみに、今回は比較のために同じ質問で実行しましたが、フィルタした場合は質問に「2023年11月に飲んだビールの中で」と期間を入れなくても同様の回答が得られます。

フィルタ設定の書き方についてはこちらを参考にしてください。
Examples of filter expressions

まとめ

今回は Vertex AI Search の基本的なフィルタの使い方とその結果を紹介しました。
フィルタには他にも設定があるので、次回はそれらの設定と適用した結果について紹介したいと思います。

今後も、具体的な事例を取り上げて、Vertex AI Search の便利な機能や使い方を紹介していこうと思います。お楽しみに。

※ データ分析や AI 活用に関するご相談は、以下よりお気軽にお問い合わせください。
お問い合わせフォーム

参考文献

Google Cloud Vertex AI Agent Builder の公式ドキュメント

Wikipedia

寒くなり、スタウトやバーレーワインが美味しい季節になりました。飲んだことがない方は、一度お試しください。

Hogetic Lab

Discussion