Cloud SQL for MySQL でベクトル エンベディングを使用する

1. はじめに

この Codelab では、エンベディングを使用したセマンティック検索に Cloud SQL for MySQL AI インテグレーションを使用する方法と、ベクトルデータのインデックスを使用してパフォーマンスを改善する方法について学びます。

8aa6ba3bc12a1593.png

前提条件

  • Google Cloud と Google Cloud コンソールの基本的な知識
  • コマンドライン インターフェースと Cloud Shell の基本的な使用経験

学習内容

  • Cloud SQL for MySQL インスタンスをデプロイする方法
  • データベースを作成して Cloud SQL AI 統合を有効にする方法
  • データベースにデータを読み込む方法
  • Cloud SQL Studio の使用方法
  • Cloud SQL で Vertex AI エンベディング モデルを使用する方法
  • Agent Platform Studio の使用方法
  • Gemini Enterprise Agent Platform モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

必要なもの

  • Google Cloud アカウントと Google Cloud プロジェクト
  • ウェブブラウザ(Chrome など)

2. 設定と要件

プロジェクトのセットアップ

  1. Google Cloud コンソールにログインします。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、Google アカウントを作成してください。

仕事用または学校用のアカウントではなく、個人用のアカウントを使用します。

  1. 新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。Google Cloud コンソールで新しいプロジェクトを作成するには、ツールバーの [プロジェクトを選択] をクリックします。

295004821bab6a87.png

[プロジェクトを選択] ウィンドウで [新しいプロジェクト] ボタンを押すと、新しいプロジェクトのダイアログ ボックスが開きます。

37d264871000675d.png

ダイアログで、プロジェクト名を入力し、ロケーションを選択します。

96d86d3d5655cdbe.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。プロジェクト名は Google API では使用されず、いつでも変更できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Google Cloud コンソールでは、一意の ID が自動的に生成されますが、カスタマイズすることもできます。生成された ID が気に入らない場合は、別のランダムな ID を生成するか、独自の ID を指定してその ID が使用可能かどうかを確認できます。ほとんどの Codelab では、プロジェクト ID を参照します。通常、プロジェクト ID は プレースホルダで識別されます。
  • なお、3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、プロジェクトの作成と管理に関するドキュメントをご覧ください。

課金を有効にする

課金を有効にするには、次の 2 つの方法があります。個人用の請求先アカウントを使用するか、次の手順でクレジットを利用できます。

Google Cloud クレジットを利用する(省略可)

このワークショップを実施するには、クレジットが設定された請求先アカウントが必要です。ワークショップの主催者から提供されたクレジットを使用するか、この Codelab の上部にあるバナーにクレジットが表示されている場合は、そのクレジットを使用して開始します。請求先アカウントにすでに接続している場合は、この手順をスキップできます。

個人用の請求先アカウントを設定する

Google Cloud クレジットを使用して課金を設定した場合は、この手順をスキップできます。

個人用請求先アカウントを設定するには、Google Cloud Billing コンソールで課金を有効にします。

注:

  • このラボを完了するために必要な Google Cloud リソースの費用は $5 USD 未満です。
  • このラボの最後の手順に沿ってリソースを削除し、追加料金が発生しないようにします。
  • 新規ユーザーは、300 米ドル分の無料トライアルをご利用いただけます。
  • 新規ユーザーと既存のユーザーは、Cloud SQL 無料トライアル インスタンスを使用して Cloud SQL を開始できます。

Cloud Shell の起動

Google Cloud はパソコンからリモートで操作できますが、この Codelab では Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

Google Cloud コンソールで、右上のツールバーにある Cloud Shell アイコンをクリックします。

Cloud Shell をアクティブにする

または、Google Cloud コンソール内で g キー、s キーの順に押すか、Cloud Shell を開きます。

環境のプロビジョニングと接続にはそれほど時間はかかりません。完了すると、接続されたターミナルが表示されます。

環境が接続されていることを示す Google Cloud Shell ターミナルのスクリーンショット

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が向上しています。この Codelab での作業はすべて、ブラウザ内から実行できます。

3. はじめに

API を有効にする

Cloud SQL、Compute Engine、Service Networking、Gemini Enterprise Agent Platform を使用するには、Google Cloud プロジェクトでそれぞれの API を有効にします。

Cloud Shell ターミナルで、プロジェクト ID が設定されていることを確認します。

gcloud config get project

空の文字列が返された場合は、次のように設定します。

gcloud config set project [YOUR-PROJECT-ID]

