1. Introdução
Neste codelab, você vai aprender a usar a integração de IA do Cloud SQL para PostgreSQL combinando a pesquisa vetorial com os embeddings da Vertex AI.

Pré-requisitos
- Conhecimentos básicos sobre o Google Cloud e o console
- Habilidades básicas na interface de linha de comando e no Cloud Shell
O que você vai aprender
- Como implantar uma instância do Cloud SQL para PostgreSQL
- Como criar um banco de dados e ativar a integração de IA do Cloud SQL
- Como carregar dados no banco de dados
- Como usar o Cloud SQL Studio
- Como usar o modelo de embedding da Vertex AI no Cloud SQL
- Como usar o Vertex AI Studio
- Como enriquecer o resultado usando o modelo generativo da Vertex AI
- Como melhorar a performance usando o índice de vetor
O que é necessário
- Uma conta e um projeto do Google Cloud
- Um navegador da Web, como o Chrome, com suporte ao console do Google Cloud e ao Cloud Shell
2. Configuração e requisitos
Configuração do projeto
- Faça login no Console do Google Cloud. Crie uma conta do Gmail ou do Google Workspace, se ainda não tiver uma.
Use uma conta pessoal em vez de uma conta escolar ou de trabalho.
- Crie um novo projeto ou reutilize um existente. Para criar um projeto no console do Google Cloud, clique no botão "Selecionar um projeto" no cabeçalho, que vai abrir uma janela pop-up.

Na janela "Selecionar um projeto", clique no botão "Novo projeto", que vai abrir uma caixa de diálogo para o novo projeto.

Na caixa de diálogo, coloque o nome do projeto de sua preferência e escolha o local.

- O Nome do projeto é o nome de exibição para os participantes do projeto. O nome do projeto não é usado pelas APIs do Google e pode ser alterado a qualquer momento.
- O ID do projeto é exclusivo em todos os projetos do Google Cloud e não pode ser mudado após a definição. O console do Google Cloud gera automaticamente um ID exclusivo, mas você pode personalizá-lo. Se você não gostar do ID gerado, crie outro aleatório ou forneça o seu para verificar a disponibilidade. Na maioria dos codelabs, é necessário fazer referência ao ID do projeto, que normalmente é identificado com o marcador de posição PROJECT_ID.
- Para sua informação, há um terceiro valor, um Número do projeto, que algumas APIs usam. Saiba mais sobre esses três valores na documentação.
Ativar faturamento
Para ativar o faturamento, você tem duas opções. Você pode usar sua conta de faturamento pessoal ou resgatar créditos seguindo estas etapas.
Resgatar US $5 em créditos do Google Cloud (opcional)
Para fazer este workshop, você precisa de uma conta de faturamento com algum crédito. Se você planeja usar seu próprio faturamento, pule esta etapa.
- Clique neste link e faça login com uma Conta do Google pessoal.
- Você verá algo como:

- Clique no botão CLIQUE AQUI PARA ACESSAR SEUS CRÉDITOS. Isso vai abrir uma página para configurar seu perfil de faturamento. Se aparecer uma tela de inscrição para um teste sem custo financeiro, clique em "Cancelar" e continue vinculando o faturamento.

- Clique em "Confirmar". Agora você está conectado a uma conta de faturamento de avaliação do Google Cloud Platform.

Configurar uma conta de faturamento pessoal
Se você configurou o faturamento usando créditos do Google Cloud, pule esta etapa.
Para configurar uma conta de faturamento pessoal, acesse este link para ativar o faturamento no console do Cloud.
Algumas observações:
- A conclusão deste laboratório custa menos de US $3 em recursos do Cloud.
- Siga as etapas no final deste laboratório para excluir recursos e evitar mais cobranças.
- Novos usuários podem fazer um teste sem custo financeiro de US$300.
Inicie o Cloud Shell
Embora o Google Cloud e o Spanner possam ser operados remotamente do seu laptop, neste codelab usaremos o Google Cloud Shell, um ambiente de linha de comando executado no Cloud.
No Console do Google Cloud, clique no ícone do Cloud Shell na barra de ferramentas superior à direita:

