AlloyDB AI でベクトル エンベディングを使ってみる

1. はじめに

この Codelab では、ベクトル検索と Vertex AI エンベディングを組み合わせて AlloyDB AI を使用する方法を学びます。このラボは、AlloyDB AI 機能専用のラボ コレクションの一部です。詳細については、ドキュメントの AlloyDB AI ページをご覧ください。

81802d1e350b59bb.png

前提条件

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

学習内容

  • AlloyDB クラスタとプライマリ インスタンスをデプロイする方法
  • Google Compute Engine VM から AlloyDB に接続する方法
  • データベースを作成して AlloyDB AI を有効にする方法
  • データベースにデータを読み込む方法
  • AlloyDB Studio の使用方法
  • AlloyDB で Gemini Enterprise Agent Platform エンベディング モデルを使用する方法
  • Gemini Enterprise Agent Platform Studio の使用方法
  • Gemini Enterprise Agent Platform の生成モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

必要なもの

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

2. 設定と要件

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

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

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

  1. 新しいプロジェクトを作成するか、既存のプロジェクトを再利用します。Google Cloud コンソールで新しいプロジェクトを作成するには、ヘッダーで [プロジェクトを選択] ボタンをクリックします。ポップアップ ウィンドウが開きます。

295004821bab6a87.png

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

37d264871000675d.png

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

96d86d3d5655cdbe.png

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

課金を有効にする

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

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

個人用の請求先アカウントを設定するには、Cloud コンソールでこちらに移動して課金を有効にします

注意事項:

  • このラボを完了するのにかかる Cloud リソースの費用は 3 米ドル未満です。
  • このラボの最後の手順に沿ってリソースを削除すると、それ以上の料金は発生しません。
  • 新規ユーザーは、300 米ドル分の無料トライアルをご利用いただけます。

Cloud Shell の起動

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

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

Cloud Shell をアクティブにする

または、G キーを押してから S キーを押します。このシーケンスは、Google Cloud コンソール内からアクセスした場合、またはこのリンクを使用した場合に Cloud Shell をアクティブにします。

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

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

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

3. はじめに

API を有効にする

出力:

AlloyDBCompute Engineネットワーキング サービスGemini Enterprise Agent Platform を使用するには、Google Cloud プロジェクトでそれぞれの API を有効にする必要があります。

API の有効化

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

gcloud config set project [YOUR-PROJECT-ID]

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

PROJECT_ID=$(gcloud config get-value project)

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

gcloud services enable alloydb.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 alloydb.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. AlloyDB をデプロイする

AlloyDB クラスタを作成する前に、VPC で使用可能なプライベート IP 範囲を割り振り、将来の AlloyDB インスタンスで使用できるようにします。ない場合は、作成して内部 Google サービスで使用されるように割り当てる必要があります。その後、クラスタとインスタンスを作成できるようになります。

プライベート IP 範囲を作成する

AlloyDB の VPC でプライベート サービス アクセス構成を構成する必要があります。ここでは、プロジェクトに「デフォルト」の VPC ネットワークがあり、すべてのアクションで使用されることを前提としています。

プライベート IP 範囲を作成します。

gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default

割り振られた IP 範囲を使用してプライベート接続を作成します。

gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default

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

student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \
    --global \
    --purpose=VPC_PEERING \
    --prefix-length=24 \
    --description="VPC private service access" \
    --network=default
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range].

student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \
    --service=servicenetworking.googleapis.com \
    --ranges=psa-range \
    --network=default
Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully.

student@cloudshell:~ (test-project-402417)$

AlloyDB クラスタを作成する

us-central1 リージョンに AlloyDB クラスタを作成する

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

export PGPASSWORD=`openssl rand -hex 16`

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