PROJECT_ID 環境変数を設定します。

PROJECT_ID=$(gcloud config get-value project)

必要な API をすべて有効にします。

gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com

想定される出力

student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$ 
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

有効になっている各 API については、ドキュメントをご覧ください。

4. Cloud SQL インスタンスを作成する

Gemini Enterprise Agent Platform データベース統合を使用して Cloud SQL インスタンスを作成します。

データベース パスワードを作成する

デフォルトのデータベース ユーザーのパスワードを定義します。独自のパスワードを定義することも、ランダム関数を使用してパスワードを生成することもできます。

export CLOUDSQL_PASSWORD=`openssl rand -hex 16`

生成されたパスワード値を表示します。

echo $CLOUDSQL_PASSWORD

後で使用できるように、生成されたパスワードをメモしておきます。

Cloud SQL for MySQL インスタンスを作成する

Cloud SQL インスタンスは、Google Cloud コンソール、Terraform、Google Cloud CLI(gcloud)など、いくつかの方法で作成できます。この Codelab では、gcloud を使用します。他のツールを使用してインスタンスを作成する方法については、インスタンスの作成のドキュメントをご覧ください。

cloudsql_vector フラグは、インスタンスの作成時に有効にできます。ベクター サポートは、MySQL 8.0 R20241208.01_00 以降で利用可能

Cloud Shell セッションで、次のコマンドを実行します。

gcloud sql instances create my-cloudsql-instance \
--database-version=MYSQL_8_4 \
--tier=db-custom-2-8192 \
--region=us-central1 \
--enable-google-ml-integration \
--edition=ENTERPRISE \
--root-password=$CLOUDSQL_PASSWORD

gcloud sql connect を使用してインスタンスに接続します。プロンプトが表示されたら、パスワードを入力します。

gcloud sql connect my-cloudsql-instance --user=root

想定される出力:

$gcloud sql connect my-cloudsql-instance --user=root
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                           
Connecting to database with SQL user [root].Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 71
Server version: 8.4.4-google (Google)

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Ctrl+D キーを押すか、exit と入力して mysql セッションを終了します。

exit

Gemini Enterprise Agent Platform の統合を有効にする

Gemini Enterprise Agent Platform の統合を有効にするために、必要な IAM ロールを Cloud SQL サービス アカウントに付与します。

Cloud SQL サービス アカウントのメールアドレスを取得し、環境変数としてエクスポートします。

SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL

Cloud SQL サービス アカウントに roles/aiplatform.user ロールを付与します。

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
  --role="roles/aiplatform.user"

インスタンスの作成と構成の詳細については、Cloud SQL のドキュメント(こちら)をご覧ください。

5. データベースを準備する

データベースを作成し、ベクトル サポートを有効にします。

データベースを作成

quickstart_db という名前のデータベースを作成します。 データベースは、データベース クライアント(mysql など)、Google Cloud CLI、Cloud SQL Studio を使用して作成できます。このステップでは、gcloud を使用します。

Cloud Shell で次のコマンドを実行して、データベースを作成します。

gcloud sql databases create quickstart_db --instance=my-cloudsql-instance

6. データを読み込む

データベースにテーブルを作成し、CSV 形式で Cloud Storage の公開バケットに保存されている架空の Cymbal Store データセット ファイルを使用してデータを読み込みます。

Cloud Shell は、データベースに接続し、すべてのオブジェクトを作成してデータを読み込むためのメイン環境になります。

Cloud Shell のパブリック IP を Cloud SQL インスタンスの承認済みネットワークのリストに追加します。

Cloud Shell で次のコマンドを実行します。

gcloud sql instances patch my-cloudsql-instance --authorized-networks=$(curl ifconfig.me)

セッションが失われた場合、リセットした場合、または別のツールから作業する場合は、CLOUDSQL_PASSWORD 変数を再度エクスポートします。

export CLOUDSQL_PASSWORD=...your password defined for the instance...

必要なデータベース オブジェクトを作成します。mysql と curl を組み合わせて使用して、一般公開ソースからスキーマをダウンロードして適用します。

Cloud Shell で次のコマンドを実行します。

export INSTANCE_IP=$(gcloud sql instances describe my-cloudsql-instance --format="value(ipAddresses.ipAddress)")
curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_mysql_schema.sql | mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

コマンドの内訳。前の手順では、データベースに接続し、SQL スクリプトを実行してテーブル、インデックス、シーケンスを作成しました。

次に、curl と mysql を実行して、cymbal_products データでデータベースを入力します。

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_products.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_products FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

