矢量嵌入使用入门:AlloyDB AI

1. 简介

在此 Codelab 中,您将学习如何通过将矢量搜索与 Vertex AI 嵌入相结合来使用 AlloyDB AI。

17e86406ab251142

前提条件

  • 对 Google Cloud、控制台有基本的了解
  • 具备命令行界面和 Google Shell 方面的基本技能

学习内容

  • 如何部署 AlloyDB 集群和主实例
  • 如何从 Google Compute Engine 虚拟机连接到 AlloyDB
  • 如何创建数据库并启用 AlloyDB AI
  • 如何将数据加载到数据库
  • 如何在 AlloyDB 中使用 Vertex AI 嵌入模型
  • 如何使用 Vertex AI 生成模型丰富结果

所需条件

  • Google Cloud 账号和 Google Cloud 项目
  • 网络浏览器,例如 Chrome

2. 设置和要求

自定进度的环境设置

  1. 登录 Google Cloud 控制台,然后创建一个新项目或重复使用现有项目。如果您还没有 Gmail 或 Google Workspace 账号,则必须创建一个

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • 项目名称是此项目参与者的显示名称。它是 Google API 尚未使用的字符串。您可以随时对其进行更新。
  • 项目 ID 在所有 Google Cloud 项目中是唯一的,并且是不可变的(一经设置便无法更改)。Cloud 控制台会自动生成一个唯一字符串;通常情况下,您无需关注该字符串。在大多数 Codelab 中,您都需要引用项目 ID(通常用 PROJECT_ID 标识)。如果您不喜欢生成的 ID,可以再随机生成一个 ID。或者,您也可以尝试自己的项目 ID,看看是否可用。完成此步骤后便无法更改该 ID,并且此 ID 在项目期间会一直保留。
  • 此外,还有第三个值,即部分 API 使用的项目编号,供您参考。如需详细了解所有这三个值,请参阅文档
  1. 接下来,您需要在 Cloud 控制台中启用结算功能,以便使用 Cloud 资源/API。运行此 Codelab 应该不会产生太多的费用(如果有的话)。若要关闭资源以避免产生超出本教程范围的结算费用,您可以删除自己创建的资源或删除项目。Google Cloud 新用户符合参与 300 美元免费试用计划的条件。

启动 Cloud Shell

虽然可以通过笔记本电脑对 Google Cloud 进行远程操作,但在此 Codelab 中,您将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

Google Cloud 控制台 中,点击右上角工具栏中的 Cloud Shell 图标:

55efc1aaa7a4d3ad.png

预配和连接到环境应该只需要片刻时间。完成后,您应该会看到如下内容:

7ffe5cbb04455448.png

这个虚拟机已加载了您需要的所有开发工具。它提供了一个持久的 5 GB 主目录,并且在 Google Cloud 中运行,大大增强了网络性能和身份验证功能。您在此 Codelab 中的所有工作都可以在浏览器中完成。您无需安装任何程序。

3. 准备工作

启用 API

输出:

在 Cloud Shell 中,确保项目 ID 已设置:

gcloud config set project [YOUR-PROJECT-ID]

设置环境变量 PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

启用所有必要的服务:

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.

配置默认区域以使用 Vertex AI 嵌入模型。详细了解 Vertex AI 的可用位置。在本示例中,我们使用的是 us-central1 区域。

gcloud config set compute/region us-central1

4. 部署 AlloyDB

在创建 AlloyDB 集群之前,我们需要 VPC 中有一个可用的专用 IP 范围,以供未来的 AlloyDB 实例使用。如果没有,则需要创建一个,并将其分配给内部 Google 服务,之后我们才能创建集群和实例。

创建专用 IP 范围

我们需要在 VPC 中为 AlloyDB 配置专用服务访问配置。这里假设我们的项目中有“默认”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 12`

预期的控制台输出:

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

请记下该 PostgreSQL 密码,以备将来使用:

echo $PGPASSWORD

预期的控制台输出:

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

定义区域和 AlloyDB 集群名称。我们将使用 us-central1 区域和 alloydb-aip-01 作为集群名称:

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.                                                                                                                                                                                                                                                           

创建 AlloyDB 主实例

在同一个 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 客户端的虚拟机才能使用数据库。

部署 GCE 虚拟机

在 AlloyDB 集群所在的区域和 VPC 中创建 GCE 虚拟机。

在 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-12 AND family!=debian-12-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

预期的控制台输出:

student@cloudshell:~ (test-project-402417)$ export ZONE=us-central1-a
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-12 AND family!=debian-12-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 客户端

在已部署的虚拟机上安装 PostgreSQL 客户端软件

连接到虚拟机:

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.us-central1-a.c.gleb-test-short-001-418811.internal 6.1.0-18-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) 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:~$ 

在虚拟机内运行以下命令来安装软件:

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 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable InRelease [5146 B]
Get:2 https://packages.cloud.google.com/apt cloud-sdk-bullseye InRelease [6406 B]   
Hit:3 https://deb.debian.org/debian bullseye InRelease  
Get:4 https://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB]
Get:5 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable/main amd64 Packages [1930 B]
Get:6 https://deb.debian.org/debian bullseye-updates InRelease [44.1 kB]
Get:7 https://deb.debian.org/debian bullseye-backports InRelease [49.0 kB]
...redacted...
update-alternatives: using /usr/share/postgresql/13/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-client (13+225) ...
Processing triggers for man-db (2.9.4-2) ...
Processing triggers for libc-bin (2.31-13+deb11u7) ...

连接到实例

使用 psql 从虚拟机连接到主实例。

在同一 Cloud Shell 标签页中,打开了与 instance-1 虚拟机之间的 SSH 会话。

使用记下的 AlloyDB 密码 (PGPASSWORD) 值和 AlloyDB 集群 ID 从 GCE 虚拟机连接到 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:~$ ADBCLUSTER=alloydb-aip-01
student@instance-1:~$ REGION=us-central1
student@instance-1:~$ INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
gleb@instance-1:~$ psql "host=$INSTANCE_IP user=postgres sslmode=require"
psql (15.6 (Debian 15.6-0+deb12u1), server 15.5)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

关闭 psql 会话:

exit

6. 准备数据库

我们需要创建数据库、启用 Vertex AI 集成、创建数据库对象并导入数据。

向 AlloyDB 授予必要的权限

为 AlloyDB 服务代理添加 Vertex AI 权限。

使用顶部的“+”号打开另一个 Cloud Shell 标签页。

4ca978f5142bb6ce.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 虚拟机会话中,执行以下命令:

创建数据库:

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 虚拟机中,执行以下命令:

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 虚拟机中,执行以下命令:

gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
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"
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"
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"

预期的控制台输出:

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 表中显示了商店的列表。我们需要根据产品描述来计算矢量数据,为此,我们将使用函数嵌入。通过使用该函数,我们将使用 Vertex AI 集成功能,根据我们的产品说明计算矢量数据并将其添加到表格中。您可以在此文档中详细了解所使用的技术。

创建嵌入列

使用 psql 连接到数据库,并使用 cymbal_products 表中的嵌入函数创建包含矢量数据的虚拟列。嵌入函数根据 product_description 列提供的数据,从 Vertex AI 返回矢量数据。

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

在连接到数据库后的 psql 会话中,执行以下命令:

ALTER TABLE cymbal_products ADD COLUMN embedding vector GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;

该命令将创建虚拟列,并在其中填充矢量数据。

预期的控制台输出:

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
psql (13.11 (Debian 13.11-0+deb11u1), server 14.7)
WARNING: psql major version 13, server major version 14.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN embedding vector GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;
ALTER TABLE
quickstart_db=> 

8. 运行相似性搜索

现在,我们可以根据为描述计算的向量值和为请求获得的向量值,使用相似度搜索来运行搜索。

可以从同一 psql 命令行界面执行 SQL 查询,也可以从 AlloyDB Studio 执行。任何多行和复杂输出在 AlloyDB Studio 中可能会看起来更好。

连接到 AlloyDB Studio

在以下章节中,所有需要连接到数据库的 SQL 命令都可以在 AlloyDB Studio 中执行。如需运行该命令,您需要点击主实例以打开 AlloyDB 集群的 Web 控制台界面。

ef4bfbcf0ed2ef3a.png

然后点击左侧的 AlloyDB Studio:

5c155cbcd7d43a1

选择 quickstart_db 数据库和用户 postgres,并提供创建集群时记下的密码。然后点击“身份验证”按钮。

432613065cac864f

此操作将打开 AlloyDB Studio 界面。要在数据库中运行命令,请点击“编辑器 1”。

b36c28f8165119ca.png

它会打开界面,您可以在其中运行 SQL 命令

cf43aa20f292797e.png

如果您更喜欢使用命令行 psql,请按照前几章中介绍的方法,从虚拟机 SSH 会话连接到数据库。

通过 psql 运行相似性搜索

如果您的数据库会话已断开连接,请使用 psql 或 AlloyDB Studio 再次连接到数据库。

连接到数据库:

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

运行查询以获取与客户请求最相关的可用商品列表。我们将向 Vertex AI 传递请求,以便获取听起来像是“这里种植哪种果树?”这样的矢量值。

您可以运行以下查询,选择最符合我们的请求的前 10 项:

SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        (cp.embedding <=> embedding('text-embedding-004','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-004','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.287184013172779
 Toyon               | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.30574073611569963
 Secateurs           | These secateurs are perfect for pruning small branches and vines.                |      15.00 |    93230 |  0.3264385326189635
 Trimming Shears     | These trimming shears are perfect for trimming hedges and bushes.                |      20.00 |    93230 | 0.33293036535756393
 Cypress Tree        | This is a beautiful cypress tree that will provide shade and privacy. It is an e |      75.00 |    93230 | 0.33485770716129326
 Madrone             | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an |      50.00 |    93230 |  0.3354408801293012
 California Redwood  | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a |    1000.00 |    93230 |  0.3427243109636263
 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.3427628377929176
 California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 |  0.3430208475356905
 Maple Tree          | This is a beautiful maple tree that will produce colorful leaves in the fall. It |     100.00 |    93230 |  0.3432609589330091
(10 rows)

quickstart_db=> 

9. 改善回答

您可以使用查询结果改进对客户端应用的响应,并使用提供的查询结果作为 Vertex AI 生成式基础语言模型提示的一部分,准备有意义的输出。

为此,我们计划使用矢量搜索的结果生成 JSON,然后使用生成的 JSON 作为 Vertex AI 中的文本 LLM 模型提示的补充,以创建有意义的输出。在第一步中,我们生成 JSON,然后在 Vertex AI Studio 中对其进行测试;在最后一步中,我们将其合并到可在应用中使用的 SQL 语句中。

以 JSON 格式生成输出

修改查询以生成 JSON 格式的输出,并仅返回一行传递给 Vertex AI

以下是该查询的示例:

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-004','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 文本模型

在 Cloud 控制台中打开 Vertex AI Studio。

e514b176aef7945e.png

54712e5ade7121f

它可能会要求您启用其他 API,但您可以忽略该请求。我们不需要任何其他 API 即可完成本实验。

我们将使用的提示如下:

您要做一名友好的顾问,协助他们根据客户的需求找到合适的产品。

根据客户的请求,我们加载了与搜索密切相关的产品列表。

JSON 格式列表,包含 {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}

产品列表如下

[JSON 的位置]

客户问:“这里的哪种树生长得最好?”

您应该提供有关商品、价格的信息以及一些补充信息。根据提示

当我们使用 JSON 值和 gemini-1.5-flash 模型运行提示时,结果如下:

30e5072cd2975685

在此示例中,我们从模型中获得的答案如下。请注意,您的答案可能会因模型和参数随时间而变化而有所不同:

“我看到您正在寻找一棵在你所在的地区生长的树。根据您的邮政编码 93230,“樱桃树”似乎是个不错的选择!

据说这棵树开出美味的樱桃,非常美丽。目前的售价为 75.00 美元。

虽然我无法提供它在你所在地区的生长率的具体细节,但我可以告诉你,樱桃树通常喜欢排水很好的土壤和充足的阳光。

为确保获得最佳效果,建议您咨询当地的苗圃或园艺专家,他们可以针对您的具体位置和土壤条件提供更有针对性的建议。他们还可以帮助您选择最符合需求的品种,并提供有关种植和养护的提示。”

使用 PSQL 运行提示

我们可以使用 AlloyDB AI 与 Vertex AI 的集成,直接在数据库中使用 SQL 从生成模型中获得同样的响应。但若要使用 gemini-1.5-flash 模型,我们需要先注册。

将扩展程序升级到版本 1.3。按照之前所示的方法从 pSQL 连接到 quickstart_db 数据库(或使用 AlloyDB Studio),并执行:

ALTER EXTENSION google_ml_integration UPDATE TO '1.3'

然后,我们需要将 google_ml_integration.enable_model_support 数据库标志设置为“on”。为此,您可以使用 AlloyDB 网页界面或运行以下 gcloud 命令。

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

该命令会在后台执行大约 3-5 分钟。然后,您可以在 psql 会话中或使用连接到 quickstart_db 数据库的 AlloyDB Studio 验证新标志。

show google_ml_integration.enable_model_support;

psql 会话的预期输出为“on”:

postgres=> show google_ml_integration.enable_model_support;
 google_ml_integration.enable_model_support 
--------------------------------------------
 on
(1 row)

然后,我们需要注册两个模型。第一个是已经使用过的 text-embedding-004 模型。由于我们启用了模型注册功能,因此需要注册该模型。

如需注册模型,请在 psql 或 AlloyDB Studio 中运行以下代码:

CALL
  google_ml.create_model(
    model_id => 'text-embedding-004',
    model_provider => 'google',
    model_qualified_name => 'text-embedding-004',
    model_type => 'text_embedding',
    model_auth_type => 'alloydb_service_agent_iam',
    model_in_transform_fn => 'google_ml.vertexai_text_embedding_input_transform',
    model_out_transform_fn => 'google_ml.vertexai_text_embedding_output_transform');

我们需要注册的下一个模型是 gemini-1.5-flash-001,将用于生成方便用户使用的输出。

CALL
  google_ml.create_model(
    model_id => 'gemini-1.5-flash-001',
    model_request_url => 'https://$REGION-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/publishers/google/models/gemini-1.5-flash-001:streamGenerateContent',
    model_provider => 'google',
    model_auth_type => 'alloydb_service_agent_iam');

您可以随时通过从 google_ml.model_info_view 中选择信息来验证已注册模型的列表。

select model_id,model_type from google_ml.model_info_view;

以下是示例输出

quickstart_db=> select model_id,model_type from google_ml.model_info_view;
        model_id         |   model_type   
-------------------------+----------------
 textembedding-gecko     | text_embedding
 textembedding-gecko@001 | text_embedding
 text-embedding-004      | text_embedding
 gemini-1.5-flash-001    | generic
(4 rows)

现在,我们可以使用子查询 JSON 中生成的 ,将其作为使用 SQL 的生成式 AI 文本模型提示的一部分提供。

在与数据库的 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-004',
        '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
        json_array_elements(google_ml.predict_row( model_id =>'gemini-1.5-flash-001',
        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
        string_agg(resp::text,
        ' ')
FROM
        response;

这是预期输出。您的输出可能会因模型版本和参数而异:

--------------------------------------------------------------------------------------------------------
 "I" " see you're interested in fruit trees! Based on your location, I found" " one great option:\n\n**Cherry Tree:** \n\nThis beautiful cherry tree will" " produce delicious cherries. It's a deciduous tree, meaning it loses its leaves in the fall, and can grow up to 15 feet tall. The" " leaves are a vibrant dark green in the summer, turning a beautiful red in the fall. \n\nCherry trees are known for their beauty and ability to provide shade" " and privacy. They prefer a cool, moist climate and sandy soil, making them a good fit for your area. \n\nThe Cherry Tree is currently on sale for $75.00.\n\nWould you like to know more about" " the Cherry Tree, or are you interested in exploring other fruit tree options? \n" ""
(1 row)

10. 清理环境

完成实验后销毁 AlloyDB 实例和集群

删除 AlloyDB 集群和所有实例

系统会通过强制选项销毁集群,该选项还会删除属于该集群的所有实例。

如果您已断开连接且之前的所有设置都已丢失,请在 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.                                                                                                                                                                                                                                                            

现在我们可以销毁虚拟机了

删除 GCE 虚拟机

在 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 

11. 恭喜

恭喜您完成此 Codelab。

所学内容

  • 如何部署 AlloyDB 集群和主实例
  • 如何从 Google Compute Engine 虚拟机连接到 AlloyDB
  • 如何创建数据库并启用 AlloyDB AI
  • 如何将数据加载到数据库
  • 如何在 AlloyDB 中使用 Vertex AI 嵌入模型
  • 如何使用 Vertex AI 生成模型丰富结果

12. 调查问卷

输出如下:

您打算如何使用本教程?

仅通读 阅读并完成练习