使用 Cloud SQL 数据库和 LangChain 构建基于 LLM 和 RAG 的聊天应用

1. 简介

在此 Codelab 中,您将学习如何部署 GenAI Retrieval Service,并使用部署的环境创建示例交互式应用。

8727a44c8c402834

您可以点击此处,详细了解 GenAI Retrieval Service 和示例应用。

前提条件

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

学习内容

  • 如何创建 Cloud SQL 实例
  • 如何连接到实例
  • 如何配置和部署 GenAI Databases Retrieval Service
  • 如何使用已部署的服务来部署示例应用

所需条件

  • 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 已设置:

通常,项目 ID 会显示在 Cloud Shell 命令提示符中的括号内,如下图所示:

fa6ee779963405d5.png

gcloud config set project [YOUR-PROJECT-ID]

然后,将 PROJECT_ID 环境变量设置为您的 Google Cloud 项目 ID:

PROJECT_ID=$(gcloud config get-value project)

启用所有必要的服务:

gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       vpcaccess.googleapis.com \
                       aiplatform.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       run.googleapis.com \
                       iam.googleapis.com

预期的控制台输出:

student@cloudshell:~ (gleb-test-short-004)$ gcloud services enable sqladmin.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       vpcaccess.googleapis.com \
                       aiplatform.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       run.googleapis.com \
                       iam.googleapis.com
Operation "operations/acf.p2-404051529011-664c71ad-cb2b-4ab4-86c1-1f3157d70ba1" finished successfully.

4. 创建 Cloud SQL 实例

创建启用了矢量支持的 Cloud SQL 实例。

创建密码

为默认数据库用户定义密码。您可以定义自己的密码,也可以使用随机函数生成一个

export CLOUDSQL_PASSWORD=`openssl rand -hex 12`

记下生成的密码值

echo $CLOUDSQL_PASSWORD

MySQL

您可以在创建实例时启用 cloudsql_vector 标志。目前,MySQL 8.0.36 和8.0.37.

export region=us-central1
gcloud sql instances create my-cloudsql-instance --region=$region --database-version=MYSQL_8_0_36 --database-flags=cloudsql_vector=ON --root-password=$CLOUDSQL_PASSWORD

预期的控制台输出(已隐去 IP 地址):

student@cloudshell:~ export region=us-central1
gcloud sql instances create my-cloudsql-instance --region=$region --database-version=MYSQL_8_0_36 --database-flags=cloudsql_vector=ON --root-password=$CLOUDSQL_PASSWORD
Creating Cloud SQL instance for MYSQL_8_0_36...done.                                                                                                                                 
Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/test-project-402417/instances/my-cloudsql-instance].
NAME                   DATABASE_VERSION  LOCATION       TIER             PRIMARY_ADDRESS  PRIVATE_ADDRESS  STATUS
my-cloudsql-instance  MYSQL_8_0_36      us-central1-a  db-n1-standard-1  00.000.00.00   -                RUNNABLE

PostgreSQL

11 及更高版本提供 pgvector 扩展。

export region=us-central1
gcloud sql instances create my-cloudsql-instance --region=$region --database-version=POSTGRES_15 --tier=db-g1-small

预期的控制台输出(已隐去 IP 地址):

student@cloudshell:~ export region=us-central1
gcloud sql instances create my-cloudsql-instance --region=$region --database-version=POSTGRES_15 --tier=db-g1-small
Creating Cloud SQL instance for POSTGRES_15...done.                                                                                                                                  
Created [https://sqladmin.googleapis.com/sql/v1beta4/projects/test-project-402417/instances/my-cloudsql-instance].
NAME                   DATABASE_VERSION  LOCATION       TIER         PRIMARY_ADDRESS  PRIVATE_ADDRESS  STATUS
my-cloudsql-instance  POSTGRES_15       us-central1-a  db-g1-small  00.000.00.00     -                RUNNABLE

创建实例后,我们需要为实例中的默认用户定义密码,并检查我们能否使用该密码进行连接。准备好进行连接时,请在提示中输入您的密码。

gcloud sql users set-password postgres \
    --instance=my-cloudsql-instance \
    --password=$CLOUDSQL_PASSWORD
gcloud sql connect my-cloudsql-instance --user=postgres

预期的控制台输出:

student@cloudshell:~ (test-project-402417)$ gcloud sql users set-password postgres \
    --instance=my-cloudsql-instance \
    --password=$CLOUDSQL_PASSWORD
gcloud sql connect my-cloudsql-instance --user=postgres
Updating Cloud SQL user...done.                                                                                                                                                                                                                                            
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                                                                                                         
Connecting to database with SQL user [postgres].Password: 
psql (16.3 (Ubuntu 16.3-1.pgdg22.04+1), server 15.7)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)
Type "help" for help.

postgres=>

退出 psql 会话:

exit

5. 准备 GCE 虚拟机

创建服务账号

由于我们将使用虚拟机部署 GenAI Databases Retrieval Service 并托管示例应用,因此第一步是创建 Google 服务账号 (GSA)。GSA 将由 GCE 虚拟机使用,我们需要授予它与其他服务协同工作的必要权限。

在 Cloud Shell 中,执行以下命令:

PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts create compute-aip --project $PROJECT_ID
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/artifactregistry.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/storage.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/run.admin"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudsql.viewer"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudsql.client"
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:compute-aip@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"

部署 GCE 虚拟机

在 Cloud SQL 实例所在的区域和 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 \
  --service-account=compute-aip@$PROJECT_ID.iam.gserviceaccount.com

预期的控制台输出:

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

授权虚拟机连接到 Cloud SQL

我们需要将虚拟机公共 IP 添加到 Cloud SQL 实例的授权网络列表中。在 Cloud Shell 中,执行以下命令:

VM_EXTERNAL_IP=$(gcloud compute instances describe instance-1 --zone=us-central1-a --format='get(networkInterfaces[0].accessConfigs[0].natIP)')
gcloud sql instances patch my-cloudsql-instance --authorized-networks=$VM_EXTERNAL_IP

预期的控制台输出:

student@cloudshell:~ (test-project-402417)$ export ZONE=us-central1-a
student@cloudshell:~ (test-project-402417)$ VM_EXTERNAL_IP=$(gcloud compute instances describe instance-1 --zone=us-central1-a --format='get(networkInterfaces[0].accessConfigs[0].natIP)')
gcloud sql instances patch my-cloudsql-instance --authorized-networks=$VM_EXTERNAL_IP
When adding a new IP address to authorized networks, make sure to also include any IP addresses that have already been authorized. Otherwise, they will be overwritten and de-authorized.

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

The following message will be used for the patch API method.
{"name": "my-cloudsql-instance", "project": "test-project-402417", "settings": {"ipConfiguration": {"authorizedNetworks": [{"value": "34.71.252.173"}]}}}
Patching Cloud SQL instance...done.                                                                                                                                                                                     
Updated [https://sqladmin.googleapis.com/sql/v1beta4/projects/test-project-402417/instances/my-cloudsql-instance].

安装数据库客户端

MySQL

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

连接到虚拟机:

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 5.10.0-26-cloud-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) 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 default-mysql-client

预期的控制台输出:

student@instance-1:~$ sudo apt-get update
sudo apt-get install --yes mysql-client
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libconfig-inifiles-perl libdbd-mariadb-perl libdbi-perl libgdbm-compat4 libperl5.32 libterm-readkey-perl mariadb-client-10.5 mariadb-client-core-10.5 perl perl-modules-5.32
Suggested packages:
  libclone-perl libmldbm-perl libnet-daemon-perl libsql-statement-perl perl-doc libterm-readline-gnu-perl | libterm-readline-perl-perl make libtap-harness-archive-perl
The following NEW packages will be installed:
  default-mysql-client libconfig-inifiles-perl libdbd-mariadb-perl libdbi-perl libgdbm-compat4 libperl5.32 libterm-readkey-perl mariadb-client-10.5 mariadb-client-core-10.5 perl
  Perl-modules-5.32
...redacted...
Processing triggers for libc-bin (2.31-13+deb11u10) ...

PostgreSQL

在已部署的虚拟机上安装 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 5.10.0-26-cloud-amd64 #1 SMP Debian 5.10.197-1 (2023-09-29) 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 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B]
Get:4 file:/etc/apt/mirrors/debian-security.list Mirrorlist [39 B]
Hit:7 https://packages.cloud.google.com/apt google-compute-engine-bookworm-stable InRelease
Get:8 https://packages.cloud.google.com/apt cloud-sdk-bookworm InRelease [1652 B]
Get:2 https://deb.debian.org/debian bookworm InRelease [151 kB]
Get:3 https://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
...redacted...
update-alternatives: using /usr/share/postgresql/15/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-client (15+248) ...
Processing triggers for man-db (2.11.2-2) ...
Processing triggers for libc-bin (2.36-9+deb12u7) ...

连接到实例

MySQL

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

使用已打开的 SSH 会话继续连接到虚拟机。如果您已断开连接,请使用与上面相同的命令重新连接。

使用前面记下的 $CLOUDSQL_PASSWORD 和实例名称从 GCE 虚拟机连接到 Cloud SQL:

export CLOUDSQL_PASSWORD=<Noted password>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export INSTANCE_NAME=my-cloudsql-instance
export INSTANCE_IP=$(gcloud sql instances list --filter=name:$INSTANCE_NAME --format="value(PRIMARY_ADDRESS)")
mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD

预期的控制台输出:

student@instance-1:~$ export CLOUDSQL_PASSWORD=P9...
student@instance-1:~$ export REGION=us-central1
student@instance-1:~$ export INSTANCE_NAME=my-cloud-sql-instance
student@instance-1:~$ export INSTANCE_IP=$(gcloud sql instances list --filter=name:$INSTANCE_NAME --format="value(PRIMARY_ADDRESS)")
student@instance-1:~$ mysql  –host=$INSTANCE_IP –user=root –password=$CLOUDSQL_PASSWORD –sslmode=require 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 2824706
Server version: 8.0.36-google (Google)

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

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

MySQL [(none)]>

退出 MySQL 会话,同时保持 SSH 连接:

exit

预期的控制台输出:

MySQL [(none)]> exit
Bye
student@instance-1:~$ 

PostgreSQL

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

使用已打开的 SSH 会话继续连接到虚拟机。如果您已断开连接,请使用与上面相同的命令重新连接。

使用前面记下的 $CLOUDSQL_PASSWORD 和实例名称从 GCE 虚拟机连接到 PostgreSQL:

export PGPASSWORD=<Noted password (CLOUDSQL_PASSWORD)>
export CLOUDSQL_PASSWORD=$PGPASSWORD
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export INSTANCE_NAME=my-cloudsql-instance
export INSTANCE_IP=$(gcloud sql instances list --filter=name:$INSTANCE_NAME --format="value(PRIMARY_ADDRESS)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"

预期的控制台输出:

student@instance-1:~$ export CLOUDSQL_PASSWORD=P9...
student@instance-1:~$ export REGION=us-central1
student@instance-1:~$ export INSTANCE_IP=$(gcloud sql instances list --filter=name:$INSTANCE_NAME --format="value(PRIMARY_ADDRESS)")
student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres sslmode=require"
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.

postgres=> 

退出 psql 会话,同时保持 SSH 连接:

exit

预期的控制台输出:

postgres=> exit
student@instance-1:~$ 

6. 初始化数据库

我们将使用客户端虚拟机作为平台,向数据库填充数据并托管应用。第一步是创建数据库并为其填充数据。

创建数据库

MySQL

创建一个名为“assistantdemo”的数据库。

在 GCE 虚拟机会话中,执行以下命令:

mysql --host=$INSTANCE_IP  --user=root --password=$CLOUDSQL_PASSWORD -e "CREATE DATABASE assistantdemo"

预期的控制台输出(无输出):

student@instance-1:~$ mysql --host=$INSTANCE_IP  --user=root --password=$CLOUDSQL_PASSWORD -e "CREATE DATABASE assistantdemo"
student@instance-1:~$  

PostgreSQL

创建一个名为“assistantdemo”的数据库。

在 GCE 虚拟机会话中,执行以下命令:

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

预期的控制台输出:

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

启用 pgvector 扩展程序。

psql "host=$INSTANCE_IP user=postgres dbname=assistantdemo" -c "CREATE EXTENSION vector"  

预期的控制台输出(无输出):

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=assistantdemo" -c "CREATE EXTENSION vector"
CREATE EXTENSION
student@instance-1:~$

准备 Python 环境

如要继续,我们将使用 GitHub 代码库中已准备好的 Python 脚本,但在此之前,我们需要安装所需的软件。

在 GCE 虚拟机中,执行以下命令:

sudo apt install -y python3.11-venv git
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip

预期的控制台输出:

student@instance-1:~$ sudo apt install -y python3.11-venv git
python3 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  git-man liberror-perl patch python3-distutils python3-lib2to3 python3-pip-whl python3-setuptools-whl
Suggested packages:
  git-daemon-run | git-daemon-sysvinit git-doc git-email git-gui gitk gitweb git-cvs git-mediawiki git-svn ed diffutils-doc
The following NEW packages will be installed:
  git git-man liberror-perl patch python3-distutils python3-lib2to3 python3-pip-whl python3-setuptools-whl python3.11-venv
0 upgraded, 9 newly installed, 0 to remove and 2 not upgraded.
Need to get 12.4 MB of archives.
After this operation, 52.2 MB of additional disk space will be used.
Get:1 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B]
...redacted...
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 23.0.1
    Uninstalling pip-23.0.1:
      Successfully uninstalled pip-23.0.1
