Начало работы с векторными встраиваниями с помощью AlloyDB AI

1. Введение

В этом практическом занятии вы научитесь использовать AlloyDB AI, комбинируя векторный поиск с встраиваниями Vertex AI. Это занятие является частью серии практических занятий, посвященных возможностям AlloyDB AI. Подробнее можно узнать на странице AlloyDB AI в документации.

81802d1e350b59bb.png

Предварительные требования

  • Базовое понимание Google Cloud и консоли.
  • Базовые навыки работы с интерфейсом командной строки и Cloud Shell.

Что вы узнаете

  • Как развернуть кластер AlloyDB и основной экземпляр
  • Как подключиться к AlloyDB из виртуальной машины Google Compute Engine
  • Как создать базу данных и включить AlloyDB AI
  • Как загрузить данные в базу данных
  • Как использовать AlloyDB Studio
  • Как использовать модель встраивания Gemini Enterprise Agent Platform в AlloyDB
  • Как использовать 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

  • Название проекта — это отображаемое имя участников данного проекта. Название проекта не используется API Google и может быть изменено в любое время.
  • Идентификатор проекта (Project ID) уникален для всех проектов Google Cloud и является неизменяемым (его нельзя изменить после установки). Консоль Google Cloud автоматически генерирует уникальный идентификатор, но вы можете настроить его. Если вам не нравится сгенерированный идентификатор, вы можете сгенерировать другой случайный или указать свой собственный, чтобы проверить его доступность. В большинстве практических заданий вам потребуется указать идентификатор вашего проекта, который обычно обозначается заполнителем PROJECT_ID.
  • К вашему сведению, существует третье значение — номер проекта , которое используется некоторыми API. Подробнее обо всех трех значениях можно узнать в документации .

Включить выставление счетов

Создайте личный платежный аккаунт.

Если вы настроили оплату с использованием кредитов Google Cloud, этот шаг можно пропустить.

Чтобы настроить личный платежный аккаунт, перейдите сюда, чтобы включить оплату в облачной консоли.

Несколько замечаний:

  • Выполнение этой лабораторной работы должно обойтись менее чем в 3 доллара США в виде облачных ресурсов.
  • В конце этой лабораторной работы вы можете выполнить действия по удалению ресурсов, чтобы избежать дальнейших списаний средств.
  • Новые пользователи могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .

Запустить Cloud Shell

Хотя Google Cloud можно управлять удаленно с ноутбука, в этом практическом занятии вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.

В консоли Google Cloud нажмите на значок Cloud Shell на панели инструментов в правом верхнем углу:

Активировать Cloud Shell

В качестве альтернативы вы можете нажать G, а затем S. Эта последовательность активирует Cloud Shell, если вы находитесь в консоли Google Cloud, или воспользуйтесь этой ссылкой .

Подготовка и подключение к среде займут всего несколько минут. После завершения вы должны увидеть что-то подобное:

Скриншот терминала Google Cloud Shell, показывающий, что среда подключена.

Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объемом 5 ГБ и работает в облаке Google, что значительно повышает производительность сети и аутентификацию. Вся работа в этом практическом задании может выполняться в браузере. Вам не нужно ничего устанавливать.

3. Прежде чем начать

Включить API

Выход:

Для использования AlloyDB , Compute Engine , сетевых сервисов и Gemini Enterprise Agent Platform необходимо включить соответствующие API в вашем проекте Google Cloud.

Включение API

В терминале Cloud Shell убедитесь, что идентификатор вашего проекта указан правильно:

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 выделите доступный диапазон частных IP-адресов в вашей VPC для использования будущим экземпляром AlloyDB. Если у вас его нет, вам необходимо его создать, назначить для использования внутренними сервисами Google, после чего вы сможете создать кластер и экземпляр.

Создать частный диапазон IP-адресов

Вам необходимо настроить параметры доступа к частной сети (Private Service Access, VPC) в вашей 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

Создайте кластер AlloyDB в регионе us-central1

Задайте пароль для пользователя 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.                                                                                                                                                                                                                                                           

Создайте основной экземпляр AlloyDB для вашего кластера в той же сессии Cloud Shell. Если вы отключены, вам потребуется заново определить переменные среды для региона и имени кластера.

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.                                                                                                                                                                                                                                                           

Создайте основной экземпляр AlloyDB для вашего кластера в той же сессии Cloud Shell. Если вы отключены, вам потребуется заново определить переменные среды для региона и имени кластера.

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 развертывается с использованием только частного подключения, поэтому для работы с базой данных вам потребуется виртуальная машина Compute Engine с установленным клиентом PostgreSQL.

Развертывание виртуальной машины GCE

Создайте виртуальную машину GCE в том же регионе и VPC, что и кластер AlloyDB.

В оболочке 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

Установите клиент 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 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:~$ 

Установите программное обеспечение, запускаемое командой внутри виртуальной машины:

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.

В той же вкладке Cloud Shell, где открыта SSH-сессия к вашей виртуальной машине instance-1.

