セマンティック検索と検索拡張生成を行う

このチュートリアルでは、ベクトル インデックスを使用して検索パフォーマンスを改善する方法など、テキスト エンベディングを作成して使用するエンドツーエンドのプロセスについて説明します。

このチュートリアルでは、次のタスクについて説明します。

  • Vertex AI エンベディング モデルを使用して BigQuery ML リモートモデルを作成する。
  • リモートモデルと ML.GENERATE_EMBEDDING 関数を使用して、BigQuery テーブルのテキストからエンベディングを生成する。
  • ベクトル インデックスを作成して、エンベディングにインデックスを付ける。
  • VECTOR_SEARCH 関数でエンベディングを使用して、類似したテキストを検索する。
  • ML.GENERATE_TEXT 関数を使用してテキストを生成し、ベクトル検索の結果からプロンプト入力を補強して結果を改善することで、検索拡張生成(RAG)を行う。

このチュートリアルでは、BigQuery の一般公開テーブル patents-public-data.google_patents_research.publications を使用します。

必要なロールと権限

  • 接続を作成するには、次の Identity and Access Management(IAM)ロールのメンバーシップが必要です。

    • roles/bigquery.connectionAdmin
  • 接続のサービス アカウントに権限を付与するには、次の権限が必要です。

    • resourcemanager.projects.setIamPolicy
  • このチュートリアルで、残りの BigQuery オペレーションに必要となる IAM 権限は、次の 2 つのロールに含まれています。

    • BigQuery データ編集者(roles/bigquery.dataEditor)。モデル、テーブル、インデックスを作成するためのロールです。
    • BigQuery ユーザー(roles/bigquery.user)。BigQuery ジョブを実行するためのロールです。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

  • BigQuery ML: You incur costs for the data that you process in BigQuery.
  • Vertex AI: You incur costs for calls to the Vertex AI service that's represented by the remote model.

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

BigQuery の料金の詳細については、BigQuery ドキュメントの BigQuery の料金をご覧ください。

Vertex AI の料金の詳細については、Vertex AI の料金のページをご覧ください。

準備

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Enable the BigQuery, BigQuery Connection, and Vertex AI APIs.

    Enable the APIs

データセットの作成

ML モデルを格納する BigQuery データセットを作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    [BigQuery] ページに移動

  2. [エクスプローラ] ペインで、プロジェクト名をクリックします。

  3. 「アクションを表示」> [データセットを作成] をクリックします。

    データセットを作成する。

  4. [データセットを作成する] ページで、次の操作を行います。

    • [データセット ID] に「bqml_tutorial」と入力します。

    • [ロケーション タイプ] で [マルチリージョン] を選択してから、[US (米国の複数のリージョン)] を選択します。

      一般公開データセットは US マルチリージョンに保存されています。わかりやすくするため、データセットを同じロケーションに保存します。

    • 残りのデフォルトの設定は変更せず、[データセットを作成] をクリックします。

      データセットの作成ページ

接続を作成する

クラウド リソース接続を作成し、接続のサービス アカウントを取得します。前の手順で作成したデータセットと同じロケーションに接続を作成します。

次のオプションのいずれかを選択します。

コンソール

  1. BigQuery ページに移動します。

    [BigQuery] に移動

  2. 接続を作成するには、[追加] をクリックし、続いて [外部データソースへの接続] をクリックします。

  3. [接続タイプ] リストで、[Vertex AI リモートモデル、リモート関数、BigLake(Cloud リソース)] を選択します。

  4. [接続 ID] フィールドに接続の名前を入力します。

  5. [接続を作成] をクリックします。

  6. [接続へ移動] をクリックします。

  7. [接続情報] ペインで、後の手順で使用するサービス アカウント ID をコピーします。

bq

  1. コマンドライン環境で接続を作成します。

    bq mk --connection --location=REGION --project_id=PROJECT_ID \
        --connection_type=CLOUD_RESOURCE CONNECTION_ID

    --project_id パラメータは、デフォルト プロジェクトをオーバーライドします。

    以下を置き換えます。

    接続リソースを作成すると、BigQuery は、一意のシステム サービス アカウントを作成し、それを接続に関連付けます。

    トラブルシューティング: 次の接続エラーが発生した場合は、Google Cloud SDK を更新します。

    Flags parsing error: flag --connection_type=CLOUD_RESOURCE: value should be one of...
    
  2. 後の手順で使用するため、サービス アカウント ID を取得してコピーします。

    bq show --connection PROJECT_ID.REGION.CONNECTION_ID

    出力は次のようになります。

    name                          properties
    1234.REGION.CONNECTION_ID     {"serviceAccountId": "connection-1234-9u56h9@gcp-sa-bigquery-condel.iam.gserviceaccount.com"}
    