Successfully installed pip-24.0
(.venv) student@instance-1:~$

验证 Python 版本。

在 GCE 虚拟机中,执行以下命令:

python -V

预期的控制台输出:

(.venv) student@instance-1:~$ python -V
Python 3.11.2
(.venv) student@instance-1:~$ 

准备配置文件

克隆包含检索服务和示例应用代码的 GitHub 代码库。

在 GCE 虚拟机中,执行以下命令:

git clone https://github.com/GoogleCloudPlatform/genai-databases-retrieval-app.git

预期的控制台输出:

student@instance-1:~$ git clone https://github.com/GoogleCloudPlatform/genai-databases-retrieval-app.git
Cloning into 'genai-databases-retrieval-app'...
remote: Enumerating objects: 525, done.
remote: Counting objects: 100% (336/336), done.
remote: Compressing objects: 100% (201/201), done.
remote: Total 525 (delta 224), reused 179 (delta 135), pack-reused 189
Receiving objects: 100% (525/525), 46.58 MiB | 16.16 MiB/s, done.
Resolving deltas: 100% (289/289), done.

MySQL

在 GCE 虚拟机中,执行以下命令:

cd ~/genai-databases-retrieval-app/retrieval_service
cp example-config-cloudsql.yml config.yml
cp example-config-cloudsql.yml config.yml
sed -i s/engine/mysql/g config.yml
sed -i s/my-project/$PROJECT_ID/g config.yml
sed -i s/my-region/$REGION/g config.yml
sed -i s/my-instance/$INSTANCE_NAME/g config.yml
sed -i s/my-password//g config.yml
sed -i s/my_database/assistantdemo/g config.yml
sed -i s/my-user/root/g config.yml
cat config.yml

预期的控制台输出:

student@instance-1:~$ cd genai-databases-retrieval-app/retrieval_service
cp example-config-cloudsql.yml config.yml
sed -i s/127.0.0.1/$INSTANCE_IP/g config.yml
sed -i s/my-password/$CLOUDSQL_PASSWORD/g config.yml
sed -i s/my_database/assistantdemo/g config.yml
sed -i s/my-user/postgres/g config.yml
cat config.yml
host: 0.0.0.0
# port: 8080
datastore:
  # Example for MySQL
  kind: "cloudsql-mysql"
  host: 10.65.0.2
  # port: 5432
  database: "assistantdemo"
  user: "root"
  password: "P9..."

Postgres

在 GCE 虚拟机中,执行以下命令:

cd ~/genai-databases-retrieval-app/retrieval_service
cp example-config-cloudsql.yml config.yml
sed -i s/engine/postgres/g config.yml
sed -i s/my-project/$PROJECT_ID/g config.yml
sed -i s/my-region/$REGION/g config.yml
sed -i s/my-instance/$INSTANCE_NAME/g config.yml
sed -i s/my-password/$PGPASSWORD/g config.yml
sed -i s/my_database/assistantdemo/g config.yml
sed -i s/my-user/postgres/g config.yml
cat config.yml