student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`

後で使用できるように PostgreSQL のパスワードをメモしておきます。

echo $PGPASSWORD

このパスワードは、後で postgres ユーザーとしてインスタンスに接続するために必要になります。このパスワードは、以降の手順で使用するために保存します。

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

student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD
bbefbfde7601985b0dee5723 (Note: Yours will be different!)

無料トライアル クラスタを作成する

AlloyDB を使用したことがない場合は、無料のトライアル クラスタを作成できます。

リージョンとクラスタ名の環境変数を設定します。

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

コマンドを実行してクラスタを作成します。

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL

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

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION \
    --subscription-type=TRIAL
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

同じ Cloud Shell セッションで、クラスタの AlloyDB プライマリ インスタンスを作成します。切断された場合は、リージョンとクラスタ名の環境変数を再度定義する必要があります。

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

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

student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=8 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

AlloyDB Standard クラスタを作成する

プロジェクトで最初の AlloyDB クラスタでない場合は、標準クラスタの作成に進みます。無料トライアル クラスタをすでに作成している場合は、この手順をスキップしてください。

リージョンとクラスタ名の環境変数を設定します。

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01

コマンドを実行してクラスタを作成します。

gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION

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

export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud alloydb clusters create $ADBCLUSTER \
    --password=$PGPASSWORD \
    --network=default \
    --region=$REGION 
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.                                                                                                                                                                                                                                                           

同じ Cloud Shell セッションで、クラスタの AlloyDB プライマリ インスタンスを作成します。切断された場合は、リージョンとクラスタ名の環境変数を再度定義する必要があります。

gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --cluster=$ADBCLUSTER

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

student@cloudshell:~ (test-project-402417)$ gcloud alloydb instances create $ADBCLUSTER-pr \
    --instance-type=PRIMARY \
    --cpu-count=2 \
    --region=$REGION \
    --availability-type ZONAL \
    --cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.                                                                                                                                                                                                                                                     

5. AlloyDB に接続する

AlloyDB はプライベート接続のみを使用してデプロイされるため、データベースを操作するには PostgreSQL クライアントがインストールされた Compute Engine VM が必要です。

GCE VM をデプロイする

AlloyDB クラスタと同じリージョンと VPC に GCE VM を作成します。

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

export ZONE=us-central1-a
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-13 AND family!=debian-13-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

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

student@cloudshell:~ (test-project-402417)$ export ZONE=us-central1-a
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-13 AND family!=debian-13-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/zones/us-central1-a/instances/instance-1].
NAME: instance-1
ZONE: us-central1-a
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE: 
INTERNAL_IP: 10.128.0.2
EXTERNAL_IP: 34.71.192.233
STATUS: RUNNING

Postgres Client をインストールする

デプロイされた VM に PostgreSQL クライアント ソフトウェアをインストールします。

VM に接続します。

gcloud compute ssh instance-1 --zone=us-central1-a

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

student@cloudshell:~ (test-project-402417)$ gcloud compute ssh instance-1 --zone=us-central1-a
Updating project ssh metadata...working..Updated [https://www.googleapis.com/compute/v1/projects/test-project-402417].                                                                                                                                                         
Updating project ssh metadata...done.                                                                                                                                                                                                                                              
Waiting for SSH key to propagate.
Warning: Permanently added 'compute.5110295539541121102' (ECDSA) to the list of known hosts.
Linux instance-1 6.12.101+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.101-1 (2026-08-05) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
student@instance-1:~$ 

VM 内でソフトウェア実行コマンドをインストールします。

sudo apt-get update
sudo apt-get install --yes postgresql-client

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

student@instance-1:~$ sudo apt-get update
sudo apt-get install --yes postgresql-client
Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B]
Get:2 file:/etc/apt/mirrors/debian-security.list Mirrorlist [39 B]                      
Hit:3 https://deb.debian.org/debian trixie InRelease                                    
Get:4 https://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:5 https://deb.debian.org/debian trixie-backports InRelease [54.0 kB]
Get:6 https://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
Hit:10 https://packages.cloud.google.com/apt google-compute-engine-trixie-stable InRelease
...redacted...
update-alternatives: using /usr/share/postgresql/17/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-client (17+278) ...
Processing triggers for man-db (2.13.1-1) ...
Processing triggers for libc-bin (2.41-12+deb13u3) ...

インスタンスに接続する

psql を使用して VM からプライマリ インスタンスに接続します。

instance-1 VM への SSH セッションが開いている Cloud Shell の同じタブで、

メモした AlloyDB パスワード(PGPASSWORD)の値と AlloyDB クラスタ ID を使用して、GCE VM から AlloyDB に接続します。

export PGPASSWORD=<Noted password>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"

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

student@instance-1:~$ export PGPASSWORD=CQhOi5OygD4ps6ty
student@instance-1:~$ export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"
psql (17.10 (Debian 17.10-0+deb13u1), server 17.9)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: postgresql)
Type "help" for help.

postgres=>

psql セッションを閉じます。

exit

6. データベースの準備

データベースを作成し、Agent Platform AI 統合を有効にして、データベース オブジェクトを作成し、データをインポートします。

AlloyDB に必要な権限を付与する

AlloyDB サービス エージェントに Gemini Enterprise Agent Platform の権限を追加します。

上部の「+」記号を選択して、別の Cloud Shell タブを開きます。

abc505ac4d41f24e.png

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

PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

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

student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-11039]
student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"
Updated IAM policy for project [test-project-001-402417].
bindings:
- members:
  - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com
  role: roles/aiplatform.user
- members:
...
etag: BwYIEbe_Z3U=
version: 1
 

タブに実行コマンド「exit」を入力して、タブを閉じます。

exit

データベースを作成する

データベース作成のクイックスタート。

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

データベースを作成します。

psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"

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

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"
CREATE DATABASE
student@instance-1:~$  

Vertex AI の統合を有効にする

Vertex AI のインテグレーションとデータベースの pgvector 拡張機能を有効にします。

GCE VM で次のコマンドを実行します。

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"

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

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"
CREATE EXTENSION
CREATE EXTENSION
student@instance-1:~$ 

データをインポート

準備したデータをダウンロードして、新しいデータベースにインポートします。

GCE VM で次のコマンドを実行します。

gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"

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

student@instance-1:~$ gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
SET
SET
SET
SET
SET
 set_config 
------------
 
(1 row)
SET
SET
SET
SET
SET
SET
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE TABLE
ALTER TABLE
CREATE SEQUENCE
ALTER TABLE
ALTER SEQUENCE
ALTER TABLE
ALTER TABLE
ALTER TABLE
student@instance-1:~$ gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
COPY 941
student@instance-1:~$ gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
COPY 263861
student@instance-1:~$ gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"
COPY 4654
student@instance-1:~$

7. エンベディングを計算する

データをインポートすると、商品データは cymbal_products テーブルに、各店舗の在庫数は cymbal_inventory テーブルに、店舗のリストは cymbal_stores テーブルに格納されます。商品の説明に基づいてベクトルデータを計算する必要があります。そのために google_ml.embedding などの関数を使用できます。使用されているテクノロジーについて詳しくは、ドキュメントをご覧ください。

数行のエンベディングを生成するのは簡単ですが、数千行ある場合は効率的に行うにはどうすればよいですか?このセクションでは、大きなテーブルのエンベディングを生成して管理する方法について説明します。さまざまなオプションと手法については、ガイドをご覧ください。

高速エンベディング生成を有効にする

AlloyDB インスタンスの IP と postgres パスワードを使用して、VM から psql を使用してデータベースに接続します。

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"

google_ml_integration 拡張機能のバージョンを確認します。

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

バージョンは 1.5.2 以降である必要があります。出力例を次に示します。

quickstart_db=> SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
 extversion 
------------
 1.6
(1 row)

デフォルトのバージョンは 1.6 以降ですが、インスタンスに古いバージョンが表示されている場合は、更新が必要になる可能性があります。インスタンスのメンテナンスが無効になっているかどうかを確認します。

google_ml_integration.enable_faster_embedding_generation データベース フラグがオンに設定されていることを確認します。同じ psql セッションで、フラグの値を確認します。

show google_ml_integration.enable_faster_embedding_generation;

フラグが正しい位置にある場合、次のような出力が表示されます。

quickstart_db=> show google_ml_integration.enable_faster_embedding_generation;                          
 google_ml_integration.enable_faster_embedding_generation 
----------------------------------------------------------
 on
(1 row)

フラグの値が「off」と表示されている場合は、インスタンスを更新する必要があります。ドキュメントに記載されているように、ウェブ コンソールまたは gcloud コマンドを使用して行います。

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

exit;

gcloud を使用してフラグを更新するには、次のコマンドを実行します。

export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
gcloud beta alloydb instances update $ADBCLUSTER-pr \
   --database-flags google_ml_integration.enable_faster_embedding_generation=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY

数分かかることがありますが、最終的にはフラグの値が「オン」に切り替わります。その後、次の手順に進むことができます。

エンベディング列を作成する

psql を使用してデータベースに接続し、cymbal_products テーブルのエンベディング関数で使用されるベクトル データ型の仮想列を作成します。

psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"

データベースに接続した後の psql セッションで、次のコマンドを実行します。

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768);

このコマンドは、将来のエンベディングの仮想列を作成します。

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

quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN embedding vector(768);
ALTER TABLE
quickstart_db=> 

50 行のバッチでエンベディングを生成します。同じ psql セッションで、次のコマンドを実行します。

タイミングを有効にして、所要時間を測定します。

\timing

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

CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'cymbal_products',
    content_column => 'product_description',
    embedding_column => 'embedding',
    batch_size => 50
);

コンソール出力には、エンベディングの生成に 2 秒未満かかったことが示されています。

quickstart_db=> CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'cymbal_products',
    content_column => 'product_description',
    embedding_column => 'embedding',
    batch_size => 50
);
NOTICE:  Initialize embedding completed successfully for table cymbal_products
CALL
Time: 1458.704 ms (00:01.459)
quickstart_db=>

さまざまなバッチサイズを試して、実行時間が変化するかどうかを確認できます。

デフォルトでは、対応する product_description 列が更新された場合や、新しい行全体が挿入された場合、エンベディングは更新されません。ただし、パラメータ incremental_refresh_mode を設定することで、これを行うことができます。

product_embeddings」という列を作成し、自動的に更新できるようにします。

ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768);
CALL ai.initialize_embeddings(
    model_id => 'text-embedding-005',
    table_name => 'cymbal_products',
    content_column => 'product_description',
    embedding_column => 'product_embedding',
    batch_size => 50,
    incremental_refresh_mode => 'transactional'
);

テーブルに新しい行を挿入します。

INSERT INTO "cymbal_products" ("uniq_id", "crawl_timestamp", "product_url", "product_name", "product_description", "list_price", "sale_price", "brand", "item_number", "gtin", "package_size", "category", "postal_code", "available", "product_embedding", "embedding") VALUES ('fd604542e04b470f9e6348e640cff794', NOW(), 'https://example.com/new_product', 'New Cymbal Product', 'This is a new cymbal product description.', 199.99, 149.99, 'Example Brand', 'EB123', '1234567890', 'Single', 'Cymbals', '12345', TRUE, NULL, NULL);

テーブルに対してクエリを実行して、2 つのエンベディング列を比較します。

SELECT uniq_id,embedding, (product_embedding::real[])[1:5] as product_embedding  FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';

出力には、product_embedding が自動的に入力され、embedding が空のままになっていることが示されます。

quickstart_db=> SELECT uniq_id,embedding, (product_embedding::real[])[1:5] as product_embedding  FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
             uniq_id              | embedding |                       product_embedding                       
----------------------------------+-----------+---------------------------------------------------------------
 fd604542e04b470f9e6348e640cff794 |           | {0.015003494,-0.005349732,-0.059790313,-0.0087091,-0.0271452}
(1 row)

Time: 3.295 ms

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

AlloyDB AI を使用して、生成されたベクトル エンベディングに基づいて類似性検索を実行します。

SQL クエリは、同じ psql コマンドライン インターフェースから実行できます。また、AlloyDB Studio から実行することもできます。複数行の複雑な出力は、AlloyDB Studio でより適切に処理されます。

AlloyDB Studio に接続する

AlloyDB Studio を開く手順は次のとおりです。

  1. Google Cloud コンソールで、AlloyDB for PostgreSQL のクラスタ ページに移動します。
  2. プライマリ インスタンスを選択して、ウェブ インターフェースを開きます。

1d7298e7096e7313.png3. 左側の [AlloyDB Studio] をクリックします。

a33131c72ad29478.png

  1. quickstart_db データベースとユーザー postgres を選択し、メモしたパスワードを入力して、[認証] をクリックします。

4f26532ecdb5bade.png

この操作により、AlloyDB Studio インターフェースが開きます。

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

6696bc771fab9983.png

次の図に示すように、SQL コマンドを実行できるエディタが開きます。

ae34288e5bf237c7.png

コマンドライン psql を使用する場合は、別の方法で、前の章で説明したように VM SSH セッションからデータベースに接続します。

クエリを実行して、クライアントのリクエストに最も関連性の高い利用可能な商品のリストを取得します。Gemini Enterprise Agent Platform のエンベディング モデルに渡される検索フレーズ(プロダクトのエンベディングの生成に使用したフレーズと同じ)。「この場所でよく育つ果樹は何ですか?」という質問に対するベクトル値を取得するために使用されます。

クエリを実行します。

SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (cp.embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::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 10;

想定される出力は次のとおりです。

quickstart_db=> SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (cp.embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::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 10;
      product_name       |                                   description                                    | sale_price | zip_code |      distance       
-------------------------+----------------------------------------------------------------------------------+------------+----------+---------------------
 Cherry Tree             | This is a beautiful cherry tree that will produce delicious cherries. It is an d |      75.00 |    93230 | 0.43922018972266397
 Meyer Lemon Tree        | Meyer Lemon trees are California's favorite lemon tree! Grow your own lemons by  |         34 |    93230 |  0.4685112926118228
 Toyon                   | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 |  0.4835677149651668
 California Lilac        | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d |       5.00 |    93230 |  0.4947204525907498
 California Peppertree   | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e |      25.00 |    93230 |  0.5054166905547247
 California Black Walnut | This is a beautiful walnut tree that can grow to be over 80 feet tall. It is a d |     100.00 |    93230 |  0.5084219510932597
 California Sycamore     | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 |  0.5140519790508755
 Coast Live Oak          | This is a beautiful oak tree that can grow to be over 100 feet tall. It is an ev |     500.00 |    93230 |  0.5143126438081371
 Fremont Cottonwood      | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i |     200.00 |    93230 |  0.5174774727252058
 Madrone                 | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an |      50.00 |    93230 |  0.5227400803389093

検索フレーズと意味的に近い説明を持つ 10 個の商品が、類似性の高い順に並んで表示されます。

9. 対応能力を強化

クエリの結果を使用してクライアント アプリケーションへのレスポンスを改善し、提供されたクエリ結果を基盤となる生成言語モデルへのプロンプトの一部として使用して、意味のある出力を準備できます。

そのため、ベクトル検索の上位結果を含む JSON を生成し、その生成された JSON を Agent Platform の Gen AI モデルへのプロンプトに追加して、意味のある出力を生成します。最初のステップで JSON を生成し、次のステップで Agent Platform Studio でテストします。最後のステップでは、すべてを 1 つの SQL ステートメントに組み込み、アプリケーションで使用できるようにします。

JSON 形式で出力を生成する

クエリを変更して、JSON 形式で出力を生成し、Agent Platform に渡す行を 1 つだけ返します。

クエリを実行します。

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
        (cp.embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

出力の JSON:

[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]

Vertex AI Studio でプロンプトを実行する

生成された JSON を使用して、Vertex AI Studio の生成 AI モデルへのプロンプトの一部として指定します。

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

154dc1a290c37f.jpeg

インターフェースにプロンプトを入力します。

fd3abd6062009ee6.jpeg

次のプロンプトを入力します。

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:

{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}

The customer asked "What tree is growing the best here?"

You should give information about the product, price and some supplemental information

edeea32a69d81aee.jpeg

プロンプトを実行した結果は次のとおりです。

831038ea1d819be6.jpeg

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

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

同様の結果は、AlloyDB AI と Gemini Enterprise Agent Platform のインテグレーションを使用して、データベースで SQL を直接使用して生成モデルから同じレスポンスを取得することでも実現できます。gemini-3.6-flash モデルを使用する前に、登録する必要があります。

gemini-3.6-flash モデルを登録します。

AlloyDB Studio で次のコマンドを実行します。

CALL google_ml.create_model(
model_id => 'gemini-3.6-flash',
model_request_url => 'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.6-flash:generateContent',
model_provider => 'google',
model_type => 'llm'
);

登録済みモデルのリストは、google_ml.model_info_view から情報を選択することでいつでも確認できます。

SELECT model_id,model_type FROM google_ml.model_info_view WHERE model_id ILIKE '%flash%';

出力例を次に示します。

quickstart_db=> SELECT model_id,model_type FROM google_ml.model_info_view WHERE model_id ILIKE '%flash%';
       model_id        | model_type 
-----------------------+------------
 gemini-3.6-flash      | llm
 gemini-2.0-flash      | llm
 gemini-2.5-flash      | llm
 gemini-2.0-flash-lite | llm
 gemini-2.5-flash-lite | llm
(5 rows)

SQL を使用して、サブクエリで生成された JSON を gemini-3.6-flash モデルのプロンプトの一部として使用できるようになりました。

psql セッションまたは AlloyDB Studio セッションで、次のクエリを実行します。

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
        (cp.embedding <=> embedding('text-embedding-005',
        'What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1),
prompt AS (
SELECT
        '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_agg(trees) || '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
        google_ml.predict_row( model_id =>'gemini-3.6-flash',
        request_body => json_build_object('contents',
        json_build_object('role',
        'user',
        'parts',
        json_build_object('text',
        prompt_text))))->'candidates'->0->'content'->'parts'->0->'text' AS resp
FROM
        prompt)
SELECT
REPLACE(resp::text, '\n', CHR(10))
FROM
        response;

想定される出力は次のとおりです。生成 AI モデルの非決定論的な性質により、出力が異なる場合があります。

"Hello there! I'd be delighted to help you pick out a wonderful fruit tree for your space. Based on our local selection, a fantastic option that grows very well is the **Cherry Tree**! Here are the details on this beautiful tree: * **Product:** Cherry Tree * **Price:** $75.00 ### Why it's a great choice: * **Delicious Harvest:** It produces tasty, fresh cherries right in your backyard. * **Size & Benefits:** It's a deciduous tree that grows to about 15 feet tall, making it ideal for providing both lovely shade and a bit of privacy. * **Year-Round Beauty:** It features lush, dark green leaves throughout the summer that transform into a stunning red in the autumn. * **Growing Requirements:** Cherry trees thrive best in cool, moist climates with sandy soil, and are perfectly suited for USDA hardiness zones 4 through 9. Please let me know if you have any questions about planting or if you'd like help adding this to your order!"

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

このデータセットは小さいため、レスポンス時間は主に Gemini Enterprise Agent Platform のモデルとのやり取りに依存します。ただし、数百万のベクトルをクエリすると、ベクトル検索自体が応答時間の大部分を消費し、データベースの負荷が増加する可能性があります。検索パフォーマンスを改善するには、ベクトル インデックスを構築します。

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

ScaNN インデックスを構築するには、追加の拡張機能を有効にする必要があります。alloydb_scann 拡張機能は、Google ScaNN アルゴリズムを使用して近似最近傍(ANN)ベクトル インデックスを操作するためのインターフェースを提供します。

AlloyDB Studio で実行します。

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

インデックスは MANUAL モードまたは AUTO モードで作成できます。MANUAL モードはデフォルトで有効になっており、他のインデックスと同様にインデックスを作成して維持できます。ただし、AUTO モードを有効にすると、ユーザー側でメンテナンスを必要としないインデックスを作成できます。すべてのオプションの詳細については、ドキュメントをご覧ください。AUTO モードでインデックスを作成するのに十分な行がないため、MANUAL として作成します。

AlloyDB Studio で実行します。

CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
  USING scann (embedding cosine)
  WITH (num_leaves=10, max_num_levels = 1);

インデックス パラメータのチューニングについては、ドキュメントをご覧ください。

予想される出力:

quickstart_db=> CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
  USING scann (embedding cosine)
  WITH (num_leaves=10, max_num_levels = 1);
CREATE INDEX
quickstart_db=>

回答を比較する

セマンティック検索で上位の値を取得するために使用したクエリを繰り返します。

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
        (cp.embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

予想される出力:

[{"product_name":"Cherry Tree","description":"This is a beautiful cherry tree that will produce delicious cherries. It is an d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}]

出力に同じ「Cherry Tree」が表示されます。

インデックスの使用状況を確認します。

EXPLAIN (analyze) 
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
        (cp.embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

想定される出力(明確にするために記すと):

...
 Aggregate  (cost=27.24..27.25 rows=1 width=32) (actual time=0.964..0.965 rows=1 loops=1)
   ->  Subquery Scan on trees  (cost=18.91..27.23 rows=1 width=142) (actual time=0.953..0.954 rows=1 loops=1)
         ->  Limit  (cost=18.91..27.22 rows=1 width=158) (actual time=0.948..0.949 rows=1 loops=1)
               ->  Nested Loop  (cost=18.91..7126.86 rows=855 width=158) (actual time=0.948..0.948 rows=1 loops=1)
                     ->  Nested Loop  (cost=18.63..7103.59 rows=855 width=907) (actual time=0.931..0.931 rows=1 loops=1)
                           ->  Index Scan using cymbal_products_embeddings_scann on cymbal_products cp  (cost=18.21..343.15 rows=942 width=903) (actual time=0.906..0.908 rows=2 loops=1)
                                 Order By: (embedding <=> '[-0.106554024,0.035774965,-0.027267234,-0.045653425,-0.03286045,0.02124319...

出力から、クエリが「cymbal_products の cymbal_products_embeddings_scann を使用したインデックス スキャン」を使用していることがわかります。

クエリは、インデックスを構築する前に検索結果の上部に表示されていたのと同じ Cherry ツリーを返します。近似最近傍(ANN)インデックスは、絶対精度と検索速度をトレードオフするため、インデックス ベースのクエリでは、インデックスなしの完全一致検索とは若干異なる上位結果が返されることがあります。ただし、ベクトル インデックスを使用すると、高い精度を維持しながらパフォーマンスを大幅に向上させることができます。

さらに詳しく調べるには、他のベクトル インデックス タイプを試すか、ドキュメント ページで LangChain 統合を使用した他のラボや例をご覧ください。

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

ラボの終了時に AlloyDB インスタンスとクラスタを破棄します。

AlloyDB クラスタとすべてのインスタンスを削除する

クラスタは force オプションで破棄され、クラスタに属するすべてのインスタンスも削除されます。

ターミナルが切断された場合は、再度接続して、Cloud Shell でプロジェクトと環境変数を定義します。

gcloud config set project <YOUR_PROJECT_ID>
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export PROJECT_ID=$(gcloud config get-value project)

クラスタを削除します。

gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force

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

student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
All of the cluster data will be lost when the cluster is deleted.

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

Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f
Deleting cluster...done.   

AlloyDB バックアップを削除する

クラスタの AlloyDB バックアップをすべて削除します。

for i in $(gcloud alloydb backups list \
  --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" \
  --format="value(name)" \
  --sort-by=~createTime) ; do \
  gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done

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

student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f
Deleting backup...done.                                                                                                                                                                                                                                                            

これで、VM を破棄できます。

GCE VM を削除する

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

export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
    --zone=$ZONE \
    --quiet

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

student@cloudshell:~ (test-project-001-402417)$ export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
    --zone=$ZONE \
    --quiet
Deleted 

12. 完了

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

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

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

学習した内容

  • AlloyDB クラスタとプライマリ インスタンスをデプロイする方法
  • Google Compute Engine VM から AlloyDB に接続する方法
  • データベースを作成して AlloyDB AI を有効にする方法
  • データベースにデータを読み込む方法
  • AlloyDB Studio の使用方法
  • AlloyDB で Gemini Enterprise Agent Platform エンベディング モデルを使用する方法
  • Gemini Enterprise Agent Platform Studio の使用方法
  • Gemini Enterprise Agent Platform の生成モデルを使用して結果を拡充する方法
  • ベクトル インデックスを使用してパフォーマンスを改善する方法

13. アンケート

出力:

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

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