1. Introdução
Os agentes de IA só são úteis com base nos dados que podem acessar. A maioria dos dados do mundo real está em bancos de dados. Conectar agentes a eles geralmente significa escrever gerenciamento de conexões, lógica de consulta e incorporar pipelines no código do agente. Cada agente que precisa de acesso ao banco de dados repete esse trabalho, e cada mudança de consulta exige a nova implantação do agente.
Este codelab mostra uma abordagem diferente. Você declara as ferramentas de banco de dados em um arquivo YAML (consultas SQL padrão, pesquisa de similaridade vetorial e até mesmo geração automática de embeddings), e a MCP Toolbox para bancos de dados processa todas as operações de banco de dados como um servidor MCP. O código do seu agente permanece mínimo: carregue as ferramentas e deixe o Gemini decidir qual chamar.
O que você vai criar
Um assistente de quadro de empregos inteligente para "TechJobs", um agente do ADK com tecnologia do Gemini que ajuda os desenvolvedores a navegar em listas de empregos de tecnologia usando filtros padrão (função, pilha de tecnologia) e descobrir vagas com descrições em linguagem natural, como "Quero um emprego remoto trabalhando com chatbots de IA". O agente lê e grava em um banco de dados PostgreSQL do Cloud SQL totalmente pela caixa de ferramentas do MCP para bancos de dados, que processa todo o acesso ao banco de dados, incluindo a geração automática de incorporações para pesquisa vetorial. No final, a caixa de ferramentas e o agente serão executados no Cloud Run.
O que você vai aprender
- Como o MCP (Protocolo de Contexto de Modelo) padroniza o acesso a ferramentas para agentes de IA e como a MCP Toolbox para bancos de dados aplica isso às operações de banco de dados
- Configurar a MCP Toolbox for Databases como middleware entre um agente do ADK e o Cloud SQL PostgreSQL
- Defina ferramentas de banco de dados de forma declarativa em
tools.yaml. Não há código de banco de dados no seu agente. - Criar um agente do ADK que carrega ferramentas de um servidor da caixa de ferramentas em execução usando
ToolboxToolset - Gerar embeddings de vetores usando a função
embedding()integrada do Cloud SQL e ativar a pesquisa semântica compgvector - Usar o recurso
valueFromParampara ingestão automática de vetores em operações de gravação - Implantar o servidor da caixa de ferramentas e o agente do ADK no Cloud Run
Pré-requisitos
- Uma conta do Google Cloud com uma conta de faturamento de teste
- Conhecimento básico de Python e SQL
- Não é necessário ter experiência com ADK, MCP Toolbox ou
pgvector
2. Configuração de seu ambiente
Esta etapa prepara seu ambiente do Cloud Shell, configura seu projeto do Google Cloud e clona o repositório de referência.
Abra o Cloud Shell
Abra o Cloud Shell no navegador. O Cloud Shell oferece um ambiente pré-configurado com todas as ferramentas necessárias para este codelab. Clique em Autorizar quando solicitado a
Em seguida, clique em Visualizar -> Terminal para abrir o terminal.Sua interface vai ficar parecida com esta:

Essa será nossa interface principal, com o IDE na parte de cima e o terminal na parte de baixo.
Configurar seu diretório de trabalho
Crie o diretório de trabalho. Todo o código que você escrever neste codelab vai ficar aqui:
mkdir -p ~/build-agent-adk-toolbox-cloudsql
cloudshell workspace ~/build-agent-adk-toolbox-cloudsql && cd ~/build-agent-adk-toolbox-cloudsql
Configuração no projeto do Google Cloud
Crie o arquivo .env com as variáveis de local:
# For Vertex AI / Gemini API calls
echo "GOOGLE_CLOUD_LOCATION=global" > .env
# For Cloud SQL, Cloud Run, Artifact Registry
echo "REGION=us-central1" >> .env
Faça o download do script de configuração do projeto para o diretório de trabalho:
curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh
Execute o script. Ele verifica sua conta de faturamento de teste, cria um novo projeto (ou valida um existente), salva o ID do projeto em um arquivo .env no diretório atual e define o projeto ativo em gcloud.
bash setup_verify_trial_project.sh && source .env
O script faz o seguinte:
- Verifique se você tem uma conta de faturamento de teste ativa
- Verifique se há um projeto em
.env(se houver). - Crie um novo projeto ou reutilize o atual
- Vincular a conta de faturamento de teste ao projeto
- Salve o ID do projeto em
.env - Defina o projeto como o projeto
gcloudativo
Verifique se o projeto está definido corretamente conferindo o texto amarelo ao lado do diretório de trabalho no prompt do terminal do Cloud Shell. Ele vai mostrar o ID do projeto.

Se a sessão do Cloud Shell for redefinida em algum momento durante este codelab, volte ao diretório de trabalho e execute bash setup_verify_trial_project.sh && source .env novamente para restaurar a configuração do projeto. Confirme se o texto amarelo do ID do projeto reaparece no prompt do terminal.
gcloud services enable \
aiplatform.googleapis.com \
sqladmin.googleapis.com \
compute.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com
- API Vertex AI (
aiplatform.googleapis.com): seu agente usa modelos do Gemini, e a caixa de ferramentas usa a API Embedding para pesquisa vetorial. - API Cloud SQL Admin (
sqladmin.googleapis.com): você provisiona e gerencia uma instância do PostgreSQL. - API Compute Engine (
compute.googleapis.com): necessária para criar instâncias do Cloud SQL. - Cloud Run, Cloud Build, Artifact Registry: usados na etapa de implantação mais adiante neste codelab.
3. Criar a instância de banco de dados
Esta etapa configura a criação da instância do Cloud SQL em segundo plano. Ela é provisionada enquanto você continua o tutorial.
Iniciar a criação da instância
Adicione a senha do banco de dados ao arquivo .env e recarregue-o:
echo "DB_PASSWORD=techjobs-pwd-2025" >> .env
source .env
Inicie a criação da instância do Cloud SQL. Isso é executado em segundo plano para que você possa continuar trabalhando:
gcloud sql instances create jobs-instance \
--database-version=POSTGRES_17 \
--tier=db-custom-1-3840 \
--edition=ENTERPRISE \
--region=$REGION \
--root-password=$DB_PASSWORD \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on \
--quiet &
db-custom-1-3840é o menor nível do Cloud SQL de núcleo dedicado (1 vCPU, 3,75 GB de RAM) na ediçãoENTERPRISE. Leia mais detalhes aqui. Um núcleo dedicado é necessário para a integração de ML da Vertex AI. Os níveis de núcleo compartilhado (db-f1-micro,db-g1-small) não oferecem suporte a ela.--root-passworddefine a senha do usuáriopostgrespadrão.- O
--enable-google-ml-integrationativa a integração integrada do Cloud SQL com a Vertex AI, permitindo que você chame modelos de embedding diretamente do SQL usando a funçãoembedding(). - O
&executa o comando em segundo plano.
Isso será executado em segundo plano. Em seguida, vamos fazer o download do binário da MCP Toolbox. Você pode fazer isso no mesmo terminal
Baixar o binário da caixa de ferramentas
Vamos usar a caixa de ferramentas do MCP neste tutorial. Felizmente, ela vem com um binário pré-criado pronto para ser usado no ambiente Linux. Vamos fazer o download em segundo plano, já que isso leva um tempo.
cd ~/build-agent-adk-toolbox-cloudsql
curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/linux/amd64/toolbox &
Deixe esse processo ser executado na guia atual. Já fazemos isso em segundo plano, mas a saída ainda será mostrada. Abra uma nova guia do terminal no Cloud Shell (clique no ícone +) para ficar mais focado.

Navegue até o diretório de trabalho novamente e ative o projeto usando o script de configuração anterior.
cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env
Esta etapa configura o projeto Python, instala dependências e cria a estrutura do diretório do agente do ADK.
4. Inicializar o projeto do agente
Configurar o projeto Python
uv é um gerenciador de projetos e pacotes Python rápido escrito em Rust ( documentações do uv). Este codelab o usa para velocidade e simplicidade.
Inicialize um projeto Python e adicione as dependências necessárias:
uv init
uv add google-adk==1.25.0 toolbox-adk==0.6.0
google-adk: o Kit de Desenvolvimento de Agente do Google, incluindo o SDK do Geminitoolbox-adk: integração do ADK com a MCP Toolbox para bancos de dados.
Criar a estrutura de diretórios do agente
O ADK espera um layout de pasta específico: um diretório com o nome do seu agente que contenha __init__.py, agent.py e .env. Para ajudar com isso, ele tem um comando integrado para estabelecer rapidamente a estrutura:
uv run adk create jobs_agent \
--model gemini-2.5-flash \
--project ${GOOGLE_CLOUD_PROJECT} \
--region ${GOOGLE_CLOUD_LOCATION}
Seu diretório vai ficar assim:
build-agent-adk-toolbox-cloudsql/ ├── jobs_agent/ │ ├── __init__.py │ ├── agent.py │ └── .env ├── pyproject.toml ├── .env (project setup — already exists) └── .venv/
5. Propagar o banco de dados de lista de empregos
Esta etapa grava os dados de inicialização, aguarda a conclusão do provisionamento da instância do Cloud SQL e carrega a tabela jobs com 15 anúncios de emprego e a incorporação da descrição deles.
Escreva o SQL de inicialização
Vamos criar um arquivo chamado seed.sql no Editor do Cloud Shell com o conteúdo da lista de vagas. Isso cria a tabela jobs com suporte a pgvector e insere 15 vagas em empresas de tecnologia.
Primeiro, crie o arquivo seed.sql usando o seguinte comando:
cloudshell edit seed.sql
Em seguida, copie esses scripts no arquivo
-- seed.sql
-- DISCLAIMER: These job listings are entirely fictional and created for tutorial
-- purposes only. Company names are used for illustrative context — the positions,
-- salaries, and descriptions do not reflect real openings.
CREATE EXTENSION IF NOT EXISTS google_ml_integration;
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE IF NOT EXISTS jobs (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
company VARCHAR NOT NULL,
role VARCHAR NOT NULL,
tech_stack VARCHAR NOT NULL,
salary_range VARCHAR NOT NULL,
location VARCHAR NOT NULL,
openings INTEGER NOT NULL,
description TEXT NOT NULL,
description_embedding vector(3072)
);
INSERT INTO jobs (title, company, role, tech_stack, salary_range, location, openings, description) VALUES
('Senior Backend Engineer', 'Stripe', 'Backend', 'Go, PostgreSQL, gRPC, Kubernetes', '$180-250K/year', 'San Francisco, Hybrid', 3,
'Design and build high-throughput microservices powering payment infrastructure for millions of businesses. Optimize Go services for sub-100ms latency at scale, work with PostgreSQL and Redis for data persistence, and deploy on Kubernetes clusters handling billions of API calls.'),
('Machine Learning Engineer', 'Spotify', 'Data/AI', 'Python, TensorFlow, BigQuery, Vertex AI', '$170-230K/year', 'Stockholm, Remote', 2,
'Build and deploy ML models for music recommendation and personalization systems serving hundreds of millions of listeners. Design feature pipelines in BigQuery, train models using distributed computing, and serve predictions through real-time APIs processing thousands of requests per second.'),
('Frontend Engineer', 'Vercel', 'Frontend', 'React, TypeScript, Next.js', '$140-190K/year', 'Remote', 4,
'Build developer-facing dashboard interfaces and deployment tools used by millions of developers worldwide. Create responsive, accessible React components for project management, analytics, and real-time deployment monitoring with a focus on developer experience.'),
('DevOps Engineer', 'Datadog', 'DevOps', 'Terraform, GCP, Docker, Kubernetes, ArgoCD', '$160-220K/year', 'New York, Hybrid', 2,
'Manage cloud infrastructure powering an observability platform used by thousands of engineering teams. Automate deployment pipelines with ArgoCD, manage multi-cloud Kubernetes clusters, and implement infrastructure-as-code with Terraform across production environments.'),
('Mobile Engineer (Android)', 'Grab', 'Mobile', 'Kotlin, Jetpack Compose, GraphQL', '$120-170K/year', 'Singapore, Hybrid', 3,
'Develop features for a super-app serving millions of users across Southeast Asia. Build modern Android UIs with Jetpack Compose, integrate GraphQL APIs, and optimize app performance for diverse device capabilities and network conditions.'),
('Data Engineer', 'Airbnb', 'Data', 'Python, Apache Spark, Airflow, BigQuery', '$160-210K/year', 'San Francisco, Hybrid', 2,
'Build data pipelines that process booking, search, and pricing data for a global travel marketplace. Design ETL workflows with Apache Spark and Airflow, maintain data warehouses in BigQuery, and ensure data quality for analytics and machine learning teams.'),
('Full Stack Engineer', 'Revolut', 'Full Stack', 'TypeScript, Node.js, React, PostgreSQL', '$130-180K/year', 'London, Remote', 5,
'Build the next generation of financial products making banking accessible to millions of users across 35 countries. Develop real-time trading interfaces with React and WebSockets, build Node.js APIs handling market data streams, and design PostgreSQL schemas for financial transactions.'),
('Site Reliability Engineer', 'Cloudflare', 'SRE', 'Go, Prometheus, Grafana, GCP, Terraform', '$170-230K/year', 'Austin, Hybrid', 2,
'Ensure 99.99% uptime for a global network handling millions of requests per second. Define SLOs, build monitoring dashboards with Prometheus and Grafana, manage incident response, and automate infrastructure scaling across 300+ data centers worldwide.'),
('Cloud Architect', 'Google Cloud', 'Cloud', 'GCP, Terraform, Kubernetes, Python', '$200-280K/year', 'Seattle, Hybrid', 1,
'Help enterprises modernize their infrastructure on Google Cloud. Design multi-region architectures, lead migration projects from on-premises to GKE, and build reference implementations using Terraform and Cloud Foundation Toolkit.'),
('Backend Engineer (Payments)', 'Square', 'Backend', 'Java, Spring Boot, PostgreSQL, Kafka', '$160-220K/year', 'San Francisco, Hybrid', 3,
'Build payment processing systems handling millions of transactions for businesses of all sizes. Design event-driven architectures using Kafka, implement idempotent payment flows with Spring Boot, and ensure PCI-DSS compliance across all services.'),
('AI Engineer', 'Hugging Face', 'Data/AI', 'Python, LangChain, Vertex AI, FastAPI, PostgreSQL', '$150-210K/year', 'Paris, Remote', 2,
'Build AI-powered tools for the largest open-source ML community. Develop RAG pipelines that index and search model documentation, create conversational agents using LangChain, and deploy AI services with FastAPI on cloud infrastructure.'),
('Platform Engineer', 'Coinbase', 'Platform', 'Rust, Kubernetes, AWS, Terraform', '$180-250K/year', 'Remote', 0,
'Build the infrastructure platform for a leading cryptocurrency exchange. Develop high-performance matching engines in Rust, manage Kubernetes clusters for microservices, and design CI/CD pipelines that enable rapid feature deployment with zero downtime.'),
('QA Automation Engineer', 'Shopify', 'QA', 'Python, Selenium, Cypress, Jenkins', '$110-160K/year', 'Toronto, Hybrid', 3,
'Design and maintain automated test suites for a commerce platform powering millions of merchants. Build end-to-end test frameworks with Cypress and Selenium, integrate tests into Jenkins CI pipelines, and establish quality gates that prevent regressions in checkout and payment flows.'),
('Security Engineer', 'CrowdStrike', 'Security', 'Python, SIEM, Kubernetes, Penetration Testing', '$170-240K/year', 'Austin, On-site', 1,
'Protect enterprise customers from cyber threats on a leading endpoint security platform. Conduct penetration testing, design security monitoring with SIEM tools, implement zero-trust networking in Kubernetes environments, and lead incident response for security events.'),
('Product Engineer', 'GitLab', 'Full Stack', 'Go, React, PostgreSQL, Redis, GCP', '$140-200K/year', 'Remote', 4,
'Own features end-to-end for an all-in-one DevSecOps platform used by millions of developers. Build Go microservices for CI/CD pipelines, create React frontends for code review and project management, and collaborate with product managers to iterate on user-facing features using data-driven development.');
O script de inicialização instala duas extensões do PostgreSQL:
google_ml_integration: fornece a função SQLembedding(), que chama modelos de embedding da Vertex AI diretamente do SQL. É uma extensão no nível do banco de dados que disponibiliza funções de ML nojobs_db. A flag no nível da instância (--enable-google-ml-integration) definida durante a criação da instância permite que a VM do Cloud SQL alcance a Vertex AI. A extensão disponibiliza as funções SQL nesse banco de dados específico.vector(pgvector): adiciona o tipo de dadosvectore operadores de distância para armazenar e consultar incorporações.
A coluna description_embedding é vector(3072), uma coluna pgvector que armazena vetores de 3.072 dimensões. Por enquanto, é NULL. Você vai gerar e preencher embeddings na próxima etapa usando a função embedding().
Concluir a configuração do banco de dados
A criação da instância do Cloud SQL iniciada na etapa anterior ainda pode estar em execução e não ter sido concluída. Verifique se a instância está pronta:
gcloud sql instances describe jobs-instance --format="value(state)"
Você verá esta resposta
RUNNABLE

Em seguida, conceda à conta de serviço da instância do Cloud SQL permissão para chamar a Vertex AI. Isso é necessário para a função embedding() integrada que você vai usar na próxima etapa:
SERVICE_ACCOUNT=$(gcloud sql instances describe jobs-instance --format="value(serviceAccountEmailAddress)")
gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
--member="serviceAccount:$SERVICE_ACCOUNT" \
--role="roles/aiplatform.user" \
--quiet
Depois disso, crie um banco de dados dedicado para as vagas de emprego:
gcloud sql databases create jobs_db --instance=jobs-instance
Você vai ver uma saída confirmando que o banco de dados foi criado:
Creating Cloud SQL database...done. Created database [jobs_db]. instance: jobs-instance name: jobs_db project: workshop-xxxxxxx
Conectar e inserir dados no banco de dados
Inicie o proxy de autenticação do Cloud SQL (cloud-sql-proxy já está pré-instalado no Cloud Shell). Isso fornece uma conexão segura e autenticada do Cloud Shell à instância do Cloud SQL:

cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:jobs-instance --port 5432 &
Se o proxy for iniciado, você verá esta saída no terminal:
... Authorizing with Application Default Credentials ... [workshop-xxxxxx:your-location:jobs-instance] Listening on 127.0.0.1:5432 ... The proxy has started successfully and is ready for new connections!
Agora, o terminal atual gera o registro do proxy do Cloud SQL continuamente. Abra uma nova guia do terminal no Cloud Shell (clique no ícone +) para ficar mais focado.

Navegue até o diretório de trabalho novamente e ative o projeto usando o script de configuração anterior.
cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env
Em seguida, execute o script de inicialização
psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" -f seed.sql
Você vai ver uma saída de terminal como esta:
CREATE EXTENSION CREATE EXTENSION CREATE TABLE INSERT 0 15
Vamos verificar os dados
psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
-c "SELECT title, company, role, openings FROM jobs ORDER BY role, title;"
Você vai encontrar 15 anúncios de vagas em várias funções:
title | company | role | openings ---------------------------------+----------------+-----------+---------- Senior Backend Engineer | Stripe | Backend | 3 Backend Engineer (Payments) | Square | Backend | 3 Cloud Architect | Google Cloud | Cloud | 1 ... (15 rows)
Gerar embeddings para descrições de cargos
A coluna description_embedding na tabela jobs está NULL no momento. A extensão google_ml_integration integrada do Cloud SQL oferece uma função embedding() que chama a Vertex AI diretamente do SQL. Não é necessário um script Python ou SDK externo.
Inicie a geração de embeddings em segundo plano. Isso chama a Vertex AI para gerar um vetor de 3.072 dimensões usando o modelo gemini-embedding-001 para cada uma das 15 descrições de vagas:
psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
-c "UPDATE jobs SET description_embedding = embedding('gemini-embedding-001', description)::vector;" &
O script faz o seguinte:
embedding('gemini-embedding-001', description): chama o modelo de embedding Gemini da Vertex AI diretamente do SQL, transmitindo o textodescriptionde cada vaga. Essa é a extensãogoogle_ml_integrationque você instalou no script de inicialização.::vector: converte a matriz de ponto flutuante retornada para o tipovectordo pgvector para que ela possa ser armazenada e consultada com operadores de distância.- O
UPDATEé executado em todas as 15 linhas, gerando uma incorporação de 3.072 dimensões por descrição de vaga. - O
&executa o comando em segundo plano para que você possa continuar trabalhando enquanto a Vertex AI processa os embeddings.
Assim como na execução anterior do processo em segundo plano, o terminal atual vai mostrar o registro do processo. Abra uma nova guia do terminal no Cloud Shell (clique no ícone +) para ficar mais focado.

Navegue até o diretório de trabalho novamente e ative o projeto usando o script de configuração anterior.
cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env
Em seguida, podemos continuar para o próximo processo.
6. Configurar a MCP Toolbox para bancos de dados
Esta etapa apresenta a caixa de ferramentas do MCP para bancos de dados, configura a conexão com a instância do Cloud SQL e define duas ferramentas padrão de consulta SQL.
O que é o MCP e por que usar a Toolbox?

O MCP (Protocolo de Contexto de Modelo) é um protocolo aberto que padroniza como os agentes de IA descobrem e interagem com ferramentas externas. Ele define um modelo cliente-servidor: o agente hospeda um cliente MCP, e as ferramentas são expostas por servidores MCP. Qualquer cliente compatível com o MCP pode usar qualquer servidor compatível com o MCP. O agente não precisa de um código de integração personalizado para cada ferramenta.

A MCP Toolbox para bancos de dados é um servidor MCP de código aberto criado especificamente para acesso a bancos de dados. Sem ele, você escreveria funções Python que abrem conexões de banco de dados, gerenciam pools de conexões, criam consultas parametrizadas para evitar injeção de SQL, processam erros e incorporam todo esse código no seu agente. Cada agente que precisa de acesso ao banco de dados repete esse trabalho. Mudar uma consulta significa reimplantação do agente.
Com a caixa de ferramentas, você escreve um arquivo YAML. Cada ferramenta é mapeada para uma instrução SQL parametrizada. A caixa de ferramentas processa o pooling de conexões, consultas parametrizadas, autenticação e capacidade de observação. As ferramentas são dissociadas do agente. Para atualizar uma consulta, edite tools.yaml e reinicie a caixa de ferramentas sem mexer no código do agente. As mesmas ferramentas funcionam no ADK, LangGraph, LlamaIndex ou em qualquer framework compatível com o MCP.
Escreva a configuração das ferramentas
Agora, precisamos criar um arquivo chamado tools.yaml no editor do Cloud Shell para configurar a configuração das ferramentas.
cloudshell edit tools.yaml
O arquivo usa YAML de vários documentos. Cada bloco separado por --- é um recurso independente. Todo recurso tem um kind que declara o que ele é (sources para conexões de banco de dados, tools para ações chamáveis por agente) e um type que especifica o back-end (cloud-sql-postgres para a origem, postgres-sql para ferramentas baseadas em SQL). Uma ferramenta faz referência à origem dela por name, que é como a caixa de ferramentas sabe qual pool de conexões executar. As variáveis de ambiente usam a sintaxe ${VAR_NAME} e são resolvidas na inicialização.
Agora, vamos copiar os seguintes scripts primeiro no arquivo tools.yaml
# tools.yaml
# --- Data Source ---
kind: sources
name: jobs-db
type: cloud-sql-postgres
project: ${GOOGLE_CLOUD_PROJECT}
region: ${REGION}
instance: jobs-instance
database: jobs_db
user: postgres
password: ${DB_PASSWORD}
---
Este script define o seguinte recurso:
- Origem (
jobs-db): informa à caixa de ferramentas como se conectar à sua instância do Cloud SQL PostgreSQL. O tipocloud-sql-postgresusa o conector do Cloud SQL internamente, processando a autenticação e as conexões seguras de forma automática. Os marcadores de posição${GOOGLE_CLOUD_PROJECT},${REGION}e${DB_PASSWORD}são resolvidos das variáveis de ambiente na inicialização.
Em seguida, adicione o script a seguir abaixo do símbolo --- em tools.yaml.
# --- Tool 1: Search jobs by role and/or tech stack ---
kind: tools
name: search-jobs
type: postgres-sql
source: jobs-db
description: >-
Search for job listings by role category and/or tech stack.
Use this tool when the developer wants to browse listings
by role (e.g., Backend, Frontend, Data) or find jobs
using a specific technology. Both parameters accept an
empty string to match all values.
statement: |
SELECT title, company, role, tech_stack, salary_range, location, openings
FROM jobs
WHERE ($1 = '' OR LOWER(role) = LOWER($1))
AND ($2 = '' OR LOWER(tech_stack) LIKE '%' || LOWER($2) || '%')
ORDER BY title
LIMIT 10
parameters:
- name: role
type: string
description: "The role category to filter by (e.g., 'Backend', 'Frontend', 'Data/AI', 'DevOps'). Use empty string for all roles."
- name: tech_stack
type: string
description: "A technology to search for in the tech stack (partial match, e.g., 'Python', 'Kubernetes'). Use empty string for all tech stacks."
---
# --- Tool 2: Get full details for a specific job ---
kind: tools
name: get-job-details
type: postgres-sql
source: jobs-db
description: >-
Get full details for a specific job listing including its description,
salary range, location, and number of openings. Use this tool when the
developer asks about a particular job by title or company.
statement: |
SELECT title, company, role, tech_stack, salary_range, location, openings, description
FROM jobs
WHERE LOWER(title) LIKE '%' || LOWER($1) || '%'
OR LOWER(company) LIKE '%' || LOWER($1) || '%'
parameters:
- name: search_term
type: string
description: "The job title or company name to look up (partial match supported)."
---
Este script define o seguinte recurso:
- Ferramentas 1 e 2 (
search-jobs,get-job-details): ferramentas de consulta SQL padrão. Cada um mapeia um nome de ferramenta (o que o agente vê) para uma instrução SQL parametrizada (o que o banco de dados executa). Os parâmetros usam marcadores de posição$1e$2. A caixa de ferramentas executa essas ações como instruções preparadas, o que evita a injeção de SQL.
Vamos continuar. Adicione o script a seguir abaixo do símbolo --- em tools.yaml.
# --- Embedding Model ---
kind: embeddingModels
name: gemini-embedding
type: gemini
model: gemini-embedding-001
dimension: 3072
---
Este script define o seguinte recurso:
- Modelo de embedding (
gemini-embedding): configura a caixa de ferramentas para chamar o modelogemini-embedding-001do Gemini e gerar embeddings de texto de 3.072 dimensões. A caixa de ferramentas usa o Application Default Credentials (ADC) para autenticar. Não é necessário ter uma chave de API no Cloud Shell ou no Cloud Run. Observa que odimensionconfigurado aqui precisa ser o mesmo que configuramos anteriormente para propagar o banco de dados.
Vamos continuar. Adicione o script a seguir abaixo do símbolo --- em tools.yaml.
# --- Tool 3: Semantic search by description ---
kind: tools
name: search-jobs-by-description
type: postgres-sql
source: jobs-db
description: >-
Find jobs that match a natural language description of what the developer
is looking for. Use this tool when the developer describes their ideal job
using interests, work style, career goals, or project type rather than a
specific role or tech stack. Examples: "I want to work on AI chatbots,"
"a remote job at a fintech startup," "something involving infrastructure
and reliability."
statement: |
SELECT title, company, role, tech_stack, salary_range, location, description
FROM jobs
WHERE description_embedding IS NOT NULL
ORDER BY description_embedding <=> $1
LIMIT 5
parameters:
- name: search_query
type: string
description: "A natural language description of the kind of job the developer is looking for."
embeddedBy: gemini-embedding
---
Este script define o seguinte recurso:
- Ferramenta 3 (
search-jobs-by-description): uma ferramenta de pesquisa vetorial. O parâmetrosearch_querytemembeddedBy: gemini-embedding, que instrui a caixa de ferramentas a interceptar o texto bruto, enviá-lo ao modelo de embedding e usar o vetor resultante na instrução SQL. O operador<=>é a distância de cosseno do pgvector. Valores menores significam descrições mais semelhantes.
Por fim, adicione a última ferramenta abaixo do símbolo --- em tools.yaml.
# --- Tool 4: Add a new job listing with automatic embedding ---
kind: tools
name: add-job
type: postgres-sql
source: jobs-db
description: >-
Add a new job listing to the platform. Use this tool when a user asks
to post a job that is not currently listed.
statement: |
INSERT INTO jobs (title, company, role, tech_stack, salary_range, location, openings, description, description_embedding)
VALUES ($1, $2, $3, $4, $5, $6, CAST($7 AS INTEGER), $8, $9)
RETURNING title, company
parameters:
- name: title
type: string
description: "The job title (e.g., 'Senior Backend Engineer')."
- name: company
type: string
description: "The company name (e.g., 'Stripe', 'Spotify')."
- name: role
type: string
description: "The role category (e.g., 'Backend', 'Frontend', 'Data/AI', 'DevOps')."
- name: tech_stack
type: string
description: "Comma-separated list of technologies (e.g., 'Python, FastAPI, GCP')."
- name: salary_range
type: string
description: "The salary range (e.g., '$150-200K/year')."
- name: location
type: string
description: "Work location and arrangement (e.g., 'Remote')."
- name: openings
type: string
description: "The number of open positions."
- name: description
type: string
description: "A short description of the job (2-3 sentences)."
- name: description_vector
type: string
description: "Auto-generated embedding vector for the job description."
valueFromParam: description
embeddedBy: gemini-embedding
Este script define o seguinte recurso:
- Ferramenta 4 (
add-job): demonstra a ingestão de vetores. O parâmetrodescription_vectortem dois campos especiais: valueFromParam: description: a caixa de ferramentas copia o valor do parâmetrodescriptionpara este. A LLM nunca vê esse parâmetro.embeddedBy: gemini-embedding: a caixa de ferramentas incorpora o texto copiado em um vetor antes de transmiti-lo ao SQL.
O resultado: uma chamada de função armazena o texto de descrição bruto e o embedding de vetor dele, sem que o agente saiba nada sobre embeddings.
O formato YAML de vários documentos separa cada recurso com ---. Cada documento tem campos kind, name e type que definem o que ele é. Em resumo, já configuramos tudo o que segue:
- Definir o banco de dados de origem
- Defina ferramentas ( ferramentas 1 e 2) para consultar o banco de dados com um filtro padrão.
- Definir o modelo de embedding
- Definir a ferramenta para fazer a pesquisa de vetor ( ferramenta 3) no banco de dados
- Defina a ferramenta para fazer a ingestão de dados de vetor ( ferramenta 4) no banco de dados.
Verificar os embeddings
Antes de iniciar a caixa de ferramentas, confirme se a geração de incorporação em segundo plano foi concluída. Verifique se todos os jobs agora têm incorporações:
psql "host=127.0.0.1 port=5432 dbname=jobs_db user=postgres password=$DB_PASSWORD" \
-c "SELECT title, (description_embedding IS NOT NULL) AS has_embedding FROM jobs ORDER BY title;"
Cada linha precisa mostrar t (verdadeiro) na coluna has_embedding. Caso contrário, aguarde até que todo o processo de criação de incorporação de linha seja concluído.
title | has_embedding -----------------------------+--------------- AI Engineer | t Backend Engineer (Payments) | t Cloud Architect | t Data Engineer | t DevOps Engineer | t Frontend Engineer | t Full Stack Engineer | t
Iniciar o servidor da caixa de ferramentas
Na etapa de configuração, já baixamos o executável toolbox. Verifique se o arquivo binário existe e foi baixado corretamente. Se não, faça o download e aguarde a conclusão.
cd ~/build-agent-adk-toolbox-cloudsql
if [ ! -f toolbox ]; then
curl -O https://storage.googleapis.com/genai-toolbox/v0.27.0/linux/amd64/toolbox
fi
chmod +x toolbox
Exporte as variáveis de ambiente necessárias e inicie a caixa de ferramentas. As variáveis GOOGLE_CLOUD_LOCATION e GOOGLE_GENAI_USE_VERTEXAI são necessárias porque a configuração inclui um modelo de incorporação. GOOGLE_GENAI_USE_VERTEXAI informa ao SDK Gemini para fazer o roteamento pela Vertex AI (em vez da API Gemini para consumidores), e GOOGLE_CLOUD_LOCATION informa qual endpoint regional usar.
export GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT
export GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION
export GOOGLE_GENAI_USE_VERTEXAI=true
export DB_PASSWORD=$DB_PASSWORD
export REGION=$REGION
./toolbox --tools-file tools.yaml &
Você vai ver uma saída confirmando que o servidor está pronto, como mostrado abaixo:
... INFO "Initialized 0 authServices: " ... INFO "Initialized 1 embeddingModels: gemini-embedding" ... INFO "Initialized 4 tools: add-job, search-jobs, get-job-details, search-jobs-by-description" ... ... INFO "Server ready to serve!"
Assim como na etapa anterior, isso vai gerar outro processo e mostrar saídas. Abra uma nova guia do terminal no Cloud Shell (clique no ícone +) para ficar mais focado.

Navegue até o diretório de trabalho novamente e ative o projeto usando o script de configuração anterior.
cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env
Verificar as ferramentas
Consulte a API Toolbox para listar todas as ferramentas registradas:
curl -s http://localhost:5000/api/toolset | python3 -m json.tool
Você vai encontrar as ferramentas com as descrições e os parâmetros. Como mostrado abaixo
...
"search-jobs-by-description": {
"description": "Find jobs that match a natural language description of what the developer is looking for. Use this tool when the developer describes their ideal job using interests, work style, career goals, or project type rather than a specific role or tech stack. Examples: \"I want to work on AI chatbots,\" \"a remote job at a fintech startup,\" \"something involving infrastructure and reliability.\"",
"parameters": [
{
"name": "search_query",
"type": "string",
"required": true,
"description": "A natural language description of the kind of job the developer is looking for.",
"authSources": []
}
],
"authRequired": []
}
...
Teste a ferramenta search-jobs diretamente:
curl -s -X POST http://localhost:5000/api/tool/search-jobs/invoke \
-H "Content-Type: application/json" \
-d '{"role": "Backend", "tech_stack": ""}' | jq '.result | fromjson'
A resposta precisa conter os dois jobs de engenharia de back-end dos seus dados iniciais.
[
{
"title": "Backend Engineer (Payments)",
"company": "Square",
"role": "Backend",
"tech_stack": "Java, Spring Boot, PostgreSQL, Kafka",
"salary_range": "$160-220K/year",
"location": "San Francisco, Hybrid",
"openings": 3
},
{
"title": "Senior Backend Engineer",
"company": "Stripe",
"role": "Backend",
"tech_stack": "Go, PostgreSQL, gRPC, Kubernetes",
"salary_range": "$180-250K/year",
"location": "San Francisco, Hybrid",
"openings": 3
}
]
7. Criar o agente do ADK
Esta etapa conecta o agente do ADK ao servidor da caixa de ferramentas em execução e testa todas as quatro ferramentas: consultas padrão, pesquisa semântica e ingestão de vetores. O código do agente é mínimo: toda a lógica do banco de dados está em tools.yaml.
Configurar o ambiente do agente
O ADK lê GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECT e GOOGLE_CLOUD_LOCATION do ambiente do shell, que você já definiu na etapa anterior. A única variável específica do agente é TOOLBOX_URL. Anexe-a ao arquivo .env do agente:
echo -e "\nTOOLBOX_URL=http://127.0.0.1:5000" >> jobs_agent/.env
Atualizar o módulo do agente
Abra jobs_agent/agent.py no editor do Cloud Shell
cloudshell edit jobs_agent/agent.py
e substitua o conteúdo pelo seguinte código:
# jobs_agent/agent.py
import os
from google.adk.agents import LlmAgent
from toolbox_adk import ToolboxToolset
TOOLBOX_URL = os.environ.get("TOOLBOX_URL", "http://127.0.0.1:5000")
toolbox = ToolboxToolset(TOOLBOX_URL)
root_agent = LlmAgent(
name="jobs_agent",
model="gemini-2.5-flash",
instruction="""You are a helpful assistant at "TechJobs," a tech job listing platform.
Your job:
- Help developers browse job listings by role or tech stack.
- Provide full details about specific positions, including salary range and number of openings.
- Recommend jobs based on natural language descriptions of what the developer is looking for.
- Add new job listings to the platform when asked.
When a developer asks about a specific job by title or company, use the get-job-details tool.
When a developer asks for a specific role category or tech stack, use the search-jobs tool.
When a developer describes what kind of job they want — by interest area, work style,
career goals, or project type — use the search-jobs-by-description tool for semantic search.
When in doubt between search-jobs and search-jobs-by-description, prefer
search-jobs-by-description — it searches job descriptions and finds more relevant matches.
If a position has no openings (openings is 0), let the developer know
and suggest similar alternatives from the search results.
Be conversational, knowledgeable, and concise.""",
tools=[toolbox],
)
Não há código de banco de dados aqui. O ToolboxToolset se conecta ao servidor da caixa de ferramentas na inicialização e carrega todas as ferramentas disponíveis. O agente chama as ferramentas por nome, e a caixa de ferramentas traduz essas chamadas em consultas SQL no Cloud SQL.
A variável de ambiente TOOLBOX_URL tem como padrão http://127.0.0.1:5000 para desenvolvimento local. Ao implantar no Cloud Run mais tarde, você vai substituir isso pelo URL do Cloud Run do serviço Toolbox. Não é necessário mudar o código.
No momento, a instrução faz referência apenas às duas ferramentas padrão (search-jobs e get-job-details). Você vai expandir isso na próxima etapa ao adicionar ferramentas de pesquisa semântica e ingestão.
Testar o agente
Inicie a interface de desenvolvimento do ADK:
cd ~/build-agent-adk-toolbox-cloudsql
uv run adk web
Abra o URL mostrado no terminal (normalmente http://localhost:8000) usando o recurso Visualização na Web do Cloud Shell ou ctrl + clique no URL mostrado no terminal. Selecione jobs_agent no menu suspenso de agentes no canto superior esquerdo.
Testar consultas padrão
Use estes comandos para verificar as ferramentas do SQL padrão:
What backend engineering jobs do you have?
Any jobs using Kubernetes?
Tell me about the Cloud Architect position

Testar a pesquisa semântica
Tente descrições em linguagem natural que não correspondam a uma função ou pilha de tecnologia específica:
I want a remote job where I can work on AI and machine learning
Find me something in fintech with good work-life balance
I'm interested in infrastructure and reliability engineering
O agente tenta escolher a ferramenta certa com base no tipo de consulta: filtros estruturados passam por search-jobs, e descrições em linguagem natural passam por search-jobs-by-description.

Teste de ingestão de vetores
Peça para o agente adicionar um novo trabalho:
Add a new job: 'Robotics Software Engineer' at Boston Dynamics, role Robotics, tech stack: Python, C++, ROS, Computer Vision, salary $160-230K/year, location Waltham MA, Hybrid, 2 openings. Description: Design and implement autonomous navigation and manipulation algorithms for next-generation robots. Work on perception pipelines using computer vision and lidar, develop motion planning software in C++ and Python, and test systems on real hardware in warehouse and logistics environments.

Agora tente pesquisar:
Find me jobs involving autonomous systems and working with physical hardware
A incorporação foi gerada automaticamente durante o INSERT. Nenhuma etapa separada é necessária.

Agora você já tem um aplicativo RAG agente completo que usa o ADK, a caixa de ferramentas do MCP e o CloudSQL. Parabéns! Vamos dar mais um passo e implantar esses apps no Cloud Run.
Agora, vamos interromper a interface de desenvolvimento encerrando o processo. Para isso, pressione Ctrl+C duas vezes antes de continuar.
8. Implantar no Cloud Run
O agente e a caixa de ferramentas funcionam localmente. Esta etapa implanta os dois como serviços do Cloud Run para que possam ser acessados pela Internet. O serviço da caixa de ferramentas é executado como um servidor MCP no Cloud Run, e o serviço do agente se conecta a ele.
Preparar a caixa de ferramentas para implantação
Crie um diretório de implantação para o serviço da caixa de ferramentas:
cd ~/build-agent-adk-toolbox-cloudsql
mkdir -p deploy-toolbox
cp toolbox tools.yaml deploy-toolbox/
Crie o Dockerfile para a caixa de ferramentas. Abra deploy-toolbox/Dockerfile no editor do Cloud Shell:
cloudshell edit deploy-toolbox/Dockerfile
e copie o seguinte script nele:
# deploy-toolbox/Dockerfile
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY toolbox tools.yaml ./
RUN chmod +x toolbox
EXPOSE 8080
CMD ["./toolbox", "--tools-file", "tools.yaml", "--address", "0.0.0.0", "--port", "8080"]
O binário da caixa de ferramentas e o tools.yaml são empacotados em uma imagem mínima do Debian. O Cloud Run encaminha o tráfego para a porta 8080.
Implantar o serviço da caixa de ferramentas
cd ~/build-agent-adk-toolbox-cloudsql
gcloud run deploy toolbox-service \
--source deploy-toolbox/ \
--region $REGION \
--set-env-vars "DB_PASSWORD=$DB_PASSWORD,GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,REGION=$REGION,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_GENAI_USE_VERTEXAI=true" \
--allow-unauthenticated \
--quiet
Esse comando envia a origem para o Cloud Build, cria uma imagem de contêiner, envia para o Artifact Registry e implanta no Cloud Run. Isso leva alguns minutos. Vamos abrir uma nova guia do terminal no Cloud Shell (clique no ícone +) para que possamos nos concentrar mais.

Navegue até o diretório de trabalho novamente e ative o projeto usando o script de configuração anterior.
cd ~/build-agent-adk-toolbox-cloudsql
bash setup_verify_trial_project.sh && source .env
Preparar o agente para implantação
Enquanto a caixa de ferramentas é criada, configure os arquivos de implantação do agente.
Crie um Dockerfile na raiz do projeto. Abra Dockerfile no editor do Cloud Shell:
cloudshell edit Dockerfile
Em seguida, copie o conteúdo a seguir:
# Dockerfile
FROM ghcr.io/astral-sh/uv:python3.12-trixie-slim
WORKDIR /app
COPY pyproject.toml ./
COPY uv.lock ./
RUN uv sync --no-dev
COPY jobs_agent/ jobs_agent/
EXPOSE 8080
CMD ["uv", "run", "adk", "web", "--host", "0.0.0.0", "--port", "8080"]
Esse Dockerfile usa ghcr.io/astral-sh/uv como a imagem de base, que inclui Python e uv pré-instalados. Não é necessário instalar o uv separadamente via pip.
Crie um arquivo .dockerignore para excluir arquivos desnecessários da imagem do contêiner:
cloudshell edit .dockerignore
Em seguida, copie o script a seguir nele:
# .dockerignore
.venv/
__pycache__/
*.pyc
.env
jobs_agent/.env
toolbox
tools.yaml
seed.sql
deploy-toolbox/
Implantar o serviço do agente
Aguarde a conclusão da implantação da caixa de ferramentas. Recupere o URL do Cloud Run usando o seguinte comando:
TOOLBOX_URL=$(gcloud run services describe toolbox-service \
--region=$REGION \
--format='value(status.url)')
echo "Toolbox URL: $TOOLBOX_URL"
Você vai ver uma saída semelhante a esta:
Toolbox URL: https://toolbox-service-xxxxxx-xx.a.run.app
Em seguida, verifique se a caixa de ferramentas implantada está funcionando:
curl -s "$TOOLBOX_URL/api/toolset" | python3 -m json.tool | head -5
Se a saída for semelhante a este exemplo, a implantação já foi concluída.
{
"serverVersion": "0.27.0+binary.linux.amd64.c5524d3",
"tools": {
"add-job": {
"description": "Add a new job listing to the platform. Use this tool when a user asks to post a job that is not currently listed.",
Em seguida, vamos implantar o agente, transmitindo o URL da caixa de ferramentas como uma variável de ambiente:
cd ~/build-agent-adk-toolbox-cloudsql
gcloud run deploy jobs-agent \
--source . \
--region $REGION \
--set-env-vars "TOOLBOX_URL=$TOOLBOX_URL,GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,GOOGLE_GENAI_USE_VERTEXAI=TRUE" \
--allow-unauthenticated \
--quiet
O código do agente lê TOOLBOX_URL do ambiente (você configurou isso antes). Localmente, ele aponta para http://127.0.0.1:5000. No Cloud Run, ele aponta para o URL do serviço da caixa de ferramentas. Não é necessário mudar o código.
Testar o agente implantado
Recupere o URL do Cloud Run do agente:
AGENT_URL=$(gcloud run services describe jobs-agent \
--region=$REGION \
--format='value(status.url)')
echo "Agent URL: $AGENT_URL"
Abra o URL no seu navegador. A interface de desenvolvimento do ADK é carregada. É a mesma interface que você estava usando localmente, agora executada no Cloud Run.
Selecione jobs_agent no menu suspenso e teste:
What backend engineering jobs do you have?
I want a remote job working on AI and machine learning
As duas consultas funcionam pelos serviços implantados: o agente no Cloud Run chama a caixa de ferramentas no Cloud Run, que consulta o Cloud SQL.
9. Parabéns / Limpeza
Você criou e implantou um assistente de quadro de empregos inteligente que usa o MCP Toolbox for Databases para conectar um agente do ADK e o Cloud SQL PostgreSQL, com consultas SQL padrão e pesquisa semântica de vetores.
O que você aprendeu
- Como o MCP padroniza o acesso a ferramentas para agentes de IA e como a MCP Toolbox for Databases aplica isso especificamente a operações de banco de dados, substituindo o código personalizado do banco de dados por uma configuração YAML declarativa
- Como configurar o Cloud SQL PostgreSQL como uma fonte de dados da caixa de ferramentas usando o tipo de origem
cloud-sql-postgres - Como definir ferramentas de consulta SQL padrão com instruções parametrizadas que evitam a injeção de SQL
- Como ativar a pesquisa vetorial usando pgvector e
gemini-embedding-001, com o parâmetroembeddedBypara incorporação automática de consultas - Como o
valueFromParampermite a ingestão automática de vetores: o LLM fornece uma descrição de texto, e a caixa de ferramentas copia, incorpora e armazena o vetor silenciosamente ao lado do texto. - Como o
ToolboxToolsetdo ADK carrega ferramentas de um servidor da caixa de ferramentas em execução, mantendo o código do agente mínimo e a lógica do banco de dados totalmente dissociada - Como implantar o servidor MCP da Toolbox e o agente do ADK no Cloud Run como serviços separados
Limpeza
Para evitar cobranças na sua conta do Google Cloud pelos recursos criados neste codelab, exclua os recursos individuais ou o projeto inteiro.
Opção 1: excluir o projeto (recomendado)
A maneira mais fácil de fazer a limpeza é excluir o projeto. Isso remove todos os recursos associados ao projeto.
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Opção 2: excluir recursos individuais
Se você quiser manter o projeto, mas remover apenas os recursos criados neste codelab:
gcloud run services delete jobs-agent --region=$REGION --quiet
gcloud run services delete toolbox-service --region=$REGION --quiet
gcloud sql instances delete jobs-instance --quiet
gcloud artifacts repositories delete cloud-run-source-deploy --location=$REGION --quiet 2>/dev/null