Ou pressione G e S. Essa sequência vai ativar o Cloud Shell se você estiver no console do Google Cloud ou usar este link.
O provisionamento e a conexão com o ambiente levarão apenas alguns instantes para serem concluídos: Quando o processamento for concluído, você verá algo como:

Essa máquina virtual contém todas as ferramentas de desenvolvimento necessárias. Ela oferece um diretório principal persistente de 5 GB, além de ser executada no Google Cloud. Isso aprimora o desempenho e a autenticação da rede. Neste codelab, todo o trabalho pode ser feito com um navegador. Você não precisa instalar nada.
3. Antes de começar
Ativar API
Saída:
Para usar o Cloud SQL, o Compute Engine, os serviços de rede e a Vertex AI, é necessário ativar as APIs correspondentes no seu projeto na nuvem do Google.
No terminal do Cloud Shell, verifique se o ID do projeto está configurado:
gcloud config set project [YOUR-PROJECT-ID]
Defina a variável de ambiente PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
Ative todos os serviços necessários:
gcloud services enable sqladmin.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 sqladmin.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.
Apresentação das APIs
- A API Cloud SQL Admin (
sqladmin.googleapis.com) permite criar, configurar e gerenciar instâncias do Cloud SQL de maneira programática. Ele fornece o plano de controle para o serviço de banco de dados relacional totalmente gerenciado do Google (com suporte para MySQL, PostgreSQL e SQL Server), lidando com tarefas como provisionamento, backups, alta disponibilidade e escalonamento. - A API Compute Engine (
compute.googleapis.com) permite criar e gerenciar máquinas virtuais (VMs), discos permanentes e configurações de rede. Ela fornece a base principal de infraestrutura como serviço (IaaS) necessária para executar suas cargas de trabalho e hospedar a infraestrutura subjacente de muitos serviços gerenciados. - A API Resource Manager (
cloudresourcemanager.googleapis.com) permite gerenciar de forma programática os metadados e a configuração do seu projeto na nuvem do Google Cloud. Ele permite organizar recursos, processar políticas de gerenciamento de identidade e acesso (IAM) e validar permissões em toda a hierarquia do projeto. - A API Service Networking (
servicenetworking.googleapis.com) permite automatizar a configuração da conectividade particular entre sua rede de nuvem privada virtual (VPC) e os serviços gerenciados do Google. Ele é especificamente necessário para estabelecer o acesso a IP particular para serviços como o AlloyDB, para que eles possam se comunicar com segurança com seus outros recursos. - A API Vertex AI (
aiplatform.googleapis.com) permite que seus aplicativos criem, implantem e escalonem modelos de machine learning. Ela oferece a interface unificada para todos os serviços de IA do Google Cloud, incluindo acesso a modelos de IA generativa (como o Gemini) e treinamento de modelos personalizados.
4. crie uma instância do Cloud SQL
Crie uma instância do Cloud SQL com integração de banco de dados à Vertex AI.
Criar senha do banco de dados
Defina a senha do usuário padrão do banco de dados. Você pode definir sua própria senha ou usar uma função aleatória para gerar uma:
export CLOUDSQL_PASSWORD=`openssl rand -hex 12`
Anote o valor gerado para a senha:
echo $CLOUDSQL_PASSWORD
Criar uma instância do Cloud SQL para PostgreSQL
As instâncias do Cloud SQL podem ser criadas de diferentes maneiras, como o console do Google Cloud, ferramentas de automação como o Terraform ou o SDK Google Cloud. Neste laboratório, vamos usar principalmente a ferramenta gcloud do SDK Google Cloud. Leia na documentação como criar uma instância usando outras ferramentas.
Na sessão do Cloud Shell, execute:
gcloud sql instances create my-cloudsql-instance \
--database-version=POSTGRES_17 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--edition=ENTERPRISE \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on
Depois de criar a instância, precisamos definir uma senha para o usuário padrão nela e verificar se é possível se conectar com a senha.
gcloud sql users set-password postgres \
--instance=my-cloudsql-instance \
--password=$CLOUDSQL_PASSWORD
Execute o comando gcloud sql connect como mostrado na caixa e insira sua senha no prompt quando estiver pronto para se conectar.
gcloud sql connect my-cloudsql-instance --user=postgres
Saia da sessão psql por enquanto usando o atalho de teclado ctrl+d ou executando o comando exit
exit
Ativar a integração com a Vertex AI
Conceda os privilégios necessários à conta de serviço interna do Cloud SQL para usar a integração da Vertex AI.
Descubra o e-mail da conta de serviço interna do Cloud SQL e exporte-o como uma variável.
SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe my-cloudsql-instance --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL
Conceda acesso à Vertex AI para a conta de serviço do Cloud SQL:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \
--role="roles/aiplatform.user"
Leia mais sobre a criação e configuração de instâncias aqui na documentação do Cloud SQL.
5. Preparar banco de dados
Agora precisamos criar um banco de dados e ativar o suporte a vetores.
Criar banco de dados
Crie um banco de dados com o nome quickstart_db .Para isso, temos diferentes opções, como clientes de banco de dados de linha de comando, como psql para PostgreSQL, SDK ou Cloud SQL Studio. Vamos usar o SDK (gcloud) para criar bancos de dados e se conectar à instância.
No Cloud Shell, execute o comando para criar o banco de dados.
gcloud sql databases create quickstart_db --instance=my-cloudsql-instance
Ativar extensões
Para trabalhar com a Vertex AI e vetores, precisamos ativar duas extensões no banco de dados criado.
No Cloud Shell, execute o comando para se conectar ao banco de dados criado (você precisará fornecer sua senha).
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
Depois de se conectar, na sessão SQL, execute dois comandos:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
Saia da sessão SQL:
exit;
6. Carregar dados
Agora precisamos criar objetos no banco de dados e carregar dados. Vamos usar dados fictícios da Cymbal Store. Os dados estão disponíveis no bucket público do Google Storage em formato CSV.
Primeiro, precisamos criar todos os objetos necessários no banco de dados. Para isso, vamos usar os comandos gcloud sql connect e gcloud storage, que já são conhecidos, para fazer o download e importar os objetos de esquema para nosso banco de dados.
No Cloud Shell, execute e forneça a senha anotada quando criamos a instância:
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
O que fizemos exatamente no comando anterior? Conectamos ao nosso banco de dados e executamos o código SQL baixado, que criou tabelas, índices e sequências.
A próxima etapa é carregar os dados. Para isso, precisamos fazer o download dos arquivos CSV do Google Cloud Storage.
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv .
gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv .
Em seguida, precisamos nos conectar ao banco de dados.
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
e importar dados dos nossos arquivos CSV.
\copy cymbal_products from 'cymbal_products.csv' csv header
\copy cymbal_inventory from 'cymbal_inventory.csv' csv header
\copy cymbal_stores from 'cymbal_stores.csv' csv header
Se você tiver seus próprios dados e os arquivos CSV forem compatíveis com a ferramenta de importação do Cloud SQL disponível no console do Cloud, use-a em vez da abordagem de linha de comando.
7. Criar embeddings
A próxima etapa é criar embeddings para as descrições de produtos usando o modelo textembedding-004 da Vertex AI do Google e armazená-los como dados vetoriais.
Conecte-se ao banco de dados (se você saiu ou se a sessão anterior foi desconectada):
gcloud sql connect my-cloudsql-instance --database quickstart_db --user=postgres
Crie uma coluna virtual embedding na tabela "cymbal_products" usando a função de embedding. O comando cria uma coluna virtual "embedding" que armazena nossos vetores com embeddings gerados com base na coluna "product_description". Ele também cria embeddings para todas as linhas na tabela. O modelo é definido como o primeiro parâmetro da função de incorporação, e os dados de origem como o segundo parâmetro.
ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',product_description)) STORED;
Pode levar algum tempo, mas para 900 a 1.000 linhas, não deve levar mais de 5 minutos e geralmente é muito mais rápido.
Quando inserimos uma nova linha na tabela ou atualizamos a "product_description" de qualquer linha existente, os dados da coluna virtual "embedding" são regenerados com base na "product_description".
8. Executar pesquisa por similaridade
Agora podemos executar nossa pesquisa usando a pesquisa por similaridade com base nos valores de vetor calculados para as descrições e o valor de vetor que recebemos para nossa solicitação.
A consulta SQL pode ser executada na mesma interface de linha de comando usando gcloud sql connect ou, como alternativa, no Cloud SQL Studio. É melhor gerenciar consultas complexas e de várias linhas no Cloud SQL Studio.
Iniciar o Cloud SQL Studio
No console, clique na instância do Cloud SQL criada anteriormente.

Quando ele estiver aberto no painel à direita, o Cloud SQL Studio vai aparecer. Clique nele.

Uma caixa de diálogo será aberta para você informar o nome do banco de dados e suas credenciais:
- Banco de dados: quickstart_db
- Usuário: postgres
- Senha: a senha anotada para o usuário principal do banco de dados
Clique no botão "AUTENTICAR".

Isso vai abrir a próxima janela. Clique na guia "Editor" no lado direito para abrir o editor de SQL.

Agora podemos executar nossas consultas.
Executar consulta
Execute uma consulta para receber uma lista de produtos disponíveis mais relacionados ao pedido de um cliente. A solicitação que vamos transmitir à Vertex AI para receber o valor do vetor é algo como "Que tipo de árvores frutíferas crescem bem aqui?"
Esta é a consulta que você pode executar para escolher os 10 primeiros itens mais adequados à nossa solicitação:
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;
Copie e cole a consulta no editor do Cloud SQL Studio e clique no botão "EXECUTAR" ou cole na sessão da linha de comando conectada ao banco de dados quickstart_db.

E aqui está uma lista de produtos escolhidos que correspondem à consulta.
product_name | description | sale_price | zip_code | distance -------------------------+----------------------------------------------------------------------------------+------------+----------+--------------------- Cherry Tree | This is a beautiful cherry tree that will produce delicious cherries. It is an d | 75.00 | 93230 | 0.43922018972266397 Meyer Lemon Tree | Meyer Lemon trees are California's favorite lemon tree! Grow your own lemons by | 34 | 93230 | 0.4685112926118228 Toyon | This is a beautiful toyon tree that can grow to be over 20 feet tall. It is an e | 10.00 | 93230 | 0.4835677149651668 California Lilac | This is a beautiful lilac tree that can grow to be over 10 feet tall. It is an d | 5.00 | 93230 | 0.4947204525907498 California Peppertree | This is a beautiful peppertree that can grow to be over 30 feet tall. It is an e | 25.00 | 93230 | 0.5054166905547247 California Black Walnut | This is a beautiful walnut tree that can grow to be over 80 feet tall. It is a d | 100.00 | 93230 | 0.5084219510932597 California Sycamore | This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is | 300.00 | 93230 | 0.5140519790508755 Coast Live Oak | This is a beautiful oak tree that can grow to be over 100 feet tall. It is an ev | 500.00 | 93230 | 0.5143126438081371 Fremont Cottonwood | This is a beautiful cottonwood tree that can grow to be over 100 feet tall. It i | 200.00 | 93230 | 0.5174774727252058 Madrone | This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an | 50.00 | 93230 | 0.5227400803389093 (10 rows)
9. Melhorar a resposta do LLM usando dados extraídos
Podemos melhorar a resposta do LLM de IA generativa a um aplicativo cliente usando o resultado da consulta executada e preparar uma saída significativa usando os resultados da consulta fornecida como parte do comando para um modelo de linguagem de base generativa da Vertex AI.
Para isso, precisamos gerar um JSON com os resultados da pesquisa vetorial e usar esse JSON gerado como complemento de um comando para um modelo de LLM na Vertex AI e criar uma saída significativa. Na primeira etapa, geramos o JSON e o testamos no Vertex AI Studio. Na última etapa, incorporamos o JSON a uma instrução SQL que pode ser usada em um aplicativo.
Gerar saída no formato JSON
Modifique a consulta para gerar a saída no formato JSON e retorne apenas uma linha para passar para a Vertex AI.
Cloud SQL para PostgreSQL
Confira um exemplo de 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;
Este é o JSON esperado na saída:
[{"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"}]
Executar o comando no Vertex AI Studio
Podemos usar o JSON gerado como parte do comando para o modelo de texto de IA generativa no Vertex AI Studio.
Abra o Vertex AI Studio no console do Google Cloud.