Terraform

google_bigquery_connection リソースを使用します。

BigQuery に対する認証を行うには、アプリケーションのデフォルト認証情報を設定します。詳細については、クライアント ライブラリの認証を設定するをご覧ください。

次の例では、US リージョンに my_cloud_resource_connection という名前の Cloud リソース接続を作成します。


# This queries the provider for project information.
data "google_project" "default" {}

# This creates a cloud resource connection in the US region named my_cloud_resource_connection.
# Note: The cloud resource nested object has only one output field - serviceAccountId.
resource "google_bigquery_connection" "default" {
  connection_id = "my_cloud_resource_connection"
  project       = data.google_project.default.project_id
  location      = "US"
  cloud_resource {}
}

Google Cloud プロジェクトで Terraform 構成を適用するには、次のセクションの手順を完了します。

Cloud Shell を準備する

  1. Cloud Shell を起動します。
  2. Terraform 構成を適用するデフォルトの Google Cloud プロジェクトを設定します。

    このコマンドは、プロジェクトごとに 1 回だけ実行する必要があります。これは任意のディレクトリで実行できます。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    Terraform 構成ファイルに明示的な値を設定すると、環境変数がオーバーライドされます。

ディレクトリを準備する

Terraform 構成ファイルには独自のディレクトリ(ルート モジュールとも呼ばれます)が必要です。

  1. Cloud Shell で、ディレクトリを作成し、そのディレクトリ内に新しいファイルを作成します。ファイルの拡張子は .tf にする必要があります(例: main.tf)。このチュートリアルでは、このファイルを main.tf とします。
    mkdir DIRECTORY && cd DIRECTORY && touch main.tf
  2. チュートリアルを使用している場合は、各セクションまたはステップのサンプルコードをコピーできます。

    新しく作成した main.tf にサンプルコードをコピーします。

    必要に応じて、GitHub からコードをコピーします。Terraform スニペットがエンドツーエンドのソリューションの一部である場合は、この方法をおすすめします。

  3. 環境に適用するサンプル パラメータを確認し、変更します。
  4. 変更を保存します。
  5. Terraform を初期化します。これは、ディレクトリごとに 1 回だけ行う必要があります。
    terraform init

    必要に応じて、最新バージョンの Google プロバイダを使用する場合は、-upgrade オプションを使用します。

    terraform init -upgrade

変更を適用する

  1. 構成を確認して、Terraform が作成または更新するリソースが想定どおりであることを確認します。
    terraform plan

    必要に応じて構成を修正します。

  2. 次のコマンドを実行し、プロンプトで「yes」と入力して、Terraform 構成を適用します。
    terraform apply

    Terraform に「Apply complete!」のメッセージが表示されるまで待ちます。

  3. Google Cloud プロジェクトを開いて結果を表示します。Google Cloud コンソールの UI でリソースに移動して、Terraform によって作成または更新されたことを確認します。

サービス アカウントにアクセス権を付与する

接続のサービス アカウントに Vertex AI ユーザーロールを付与します。このロールは、始める前にで作成または選択したプロジェクトで付与する必要があります。別のプロジェクトでロールを付与すると、「bqcx-1234567890-xxxx@gcp-sa-bigquery-condel.iam.gserviceaccount.com does not have the permission to access resource」というエラーが発生します。

ロールを付与する手順は次のとおりです。

  1. [IAM と管理] ページに移動します。

    [IAM と管理] に移動

  2. [アクセス権を付与] をクリックします。

  3. [新しいプリンシパル] フィールドに、前の手順でコピーしたサービス アカウント ID を入力します。

  4. [ロールを選択] フィールドで、[Vertex AI]、[Vertex AI ユーザーロール] の順に選択します。

  5. [保存] をクリックします。

テキスト エンベディング生成用のリモートモデルを作成する