预期的控制台输出:

student@instance-1:~$ cd genai-databases-retrieval-app/retrieval_service
cp example-config-cloudsql.yml config.yml
sed -i s/engine/postgres/g config.yml
sed -i s/my-project/$PROJECT_ID/g config.yml
sed -i s/my-region/$REGION/g config.yml
sed -i s/my-instance/$INSTANCE_NAME/g config.yml
sed -i s/my-password/$CLOUDSQL_PASSWORD/g config.yml
sed -i s/my_database/assistantdemo/g config.yml
sed -i s/my-user/postgres/g config.yml
cat config.yml
host: 0.0.0.0
# port: 8080
datastore:
  # Example for Postgres
  kind: "cloudsql-postgres"
  host: 10.65.0.2
  # port: 5432
  database: "assistantdemo"
  user: "postgres"
  password: "P9..."

填充数据库

使用示例数据集填充数据库。第一个命令是将所有必需的软件包添加到 Python 虚拟环境中,第二个命令是用数据填充我们的数据库。

在 GCE 虚拟机中,执行以下命令:

cd ~/genai-databases-retrieval-app/retrieval_service
pip install -r requirements.txt
python run_database_init.py

预期的控制台输出(已隐去部分信息):

student@instance-1:~/genai-databases-retrieval-app/retrieval_service$ pip install -r requirements.txt
python run_database_init.py
Collecting asyncpg==0.28.0 (from -r requirements.txt (line 1))
  Obtaining dependency information for asyncpg==0.28.0 from https://files.pythonhosted.org/packages/77/a4/88069f7935b14c58534442a57be3299179eb46aace2d3c8716be199ff6a6/asyncpg-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata
  Downloading asyncpg-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.3 kB)
Collecting fastapi==0.101.1 (from -r requirements.txt (line 2))
...
database init done.
student@instance-1:~/genai-databases-retrieval-app/retrieval_service$

7. 将检索服务部署到 Cloud Run

现在,我们可以将检索服务部署到 Cloud Run。该服务负责与数据库合作,并根据 AI 应用的请求从数据库中提取必要的信息。

创建服务账号

为检索服务创建服务账号并授予必要的权限。

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

4ca978f5142bb6ce.png

在新的 Cloud Shell 标签页中,执行以下命令:

export PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts create retrieval-identity
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:retrieval-identity@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/aiplatform.user"
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:retrieval-identity@$PROJECT_ID.iam.gserviceaccount.com" \
  --role="roles/cloudsql.client"

预期的控制台输出:

student@cloudshell:~ (gleb-test-short-003)$ gcloud iam service-accounts create retrieval-identity
Created service account [retrieval-identity].

在标签页中执行命令“exit”,关闭该标签页:

exit

部署检索服务

在通过 SSH 连接到虚拟机的第一个标签页中,继续部署该服务。

在虚拟机 SSH 会话中,执行以下命令:

cd ~/genai-databases-retrieval-app
gcloud alpha run deploy retrieval-service \
    --source=./retrieval_service/\
    --no-allow-unauthenticated \
    --service-account retrieval-identity \
    --region us-central1 \
    --network=default \
    --quiet

预期的控制台输出:

student@instance-1:~/genai-databases-retrieval-app$ gcloud alpha run deploy retrieval-service \
    --source=./retrieval_service/\
    --no-allow-unauthenticated \
    --service-account retrieval-identity \
    --region us-central1 \
    --network=default
This command is equivalent to running `gcloud builds submit --tag [IMAGE] ./retrieval_service/` and `gcloud run deploy retrieval-service --image [IMAGE]`

Building using Dockerfile and deploying container to Cloud Run service [retrieval-service] in project [gleb-test-short-003] region [us-central1]
X Building and deploying... Done.
  ✓ Uploading sources...
  ✓ Building Container... Logs are available at [https://console.cloud.google.com/cloud-build/builds/6ebe74bf-3039-4221-b2e9-7ca8fa8dad8e?project=1012713954588].
  ✓ Creating Revision...
  ✓ Routing traffic...
    Setting IAM Policy...
Completed with warnings:
  Setting IAM policy failed, try "gcloud beta run services remove-iam-policy-binding --region=us-central1 --member=allUsers --role=roles/run.invoker retrieval-service"
Service [retrieval-service] revision [retrieval-service-00002-4pl] has been deployed and is serving 100 percent of traffic.
Service URL: https://retrieval-service-onme64eorq-uc.a.run.app
student@instance-1:~/genai-databases-retrieval-app$

验证服务

现在,我们可以检查服务是否正常运行,以及虚拟机是否有权访问端点。我们使用 gcloud 实用程序获取检索服务端点。或者,您可以在 Cloud 控制台中进行查看,并在 curl 命令中将 "$(gcloud run services list –filter="retrieve-service)" 替换为其中的值。

在虚拟机 SSH 会话中,执行以下命令:

curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $(gcloud  run services list --filter="(retrieval-service)" --format="value(URL)")

预期的控制台输出:

student@instance-1:~/genai-databases-retrieval-app$ curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $(gcloud  run services list --filter="(retrieval-service)" --format="value(URL)")
{"message":"Hello World"}student@instance-1:~/genai-databases-retrieval-app$

如果我们看到“Hello World”消息,则表示我们的服务已启动并正在处理请求。

8. 部署示例应用

现在,在启动并运行检索服务后,我们可以部署将使用该服务的示例应用。该应用可以部署在虚拟机或任何其他服务(如 Cloud Run、Kubernetes)上,甚至可以在本地部署到笔记本电脑上。下面我们将介绍如何在虚拟机上部署该应用。

准备好环境

我们将继续使用同一 SSH 会话在虚拟机上执行操作。如需运行我们的应用,我们需要添加一些 Python 模块。该命令将从同一 Python 虚拟环境中的应用目录执行。

在虚拟机 SSH 会话中,执行以下命令:

cd ~/genai-databases-retrieval-app/llm_demo
pip install -r requirements.txt

预期输出(已隐去部分信息):

student@instance-1:~$ cd ~/genai-databases-retrieval-app/llm_demo
pip install -r requirements.txt
Collecting fastapi==0.104.0 (from -r requirements.txt (line 1))
  Obtaining dependency information for fastapi==0.104.0 from https://files.pythonhosted.org/packages/db/30/b8d323119c37e15b7fa639e65e0eb7d81eb675ba166ac83e695aad3bd321/fastapi-0.104.0-py3-none-any.whl.metadata
  Downloading fastapi-0.104.0-py3-none-any.whl.metadata (24 kB)
...

准备客户端 ID

如需使用应用的预订功能,我们需要使用 Cloud 控制台准备 OAuth 2.0 客户端 ID。我们将登录应用,因为预订会使用客户端凭据将预订数据记录在数据库中。

在 Cloud 控制台中,前往“API 和服务”,然后点击“OAuth 同意屏幕”然后选择“内部”用户。

2400e5dcdb93eab8.png

然后推送“创建”然后按照下一个屏幕中的说明操作

6c34d235156e571f

您需要填写“应用名称”等必填字段和“用户支持电子邮件地址”此外,您还可以添加要在同意屏幕上显示的域名,最后添加“开发者联系信息”

2b7cd51aff915072

然后按提示点击“保存并继续”按钮,即可转到下一页。

d90c10c88fd347f9.png

您无需在此处进行任何更改,除非您想指定范围。最后,请点击“保存并继续”按钮。这将设置应用同意屏幕。

下一步是创建客户端 ID。在左侧面板中,点击“凭据”系统会将您转到 OAuth2 凭据。

7ad97432390f224c

在这里点击“Create Credentials”然后选择“OAuth ClientID”。然后,系统会打开另一个屏幕。

325a926431c8f16d

选择“Web 应用”应用类型下拉列表,然后将应用 URI(和端口 - 可选)作为“已获授权的 JavaScript 来源”。此外,您需要将“已获授权的重定向 URI”添加到输入“/login/google”以便能够使用授权弹出屏幕。在上图中,您可以看到我已使用 http://localhost 作为基础应用 URI。

