Cómo comenzar a usar las incorporaciones vectoriales con la IA de AlloyDB

1. Introducción

En este codelab, aprenderás a usar AlloyDB AI combinando la búsqueda vectorial con los embeddings de Vertex AI. Este lab forma parte de una colección de labs dedicados a las funciones potenciadas por IA de AlloyDB. Puedes obtener más información en la página de AlloyDB AI en la documentación.

81802d1e350b59bb.png

Requisitos previos

  • Conocimientos básicos sobre la consola de Google Cloud
  • Habilidades básicas de la interfaz de línea de comandos y de Google Shell

Qué aprenderás

  • Cómo implementar un clúster y una instancia principal de AlloyDB
  • Cómo conectarse a AlloyDB desde una VM de Google Compute Engine
  • Cómo crear una base de datos y habilitar AlloyDB AI
  • Cómo cargar datos en la base de datos
  • Cómo usar AlloyDB Studio
  • Cómo usar el modelo de incorporación de Vertex AI en AlloyDB
  • Cómo usar Vertex AI Studio
  • Cómo enriquecer el resultado con el modelo generativo de Vertex AI
  • Cómo mejorar el rendimiento con el índice de vectores

Requisitos

  • Una cuenta de Google Cloud y un proyecto de Google Cloud
  • Un navegador web, como Chrome

2. Configuración y requisitos

Configuración del proyecto

  1. Accede a la consola de Google Cloud. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

Usa una cuenta personal en lugar de una cuenta de trabajo o institución educativa.

  1. Crea un proyecto nuevo o reutiliza uno existente. Para crear un proyecto nuevo en la consola de Google Cloud, haz clic en el botón Seleccionar un proyecto en el encabezado, lo que abrirá una ventana emergente.

295004821bab6a87.png

En la ventana Selecciona un proyecto, presiona el botón Proyecto nuevo, que abrirá un cuadro de diálogo para el proyecto nuevo.

37d264871000675d.png

En el cuadro de diálogo, ingresa el nombre del proyecto que prefieras y elige la ubicación.

96d86d3d5655cdbe.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. El nombre del proyecto no se usa en las APIs de Google y se puede cambiar en cualquier momento.
  • El ID del proyecto es único en todos los proyectos de Google Cloud y es inmutable (no se puede cambiar después de configurarlo). La consola de Google Cloud genera automáticamente un ID único, pero puedes personalizarlo. Si no te gusta el ID generado, puedes generar otro aleatorio o proporcionar el tuyo para verificar su disponibilidad. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto, que suele identificarse con el marcador de posición PROJECT_ID.
  • Recuerda que hay un tercer valor, un número de proyecto, que usan algunas APIs. Obtén más información sobre estos tres valores en la documentación.

Habilitar facturación

Para habilitar la facturación, tienes dos opciones. Puedes usar tu cuenta de facturación personal o canjear créditos siguiendo los pasos que se indican a continuación.

Canjea USD 5 en créditos de Google Cloud (opcional)

Para realizar este taller, necesitas una cuenta de facturación con algo de crédito. Si planeas usar tu propia facturación, puedes omitir este paso.

  1. Haz clic en este vínculo y accede con una Cuenta de Google personal.
  2. Verá un resultado similar al que se detalla a continuación:

f54628965f465486.png

  1. Haz clic en el botón HAZ CLIC AQUÍ PARA ACCEDER A TU CRÉDITO. Esto te dirigirá a una página para configurar tu perfil de facturación. Si aparece una pantalla de registro de prueba gratuita, haz clic en Cancelar y continúa con la vinculación de la facturación.

20e88842cf2a732e.png

  1. Haz clic en Confirmar. Ahora estás conectado a una cuenta de facturación de prueba de Google Cloud Platform.

cdc87f1c57777951.png

Configura una cuenta de facturación personal

Si configuraste la facturación con créditos de Google Cloud, puedes omitir este paso.

Para configurar una cuenta de facturación personal, ve aquí para habilitar la facturación en Cloud Console.

Notas:

  • Completar este lab debería costar menos de USD 3 en recursos de Cloud.
  • Puedes seguir los pasos al final de este lab para borrar recursos y evitar cargos adicionales.
  • Los usuarios nuevos son aptos para obtener la prueba gratuita de USD 300.

Inicia Cloud Shell

Si bien Google Cloud y Spanner se pueden operar de manera remota desde tu laptop, en este codelab usarás Google Cloud Shell, un entorno de línea de comandos que se ejecuta en la nube.

En Google Cloud Console, haz clic en el ícono de Cloud Shell en la barra de herramientas en la parte superior derecha:

Activar Cloud Shell

También puedes presionar G y, luego, S. Esta secuencia activará Cloud Shell si estás en la consola de Google Cloud o usas este vínculo.

El aprovisionamiento y la conexión al entorno deberían tomar solo unos minutos. Cuando termine el proceso, debería ver algo como lo siguiente:

Captura de pantalla de la terminal de Google Cloud Shell que muestra que el entorno se conectó

Esta máquina virtual está cargada con todas las herramientas de desarrollo que necesitarás. Ofrece un directorio principal persistente de 5 GB y se ejecuta en Google Cloud, lo que permite mejorar considerablemente el rendimiento de la red y la autenticación. Todo tu trabajo en este codelab se puede hacer en un navegador. No es necesario que instales nada.

3. Antes de comenzar

Habilita la API

Resultado:

Para usar AlloyDB, Compute Engine, servicios de redes y Vertex AI, debes habilitar sus APIs respectivas en tu proyecto de Google Cloud.

Habilita las API

En Cloud Shell, en la terminal, asegúrate de que tu ID del proyecto esté configurado:

gcloud config set project [YOUR-PROJECT-ID]

Configura la variable de entorno PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

Habilita todas las APIs necesarias:

gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com

Resultado esperado

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.

Presentamos las APIs

  • La API de AlloyDB (alloydb.googleapis.com) te permite crear, administrar y escalar clústeres de AlloyDB para PostgreSQL. Proporciona un servicio de base de datos completamente administrado y compatible con PostgreSQL diseñado para cargas de trabajo empresariales transaccionales y analíticas exigentes.
  • La API de Compute Engine (compute.googleapis.com) te permite crear y administrar máquinas virtuales (VM), discos persistentes y parámetros de configuración de red. Proporciona la base de infraestructura como servicio (IaaS) principal necesaria para ejecutar tus cargas de trabajo y alojar la infraestructura subyacente de muchos servicios administrados.
  • La API de Cloud Resource Manager (cloudresourcemanager.googleapis.com) te permite administrar de forma programática los metadatos y la configuración de tu proyecto de Google Cloud. Te permite organizar recursos, controlar políticas de Identity and Access Management (IAM) y validar permisos en toda la jerarquía del proyecto.
  • La API de Service Networking (servicenetworking.googleapis.com) te permite automatizar la configuración de la conectividad privada entre tu red de nube privada virtual (VPC) y los servicios administrados de Google. Se requiere específicamente para establecer el acceso a la IP privada para servicios como AlloyDB, de modo que puedan comunicarse de forma segura con tus otros recursos.
  • La API de Vertex AI (aiplatform.googleapis.com) permite que tus aplicaciones compilen, implementen y escalen modelos de aprendizaje automático. Proporciona la interfaz unificada para todos los servicios de IA de Google Cloud, incluido el acceso a modelos de IA generativa (como Gemini) y el entrenamiento de modelos personalizados.

De manera opcional, puedes configurar tu región predeterminada para usar los modelos de incorporación de Vertex AI. Obtén más información sobre las ubicaciones disponibles para Vertex AI. En el ejemplo, usamos la región us-central1.

gcloud config set compute/region us-central1

4. Implementa AlloyDB

Antes de crear un clúster de AlloyDB, necesitamos un rango de IP privada disponible en nuestra VPC para que lo utilice la instancia futura de AlloyDB. Si no lo tenemos, debemos crearlo, asignarlo para que lo usen los servicios internos de Google y, luego, podremos crear el clúster y la instancia.

Crea un rango de IP privada

Debemos establecer la configuración del acceso privado a servicios en nuestra VPC para AlloyDB. Aquí, suponemos que tenemos la red de VPC “predeterminada” en el proyecto y que se utilizará para todas las acciones.

Crea el rango de IP privada:

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

Crea una conexión privada con el rango de IP asignado:

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

Resultado esperado en la consola:

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)$

Crea un clúster de AlloyDB

En esta sección, crearemos un clúster de AlloyDB en la región us-central1.

Define la contraseña para el usuario de postgres. Puedes definir tu propia contraseña o usar una función aleatoria para generar una.

export PGPASSWORD=`openssl rand -hex 12`

Resultado esperado en la consola:

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

Toma nota de la contraseña de PostgreSQL para utilizarla más adelante.

echo $PGPASSWORD

Necesitarás esa contraseña en el futuro para conectarte a la instancia como usuario de postgres. Te sugiero que lo anotes o lo copies en algún lugar para poder usarlo más adelante.

Resultado esperado en la consola:

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

Crea un clúster de prueba gratuita

Si no usaste AlloyDB antes, puedes crear un clúster de prueba gratuito:

Define la región y el nombre del clúster de AlloyDB. Usaremos la región us-central1 y alloydb-aip-01 como nombre del clúster:

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

Ejecuta el comando para crear el clúster:

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

Resultado esperado en la consola:

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.                                                                                                                                                                                                                                                           

Crea una instancia principal de AlloyDB para nuestro clúster en la misma sesión de Cloud Shell. Si te desconectas, deberás volver a definir las variables de entorno de la región y el nombre del clúster.

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

Resultado esperado en la consola:

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.                                                                                                                                                                                                                                                     

Crea un clúster estándar de AlloyDB

Si no es tu primer clúster de AlloyDB en el proyecto, continúa con la creación de un clúster estándar.

Define la región y el nombre del clúster de AlloyDB. Usaremos la región us-central1 y alloydb-aip-01 como nombre del clúster:

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

Ejecuta el comando para crear el clúster:

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

Resultado esperado en la consola:

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.                                                                                                                                                                                                                                                           

Crea una instancia principal de AlloyDB para nuestro clúster en la misma sesión de Cloud Shell. Si te desconectas, deberás volver a definir las variables de entorno de la región y el nombre del clúster.

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

Resultado esperado en la consola:

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. Conectarte a AlloyDB

AlloyDB se implementa con una conexión solo privada, por lo que necesitamos una VM con el cliente de PostgreSQL instalado para trabajar con la base de datos.

Implementa la VM de GCE

Crea una VM de GCE en la misma región y VPC que el clúster de AlloyDB.

En Cloud Shell, ejecuta el siguiente comando:

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

Resultado esperado en la consola:

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

Instala el cliente de Postgres

Instala el software del cliente de PostgreSQL en la VM implementada

Conéctate a la VM:

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

Resultado esperado en la consola:

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:~$ 

Instala el comando de ejecución de software dentro de la VM:

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

Resultado esperado en la consola:

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

Conéctate a la instancia

Conéctate a la instancia principal desde la VM usando psql.

En la misma pestaña de Cloud Shell con la sesión SSH abierta en tu VM instance-1

Usa el valor de la contraseña de AlloyDB (PGPASSWORD) que se indicó y el ID del clúster de AlloyDB para conectarte a AlloyDB desde la VM de 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"

Resultado esperado en la consola:

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

Cierra la sesión de psql:

exit

6. Prepara la base de datos

Debemos crear una base de datos, habilitar la integración de Vertex AI, crear objetos de base de datos y, luego, importar los datos.

Otorga los permisos necesarios a AlloyDB

Agrega permisos de Vertex AI al agente de servicio de AlloyDB.

Abre otra pestaña de Cloud Shell con el signo "+" en la parte superior.

abc505ac4d41f24e.png

En la nueva pestaña de Cloud Shell, ejecuta lo siguiente:

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"

Resultado esperado en la consola:

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
 

Cierra la pestaña con el comando de ejecución “exit” en la pestaña:

exit

Crea la base de datos

Guía de inicio rápido para crear una base de datos

En la sesión de la VM de GCE, ejecuta lo siguiente:

Crea la base de datos:

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

Resultado esperado en la consola:

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

Habilita la integración de Vertex AI

Habilita la integración en Vertex AI y las extensiones de pgvector en la base de datos.

En la VM de GCE, ejecuta lo siguiente:

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"

Resultado esperado en la consola:

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:~$ 

Importar datos

Descarga los datos preparados y, luego, impórtalos a la nueva base de datos.

En la VM de GCE, ejecuta lo siguiente:

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"

Resultado esperado en la consola:

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. Cómo calcular embeddings

Después de importar los datos, obtuvimos los datos de los productos en la tabla cymbal_products, el inventario que muestra la cantidad de productos disponibles en cada tienda en la tabla cymbal_inventory y la lista de las tiendas en la tabla cymbal_stores. Necesitamos calcular los datos vectoriales en función de las descripciones de nuestros productos, y para ello usaremos la función embedding. Con la función que usaremos, integraremos Vertex AI para calcular los datos vectoriales según las descripciones de nuestros productos y agregarlos a la tabla. Puedes obtener más información sobre la tecnología utilizada en la documentación.

Es fácil generarlo para unas pocas filas, pero ¿cómo hacerlo de manera eficiente si tenemos miles? Aquí te mostraré cómo generar y administrar incorporaciones para tablas grandes. También puedes obtener más información sobre las diferentes opciones y técnicas en la guía.

Habilita la generación rápida de embeddings

Conéctate a la base de datos con psql desde tu VM usando la IP de la instancia de AlloyDB y la contraseña de postgres:

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

Verifica la versión de la extensión google_ml_integration.

SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';

La versión debe ser 1.5.2 o superior. Este es un ejemplo del resultado:

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

La versión predeterminada debe ser la 1.5.2 o una posterior, pero si tu instancia muestra una versión anterior, es probable que deba actualizarse. Verifica si se inhabilitó el mantenimiento de la instancia.

Luego, debemos verificar la marca de la base de datos. Necesitamos que se active la marca google_ml_integration.enable_faster_embedding_generation. En la misma sesión de psql, verifica el valor de la marca.

show google_ml_integration.enable_faster_embedding_generation;

Si la marca está en la posición correcta, el resultado esperado se verá de la siguiente manera:

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

Pero si se muestra como “apagada”, debemos actualizar la instancia. Puedes hacerlo con la consola web o el comando de gcloud, como se describe en la documentación. Aquí te muestro cómo hacerlo con el comando de 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

Puede tardar unos minutos, pero, finalmente, el valor de la marca debería cambiar a "activado". Después, puedes continuar con los siguientes pasos.

Crea una columna de embedding

Conéctate a la base de datos con psql y crea una columna virtual con los datos del vector usando la función de incorporación en la tabla cymbal_products. La función de embedding devuelve datos de vectores de Vertex AI según los datos proporcionados en la columna product_description.

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

En la sesión de psql, después de conectarte a la base de datos, ejecuta el siguiente comando:

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768);

El comando creará la columna virtual y la completará con datos vectoriales.

Resultado esperado en la consola:

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

Ahora podemos generar embeddings en lotes de 50 filas cada uno. Puedes experimentar con diferentes tamaños de lote y ver si cambia el tiempo de ejecución. En la misma sesión de psql, ejecuta lo siguiente:

Habilita la medición del tiempo para calcular cuánto tardará:

\timing

Ejecuta el siguiente comando:

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

Además, el resultado de la consola mostró menos de 2 segundos para la generación de la incorporación:

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

De forma predeterminada, las incorporaciones no se actualizarán si se actualiza la columna product_description correspondiente o se inserta una fila completamente nueva. Sin embargo, puedes hacerlo definiendo el parámetro incremental_refresh_mode. Creemos una columna "product_embeddings" y hagamos que se actualice automáticamente.

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'
);

Ahora, si insertamos una fila nueva en la tabla,

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);

Podemos comparar la diferencia en las columnas con la siguiente consulta:

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

En el resultado, podemos ver que, si bien la columna embedding permanece vacía, la columna product_embedding se actualiza automáticamente.

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. Ejecuta la búsqueda de similitud

Ahora podemos ejecutar nuestra búsqueda con la búsqueda de similitud basada en los valores de vectores calculados para las descripciones y el valor de vector que obtenemos para nuestra solicitud.

La consulta SQL se puede ejecutar desde la misma interfaz de línea de comandos de psql o, como alternativa, desde AlloyDB Studio. Cualquier resultado complejo y de varias filas podría verse mejor en AlloyDB Studio.

Conéctate a AlloyDB Studio

En los siguientes capítulos, todos los comandos de SQL que requieren conexión a la base de datos se pueden ejecutar de forma alternativa en AlloyDB Studio. Para ejecutar el comando, haz clic en la instancia principal para abrir la interfaz de la consola web de tu clúster de AlloyDB.

1d7298e7096e7313.png

Luego, haz clic en AlloyDB Studio a la izquierda:

a33131c72ad29478.png

Elige la base de datos quickstart_db, el usuario postgres y proporciona la contraseña que anotamos cuando creamos el clúster. Luego, haz clic en el botón "Autenticar".

4f26532ecdb5bade.png

Se abrirá la interfaz de AlloyDB Studio. Para ejecutar los comandos en la base de datos, haz clic en la pestaña "Editor 1" que se encuentra a la derecha.

a127047c343731ff.png

Se abre una interfaz en la que puedes ejecutar comandos de SQL.

9d312d5053c1296c.png

Si prefieres usar psql desde la línea de comandos, sigue la ruta alternativa y conéctate a la base de datos desde la sesión SSH de tu VM, como se describió en los capítulos anteriores.

Ejecuta la búsqueda de similitud desde psql

Si se desconectó tu sesión de base de datos, vuelve a conectarte a la base de datos con psql o AlloyDB Studio.

Conéctate a la base de datos:

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

Ejecuta una búsqueda para obtener una lista de los productos disponibles que se relacionan más estrechamente con la solicitud de un cliente. La solicitud que le pasaremos a Vertex AI para obtener el valor del vector será algo así como "¿Qué tipo de árboles frutales crecen bien aquí?".

Esta es la consulta que puedes ejecutar para elegir los primeros 10 elementos más adecuados para nuestra solicitud:

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;

Y este es el resultado esperado:

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. Mejorar la respuesta

Puedes mejorar la respuesta a una aplicación cliente usando el resultado de la búsqueda y preparar un resultado significativo usando los resultados de la búsqueda proporcionados como parte de la instrucción para el modelo de lenguaje fundamental generativo de Vertex AI.

Para lograrlo, planeamos generar un archivo JSON con los resultados de la búsqueda vectorial y, luego, usar ese archivo JSON generado como complemento de una instrucción para un modelo de LLM de texto en Vertex AI y crear un resultado significativo. En el primer paso, generamos el JSON, luego lo probamos en Vertex AI Studio y, en el último paso, lo incorporamos a una instrucción SQL que se puede usar en una aplicación.

Genera el resultado en formato JSON

Modifica la consulta para generar el resultado en formato JSON y devolver solo una fila para pasar a Vertex AI.

A continuación, se muestra un ejemplo de la consulta:

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;

Y aquí está el JSON esperado en el resultado:

[{"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"}]

Ejecuta la instrucción en Vertex AI Studio

Podemos usar el JSON generado para proporcionarlo como parte de la instrucción al modelo de texto de IA generativa en Vertex AI Studio.

Abre Vertex AI Studio en la consola de Cloud.

d48549b1b0f449b4.png

Es posible que te pida que aceptes las condiciones de uso si no lo usaste antes. Presiona el botón "Aceptar y continuar".

Escribe tu instrucción en la interfaz.

2a6f5a338fefd229.png

Es posible que te solicite que habilites APIs adicionales, pero puedes ignorar la solicitud. No necesitamos ninguna API adicional para terminar el lab.

Esta es la instrucción que usaremos con el resultado JSON de la primera búsqueda sobre los árboles:

Eres un asesor amigable que ayuda a encontrar un producto según las necesidades del cliente.

Según la solicitud del cliente, cargamos una lista de productos estrechamente relacionados con la búsqueda.

La lista en formato JSON con una lista de valores como {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}

Esta es la lista de productos:

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

El cliente preguntó: "¿Qué árbol crece mejor aquí?"

Debes proporcionar información sobre el producto, el precio y algunos datos complementarios

d1bde56c910a1627.png

Y aquí está el resultado cuando ejecutamos la instrucción con nuestros valores JSON y usamos el modelo gemini-2.5-flash-light:

9371b7552a73e2bf.png

A continuación, se muestra la respuesta que obtuvimos del modelo en este ejemplo. Ten en cuenta que tu respuesta puede ser diferente debido a los cambios en el modelo y los parámetros a lo largo del tiempo:

"Según los productos disponibles, esto es lo que puedo decirte sobre "Cherry Tree":

Producto: Cherry Tree

Precio: USD 75.00

Descripción: Este es un hermoso cerezo que producirá cerezas deliciosas.

Para determinar qué árbol "crece mejor aquí", necesitaría más información. ¿Tienes otros árboles en la lista que podamos comparar, o hay algún aspecto específico de "crecimiento óptimo" que te interese (p. ej., el crecimiento más rápido, la mayor producción de frutas o la resistencia en tu clima específico)?".

Ejecuta la instrucción en PSQL

Podemos usar la integración de AlloyDB AI con Vertex AI para obtener la misma respuesta de un modelo generativo usando SQL directamente en la base de datos. Sin embargo, para usar el modelo gemini-1.5-flash, primero debemos registrarlo.

Verifica la extensión google_ml_integration. Debe tener la versión 1.4.2 o una posterior.

Conéctate a la base de datos quickstart_db desde psql como se mostró antes (o usa AlloyDB Studio) y ejecuta el siguiente comando:

SELECT extversion from pg_extension where extname='google_ml_integration';

Verifica la marca de base de datos google_ml_integration.enable_model_support.

show google_ml_integration.enable_model_support;

El resultado esperado de la sesión de psql es "on":

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

Si se muestra "off", debemos establecer la marca de base de datos google_ml_integration.enable_model_support en "on". Para ello, puedes usar la interfaz de la consola web de AlloyDB o ejecutar el siguiente comando de 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_faster_embedding_generation=on,google_ml_integration.enable_model_support=on \
  --region=$REGION \
  --cluster=$ADBCLUSTER \
  --project=$PROJECT_ID \
  --update-mode=FORCE_APPLY

El comando tarda entre 1 y 3 minutos en ejecutarse en segundo plano. Luego, puedes volver a verificar el indicador.

Para nuestra búsqueda, necesitamos dos modelos. El primero es el modelo text-embedding-005 que ya se usó, y el segundo es uno de los modelos genéricos de Gemini de Google.

Comenzamos con el modelo de incorporación de texto. Para registrar la ejecución del modelo en psql o AlloyDB Studio, usa el siguiente código:

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');

El siguiente modelo que debemos registrar es gemini-2.0-flash-001, que se usará para generar el resultado fácil de usar.

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');

Siempre puedes verificar la lista de modelos registrados seleccionando información de google_ml.model_info_view.

select model_id,model_type from google_ml.model_info_view;

Este es un ejemplo de resultado:

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)

Ahora podemos usar el JSON generado en una subconsulta para proporcionarlo como parte de la instrucción al modelo de texto de IA generativa con SQL.

En la sesión de psql o AlloyDB Studio de la base de datos, ejecuta la consulta.

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;

Y este es el resultado esperado. Tu resultado puede variar según la versión y los parámetros del modelo:

"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. Crear índice vectorial

Nuestro conjunto de datos es bastante pequeño, y el tiempo de respuesta depende principalmente de la interacción con los modelos de IA. Sin embargo, cuando tienes millones de vectores, la parte de la búsqueda de vectores puede ocupar una parte significativa de nuestro tiempo de respuesta y generar una carga alta en el sistema. Para mejorar eso, podemos crear un índice sobre nuestros vectores.

Crea un índice de ScaNN

Para compilar el índice de SCANN, debemos habilitar una extensión más. La extensión alloydb_scann proporciona una interfaz para trabajar con el índice de vectores de tipo ANN usando el algoritmo ScaNN de Google.

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

Resultado esperado:

quickstart_db=> CREATE EXTENSION IF NOT EXISTS alloydb_scann;
CREATE EXTENSION
Time: 27.468 ms
quickstart_db=> 

El índice se puede crear en modo MANUAL o AUTO. El modo MANUAL está habilitado de forma predeterminada y puedes crear un índice y mantenerlo como cualquier otro índice. Sin embargo, si habilitas el modo AUTO, podrás crear el índice que no requiere mantenimiento de tu parte. Puedes leer en detalle sobre todas las opciones en la documentación. Aquí te mostraré cómo habilitar el modo AUTO y crear el índice. En nuestro caso, no tenemos suficientes filas para crear el índice en modo AUTOMÁTICO, por lo que lo crearemos como MANUAL.

En el siguiente ejemplo, dejo la mayoría de los parámetros como predeterminados y solo proporciono una cantidad de particiones (num_leaves) para el índice:

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

Puedes obtener información sobre el ajuste de los parámetros del índice en la documentación.

Resultado esperado:

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

Compare Response

Ahora podemos ejecutar la consulta de búsqueda vectorial en el modo EXPLAIN y verificar si se usó el índice.

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;

Resultado esperado (oculto para mayor claridad):

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

En el resultado, se puede ver claramente que la consulta usó "Index Scan using cymbal_products_embeddings_scann on cymbal_products".

Y si ejecutamos la consulta sin explicarla:

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;

Resultado esperado:

[{"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"}]

Podemos ver que el resultado es el mismo cerezo que estaba en la parte superior de nuestra búsqueda sin índice. A veces, es posible que no sea el caso y la respuesta pueda devolver no el mismo árbol, sino otros árboles de la parte superior. Por lo tanto, el índice nos brinda rendimiento y, a la vez, es lo suficientemente preciso como para ofrecer buenos resultados.

Puedes probar diferentes índices disponibles para los vectores y más labs y ejemplos con la integración de LangChain disponibles en la página de documentación.

11. Limpia el entorno

Cuando termines el lab, destruye las instancias y el clúster de AlloyDB.

Borra el clúster de AlloyDB y todas las instancias

Si usaste la versión de prueba de AlloyDB No borres el clúster de prueba si planeas probar otros labs y recursos con él. No podrás crear otro clúster de prueba en el mismo proyecto.

El clúster se destruye con la opción force que también borra todas las instancias que pertenecen al clúster.

En Cloud Shell, define el proyecto y las variables de entorno si te desconectaste y se perdieron todos los parámetros de configuración anteriores:

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

Borra el clúster:

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

Resultado esperado en la consola:

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.   

Borra las copias de seguridad de AlloyDB

Borra todas las copias de seguridad de AlloyDB del clúster:

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

Resultado esperado en la consola:

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.                                                                                                                                                                                                                                                            

Ahora podemos destruir nuestra VM

Borra la VM de GCE

En Cloud Shell, ejecuta el siguiente comando:

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

Resultado esperado en la consola:

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

Felicitaciones por completar el codelab.

Este lab forma parte de la ruta de aprendizaje de IA lista para producción con Google Cloud.

Temas abordados

  • Cómo implementar un clúster y una instancia principal de AlloyDB
  • Cómo conectarse a AlloyDB desde una VM de Google Compute Engine
  • Cómo crear una base de datos y habilitar AlloyDB AI
  • Cómo cargar datos en la base de datos
  • Cómo usar AlloyDB Studio
  • Cómo usar el modelo de incorporación de Vertex AI en AlloyDB
  • Cómo usar Vertex AI Studio
  • Cómo enriquecer el resultado con el modelo generativo de Vertex AI
  • Cómo mejorar el rendimiento con el índice de vectores

13. Encuesta

Resultado:

¿Cómo usarás este instructivo?

Solo lo leeré Lo leeré y completaré los ejercicios