ホストされる Vertex AI テキスト エンベディング生成モデルを表すリモートモデルを作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    BigQuery に移動

  2. クエリエディタで次のステートメントを実行します。

    CREATE OR REPLACE MODEL `bqml_tutorial.embedding_model`
      REMOTE WITH CONNECTION `LOCATION.CONNECTION_ID`
      OPTIONS (ENDPOINT = 'text-embedding-004');

    以下を置き換えます。

    • LOCATION: 接続のロケーション
    • CONNECTION_ID: BigQuery 接続の ID

      Google Cloud コンソールで接続の詳細を表示する場合、CONNECTION_ID は、[接続 ID] に表示される完全修飾接続 ID の最後のセクションの値になります(例: projects/myproject/locations/connection_location/connections/myconnection)。

    クエリが完了するまでに数秒かかります。完了後、モデル embedding_model が [エクスプローラ] ペインの bqml_tutorial データセットに表示されます。クエリは CREATE MODEL ステートメントを使用してモデルを作成するため、クエリの結果はありません。

テキスト エンベディングを生成する

ML.GENERATE_EMBEDDING 関数を使用して特許の要約からテキスト エンベディングを生成し、BigQuery テーブルに書き込み、検索できるようにします。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    BigQuery に移動

  2. クエリエディタで次のステートメントを実行します。

    CREATE OR REPLACE TABLE `bqml_tutorial.embeddings` AS
    SELECT * FROM ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.embedding_model`,
      (
        SELECT *, abstract AS content
        FROM `patents-public-data.google_patents_research.publications`
        WHERE LENGTH(abstract) > 0 AND LENGTH(title) > 0 AND country = 'Singapore'
      )
    )
    WHERE LENGTH(ml_generate_embedding_status) = 0;

ML.GENERATE_EMBEDDING 関数を使用したエンベディングの生成は、Vertex AI LLM の割り当てまたはサービスの利用不可が原因で失敗することがあります。エラーの詳細は ml_generate_embedding_status 列に返されます。ml_generate_embedding_status 列が空の場合は、エンベディングの生成が成功したことを示します。

BigQuery でテキスト エンベディングを生成する他の方法については、事前トレーニング済みの TensorFlow モデルを使用してテキストをエンベディングするチュートリアルをご覧ください。

ベクトル インデックスを作成する

ベクトル インデックスを作成するには、CREATE VECTOR INDEX データ定義言語(DDL)ステートメントを使用します。

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで、次の SQL ステートメントを実行します。

    CREATE OR REPLACE VECTOR INDEX my_index
    ON `bqml_tutorial.embeddings`(ml_generate_embedding_result)
    OPTIONS(index_type = 'IVF',
      distance_type = 'COSINE',
      ivf_options = '{"num_lists":500}')

ベクトル インデックスの作成を確認する

ベクトル インデックスは非同期で入力されます。インデックスが使用できる状態かどうかを確認するには、INFORMATION_SCHEMA.VECTOR_INDEXES ビューをクエリして、coverage_percentage 列の値が 0 よりも大きく、last_refresh_time 列の値が NULL でないことを確認します。

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで、次の SQL ステートメントを実行します。

    SELECT table_name, index_name, index_status,
    coverage_percentage, last_refresh_time, disable_reason
    FROM `PROJECT_ID.bqml_tutorial.INFORMATION_SCHEMA.VECTOR_INDEXES`

    PROJECT_ID は、実際のプロジェクト ID に置き換えます。

ベクトル インデックスを使用してテキストの類似度検索を行う

VECTOR_SEARCH 関数を使用して、テキスト クエリから生成されたエンベディングに一致する上位 5 件の関連特許を検索します。このクエリでエンベディングの生成に使用するモデルは、比較するテーブルのエンベディングの生成に使用するモデルと同じである必要があります。そうしないと、検索結果の精度が低下します。

  1. [BigQuery] ページに移動します。

    [BigQuery] に移動

  2. クエリエディタで、次の SQL ステートメントを実行します。

    SELECT query.query, base.publication_number, base.title, base.abstract
    FROM VECTOR_SEARCH(
      TABLE `bqml_tutorial.embeddings`, 'ml_generate_embedding_result',
      (
      SELECT ml_generate_embedding_result, content AS query
      FROM ML.GENERATE_EMBEDDING(
      MODEL `bqml_tutorial.embedding_model`,
      (SELECT 'improving password security' AS content))
      ),
      top_k => 5, options => '{"fraction_lists_to_search": 0.01}')

    出力は次のようになります。

    +-----------------------------+--------------------+-------------------------------------------------+-------------------------------------------------+
    |            query            | publication_number |                       title                     |                      abstract                   |
    +-----------------------------+--------------------+-------------------------------------------------+-------------------------------------------------+
    | improving password security | SG-120868-A1       | Data storage device security method and a...    | Methods for improving security in data stora... |
    | improving password security | SG-10201610585W-A  | Passsword management system and process...      | PASSSWORD MANAGEMENT SYSTEM AND PROCESS ...     |
    | improving password security | SG-148888-A1       | Improved system and method for...               | IMPROVED SYSTEM AND METHOD FOR RANDOM...        |
    | improving password security | SG-194267-A1       | Method and system for protecting a password...  | A system for providing security for a...        |
    | improving password security | SG-120868-A1       | Data storage device security...                 | Methods for improving security in data...       |
    +-----------------------------+--------------------+-------------------------------------------------+-------------------------------------------------+
    

テキスト生成用のリモートモデルを作成する

ホストされる Vertex AI テキスト生成モデルを表すリモートモデルを作成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    BigQuery に移動

  2. クエリエディタで次のステートメントを実行します。

    CREATE OR REPLACE MODEL `bqml_tutorial.text_model`
      REMOTE WITH CONNECTION `LOCATION.CONNECTION_ID`
      OPTIONS (ENDPOINT = 'gemini-1.5-flash-002');

    以下を置き換えます。

    • LOCATION: 接続のロケーション
    • CONNECTION_ID: BigQuery 接続の ID

      Google Cloud コンソールで接続の詳細を表示する場合、CONNECTION_ID は、[接続 ID] に表示される完全修飾接続 ID の最後のセクションの値になります(例: projects/myproject/locations/connection_location/connections/myconnection)。

    クエリが完了するまでに数秒かかります。完了後、モデル text_model が [エクスプローラ] ペインの bqml_tutorial データセットに表示されます。クエリは CREATE MODEL ステートメントを使用してモデルを作成するため、クエリの結果はありません。

ベクトル検索の結果で拡張されたテキストを生成する

ML.GENERATE_TEXT 関数を使用して、検索結果をプロンプトとしてフィードし、テキストを生成します。

  1. Google Cloud コンソールで [BigQuery] ページに移動します。

    BigQuery に移動

  2. クエリエディタで、次のステートメントを実行します。

    SELECT ml_generate_text_llm_result AS generated, prompt
    FROM ML.GENERATE_TEXT(
      MODEL `bqml_tutorial.text_model`,
      (
        SELECT CONCAT(
          'Propose some project ideas to improve user password security using the context below: ',
          STRING_AGG(
            FORMAT("patent title: %s, patent abstract: %s", base.title, base.abstract),
            ',\n')
          ) AS prompt,
        FROM VECTOR_SEARCH(
          TABLE `bqml_tutorial.embeddings`, 'ml_generate_embedding_result',
          (
            SELECT ml_generate_embedding_result, content AS query
            FROM ML.GENERATE_EMBEDDING(
              MODEL `bqml_tutorial.embedding_model`,
             (SELECT 'improving password security' AS content)
            )
          ),
        top_k => 5, options => '{"fraction_lists_to_search": 0.01}')
      ),
      STRUCT(600 AS max_output_tokens, TRUE AS flatten_json_output));

    出力は次のようになります。

    +------------------------------------------------+------------------------------------------------------------+
    |            generated                           | prompt                                                     |
    +------------------------------------------------+------------------------------------------------------------+
    | These patents suggest several project ideas to | Propose some project ideas to improve user password        |
    | improve user password security.  Here are      | security using the context below: patent title: Active     |
    | some, categorized by the patent they build     | new password entry dialog with compact visual indication   |
    | upon:                                          | of adherence to password policy, patent abstract:          |
    |                                                | An active new password entry dialog provides a compact     |
    | **I. Projects based on "Active new password    | visual indication of adherence to password policies. A     |
    | entry dialog with compact visual indication of | visual indication of progress towards meeting all          |
    | adherence to password policy":**               | applicable password policies is included in the display    |
    |                                                | and updated as new password characters are being...        |
    +------------------------------------------------+------------------------------------------------------------+
     

クリーンアップ

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

次のステップ