Talvez seja necessário ativar outras APIs, mas você pode ignorar a solicitação. Não precisamos de outras APIs para concluir o laboratório.
Insira um comando no Studio.

Este é o comando que vamos usar:
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:
[place your JSON here]
The customer asked "What tree is growing the best here?"
You should give information about the product, price and some supplemental information.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.
E aqui está como fica quando substituímos o marcador de posição JSON pela resposta da consulta:
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.
Do not ask any additional questions and assume location based on the zip code provided in the list of products.
E aqui está o resultado quando executamos o comando com nossos valores JSON:

Confira a resposta que recebemos do modelo neste exemplo. Sua resposta pode ser diferente devido a mudanças no modelo e nos parâmetros ao longo do tempo:
"Com base no CEP fornecido na nossa lista de produtos (93230), parece que você está na área de Hanford, na Califórnia.1346 Essa região, localizada no Vale de San Joaquin, é um dos principais locais do país para o cultivo de frutas de caroço.
Para responder à sua pergunta, a melhor árvore da nossa seleção para sua região é a cerejeira.
Confira os detalhes:
Produto: Cherry Tree
Preço: R$ 75,00
Descrição: esta é uma linda cerejeira que vai produzir cerejas deliciosas.2
Por que ela cresce melhor aqui: o clima do Vale de San Joaquin oferece as condições específicas de que as cerejas precisam para prosperar: dias longos e quentes de verão para o desenvolvimento dos frutos e noites frescas.Como Hanford está em um importante centro agrícola conhecido pela produção de frutas de caroço, você pode esperar que essa árvore seja muito produtiva no seu solo local. Plante em um local com sol pleno e solo bem drenado para ter a melhor colheita"
Executar o comando no PSQL
Também podemos usar a integração de IA do Cloud SQL com a Vertex AI para receber a resposta semelhante de um modelo generativo usando SQL diretamente no banco de dados. Mas, para usar o modelo gemini-2.0-flash-exp, primeiro precisamos registrá-lo.
Executar no Cloud SQL para PostgreSQL
Faça upgrade da extensão para a versão 1.4.2 ou mais recente (se a versão atual for mais antiga). Conecte-se ao banco de dados quickstart_db usando gcloud sql connect, como mostrado anteriormente (ou use o Cloud SQL Studio), e execute:
SELECT extversion from pg_extension where extname='google_ml_integration';
Se o valor retornado for menor que 1.4.3, execute:
ALTER EXTENSION google_ml_integration UPDATE TO '1.4.3';
Em seguida, defina a flag de banco de dados google_ml_integration.enable_model_support como "on". Para verificar as configurações atuais, execute.
show google_ml_integration.enable_model_support;
A saída esperada da sessão psql é "on":
quickstart_db => show google_ml_integration.enable_model_support; google_ml_integration.enable_model_support -------------------------------------------- on (1 row)
Se aparecer "desativado", será necessário atualizar a flag do banco de dados. Para fazer isso, use a interface do console da Web ou execute o seguinte comando gcloud.
gcloud sql instances patch my-cloudsql-instance \
--database-flags google_ml_integration.enable_model_support=on,cloudsql.enable_google_ml_integration=on
O comando leva de 1 a 3 minutos para ser executado em segundo plano. Em seguida, verifique a nova flag na sessão psql ou usando o Cloud SQL Studio ao se conectar ao banco de dados quickstart_db.
show google_ml_integration.enable_model_support;
A saída esperada da sessão psql é "on":
quickstart_db => show google_ml_integration.enable_model_support; google_ml_integration.enable_model_support -------------------------------------------- on (1 row)
Em seguida, precisamos registrar dois modelos. O primeiro é o modelo text-embedding-005, que já foi usado. Ele precisa ser registrado porque ativamos os recursos de registro de modelo.
Para registrar a execução do modelo no psql ou no Cloud SQL Studio, use o seguinte 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 => 'cloudsql_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');
O próximo modelo que precisamos registrar é o gemini-2.0-flash-001, que será usado para gerar a saída fácil de usar.
CALL
google_ml.create_model(
model_id => 'gemini-2.5-flash',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-2.5-flash:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'cloudsql_service_agent_iam');
Você pode verificar a lista de modelos registrados selecionando informações de google_ml.model_info_view.
select model_id,model_type from google_ml.model_info_view;
Confira um exemplo de saída:
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
gemini-1.5-pro:streamGenerateContent | generic
gemini-1.5-pro:generateContent | generic
gemini-1.0-pro:generateContent | generic
text-embedding-005 | text_embedding
gemini-2.5-flash | generic
Agora podemos usar o JSON gerado em uma subconsulta para fornecê-lo como parte do comando ao modelo de texto de IA generativa usando SQL.
Na sessão psql ou do Cloud SQL Studio para o banco de dados, execute a 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 <=> google_ml.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;
Esta é a saída esperada. Sua saída pode ser diferente dependendo da versão do modelo e dos parâmetros:
"That's a great question! It sounds like you're looking to add some delicious fruit to your garden.\n\nBased on the products we have that are closely related to your search, I can tell you about a fantastic option:\n\n**Cherry Tree**" "\n* **Description:** This beautiful deciduous tree will produce delicious cherries. It grows to be about 15 feet tall, with dark green leaves in summer that turn a beautiful red in the fall. Cherry trees are known for their beauty, shade, and privacy. They prefer a cool, moist climate and sandy soil." "\n* **Price:** $75.00\n* **Grows well in:** USDA Zones 4-9.\n\nTo confirm if this Cherry Tree will thrive in your specific location, you might want to check which USDA Hardiness Zone your area falls into. If you're in zones 4-9, this" " could be a wonderful addition to your yard!"
10. Criar um índice de vizinho mais próximo
Nosso conjunto de dados é bem pequeno, e o tempo de resposta depende principalmente das interações com modelos de IA. Mas quando você tem milhões de vetores, a pesquisa vetorial pode levar uma parte significativa do nosso tempo de resposta e colocar uma carga alta no sistema. Para melhorar isso, podemos criar um índice sobre nossos vetores.
Criar índice HNSW
Vamos testar o tipo de índice HNSW. HNSW significa Hierarchical Navigable Small World e representa um índice de gráfico multicamadas.
Para criar o índice da coluna de embedding, precisamos definir a coluna de embedding, a função de distância e, opcionalmente, parâmetros como m ou ef_constructions. Leia sobre os parâmetros em detalhes na documentação.
CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
Saída esperada:
quickstart_db=> CREATE INDEX cymbal_products_embeddings_hnsw ON cymbal_products USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); CREATE INDEX quickstart_db=>
Comparar resposta
Agora podemos executar a consulta de pesquisa vetorial no modo EXPLAIN e verificar se o índice foi usado.
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;
Saída esperada:
Aggregate (cost=779.12..779.13 rows=1 width=32) (actual time=1.066..1.069 rows=1 loops=1)
-> Subquery Scan on trees (cost=769.05..779.12 rows=1 width=142) (actual time=1.038..1.041 rows=1 loops=1)
-> Limit (cost=769.05..779.11 rows=1 width=158) (actual time=1.022..1.024 rows=1 loops=1)
-> Nested Loop (cost=769.05..9339.69 rows=852 width=158) (actual time=1.020..1.021 rows=1 loops=1)
-> Nested Loop (cost=768.77..9316.48 rows=852 width=945) (actual time=0.858..0.859 rows=1 loops=1)
-> Index Scan using cymbal_products_embeddings_hnsw on cymbal_products cp (cost=768.34..2572.47 rows=941 width=941) (actual time=0.532..0.539 rows=3 loops=1)
Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,...
<redacted>
...,0.017593635,-0.040275685,-0.03914233,-0.018452475,0.00826032,-0.07372604
]'::vector)
-> Index Scan using product_inventory_pkey on cymbal_inventory ci (cost=0.42..7.17 rows=1 width=37) (actual time=0.104..0.104 rows=0 loops=3)
Index Cond: ((store_id = 1583) AND (uniq_id = (cp.uniq_id)::text))
Filter: (inventory > 0)
Rows Removed by Filter: 1
-> Materialize (cost=0.28..8.31 rows=1 width=8) (actual time=0.133..0.134 rows=1 loops=1)
-> Index Scan using product_stores_pkey on cymbal_stores cs (cost=0.28..8.30 rows=1 width=8) (actual time=0.129..0.129 rows=1 loops=1)
Index Cond: (store_id = 1583)
Planning Time: 112.398 ms
Execution Time: 1.221 ms
Na saída, podemos ver claramente que a consulta estava usando "Index Scan using cymbal_products_embeddings_hnsw".
E se executarmos a consulta sem a explicação:
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;
Saída esperada (pode variar de acordo com o modelo e o índice):
[{"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 o resultado é o mesmo e retornar a mesma cerejeira que estava no topo da nossa pesquisa sem índice. Dependendo dos parâmetros e do tipo de índice, o resultado pode ser um pouco diferente e retornar um registro principal diferente para a árvore. Durante meus testes, a consulta indexada retornou resultados em 131.301 ms contra 167.631 ms sem índice. No entanto, estávamos trabalhando com um conjunto de dados muito pequeno, e a diferença seria mais substancial em um conjunto de dados maior.
Você pode testar diferentes índices disponíveis para os vetores e mais laboratórios e exemplos com integração do langchain disponíveis na documentação.
11. Limpar o ambiente
Exclua a instância do Cloud SQL
Destrua a instância do Cloud SQL quando terminar o laboratório.
No Cloud Shell, defina o projeto e as variáveis de ambiente se tiver ocorrido uma desconexão e todas as configurações anteriores forem perdidas:
export INSTANCE_NAME=my-cloudsql-instance
export PROJECT_ID=$(gcloud config get-value project)
Exclua a instância:
gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID
Saída esperada do console:
student@cloudshell:~$ gcloud sql instances delete $INSTANCE_NAME --project=$PROJECT_ID All of the instance data will be lost when the instance is deleted. Do you want to continue (Y/n)? y Deleting Cloud SQL instance...done. Deleted [https://sandbox.googleapis.com/v1beta4/projects/test-project-001-402417/instances/my-cloudsql-instance].
12. Parabéns
Parabéns por concluir o codelab.
Este laboratório faz parte do programa de aprendizado "IA pronta para produção com o Google Cloud".
- Confira o currículo completo para diminuir a distância entre o protótipo e a produção.
- Compartilhe seu progresso com a hashtag
#ProductionReadyAI.
O que vimos
- Como implantar uma instância do Cloud SQL para PostgreSQL
- Como criar um banco de dados e ativar a integração de IA do Cloud SQL
- Como carregar dados no banco de dados
- Como usar o Cloud SQL Studio
- Como usar o modelo de embedding da Vertex AI no Cloud SQL
- Como usar o Vertex AI Studio
- Como enriquecer o resultado usando o modelo generativo da Vertex AI
- Como melhorar a performance usando o índice de vetor
Teste um codelab semelhante para o AlloyDB com o índice ScaNN em vez do HNSW
13. Pesquisa
Saída: