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 de AlloyDB AI. 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 Google Cloud y la consola
  • Habilidades básicas con la interfaz de línea de comandos y Cloud 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 Gemini Enterprise Agent Platform en AlloyDB
  • Cómo usar Gemini Enterprise Agent Platform Studio
  • Cómo enriquecer el resultado con el modelo generativo de Gemini Enterprise Agent Platform
  • 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 laboral o 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 del encabezado, que abrirá una ventana emergente.

295004821bab6a87.png

En la ventana Select a project, presiona el botón New Project, 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 del 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

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 la consola de Cloud.

Algunas 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 pueden acceder a 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 Gemini Enterprise Agent Platform, debes habilitar sus respectivas APIs 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.

Puedes leer sobre cada API habilitada en la documentación.

4. Implementa AlloyDB

Antes de crear un clúster de AlloyDB, asigna un rango de IP privada disponible en tu VPC para que lo utilice la instancia futura de AlloyDB. Si no la tienes, debes crearla, asignarla para que la usen los servicios internos de Google y, luego, podrás crear el clúster y la instancia.

Crea un rango de IP privada

Debes establecer la configuración del acceso privado a servicios en nuestra VPC para AlloyDB. Aquí, suponemos que tienes 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

Crea 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 16`

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 el usuario postgres. Guarda esta contraseña para usarla en los pasos posteriores.

Resultado esperado en la consola:

student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD
bbefbfde7601985b0dee5723 (Note: Yours will be different!)

Crea un clúster de prueba gratuita

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

Configura las variables de entorno para la región y el 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 tu 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. Si ya creaste un clúster de prueba gratuita, omite este paso.

Configura las variables de entorno para la región y el 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 tu 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 necesitas una VM de Compute Engine 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-13 AND family!=debian-13-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
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-13 AND family!=debian-13-arm64" --format="value(name)") \
    --scopes=https://www.googleapis.com/auth/cloud-platform

Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/zones/us-central1-a/instances/instance-1].
NAME: instance-1
ZONE: us-central1-a
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE: 
INTERNAL_IP: 10.128.0.2
EXTERNAL_IP: 34.71.192.233
STATUS: RUNNING

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 6.12.101+deb13-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.101-1 (2026-08-05) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
student@instance-1:~$ 

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 file:/etc/apt/mirrors/debian.list Mirrorlist [30 B]
Get:2 file:/etc/apt/mirrors/debian-security.list Mirrorlist [39 B]                      
Hit:3 https://deb.debian.org/debian trixie InRelease                                    
Get:4 https://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:5 https://deb.debian.org/debian trixie-backports InRelease [54.0 kB]
Get:6 https://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]
Hit:10 https://packages.cloud.google.com/apt google-compute-engine-trixie-stable InRelease
...redacted...
update-alternatives: using /usr/share/postgresql/17/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode
Setting up postgresql-client (17+278) ...
Processing triggers for man-db (2.13.1-1) ...
Processing triggers for libc-bin (2.41-12+deb13u3) ...

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 de 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:~$ export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-aip-01
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"
psql (17.10 (Debian 17.10-0+deb13u1), server 17.9)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: postgresql)
Type "help" for help.

postgres=>

Cierra la sesión de psql:

exit

6. Prepara la base de datos

Crea una base de datos, habilita la integración de IA de Agent Platform, crea objetos de base de datos y, luego, importa datos.

Otorga los permisos necesarios a AlloyDB

Agrega permisos de Gemini Enterprise Agent Platform 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 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, tendrás los datos de 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. Debes calcular los datos vectoriales en función de las descripciones de los productos y puedes usar funciones como google_ml.embedding para ello. Obtén más información sobre la tecnología utilizada en la documentación.

Es fácil generar embeddings para unas pocas filas, pero ¿cómo hacerlo de manera eficiente si tenemos miles? En esta sección, se explica cómo generar y administrar embeddings para tablas grandes. Obtén 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.6
(1 row)

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

Verifica que la marca de base de datos google_ml_integration.enable_faster_embedding_generation esté activada. 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)

Si el valor de la marca muestra "off", debes actualizar la instancia. Hazlo con la consola web o el comando de gcloud como se describe en la documentación.

Sal de la sesión de psql:

exit;

Para actualizar la marca con gcloud, ejecuta el siguiente comando:

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 el tipo de datos vectoriales que usará la función de incorporación en la tabla cymbal_products.

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 crea una columna virtual para las futuras incorporaciones.

Resultado esperado en la consola:

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

Genera embeddings en lotes de 50 filas. En la misma sesión de psql, ejecuta lo siguiente:

Habilita la sincronización para medir cuánto tiempo 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=>

Puedes experimentar con diferentes tamaños de lote y ver si cambia el tiempo de ejecución.

De forma predeterminada, las incorporaciones no se actualizan si se actualiza la columna product_description correspondiente o se inserta una fila nueva completa. Sin embargo, puedes hacerlo configurando el parámetro incremental_refresh_mode.

Crea una columna "product_embeddings" y haz 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'
);

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

Consulta la tabla para comparar dos columnas de incorporación:

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

El resultado muestra que product_embedding se completa automáticamente, mientras que embedding permanece vacío:

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

Ejecuta una búsqueda de similitud basada en los embeddings de vectores generados con AlloyDB AI.

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 funciona mejor en AlloyDB Studio.

Conéctate a AlloyDB Studio

Para abrir AlloyDB Studio, sigue estos pasos:

  1. En la consola de Google Cloud, ve a la página Clústeres de AlloyDB para PostgreSQL.
  2. Selecciona tu instancia principal para abrir su interfaz web.

1d7298e7096e7313.png3. Luego, haz clic en AlloyDB Studio a la izquierda:

a33131c72ad29478.png

  1. Selecciona la base de datos quickstart_db, el usuario postgres, proporciona la contraseña que se indicó y haz clic en Autenticar.

4f26532ecdb5bade.png

Esta acción abrirá la interfaz de AlloyDB Studio.

  1. Selecciona la pestaña Consulta sin título para abrir el editor de SQL.

6696bc771fab9983.png

Se abrirá un editor en el que podrás ejecutar comandos de SQL, como se muestra en la siguiente imagen:

ae34288e5bf237c7.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 una búsqueda para obtener una lista de los productos disponibles que se relacionan más estrechamente con la solicitud de un cliente. La frase de búsqueda que se pasó al modelo de embedding en Gemini Enterprise Agent Platform (la misma que usamos para generar embeddings para nuestros productos) para obtener el valor del vector de "¿Qué tipo de árboles frutales crecen bien aquí?".

Ejecuta la consulta:

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

Obtendrás 10 productos con descripciones semánticamente cercanas a la frase de búsqueda, ordenados por la distancia, con los más similares en la parte superior.

9. Mejora la respuesta

Puedes mejorar la respuesta a una aplicación cliente usando el resultado de la búsqueda y preparar una salida significativa usando los resultados de la búsqueda proporcionados como parte de la instrucción a un modelo de lenguaje generativo de base.

Para lograrlo, generas un JSON con los principales resultados de la búsqueda vectorial y, luego, usas ese JSON generado como complemento de una instrucción para un modelo de IA generativa en Agent Platform para crear un resultado significativo. El primer paso genera el JSON, luego se prueba en Agent Platform Studio y el último paso incorpora todo en una sentencia de SQL que se puede usar en una aplicación.

Genera resultados en formato JSON

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

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

El JSON 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

Usa el JSON generado para proporcionarlo como parte del mensaje al modelo de IA generativa en Vertex AI Studio.

Abre Gemini Enterprise Agent Platform Studio en la consola de Google Cloud.

154dc1a290c37f.jpeg

Escribe tu instrucción en la interfaz:

fd3abd6062009ee6.jpeg

Escribe la siguiente instrucción:

You are a friendly advisor helping to find a product based on the customer's needs.

Based on the client request we have loaded a list of products closely related to search.

The list in JSON format with list of values like {"product_name":"name","description":"some description","sale_price":10,"zip_code": 10234, "produt_id": "02056727942aeb714dc9a2313654e1b0"}

Here is the list of products:

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

The customer asked "What tree is growing the best here?"

You should give information about the product, price and some supplemental information

edeea32a69d81aee.jpeg

Y este es el resultado cuando ejecutamos la instrucción :

831038ea1d819be6.jpeg

La respuesta incluye el precio, la descripción y la información complementaria que el modelo obtiene de fuentes externas en función de la información sobre el árbol y la ubicación.

Ejecuta la instrucción en PSQL

Puedes obtener un resultado similar ejecutando la integración de AlloyDB AI con Gemini Enterprise Agent Platform para obtener la misma respuesta de un modelo generativo con SQL directamente en la base de datos. Antes de usar el modelo gemini-3.6-flash, debes registrarlo.

Registra el modelo gemini-3.6-flash:

En la ejecución de AlloyDB Studio, haz lo siguiente:

CALL google_ml.create_model(
model_id => 'gemini-3.6-flash',
model_request_url => 'https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/publishers/google/models/gemini-3.6-flash:generateContent',
model_provider => 'google',
model_type => 'llm'
);

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 WHERE model_id ILIKE '%flash%';

Este es un ejemplo de resultado:

quickstart_db=> SELECT model_id,model_type FROM google_ml.model_info_view WHERE model_id ILIKE '%flash%';
       model_id        | model_type 
-----------------------+------------
 gemini-3.6-flash      | llm
 gemini-2.0-flash      | llm
 gemini-2.5-flash      | llm
 gemini-2.0-flash-lite | llm
 gemini-2.5-flash-lite | llm
(5 rows)

Ahora puedes usar el JSON generado en una subconsulta como parte de la instrucción para el modelo gemini-3.6-flash con SQL.

En tu sesión de psql o AlloyDB Studio, ejecuta la siguiente 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
        google_ml.predict_row( model_id =>'gemini-3.6-flash',
        request_body => json_build_object('contents',
        json_build_object('role',
        'user',
        'parts',
        json_build_object('text',
        prompt_text))))->'candidates'->0->'content'->'parts'->0->'text' AS resp
FROM
        prompt)
SELECT
REPLACE(resp::text, '\n', CHR(10))
FROM
        response;

Y este es el resultado esperado. El resultado podría ser diferente debido a la naturaleza no determinística de los modelos de IA generativa:

"Hello there! I'd be delighted to help you pick out a wonderful fruit tree for your space. Based on our local selection, a fantastic option that grows very well is the **Cherry Tree**! Here are the details on this beautiful tree: * **Product:** Cherry Tree * **Price:** $75.00 ### Why it's a great choice: * **Delicious Harvest:** It produces tasty, fresh cherries right in your backyard. * **Size & Benefits:** It's a deciduous tree that grows to about 15 feet tall, making it ideal for providing both lovely shade and a bit of privacy. * **Year-Round Beauty:** It features lush, dark green leaves throughout the summer that transform into a stunning red in the autumn. * **Growing Requirements:** Cherry trees thrive best in cool, moist climates with sandy soil, and are perfectly suited for USDA hardiness zones 4 through 9. Please let me know if you have any questions about planting or if you'd like help adding this to your order!"

10. Crear índice vectorial

Dado que este conjunto de datos es pequeño, los tiempos de respuesta dependen principalmente de las interacciones con los modelos en Gemini Enterprise Agent Platform. Sin embargo, cuando consultas millones de vectores, la búsqueda de vectores en sí puede consumir una parte significativa del tiempo de respuesta y aumentar la carga en tu base de datos. Para mejorar el rendimiento de la búsqueda, puedes compilar un índice de vectores.

Crea un índice de ScaNN

Para compilar un índice de ScaNN, debes habilitar una extensión adicional. La extensión alloydb_scann proporciona una interfaz para trabajar con índices de vectores de vecino más cercano aproximado (ANN) con el algoritmo ScaNN de Google.

Ejecuta el código en AlloyDB Studio:

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

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. No tenemos suficientes filas para crear el índice en el modo AUTOMÁTICO, por lo que lo crearás como MANUAL.

Ejecuta el siguiente comando en AlloyDB Studio:

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

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=10, max_num_levels = 1);
CREATE INDEX
quickstart_db=>

Comparar respuesta

Repite la consulta que usamos para obtener el valor superior en la búsqueda semántica:

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

El mismo "Cherry Tree" en el resultado.

Verifica el uso del í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=27.24..27.25 rows=1 width=32) (actual time=0.964..0.965 rows=1 loops=1)
   ->  Subquery Scan on trees  (cost=18.91..27.23 rows=1 width=142) (actual time=0.953..0.954 rows=1 loops=1)
         ->  Limit  (cost=18.91..27.22 rows=1 width=158) (actual time=0.948..0.949 rows=1 loops=1)
               ->  Nested Loop  (cost=18.91..7126.86 rows=855 width=158) (actual time=0.948..0.948 rows=1 loops=1)
                     ->  Nested Loop  (cost=18.63..7103.59 rows=855 width=907) (actual time=0.931..0.931 rows=1 loops=1)
                           ->  Index Scan using cymbal_products_embeddings_scann on cymbal_products cp  (cost=18.21..343.15 rows=942 width=903) (actual time=0.906..0.908 rows=2 loops=1)
                                 Order By: (embedding <=> '[-0.106554024,0.035774965,-0.027267234,-0.045653425,-0.03286045,0.02124319...

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

La consulta devuelve el mismo árbol de cerezo que apareció en la parte superior de los resultados de la búsqueda antes de que crearas el índice. Dado que los índices de vecino más cercano aproximado (ANN) sacrifican la exactitud absoluta por la velocidad de búsqueda, es posible que, en ocasiones, las búsquedas basadas en índices muestren resultados principales ligeramente diferentes a los de una búsqueda exacta sin indexar. Sin embargo, el índice de vectores proporciona un aumento significativo del rendimiento y, al mismo tiempo, mantiene una alta precisión.

Para explorar más, puedes probar otros tipos de índices de vectores o encontrar más labs y ejemplos con la integración de LangChain 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

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

Si se desconectó tu terminal, vuelve a conectarte y define las variables de entorno y del proyecto en Cloud Shell:

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

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 Gemini Enterprise Agent Platform en AlloyDB
  • Cómo usar Gemini Enterprise Agent Platform Studio
  • Cómo enriquecer el resultado con el modelo generativo de Gemini Enterprise Agent Platform
  • 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