cymbal_stores を続行します。

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_stores.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_stores FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

また、各ストアの各商品の数を表す cymbal_inventory も完成させます。

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_inventory.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_inventory FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

省略可: 独自のサンプル データセットがある場合は、Google Cloud コンソールのインポート ツールを使用して、互換性のある CSV ファイルをインポートできます。

7. エンベディングを作成する

Gemini Enterprise Agent Platform の text-embedding-005 モデルを使用して商品紹介のエンベディングを構築し、ベクトルデータとして保存します。

ベクトル データを保存するには、Cloud SQL インスタンスでベクトル機能を有効にする必要があります。

Cloud Shell で次のコマンドを実行します。

gcloud sql instances patch my-cloudsql-instance \
--database-flags=cloudsql_vector=on

データベースに接続します。

mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

エンベディング関数を使用して、cymbal_products テーブルに新しい列 embedding を作成します。新しい列には、product_description 列のテキストに基づくベクトル エンベディングが格納されます。

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) using varbinary;
UPDATE cymbal_products SET embedding = mysql.ml_embedding('text-embedding-005', product_description);

注: 通常、2,000 行のエンベディング生成は 5 分以内に完了します。

MySQL セッションを終了します。

exit

8. 類似性検索を実行する

商品紹介用に計算されたベクトル エンベディングと検索クエリのエンベディングを比較して、類似性検索を実行します。

SQL クエリは、コマンドラインまたは Cloud SQL Studio から実行できます。Cloud SQL Studio を使用すると、出力に複数の行を含む長い SQL ステートメントをより簡単に編集して実行できます。

Cloud SQL Studio の MySQL ユーザーを作成する

Cloud SQL Studio で使用できる新しいデータベース ユーザーが必要です。root ユーザーに使用したパスワードと同じパスワードを使用して、組み込みタイプのユーザー student を作成します。

Cloud Shell で、次のコマンドを実行します。

gcloud sql users create student  --instance=my-cloudsql-instance --password=$CLOUDSQL_PASSWORD --host=%

Cloud SQL Studio を起動する

  1. Google Cloud コンソールで Cloud SQL インスタンスに移動し、my-cloudsql-instance をクリックします。

Google Cloud コンソールの Cloud SQL インスタンスのリスト

  1. ナビゲーション メニューで [Cloud SQL Studio] をクリックします。

Cloud SQL Studio メニュー項目

  1. 認証ダイアログで、データベース名と認証情報を入力します。
    • データベース: quickstart_db
    • ユーザー: student
    • パスワード:
  2. [認証] をクリックします。

Cloud SQL Studio の認証ダイアログ

  1. [無題のクエリ] タブをクリックして、SQL エディタを開きます。

Cloud SQL Studio の SQL エディタタブ

クエリを実行

クエリを実行して、お客様のクエリ「この地域でよく育つ果樹は何ですか?」に最も関連性の高い上位 5 つの商品を取得します。

cosine_distance 関数を使用してリクエストに最も適した上位 5 つのアイテムを選択するために実行できるクエリは次のとおりです。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cosine_distance(cp.embedding ,@query_vector) as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

Cloud SQL Studio でクエリを入力し、[実行] をクリックします(または、sql セッションでクエリを実行します)。

Cloud SQL Studio で SQL クエリを実行する

クエリは、コサイン距離で並べ替えられた一致する商品を返します。

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.13 sec)

cosine_distance 関数を使用した場合、クエリの実行時間は約 0.13 秒です。

approx_distance 関数を使用して KNN 検索を使用する同じクエリを実行します。エンベディングの ANN インデックスがない場合、バックグラウンドで自動的に完全一致検索に戻ります。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

クエリによって返された商品のリストは次のとおりです。

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set, 1 warning (0.12 sec)

クエリの実行には 0.12 秒しかかかりませんでした。KNN の厳密な cosine_distance 関数と同じ結果が得られました。

この関数の詳細については、Cloud SQL for MySQL のドキュメントをご覧ください。

9. 取得したデータを使用して LLM のレスポンスを改善する

Gemini Enterprise Agent Platform の基盤言語モデルへのプロンプトで、クエリ結果をグラウンディングされたコンテキストとして渡すことで、クライアント アプリケーションに対する生成 AI のレスポンスを改善します。

手順は次のとおりです。

  1. Cloud SQL のベクトル検索結果から JSON ペイロードを生成します。
  2. Agent Platform Studio でプロンプトをテストします。
  3. google_ml 統合を使用して、SQL からエンドツーエンドのプロンプトを直接実行します。

JSON 形式で出力を生成する

クエリを変更して、結果を JSON としてフォーマットし、1 行を返します。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
WITH trees as (
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id as product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1)
SELECT json_arrayagg(json_object('product_name',product_name,'description',description,'sale_price',sale_price,'zip_code',zip_code,'product_id',product_id)) FROM trees;

想定される JSON 出力:

[{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}]

Agent Platform Studio でプロンプトを実行する

生成された JSON を Agent Platform Studio の生成モデルへのプロンプトのコンテキストとして指定します。

  1. Google Cloud コンソールで Agent Platform Studio を開きます。

Agent Platform Studio のナビゲーション

  1. Agent Platform Studio に次のプロンプトを入力します。

Agent Platform Studio でプロンプトを入力する

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
<JSON_OUTPUT>
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

は、クエリからの JSON レスポンスに置き換えます。

You are a friendly advisor helping to find a product based on the customer's needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Here is the list of products:
{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.

Agent Platform Studio のプロンプト

  1. プロンプトを実行します。

Agent Platform Studio のプロンプトの結果

回答には、木と場所に関する情報に基づいてモデルが外部ソースから取得した価格、説明、補足情報が含まれます。

SQL でプロンプトを実行する

また、Cloud SQL AI 統合と Gemini Enterprise Agent Platform を使用して、生成モデルから SQL 内で直接レスポンスを取得することもできます。

まず、モデルを登録します。

  1. レスポンスを生成する gemini-3.5-flash モデルを登録します( は実際のプロジェクト ID に置き換えます)。
CALL
  mysql.ml_create_model_registration(
  'gemini-3.5-flash',
  'https://aiplatform.googleapis.com/v1/projects/<PROJECT_ID>/locations/global/publishers/google/models/gemini-3.5-flash:generateContent',
  'google',
  'GENERIC',
  NULL,
  'auth_type_cloudsql_service_agent_iam',
  NULL, NULL, NULL, NULL);

また、Cloud SQL AI と Gemini Enterprise Agent Platform の統合を使用して、データベースで SQL を直接使用して生成モデルから同様のレスポンスを取得することもできます。

これで、生成された JSON 結果を含むサブクエリを SQL で使用して、生成 AI テキスト モデルのプロンプトの一部として指定できるようになりました。

データベースへの mysql セッションまたは Cloud SQL Studio セッションでクエリを実行します。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
WITH trees AS (
SELECT
        cp.product_name,
        cp.product_description AS description,
        cp.sale_price,
        cs.zip_code,
        cp.uniq_id AS product_id
FROM
        cymbal_products cp
JOIN cymbal_inventory ci ON
        ci.uniq_id = cp.uniq_id
JOIN cymbal_stores cs ON
        cs.store_id = ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
         (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1),
prompt AS (
SELECT
       CONCAT( 'You are a friendly advisor helping to find a product based on the customer''s needs.
Based on the client request we have loaded a list of products closely related to search.
The list in JSON format with list of values like {"product_name":"name","product_description":"some description","sale_price":10}
Here is the list of products:', json_arrayagg(json_object('product_name',trees.product_name,'description',trees.description,'sale_price',trees.sale_price,'zip_code',trees.zip_code,'product_id',trees.product_id)) , 'The customer asked "What kind of fruit trees grow well here?"
You should give information about the product, price and some supplemental information') AS prompt_text
FROM
        trees),
response AS (
SELECT
       mysql.ML_PREDICT_ROW('gemini-3.5-flash',
        json_object('contents',
        json_object('role',
        'user',
        'parts',
        json_array(
        json_object('text',
        prompt_text))))) AS resp
FROM
        prompt)
SELECT
JSON_EXTRACT(resp, '$.candidates[0].content.parts[0].text')
FROM
        response;

出力例を次に示します。出力は、モデルのバージョンとパラメータによって異なる場合があります。

"Hello there! I'd be happy to help you find the perfect fruit tree for your space. \n\nBased on your area, a wonderful option we currently have in stock is the **Malus Domestica** (the classic Apple Tree)!\n\nHere are the key details:\n\n* **Product Name:** Malus Domestica (Classic Apple Tree)\n* **Price:** $100.00\n\n### Why it's a great choice:\n* **Beautiful Seasonal Foliage:** It features vibrant green leaves during the summer that turn into gorgeous shades of red, orange, and yellow in the autumn. \n* **Shade & Size:** It grows to approximately 30 feet tall, making it a strong, durable tree that offers excellent shade for your yard alongside delicious fresh fruit.\n* **Growing Conditions:** It thrives best in cool, moist climates with well-draining, loamy soil and is ideal for USDA Hardiness Zones 4–8.\n\n### Supplemental Care Tips:\n* **Planting Location:** Choose a spot that gets full sunlight (at least 6 hours a day) to ensure maximum fruit production.\n* **Soil:** Make sure the soil is rich and loamy with good drainage so the roots stay healthy.\n* **Cross-Pollination:** Apple trees often produce a higher yield when planted near another compatible apple tree variety, so if you have extra space, adding a companion tree in the future can boost your harvest!\n\nLet me know if you have any questions about planting or care, or if you'd like help adding this to your cart!"

出力はマークダウン形式で提供されます。

10. 最近傍インデックスを作成する

数百万のベクトルを含む大規模なデータセットの場合、ベクトル検索にはかなりのコンピューティング リソースが必要になることがあります。クエリのパフォーマンスを向上させるには、ベクトル エンベディングにインデックスを作成します。

ScaNN インデックスを作成する

テストでは ScaNN インデックス タイプを試してみます。

埋め込み列のインデックスを構築するには、埋め込み列の距離測定を定義する必要があります。パラメータの詳細については、ドキュメントをご覧ください。

CREATE VECTOR INDEX cymbal_products_embedding_idx ON cymbal_products(embedding) USING SCANN DISTANCE_MEASURE=COSINE;

回答を比較する

ベクトル検索クエリをもう一度実行して、結果を確認します。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

予想される出力:

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.08 sec)

パフォーマンスの改善はわずかですが、このような小さなデータセットでは想定内です。数百万のベクトルを含む大規模なデータセットでは、この違いがより顕著になります。

EXPLAIN コマンドを使用して実行プランを確認します。

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
EXPLAIN ANALYZE SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') as distance
FROM
        cymbal_products cp
JOIN cymbal_inventory ci on
        ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
        cs.store_id=ci.store_id
        AND ci.inventory>0
        AND cs.store_id = 1583
ORDER BY
        distance ASC
LIMIT 5;

実行プラン(抜粋):

...
-> Nested loop inner join  (cost=443 rows=5) (actual time=1.14..1.18 rows=5 loops=1)
                                -> Vector index scan on cp  (cost=441 rows=5) (actual time=1.1..1.1 rows=5 loops=1)
                                -> Single-row index lookup on cp using PRIMARY (uniq_id=cp.uniq_id)  (cost=0.25 rows=1) (actual time=0.0152..0.0152 rows=1 loops=5)

...

cp テーブル(cymbal_products テーブルのエイリアス)のベクトル インデックス スキャンを示しています。

独自のデータで試したり、さまざまな検索クエリをテストして、MySQL でのセマンティック検索の仕組みを確認したりできます。

11. 環境をクリーンアップする

Cloud SQL インスタンスを削除します。

ラボの終了時に Cloud SQL インスタンスを破棄します。

接続が切断され、以前の設定がすべて失われた場合は、Cloud Shell でプロジェクトと環境変数を定義します。

export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)

インスタンスを削除します。

gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID

想定されるコンソール出力:

student@cloudshell:~$ gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID
All of the instance data will be lost when the instance is deleted.

Do you want to continue (Y/n)?  y

Deleting Cloud SQL instance...done.                                                                                                                
Deleted [https://sandbox.googleapis.com/v1beta4/projects/test-project-001-402417/instances/my-cloudsql-instance].

12. 完了

以上で、この Codelab は完了です。

Google Cloud 学習プログラム

このラボは、「Google Cloud でのプロダクション レディな AI の開発」学習プログラムの一部です。

  • カリキュラム全体を確認して、プロトタイプから本番環境への移行をスムーズに進めましょう。
  • ハッシュタグ #ProductionReadyAI を使用して進捗状況を共有しましょう。

学習した内容

  • Cloud SQL for MySQL インスタンスをデプロイする方法
  • データベースを作成して Cloud SQL AI 統合を有効にする方法
  • データベースにデータを読み込む方法
  • Cloud SQL Studio の使用方法
  • Cloud SQL で Vertex AI エンベディング モデルを使用する方法
  • Agent Platform Studio の使用方法
  • Gemini Enterprise Agent Platform モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

同様の AlloyDB の Codelab または Cloud SQL for Postgres の Codelab を試す

アンケート

出力:

このチュートリアルをどのように使用されますか?

全体を通して読むだけ 内容を読んで演習をやり遂げる