Introdução às embeddings de vetor no Cloud SQL para MySQL

1. Introdução

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

8aa6ba3bc12a1593.png

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

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

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

295004821bab6a87.png

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

37d264871000675d.png

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

96d86d3d5655cdbe.png

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

  1. Clique neste link e faça login com uma Conta do Google pessoal.
  2. Você verá algo como:

f54628965f465486.png

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

20e88842cf2a732e.png

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

cdc87f1c57777951.png

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:

Ativar o Cloud Shell

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:

Captura de tela do terminal do Google Cloud Shell mostrando que o ambiente foi conectado

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

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 MySQL

A flag cloudsql_vector pode ser ativada ao criar uma instância. O suporte a vetores está disponível para MySQL 8.0 R20241208.01_00 ou mais recente.

Na sessão do Cloud Shell, execute:

gcloud sql instances create my-cloudsql-instance \
--database-version=MYSQL_8_4 \
--tier=db-custom-2-8192 \
--region=us-central1 \
--enable-google-ml-integration \
--edition=ENTERPRISE \
--root-password=$CLOUDSQL_PASSWORD

Podemos verificar nossa conexão executando no Cloud Shell

gcloud sql connect my-cloudsql-instance --user=root

Execute o comando e insira sua senha quando o prompt estiver pronto para se conectar.

A saída esperada:

$gcloud sql connect my-cloudsql-instance --user=root
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                           
Connecting to database with SQL user [root].Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 71
Server version: 8.4.4-google (Google)

Copyright (c) 2000, 2025, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Saia da sessão do mysql 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:

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 mysql para MySQL, SDK ou Cloud SQL Studio. Vamos usar o SDK (gcloud) para criar o banco de dados.

No Cloud Shell, execute o comando para criar o banco de dados.

gcloud sql databases create quickstart_db --instance=my-cloudsql-instance

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 em SQL (para esquema) e formato CSV (para dados).

O Cloud Shell será nosso ambiente principal para se conectar a um banco de dados, criar todos os objetos e carregar os dados.

Primeiro, adicione o IP público do Cloud Shell à lista de redes autorizadas da instância do Cloud SQL. No Cloud Shell, execute:

gcloud sql instances patch my-cloudsql-instance --authorized-networks=$(curl ifconfig.me)

Se a sessão foi perdida, redefinida ou você trabalha em outra ferramenta, exporte a variável CLOUDSQL_PASSWORD novamente:

export CLOUDSQL_PASSWORD=...your password defined for the instance...

Agora podemos criar todos os objetos necessários no nosso banco de dados. Para isso, vamos usar o utilitário mysql do MySQL em combinação com o utilitário curl, que recebe os dados da fonte pública.

No Cloud Shell, execute:

export INSTANCE_IP=$(gcloud sql instances describe my-cloudsql-instance --format="value(ipAddresses.ipAddress)")
curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_mysql_schema.sql | mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

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 de cymbal_products. Usamos os mesmos utilitários curl e mysql.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_products.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_products FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Em seguida, continuamos com cymbal_stores.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_stores.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_stores FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

E complete com cymbal_inventory, que tem o número de cada produto em cada loja.

curl -LJ https://raw.githubusercontent.com/GoogleCloudPlatform/devrel-demos/main/infrastructure/cymbal-store-embeddings/cymbal_inventory.csv | mysql --enable-local-infile --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db -e "LOAD DATA LOCAL INFILE '/dev/stdin'  INTO TABLE cymbal_inventory FIELDS TERMINATED BY ','  OPTIONALLY ENCLOSED BY '\"'  LINES TERMINATED BY '\n'  IGNORE 1 LINES;"

Se você tiver seus próprios dados de amostra e arquivos CSV compatíveis com a ferramenta de importação do Cloud SQL disponível no console do Cloud, use-os em vez da abordagem apresentada.

7. Criar embeddings

A próxima etapa é criar embeddings para as descrições de produtos usando o modelo textembedding-005 da Vertex AI do Google e armazená-los na nova coluna da tabela cymbal_products.

Para armazenar os dados de vetor, precisamos ativar a funcionalidade de vetor na instância do Cloud SQL. Execute no Cloud Shell:

gcloud sql instances patch my-cloudsql-instance \
--database-flags=cloudsql_vector=on

Conecte-se ao banco de dados:

mysql --host=$INSTANCE_IP --user=root --password=$CLOUDSQL_PASSWORD quickstart_db

E crie uma nova coluna embedding na tabela cymbal_products usando a função de embedding. Essa nova coluna vai conter os embeddings de vetor com base no texto da coluna product_description.

ALTER TABLE cymbal_products ADD COLUMN embedding vector(768) using varbinary;
UPDATE cymbal_products SET embedding = mysql.ml_embedding('text-embedding-005', product_description);

A geração de incorporações de vetores para 2.000 linhas geralmente leva menos de 5 minutos, mas às vezes pode demorar um pouco mais e, muitas vezes, termina muito mais rápido.

8. Executar pesquisa por similaridade

Agora podemos executar nossa pesquisa usando a pesquisa de similaridade com base nos valores de vetor calculados para as descrições e o valor de vetor que geramos para nossa solicitação usando o mesmo modelo de embedding.

A consulta SQL pode ser executada na mesma interface de linha de comando ou no Cloud SQL Studio. É melhor gerenciar consultas complexas e de várias linhas no Cloud SQL Studio.

Criar um usuário

Precisamos de um novo usuário que possa usar o Cloud SQL Studio. Vamos criar um estudante usuário do tipo integrado com a mesma senha usada para o usuário raiz.

No Cloud Shell, execute:

gcloud sql users create student  --instance=my-cloudsql-instance --password=$CLOUDSQL_PASSWORD --host=%

Iniciar o Cloud SQL Studio

No console, clique na instância do Cloud SQL criada anteriormente.

27f060eb2764a26a.png

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

f08ce4794fce5bce.png

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: estudante
  • Senha: a senha anotada para o usuário

Clique no botão "AUTENTICAR".

5c898e4a4a0adb96.png

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

983d35d20f8a3dda.png

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 cinco primeiros itens mais adequados à nossa solicitação usando a função cosine_distance:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        cosine_distance(cp.embedding ,@query_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 5;

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.

a8be9da7d5c2b176.png

E aqui está uma lista de produtos escolhidos que correspondem à consulta.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.13 sec)

A execução da consulta levou 0,13 segundo com a função "cosine_distance".

Agora, vamos executar a mesma consulta, mas usando a pesquisa de KNN com a função approx_distance. Se não tivermos um índice de rede neural artificial para nossos embeddings, ele vai voltar automaticamente para a pesquisa exata nos bastidores:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Confira uma lista de produtos retornados pela consulta.

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set, 1 warning (0.12 sec)

A execução da consulta levou apenas 0,12 segundo. Tivemos os mesmos resultados da função "cosine_distance".

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.

Confira um exemplo de consulta usando a pesquisa de ANN:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
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
        (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1)
SELECT json_arrayagg(json_object('product_name',product_name,'description',description,'sale_price',sale_price,'zip_code',zip_code,'product_id',product_id)) FROM trees;

Este é o JSON esperado na saída:

[{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}]

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 comando do Vertex AI Studio no console do Cloud.

d48549b1b0f449b4.png

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.

2a6f5a338fefd229.png

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:
{"zip_code": 93230, "product_id": "23e41a71d63d8bbc9bdfa1d118cfddc5", "sale_price": 100.00, "description": "Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo", "product_name": "Malus Domestica"}
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.

Este é o resultado quando executamos o comando com nossos valores JSON e usando o modelo gemini-2.5-flash:

62fccb783d4d4985.png

A resposta que recebemos do modelo neste exemplo usa os resultados da pesquisa semântica e o produto mais adequado disponível no CEP mencionado.

Executar o comando no SQL

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.

Agora podemos usar o gerado em uma subconsulta com resultados JSON para fornecê-lo como parte do comando ao modelo de texto de IA generativa usando SQL.

Na sessão do mysql ou do Cloud SQL Studio para o banco de dados, execute a consulta

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
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
         (approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine')) ASC
LIMIT 1),
prompt AS (
SELECT
       CONCAT( '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_arrayagg(json_object('product_name',trees.product_name,'description',trees.description,'sale_price',trees.sale_price,'zip_code',trees.zip_code,'product_id',trees.product_id)) , '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
       mysql.ML_PREDICT_ROW('publishers/google/models/gemini-2.0-flash-001:generateContent',
        json_object('contents',
        json_object('role',
        'user',
        'parts',
        json_array(
        json_object('text',
        prompt_text))))) AS resp
FROM
        prompt)
SELECT
JSON_EXTRACT(resp, '$.candidates[0].content.parts[0].text')
FROM
        response;

Confira um exemplo de saída. Sua saída pode ser diferente dependendo da versão do modelo e dos parâmetros:

"Okay, I see you're looking for fruit trees that grow well in your area. Based on the available product, the **Malus Domestica** (Apple Tree) is a great option to consider!\n\n* **Product:** Malus Domestica (Apple Tree)\n* **Description:** This classic apple tree grows to about 30 feet tall and provides beautiful seasonal color with green leaves in summer and fiery colors in the fall. It's known for its strength and provides good shade. Most importantly, it produces delicious apples!\n* **Price:** \\$100.00\n* **Growing Zones:** This particular apple tree is well-suited for USDA zones 4-8. Since your zip code is 93230, you are likely in USDA zone 9a or 9b. While this specific tree is rated for zones 4-8, with proper care and variety selection, apple trees can still thrive in slightly warmer climates. You may need to provide extra care during heat waves.\n\n**Recommendation:** I would recommend investigating varieties of Malus Domestica suited to slightly warmer climates or contacting a local nursery/arborist to verify if it is a good fit for your local climate conditions.\n"

A saída é fornecida no formato Markdown.

10. Criar um índice de vizinho mais próximo

Nosso conjunto de dados é relativamente 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 do ScANN

Vamos testar o tipo de índice ScANN.

Para criar o índice da coluna de embedding, precisamos definir a medição de distância dela. Leia sobre os parâmetros em detalhes na documentação.

CREATE VECTOR INDEX cymbal_products_embedding_idx ON cymbal_products(embedding) USING SCANN DISTANCE_MEASURE=COSINE;

Comparar resposta

Agora podemos executar a consulta de pesquisa vetorial novamente e conferir os resultados.

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Saída esperada:

+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| product_name    | description                                                                      | sale_price | zip_code | distance            |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
| Malus Domestica | Malus Domestica, the classic apple tree, brings beauty and delicious fruit to yo |     100.00 |    93230 | 0.37740096545831603 |
| Cerasus         | Cerasus: A beautiful cherry tree that brings delicious fruit and vibrant color t |      75.00 |    93230 |   0.405704177142419 |
| Persica         | Persica: Enjoy homegrown, delicious peaches with this beautiful peach tree. Reac |     150.00 |    93230 | 0.41031799106722877 |
| Meyer Lemon     | Grow your own juicy Meyer Lemons with this semi-dwarf tree, California's favorit |      34.00 |    93230 | 0.42823360959352186 |
| Acer            | Acer, the classic maple. Known for vibrant fall foliage in reds, oranges, and ye |     100.00 |    93230 | 0.42953897057301615 |
+-----------------+----------------------------------------------------------------------------------+------------+----------+---------------------+
5 rows in set (0.08 sec)

Podemos ver que o tempo de execução foi apenas um pouco diferente, o que é esperado para um conjunto de dados tão pequeno. Isso é muito mais perceptível em grandes conjuntos de dados com milhões de vetores.

Podemos conferir o plano de execução usando o comando EXPLAIN:

SELECT mysql.ML_EMBEDDING('text-embedding-005','What kind of fruit trees grow well here?') into @query_vector;
EXPLAIN ANALYZE SELECT
        cp.product_name,
        left(cp.product_description,80) as description,
        cp.sale_price,
        cs.zip_code,
        approx_distance(cp.embedding ,@query_vector, 'distance_measure=cosine') 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 5;

Plano de execução (trecho):

...
-> Nested loop inner join  (cost=443 rows=5) (actual time=1.14..1.18 rows=5 loops=1)
                                -> Vector index scan on cp  (cost=441 rows=5) (actual time=1.1..1.1 rows=5 loops=1)
                                -> Single-row index lookup on cp using PRIMARY (uniq_id=cp.uniq_id)  (cost=0.25 rows=1) (actual time=0.0152..0.0152 rows=1 loops=5)

...

Podemos ver que ele estava usando a verificação do índice de vetor em cp (alias da tabela cymbal_products).

Você pode testar com seus próprios dados ou diferentes consultas de pesquisa para ver como a pesquisa semântica funciona no MySQL.

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.

Programa de aprendizado do Google Cloud

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 ou um codelab para o Cloud SQL para Postgres.

13. Pesquisa

Saída:

Como você usará este tutorial?

Apenas leitura Leitura e exercícios