1. Введение
В этой лабораторной работе вы научитесь использовать искусственный интеллект AlloyDB, комбинируя векторный поиск с встраиванием вершинного искусственного интеллекта. Эта лабораторная работа входит в серию лабораторных работ, посвящённых функциям искусственного интеллекта AlloyDB. Подробнее см. на странице документации, посвящённой искусственному интеллекту AlloyDB .
Предпосылки
- Базовое понимание Google Cloud, Console
- Базовые навыки работы с интерфейсом командной строки и оболочкой Google
Чему вы научитесь
- Как развернуть кластер AlloyDB и основной экземпляр
- Как подключиться к AlloyDB из виртуальной машины Google Compute Engine
- Как создать базу данных и включить искусственный интеллект AlloyDB
- Как загрузить данные в базу данных
- Как использовать модель встраивания Vertex AI в AlloyDB
- Как обогатить результат с помощью генеративной модели Vertex AI
- Как улучшить производительность с помощью векторного индекса
Что вам понадобится
- Учетная запись Google Cloud и проект Google Cloud
- Веб-браузер, такой как Chrome
2. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в Google Cloud Console и создайте новый проект или используйте существующий. Если у вас ещё нет учётной записи Gmail или Google Workspace, вам необходимо её создать .
- Название проекта — отображаемое имя участников проекта. Это строка символов, не используемая API Google. Вы можете изменить её в любой момент.
- Идентификатор проекта уникален для всех проектов Google Cloud и неизменяем (нельзя изменить после установки). Cloud Console автоматически генерирует уникальную строку; обычно вам не важно, какой именно. В большинстве практических работ вам потребуется указать идентификатор проекта (обычно обозначаемый как
PROJECT_ID
). Если вам не нравится сгенерированный идентификатор, вы можете сгенерировать другой случайный идентификатор. Вы также можете попробовать использовать свой собственный идентификатор и посмотреть, доступен ли он. После этого шага его нельзя будет изменить, и он останется на протяжении всего проекта. - К вашему сведению, существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трёх значениях можно узнать в документации .
- Далее вам нужно включить биллинг в Cloud Console для использования облачных ресурсов/API. Выполнение этой лабораторной работы не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать списания средств за пределами этого руководства, вы можете удалить созданные вами ресурсы или проект. Новые пользователи Google Cloud могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .
Запустить Cloud Shell
Хотя Google Cloud можно управлять удаленно с вашего ноутбука, в этой лабораторной работе вы будете использовать Google Cloud Shell — среду командной строки, работающую в облаке.
В консоли Google Cloud Console нажмите значок Cloud Shell на верхней правой панели инструментов:
Подготовка и подключение к среде займёт всего несколько минут. После завершения вы увидите примерно следующее:
Эта виртуальная машина содержит все необходимые инструменты разработки. Она предоставляет постоянный домашний каталог объёмом 5 ГБ и работает в облаке Google Cloud, что значительно повышает производительность сети и аутентификацию. Всю работу в этой лабораторной работе можно выполнять в браузере. Вам не нужно ничего устанавливать.
3. Прежде чем начать
Включить API
Выход:
Внутри Cloud Shell убедитесь, что настроен идентификатор вашего проекта:
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 нам понадобится доступный диапазон частных IP-адресов в нашей VPC, который будет использоваться будущим экземпляром 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
В этом разделе мы создаем кластер AlloyDB в регионе us-central1.
Задайте пароль для пользователя Postgres. Вы можете задать свой пароль или использовать функцию случайной генерации.
export PGPASSWORD=`openssl rand -hex 12`
Ожидаемый вывод консоли:
student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`
Сохраните пароль PostgreSQL для дальнейшего использования.
echo $PGPASSWORD
Этот пароль понадобится вам в будущем для подключения к экземпляру как пользователь postgres. Рекомендую записать его или скопировать куда-нибудь для дальнейшего использования.
Ожидаемый вывод консоли:
student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD bbefbfde7601985b0dee5723
Создайте бесплатный пробный кластер
Если вы ранее не использовали AlloyDB, вы можете создать бесплатный пробный кластер:
Определите регион и имя кластера 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 \
--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
Если это не первый кластер AlloyDB в проекте, приступайте к созданию стандартного кластера.
Определите регион и имя кластера 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. При отсутствии подключения вам потребуется заново определить переменные среды региона и имени кластера.
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
Создайте виртуальную машину 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-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 с открытым сеансом 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:~$ 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
Добавьте разрешения Vertex AI к агенту службы AlloyDB.
Откройте еще одну вкладку 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
Создать базу данных
Быстрый старт по созданию базы данных.
В сеансе виртуальной машины 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. Функция встраивания возвращает векторные данные из Vertex AI на основе данных из столбца product_description.
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
В сеансе psql после подключения к базе данных выполните:
ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',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(768) GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED; ALTER TABLE quickstart_db=>
8. Запустить поиск по сходству
Теперь мы можем выполнить наш поиск, используя поиск по сходству на основе векторных значений, рассчитанных для описаний, и векторного значения, которое мы получаем для нашего запроса.
SQL-запрос можно выполнить из того же интерфейса командной строки psql или, в качестве альтернативы, из AlloyDB Studio. Многострочные и сложные данные могут выглядеть лучше в AlloyDB Studio.
Подключиться к AlloyDB Studio
В следующих главах все команды SQL, требующие подключения к базе данных, можно также выполнить в AlloyDB Studio. Для выполнения команды необходимо открыть веб-интерфейс консоли кластера AlloyDB, щёлкнув по основному экземпляру.
Затем нажмите на AlloyDB Studio слева:
Выберите базу данных quickstart_db, пользователя postgres и введите пароль, указанный при создании кластера. Затем нажмите кнопку «Аутентифицировать».
Откроется интерфейс AlloyDB Studio. Для выполнения команд в базе данных нажмите на вкладку «Редактор 1» справа.
Открывает интерфейс, в котором можно запускать команды SQL.
Если вы предпочитаете использовать командную строку 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-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
9. Улучшить реакцию
Вы можете улучшить ответ клиентского приложения, используя результат запроса, и подготовить содержательный вывод, используя предоставленные результаты запроса как часть подсказки для базовой языковой модели генеративного ИИ Vertex.
Для этого мы планируем сгенерировать JSON-файл с результатами векторного поиска, а затем использовать этот JSON-файл в качестве дополнения к запросу на текстовую модель LLM в Vertex AI для создания осмысленного результата. На первом этапе мы генерируем 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-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.
Откройте Vertex AI Studio в облачной консоли.
Если вы ещё не пользовались этим сервисом, вам может быть предложено согласиться с его условиями. Нажмите кнопку «Согласен и продолжить».
Напишите подсказку в интерфейсе.
Вам может быть предложено включить дополнительные API, но вы можете проигнорировать этот запрос. Для завершения нашей лабораторной работы нам не нужны дополнительные API.
Вот подсказка, которую мы будем использовать с выводом JSON раннего запроса о деревьях:
Вы дружелюбный консультант, помогающий подобрать продукт, соответствующий потребностям клиента.
По запросу клиента мы загрузили список товаров, тесно связанных с поиском.
Список в формате JSON со списком значений вида {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}
Вот список продуктов:
{"product_name":"Вишневое дерево","description":"Это прекрасное вишневое дерево, которое даст вкусные плоды. Это d","sale_price":75.00,"zip_code":93230,"product_id":"d536e9e823296a2eba198e52dd23e712"}
Клиент спросил: «Какое дерево здесь растет лучше всего?»
Вам следует предоставить информацию о продукте, цене и некоторую дополнительную информацию.
А вот результат, когда мы запускаем приглашение с нашими значениями JSON и используем модель gemini-2.5-flash-light:
Вот ответ, который мы получили от модели в этом примере. Обратите внимание, что ваш ответ может отличаться из-за изменений модели и параметров с течением времени:
«Исходя из имеющихся в наличии продуктов, вот что я могу вам рассказать о «Вишневом дереве»:
Продукт: Вишневое дерево
Цена: 75,00 долларов США
Описание: Это прекрасное вишневое дерево, которое приносит вкусные вишни.
Чтобы определить, какое дерево «растёт здесь лучше всего», мне потребуется больше информации. Есть ли у вас в списке другие деревья, которые мы могли бы сравнить, или вас интересует какой-то конкретный аспект «лучшего роста» (например, самый быстрый рост, самая высокая урожайность, морозостойкость в вашем конкретном климате)?
Запустить приглашение в PSQL
Мы можем использовать интеграцию AlloyDB AI с Vertex AI, чтобы получить тот же ответ от генеративной модели, используя SQL непосредственно в базе данных. Но для использования модели gemini-1.5-flash её необходимо сначала зарегистрировать.
Проверьте расширение google_ml_integration. Оно должно иметь версию 1.4.2 или более позднюю.
Подключитесь к базе данных quickstart_db из psql , как было показано ранее (или используйте AlloyDB Studio), и выполните:
SELECT extversion from pg_extension where extname='google_ml_integration';
Проверьте флаг базы данных google_ml_integration.enable_model_support.
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)
Если отображается значение «off», необходимо установить флаг базы данных 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 минут. После этого вы можете снова проверить флаг.
Для нашего запроса нам понадобятся две модели: первая — уже используемая модель text-embedding-005 , а вторая — одна из универсальных моделей Google Gemini.
Начнём с модели встраивания текста. Чтобы зарегистрировать модель, выполните в psql или AlloyDB Studio следующий код:
CALL
google_ml.create_model(
model_id => 'text-embedding-005',
model_provider => 'google',
model_qualified_name => 'text-embedding-005',
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-2.0-flash-001 , которая будет использоваться для генерации удобного для пользователя вывода.
CALL
google_ml.create_model(
model_id => 'gemini-2.5-flash',
model_request_url => 'publishers/google/models/gemini-2.5-flash: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-005 | text_embedding gemini-2.5-flash | generic (4 rows)
Теперь мы можем использовать сгенерированный в подзапросе JSON для предоставления его как части подсказки для генеративной текстовой модели ИИ с помощью 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
json_array_elements(google_ml.predict_row( model_id =>'gemini-2.5-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
string_agg(resp::text,
' ')
FROM
response;
Вот ожидаемый результат. Ваш результат может отличаться в зависимости от версии модели и параметров:
"Hello there! I can certainly help you with finding a great fruit tree for your area.\n\nBased on what grows well, we have a wonderful **Cherry Tree** that could be a perfect fit!\n\nThis beautiful cherry tree is an excellent choice for producing delicious cherries right in your garden. It's an deciduous tree that typically" " grows to about 15 feet tall. Beyond its fruit, it offers lovely aesthetics with dark green leaves in the summer that transition to a beautiful red in the fall, making it great for shade and privacy too.\n\nCherry trees generally prefer a cool, moist climate and sandy soil, and they are best suited for USDA Zones" " 4-9. Given the zip code you're inquiring about (93230), which is typically in USDA Zone 9, this Cherry Tree should thrive wonderfully!\n\nYou can get this magnificent tree for just **$75.00**.\n\nLet me know if you have any other questions!" "
10. Создать векторный индекс
Наш набор данных довольно небольшой, и время отклика в основном зависит от взаимодействия с моделями ИИ. Но при наличии миллионов векторов поиск по ним может занять значительную часть времени отклика и создать высокую нагрузку на систему. Чтобы улучшить ситуацию, мы можем создать индекс на основе наших векторов.
Создать индекс ScaNN
Для построения индекса SCANN нам потребуется включить ещё одно расширение. Расширение alloydb_scann предоставляет интерфейс для работы с векторным индексом типа ANN с использованием алгоритма Google ScaNN.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
Ожидаемый результат:
quickstart_db=> CREATE EXTENSION IF NOT EXISTS alloydb_scann; CREATE EXTENSION Time: 27.468 ms quickstart_db=>
Теперь мы можем создать индекс. В следующем примере я оставляю большинство параметров по умолчанию и указываю только количество разделов (num_leaves) для индекса:
CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
USING scann (embedding cosine)
WITH (num_leaves=31, max_num_levels = 2);
О настройке параметров индекса можно прочитать в документации .
Ожидаемый результат:
quickstart_db=> CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products USING scann (embedding cosine) WITH (num_leaves=31, max_num_levels = 2); CREATE INDEX quickstart_db=>
Сравнить ответ
Теперь мы можем запустить запрос поиска вектора в режиме EXPLAIN и проверить, использовался ли индекс.
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=16.59..16.60 rows=1 width=32) (actual time=2.875..2.877 rows=1 loops=1) -> Subquery Scan on trees (cost=8.42..16.59 rows=1 width=142) (actual time=2.860..2.862 rows=1 loops=1) -> Limit (cost=8.42..16.58 rows=1 width=158) (actual time=2.855..2.856 rows=1 loops=1) -> Nested Loop (cost=8.42..6489.19 rows=794 width=158) (actual time=2.854..2.855 rows=1 loops=1) -> Nested Loop (cost=8.13..6466.99 rows=794 width=938) (actual time=2.742..2.743 rows=1 loops=1) -> Index Scan using cymbal_products_embeddings_scann on cymbal_products cp (cost=7.71..111.99 rows=876 width=934) (actual time=2.724..2.724 rows=1 loops=1) Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,-0.00355923,0.0055611245,0.015985578,...<redacted>...5685,-0.03914233,-0.018452475,0.00826032,-0.07372604]'::vector) -> Index Scan using walmart_inventory_pkey on cymbal_inventory ci (cost=0.42..7.26 rows=1 width=37) (actual time=0.015..0.015 rows=1 loops=1) Index Cond: ((store_id = 1583) AND (uniq_id = (cp.uniq_id)::text)) ...
Из выходных данных ясно видно, что запрос использовал «Сканирование индекса с использованием cymbal_products_embeddings_scann на cymbal_products».
А если мы выполним запрос без объяснения:
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":"Meyer Lemon Tree","description":"Meyer Lemon trees are California's favorite lemon tree! Grow your own lemons by ","sale_price":34,"zip_code":93230,"product_id":"02056727942aeb714dc9a2313654e1b0"}]
Мы видим, что результат немного отличается и возвращает не вишню, которая была на первом месте в нашем поиске без индекса, а лимон Мейера, который оказался на втором месте. Таким образом, индекс обеспечивает производительность, но при этом достаточно точен для получения хороших результатов.
Вы можете попробовать различные индексы, доступные для векторов, а также больше лабораторных работ и примеров с интеграцией langchain, доступных на странице документации .
11. Очистите окружающую среду
По завершении лабораторной работы уничтожьте экземпляры и кластер AlloyDB.
Удалить кластер AlloyDB и все экземпляры
Если вы использовали пробную версию AlloyDB. Не удаляйте пробный кластер, если планируете тестировать другие лабораторные работы и ресурсы с его помощью. Вы не сможете создать другой пробный кластер в том же проекте.
Кластер уничтожается с помощью опции force, которая также удаляет все экземпляры, принадлежащие кластеру.
В облачной оболочке определите переменные проекта и среды, если вы были отключены и все предыдущие настройки были утеряны:
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 VM
В Cloud Shell выполните:
export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
Ожидаемый вывод консоли:
student@cloudshell:~ (test-project-001-402417)$ export GCEVM=instance-1 export ZONE=us-central1-a gcloud compute instances delete $GCEVM \ --zone=$ZONE \ --quiet Deleted
12. Поздравления
Поздравляем с завершением лабораторной работы.
Что мы рассмотрели
- Как развернуть кластер AlloyDB и основной экземпляр
- Как подключиться к AlloyDB из виртуальной машины Google Compute Engine
- Как создать базу данных и включить искусственный интеллект AlloyDB
- Как загрузить данные в базу данных
- Как использовать модель встраивания Vertex AI в AlloyDB
- Как обогатить результат с помощью генеративной модели Vertex AI
- Как улучшить производительность с помощью векторного индекса
13. Опрос
Выход: