Comienza a usar las incorporaciones de vectores con la IA de AlloyDB

1. Introducción

En este codelab, aprenderás a usar AlloyDB AI combinando la búsqueda de vectores con las incorporaciones de Vertex AI.

17e86406ab251142.png

Requisitos previos

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

Qué aprenderás

  • Cómo implementar el clúster y la instancia principal de AlloyDB
  • Cómo conectarte a la VM de AlloyDB desde Google Compute Engine
  • Cómo crear una base de datos y habilitar la IA de AlloyDB
  • Cómo cargar datos en la base de datos
  • Cómo usar el modelo de incorporación de Vertex AI en AlloyDB
  • Cómo enriquecer el resultado con el modelo generativo de Vertex AI

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 entorno de autoaprendizaje

  1. Accede a Google Cloud Console y crea un proyecto nuevo o reutiliza uno existente. Si aún no tienes una cuenta de Gmail o de Google Workspace, debes crear una.

fbef9caa1602edd0.png

a99b7ace416376c4.png

5e3ff691252acf41.png

  • El Nombre del proyecto es el nombre visible de los participantes de este proyecto. Es una cadena de caracteres que no se utiliza en las APIs de Google. Puedes actualizarla cuando quieras.
  • 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 Cloud genera automáticamente una cadena única. Por lo general, no importa cuál sea. En la mayoría de los codelabs, deberás hacer referencia al ID de tu proyecto (suele identificarse como PROJECT_ID). Si no te gusta el ID que se generó, podrías generar otro aleatorio. También puedes probar uno propio y ver si está disponible. No se puede cambiar después de este paso y se usa el mismo durante todo el proyecto.
  • 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.
  1. A continuación, deberás habilitar la facturación en la consola de Cloud para usar las APIs o los recursos de Cloud. Ejecutar este codelab no costará mucho, tal vez nada. Para cerrar recursos y evitar que se generen cobros más allá de este instructivo, puedes borrar los recursos que creaste o borrar el proyecto. Los usuarios nuevos de Google Cloud son aptos para participar en el programa Prueba gratuita de $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:

55efc1aaa7a4d3ad.png

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:

7ffe5cbb04455448.png

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:

En Cloud Shell, 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 todos los servicios necesarios con el siguiente comando:

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.

Configura la 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 privado disponible en nuestra VPC para que lo use la instancia futura de AlloyDB. Si no los tenemos, debemos crearlos y asignarlos para que los usen los servicios internos de Google. Después de eso, 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

Crea un clúster de AlloyDB en la región us-central1.

Define una 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

Resultado esperado en la consola:

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

Define la región y el nombre del clúster de AlloyDB. Vamos a usar 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 siguiente 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

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 región y 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. Conéctate a AlloyDB

AlloyDB se implementa con una conexión solo privada, por lo que necesitamos una VM con el cliente 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 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 a tu VM de instance-1.

Usa el valor de la contraseña de AlloyDB indicada (PGPASSWORD) 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 e 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.

4ca978f5142bb6ce.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 bases 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:~$  

Habilitar la integración de Vertex AI

Habilitar la integración de 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:~$ 

Importación de datos

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

En la VM de GCE, ejecuta lo siguiente:

gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
gsutil cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"

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. Calcular las incorporaciones

Después de importar los datos, obtuvimos 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 tiendas en la tabla cymbal_stores. Debemos calcular los datos vectoriales según las descripciones de nuestros productos y para ello usaremos la incorporación de funciones. Usaremos la integración de Vertex AI para calcular datos vectoriales según las descripciones de nuestros productos y agregarlos a la tabla. Puedes leer más sobre la tecnología que se usa en la documentación.

Crear columna de incorporación

Conéctate a la base de datos con psql y crea una columna virtual con los datos vectoriales usando la función de incorporación en la tabla cymbal_products. La función de incorporación devuelve datos vectoriales de Vertex AI según los datos proporcionados desde 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 lo siguiente:

ALTER TABLE cymbal_products ADD COLUMN embedding vector GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;

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

Resultado esperado en la consola:

student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
psql (13.11 (Debian 13.11-0+deb11u1), server 14.7)
WARNING: psql major version 13, server major version 14.
         Some psql features might not work.
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN embedding vector GENERATED ALWAYS AS (embedding('text-embedding-004',product_description)) STORED;
ALTER TABLE
quickstart_db=> 

8. Ejecutar Similarity Search

Ahora podemos ejecutar nuestra búsqueda mediante la búsqueda de similitudes basada en valores vectoriales calculados para las descripciones y el valor vectorial que obtenemos para nuestra solicitud.

La consulta en 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 puede 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 como alternativa en AlloyDB Studio. Para ejecutar el comando, debes hacer clic en la instancia principal a fin de abrir la interfaz de la consola web de tu clúster de AlloyDB.

ef4bfbcf0ed2ef3a.png

Luego, haz clic en AlloyDB Studio a la izquierda:

5c155cbcd7d43a1.png

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

432613065cac864f.png

Se abrirá la interfaz de AlloyDB Studio. Para ejecutar los comandos en la base de datos, haz clic en el botón “Editor 1” a la derecha.

b36c28f8165119ca.png

Abre una interfaz en la que puedes ejecutar comandos de SQL

cf43aa20f292797e.png

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

Ejecuta Similarity Search desde psql

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

Conéctate a la base de datos:

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

Ejecuta una consulta para obtener una lista de los productos disponibles que más se relacionen con la solicitud de un cliente. La solicitud que vamos a pasar a Vertex AI para obtener el valor vectorial suena 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-004','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;

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-004','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.287184013172779
 Toyon               | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e |      10.00 |    93230 | 0.30574073611569963
 Secateurs           | These secateurs are perfect for pruning small branches and vines.                |      15.00 |    93230 |  0.3264385326189635
 Trimming Shears     | These trimming shears are perfect for trimming hedges and bushes.                |      20.00 |    93230 | 0.33293036535756393
 Cypress Tree        | This is a beautiful cypress tree that will provide shade and privacy. It is an e |      75.00 |    93230 | 0.33485770716129326
 Madrone             | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an |      50.00 |    93230 |  0.3354408801293012
 California Redwood  | This is a beautiful redwood tree that can grow to be over 300 feet tall. It is a |    1000.00 |    93230 |  0.3427243109636263
 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.3427628377929176
 California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is  |     300.00 |    93230 |  0.3430208475356905
 Maple Tree          | This is a beautiful maple tree that will produce colorful leaves in the fall. It |     100.00 |    93230 |  0.3432609589330091
(10 rows)

quickstart_db=> 

9. Mejorar respuesta

Puedes mejorar la respuesta de una aplicación cliente con el resultado de la consulta y preparar un resultado significativo con los resultados de la consulta proporcionados como parte de la instrucción para el modelo de lenguaje de base generativo de Vertex AI.

Para lograrlo, planeamos generar un JSON con los resultados de la búsqueda vectorial y, luego, usar ese JSON generado junto con una instrucción de un modelo de LLM de texto en Vertex AI para crear un resultado significativo. En el primer paso, generamos el JSON, lo probamos en Vertex AI Studio y, en el último paso, lo incorporamos en una instrucción 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 devuelve solo una fila para pasar a Vertex AI

Este es el 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-004','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;

Y este es 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 del modelo de texto de IA generativa en Vertex AI Studio.

Abre Vertex AI Studio en la consola de Cloud.

e514b176aef7945e.png

54712e5ade7121f.png

Es posible que se te solicite que habilites APIs adicionales, pero puedes ignorar la solicitud. No necesitamos APIs adicionales para completar nuestro lab.

Esta es la instrucción que usaremos:

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

De acuerdo con 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:

[lugar para nuestro JSON]

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

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

Y este es el resultado cuando ejecutamos la instrucción con nuestros valores JSON y usamos el modelo gemini-1.5-flash:

30e5072cd2975685.png

La respuesta que obtuvimos del modelo en este ejemplo es la siguiente. Ten en cuenta que tu respuesta puede ser diferente debido a que el modelo y los parámetros cambian con el tiempo:

"Veo que estás buscando un árbol que crezca en tu zona. Según tu código postal, 93230, el cerezo parece una gran opción.

Se describe como un hermoso árbol que produce deliciosas cerezas. Actualmente, está en oferta por USD 75.00.

Si bien no tengo detalles específicos sobre la tasa de crecimiento de tu zona, los cerezos suelen preferir un suelo bien drenado y pleno sol.

Para obtener los mejores resultados, te recomendamos que consultes a un experto en jardinería o vivero local que pueda brindarte consejos más personalizados según tu ubicación específica y las condiciones del suelo. También pueden ayudarte a elegir la mejor variedad para tus necesidades y te ofrecen consejos sobre la plantación y el cuidado".

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 con SQL directamente en la base de datos. Pero para usar el modelo gemini-1.5-flash, primero debemos registrarlo.

Actualiza la extensión a la versión 1.3. Conéctate a la base de datos quickstart_db desde pSQL como se mostró antes (o usa AlloyDB Studio) y ejecuta lo siguiente:

ALTER EXTENSION google_ml_integration UPDATE TO '1.3'

Luego, debemos configurar la marca de base de datos google_ml_integration.enable_model_support como "activada". 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_model_support=on \
  --region=$REGION \
  --cluster=$ADBCLUSTER \
  --project=$PROJECT_ID \
  --update-mode=FORCE_APPLY

El comando tarda entre 3 y 5 min en ejecutarse en segundo plano. Luego, puedes verificar la marca nueva en la sesión de psql o usando AlloyDB Studio conectándote a la base de datos quickstart_db.

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)

A continuación, tenemos que registrar dos modelos. El primero es el modelo de text-embedding-004 ya usado. Debe estar registrado porque habilitamos las capacidades de registro de modelos.

Para registrar el modelo, ejecuta el siguiente código en psql o AlloyDB Studio:

CALL
  google_ml.create_model(
    model_id => 'text-embedding-004',
    model_provider => 'google',
    model_qualified_name => 'text-embedding-004',
    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');

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

CALL
  google_ml.create_model(
    model_id => 'gemini-1.5-flash-001',
    model_request_url => 'https://$REGION-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/publishers/google/models/gemini-1.5-flash-001: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 resultado de muestra

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-004      | text_embedding
 gemini-1.5-flash-001    | generic
(4 rows)

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

Ejecuta la consulta en la sesión de psql o AlloyDB Studio en la base de datos.

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-004',
        '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-1.5-flash-001',
        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;

Este es el resultado esperado. El resultado puede ser diferente según la versión del modelo y los parámetros:

--------------------------------------------------------------------------------------------------------
 "I" " see you're interested in fruit trees! Based on your location, I found" " one great option:\n\n**Cherry Tree:** \n\nThis beautiful cherry tree will" " produce delicious cherries. It's a deciduous tree, meaning it loses its leaves in the fall, and can grow up to 15 feet tall. The" " leaves are a vibrant dark green in the summer, turning a beautiful red in the fall. \n\nCherry trees are known for their beauty and ability to provide shade" " and privacy. They prefer a cool, moist climate and sandy soil, making them a good fit for your area. \n\nThe Cherry Tree is currently on sale for $75.00.\n\nWould you like to know more about" " the Cherry Tree, or are you interested in exploring other fruit tree options? \n" ""
(1 row)

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

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 

11. Felicitaciones

Felicitaciones por completar el codelab.

Temas abordados

  • Cómo implementar el clúster y la instancia principal de AlloyDB
  • Cómo conectarte a la VM de AlloyDB desde Google Compute Engine
  • Cómo crear una base de datos y habilitar la IA de AlloyDB
  • Cómo cargar datos en la base de datos
  • Cómo usar el modelo de incorporación de Vertex AI en AlloyDB
  • Cómo enriquecer el resultado con el modelo generativo de Vertex AI

12. Encuesta

Resultado:

¿Cómo usarás este instructivo?

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