Используйте указанное значение пароля AlloyDB (PGPASSWORD) и идентификатор кластера AlloyDB для подключения к AlloyDB с виртуальной машины GCE:

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

Добавьте разрешения Gemini Enterprise Agent Platform для агента службы AlloyDB.

Откройте еще одну вкладку Cloud Shell, используя знак "+" вверху.

abc505ac4d41f24e.png

В новой вкладке облачной оболочки выполните:

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

Создать базу данных

Быстрый старт создания базы данных.

В сессии виртуальной машины 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 выполните:

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 . Подробнее об используемой технологии читайте в документации .

Создать векторные представления для нескольких строк несложно, но как сделать это эффективно, если их тысячи? В этом разделе объясняется, как создавать и управлять векторными представлениями для больших таблиц. Подробнее о различных вариантах и ​​методах читайте в руководстве .

Включить быструю генерацию встраиваний

Подключитесь к базе данных с помощью psql с вашей виртуальной машины, используя IP-адрес экземпляра AlloyDB и пароль от PostgreSQL:

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 установлен в значение on. В той же сессии 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);

Выполните запрос к таблице для сравнения двух столбцов с векторными представлениями:

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.png 3. Затем нажмите на AlloyDB Studio слева:

a33131c72ad29478.png

  1. Выберите базу данных quickstart_db , пользователя postgres, укажите указанный пароль и нажмите «Аутентифицировать».

4f26532ecdb5bade.png

Это действие открывает интерфейс AlloyDB Studio.

  1. Чтобы открыть редактор SQL-запросов, выберите вкладку «Безымянный запрос».

6696bc771fab9983.png

Это откроет редактор, в котором можно выполнять команды SQL, как показано на следующем изображении:

ae34288e5bf237c7.png

Если вы предпочитаете использовать psql из командной строки, то воспользуйтесь альтернативным способом и подключитесь к базе данных из 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 используется в качестве дополнения к запросу для модели Gen AI в Agent Platform для создания осмысленного выходного результата. На первом этапе генерируется JSON, затем он тестируется в Agent Platform Studio, а на последнем этапе все объединяется в один SQL-запрос, который можно использовать в приложении.

Сгенерировать выходные данные в формате JSON.

Измените запрос так, чтобы он генерировал выходные данные в формате JSON и возвращал только одну строку для передачи на платформу агента.

Выполните запрос:

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.

Откройте Gemini Enterprise Agent Platform Studio в консоли Google Cloud.

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)

Теперь вы можете использовать JSON, сгенерированный в подзапросе, в качестве части запроса для модели gemini-3.6-flash с помощью SQL.

В сессии 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;

А вот ожидаемый результат. Результат может отличаться из-за недетерминированной природы генеративных моделей ИИ:

"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 предоставляет интерфейс для работы с векторными индексами приближенного ближайшего соседа (ANN) с использованием алгоритма Google ScaNN.

Запустите в AlloyDB Studio:

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

Индекс можно создать в ручном (MANUAL) или автоматическом (AUTO) режиме. Ручной режим включен по умолчанию, и вы можете создать индекс и поддерживать его так же, как и любой другой индекс. Но если вы включите автоматический режим, вы сможете создать индекс, который не потребует от вас никакого обслуживания. Подробно обо всех параметрах можно прочитать в документации. У нас недостаточно строк для создания индекса в автоматическом режиме, поэтому вам нужно будет создать его в ручном режиме.

Запустите в 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"}]

В выходных данных та же самая "вишневая роща".

Проверьте использование индекса:

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...

Из выходных данных видно, что запрос использовал "Index Scan using cymbal_products_embeddings_scann on cymbal_products".

Запрос возвращает то же самое дерево черешни, которое отображалось вверху результатов поиска до создания индекса. Поскольку индексы приблизительного ближайшего соседа (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.                                                                                                                                                                                                                                                            

Теперь мы можем уничтожить нашу виртуальную машину.

Удалить виртуальную машину 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 

12. Поздравляем!

Поздравляем с завершением практического занятия!

Данная лабораторная работа является частью учебного курса "Готовый к внедрению ИИ в производство с использованием Google Cloud".

  • Изучите полный учебный план , чтобы преодолеть разрыв между прототипом и серийным производством.
  • Делитесь своими успехами, используя хэштег #ProductionReadyAI .

Что мы рассмотрели

  • Как развернуть кластер AlloyDB и основной экземпляр
  • Как подключиться к AlloyDB из виртуальной машины Google Compute Engine
  • Как создать базу данных и включить AlloyDB AI
  • Как загрузить данные в базу данных
  • Как использовать AlloyDB Studio
  • Как использовать модель встраивания Gemini Enterprise Agent Platform в AlloyDB
  • Как использовать Gemini Enterprise Agent Platform Studio
  • Как улучшить результаты, используя генеративную модель платформы Gemini Enterprise Agent Platform
  • Как повысить производительность с помощью векторного индекса

13. Опрос

Выход:

Как вы будете использовать этот учебный материал?

Прочитайте только до конца. Прочитайте текст и выполните упражнения.