推送“创建”按钮,系统会显示一个包含您客户端凭据的弹出式窗口。

e91adf03ec31cd15.png

稍后我们需要将客户端 ID(以及可选的客户端密钥)用于我们的应用

运行助理应用

在启动应用之前,我们需要设置一些环境变量。该应用的基本功能(例如查询航班和机场设施)仅需要 BASE_URL,它将应用指向检索服务。我们可以使用 gcloud 命令获取它。

在虚拟机 SSH 会话中,执行以下命令:

export BASE_URL=$(gcloud  run services list --filter="(retrieval-service)" --format="value(URL)")

预期输出(已隐去部分信息):

student@instance-1:~/genai-databases-retrieval-app/llm_demo$ export BASE_URL=$(gcloud  run services list --filter="(retrieval-service)" --format="value(URL)")

要使用应用程序的更高级的功能(如预订和更改航班),我们需要使用 Google 账号登录应用程序,为此,我们需要使用“准备客户端 ID”一章中的 OAuth 客户端 ID 提供 CLIENT_ID 环境变量:

export CLIENT_ID=215....apps.googleusercontent.com

预期输出(已隐去部分信息):

student@instance-1:~/genai-databases-retrieval-app/llm_demo$ export CLIENT_ID=215....apps.googleusercontent.com

现在,我们可以运行应用:

python run_app.py

预期输出:

student@instance-1:~/genai-databases-retrieval-app/llm_demo$ python main.py
INFO:     Started server process [28565]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)

连接到应用

您可以通过多种方式连接到虚拟机上运行的应用。例如,您可以在 VPC 中使用防火墙规则打开虚拟机上的端口 8081,或创建具有公共 IP 的负载均衡器。在这里,我们将使用通向虚拟机的 SSH 隧道将本地端口 8080 转换为虚拟机端口 8081。

从本地机器连接

当我们需要从本地机器建立连接时,需要运行 SSH 隧道。您可以使用 gcloud compute ssh 完成此操作:

gcloud compute ssh instance-1 --zone=us-central1-a -- -L 8081:localhost:8081

预期输出:

student-macbookpro:~ student$ gcloud compute ssh instance-1 --zone=us-central1-a -- -L 8080:localhost:8081
Warning: Permanently added 'compute.7064281075337367021' (ED25519) to the list of known hosts.
Linux instance-1.us-central1-c.c.gleb-test-001.internal 6.1.0-21-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) 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:~$

现在,我们可以打开浏览器,并使用 http://localhost:8081 连接到我们的应用。我们应该会看到应用屏幕。

c667b9013afac3f9.png

从 Cloud Shell 连接

我们也可以使用 Cloud Shell 进行连接。使用顶部的“+”号打开另一个 Cloud Shell 标签页。

4ca978f5142bb6ce.png

在新 Cloud Shell 标签页中执行 gcloud 命令,启动通向虚拟机的隧道:

gcloud compute ssh instance-1 --zone=us-central1-a -- -L 8080:localhost:8081

系统会显示“Cannot assign requested address”错误,请忽略该错误。

预期输出如下:

student@cloudshell:~ gcloud compute ssh instance-1 --zone=us-central1-a -- -L 8080:localhost:8081
bind [::1]:8081: Cannot assign requested address
inux instance-1.us-central1-a.c.gleb-codelive-01.internal 6.1.0-21-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) 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.
Last login: Sat May 25 19:15:46 2024 from 35.243.235.73
student@instance-1:~$

此操作会在您的 Cloud Shell 上打开端口 8080,该端口可用于“网页预览”。

点击“网页预览”按钮,然后从下拉菜单中选择“在端口 8080 上预览”。

444fbf54dcd4d160.png

系统会在网络浏览器中打开一个包含应用界面的新标签页。您应该能看到“Cymbal Air Customer Service Assistant”页面。在网页的地址栏中,我们可以看到预览页的 URI。我们需要删除“/?authuser=0&redirectedPreviously=true”部分末尾

389f0ae2945beed5

并使用 URI 的第一部分,例如“https://8080-cs-35704030349-default.cs-us-east1-vpcf.cloudshell.dev/”留在浏览器窗口中,并以“已获授权的 JavaScript 来源”的形式提供和“已获授权的重定向 URI”创建在“Prepare Client ID”章节替换或添加最初提供的 http://localhost:8080 值。上限值类似于“https://8080-cs-35704030349-default.cs-us-east1-vpcf.cloudshell.dev”位于较低的位置是“https://8080-cs-35704030349-default.cs-us-east1-vpcf.cloudshell.dev/login/google

2c37eeda0a7e2f80

登录应用

当一切设置完毕且您的应用已打开时,我们就可以使用“登录”按钮,提供我们的凭据。这是可选的,且仅当您想尝试应用的预订功能时才是必需的。

a1f571371b957129.png

系统会打开一个弹出式窗口,供我们选择凭据。

登录后,应用已准备就绪,您可以开始将请求发布到窗口底部的字段中。

此演示展示了 Cymbal Air 客户服务助理。Cymbal Air 是一家虚构的客运航空公司。该助理是一个 AI 聊天机器人,可帮助旅客管理航班,以及查询 Cymbal Air 位于旧金山国际机场 (SFO) 的航空枢纽的相关信息。

在不登录(不登录 CLIENT_ID)的情况下,该选项可以帮助回答用户的问题,例如:

飞往丹佛的下一趟航班是什么时候?

C28 号登机口附近有没有奢侈品商店?

A6 号登机口附近在哪里可以喝杯咖啡?

我可以在哪里购买礼物?

请预订上午 10:35 起飞的飞往丹佛的航班

登录该应用后,您可以尝试其他功能,例如预订航班或查看分配给您的座位是否为靠窗或过道座位。

6e7758f707c67c3e

该应用使用最新的 Google 基础模型来生成回答,并通过 Cloud SQL 运营数据库中有关航班和酒店设施的信息扩充回答内容。如需详细了解此演示版应用,请访问项目的 GitHub 页面

9. 清理环境

完成所有任务后,我们就可以清理环境了。

删除 Cloud Run 服务

在 Cloud Shell 中,执行以下命令:

gcloud run services delete retrieval-service --region us-central1

预期的控制台输出:

student@cloudshell:~ (gleb-test-short-004)$ gcloud run services delete retrieval-service --region us-central1
Service [retrieval-service] will be deleted.

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

Deleting [retrieval-service]...done.                                                                                                                                                                                                                 
Deleted service [retrieval-service].

删除 Cloud Run 服务的服务账号

在 Cloud Shell 中,执行以下命令:

PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts delete retrieval-identity@$PROJECT_ID.iam.gserviceaccount.com --quiet

预期的控制台输出:

student@cloudshell:~ (gleb-test-short-004)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-222]
student@cloudshell:~ (gleb-test-short-004)$ gcloud iam service-accounts delete retrieval-identity@$PROJECT_ID.iam.gserviceaccount.com --quiet
deleted service account [retrieval-identity@gleb-test-short-004.iam.gserviceaccount.com]
student@cloudshell:~ (gleb-test-short-004)$

删除 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].

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

删除 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 

删除 GCE 虚拟机和检索服务的服务账号

在 Cloud Shell 中,执行以下命令:

PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts delete compute-aip@$PROJECT_ID.iam.gserviceaccount.com --quiet

预期的控制台输出:

student@cloudshell:~ (gleb-test-short-004)$ PROJECT_ID=$(gcloud config get-value project)
gcloud iam service-accounts delete compute-aip@$PROJECT_ID.iam.gserviceaccount.com --quiet
Your active configuration is: [cloudshell-222]
deleted service account [compute-aip@gleb-test-short-004.iam.gserviceaccount.com]
student@cloudshell:~ (gleb-test-short-004)$ 

10. 恭喜

恭喜您完成此 Codelab。

所学内容

  • 如何创建 Cloud SQL 实例
  • 如何连接到 Cloud SQL 实例
  • 如何配置和部署 GenAI Databases Retrieval Service
  • 如何使用已部署的服务来部署示例应用

11. 调查问卷

您打算如何使用本教程?

仅通读 阅读并完成练习