1. Introdução
Neste laboratório, você vai criar um agente com o Kit de desenvolvimento de agentes (ADK). Você vai aprender a criar um agente assistente de bugs de software usando o ADK e vários tipos de ferramentas. Você vai começar com um agente básico e adicionar ferramentas progressivamente para melhorar os recursos dele, incluindo ferramentas de função, ferramentas integradas, ferramentas de terceiros e ferramentas do protocolo de contexto de modelo (MCP).
O que você vai aprender
- Como configurar um projeto Python para desenvolvimento do ADK.
- Como criar um agente básico do ADK.
- Como implementar e usar as ferramentas de função.
- Como integrar ferramentas integradas, como a Pesquisa Google.
- Como usar ferramentas de terceiros de frameworks como o LangChain no ADK.
- Como usar as ferramentas do MCP para interagir com bancos de dados (Cloud SQL) e APIs.
2. Visão geral
Imagine que você é gerente de projetos na QuantumRoast, uma empresa global de máquinas de café.
Você ajuda seus colegas de equipe a navegar em um mar de planos de engenharia, mudanças repentinas de estratégia (agora estamos fazendo matcha!) e tíquetes recebidos de clientes, desde sistemas de faturamento com bugs até uma máquina de café que faz um ruído agudo 24 horas por dia, 7 dias por semana.
Em um dia normal, você tem cerca de 50 guias abertas no navegador: o sistema interno de tíquetes, e-mail, chat, GitHub, Pesquisa Google, StackOverflow e muito mais. Você gosta do seu trabalho e dos seus colegas, mas às vezes se sente sobrecarregado.
E se pudéssemos criar um assistente para ajudar você a criar e classificar tíquetes de software e depurar problemas? Um agente de IA torna isso possível.
Agent Development Kit (ADK)
O Agent Development Kit (ADK) é um framework flexível e modular para desenvolver e implantar agentes de IA. Embora seja otimizado para o Gemini e o ecossistema do Google, o ADK é independente de modelo e implantação e foi criado para ser compatível com outras estruturas. O ADK foi projetado para tornar o desenvolvimento de agentes mais parecido com o desenvolvimento de software, facilitando a criação, implantação e orquestração de arquiteturas de agentes que variam de tarefas simples a fluxos de trabalho complexos.
O ADK é o framework que vamos usar para criar o assistente de bugs de software QuantumRoast.
Noções básicas sobre ferramentas
Os agentes de IA usam modelos, não apenas lógica codificada, para resolver um problema. Mas, além do raciocínio baseado em LLMs, os agentes de IA têm a capacidade exclusiva de coletar dados externos e realizar ações em nome do usuário. Em vez de dizer como resolver um problema, um agente de IA pode ajudar você a resolver de verdade. Como fazemos isso? Com ferramentas!
Uma ferramenta é uma capacidade que ajuda um agente de IA a interagir com o mundo. Uma ferramenta pode ser quase qualquer coisa: uma função inline, um banco de dados hospedado, uma API de terceiros ou até mesmo outro agente. Os frameworks de agentes de IA, como o Agent Development Kit (ADK), têm suporte integrado para ferramentas, oferecendo suporte a vários tipos de ferramentas que vamos abordar em breve.
Mas como um agente sabe não apenas quando chamar uma determinada ferramenta, mas também como fazer isso? O modelo do agente desempenha algumas funções importantes aqui.
A primeira é a seleção de ferramentas. Fornecemos ao nosso agente uma lista de ferramentas e algumas instruções sobre como usá-las. Quando um usuário faz um comando para o agente, o modelo dele ajuda a decidir quais ferramentas chamar e por quê, para ajudar o usuário.
A segunda etapa principal é a chamada de função. A chamada de função é um pouco inadequada porque o modelo não está realmente chamando a ferramenta, mas sim se preparando para chamá-la ao formatar o corpo da solicitação que o framework usa para chamar a ferramenta.
Por fim, o modelo ajuda a interpretar a resposta dessa ferramenta, por exemplo, uma lista de bugs abertos do banco de dados, e decide se é necessário tomar outras medidas ou responder ao usuário com essas informações.
Para ver tudo isso em ação, é hora de criar o agente assistente de bugs do QuantumRoast usando o ADK Python.
3. Antes de começar
Configuração do projeto do Google Cloud
- Se você ainda não tiver uma Conta do Google, crie uma.
- Use uma conta pessoal em vez de uma conta escolar ou de trabalho. As contas escolares e de trabalho podem ter restrições que impedem a ativação das APIs necessárias para este laboratório.
- Faça login no Console do Google Cloud.
- Ative o faturamento no Console do Cloud.
- A conclusão deste laboratório custa menos de US $1 em recursos do Cloud.
- Siga as etapas no final deste laboratório para excluir recursos e evitar mais cobranças.
- Novos usuários podem aproveitar a avaliação sem custo financeiro de US$300.
- Crie um projeto ou reutilize um projeto existente.
Abrir editor do Cloud Shell
- Acesse o editor do Cloud Shell.
- Se o terminal não aparecer na parte de baixo da tela, abra-o:
- Clique no menu de navegação
.
- Clique em Terminal.
- Clique em Novo Terminal.
- Clique no menu de navegação
- No terminal, defina seu projeto com este comando (substituindo
YOUR_PROJECT_ID
):- Formato:
gcloud config set project YOUR_PROJECT_ID
- Exemplo:
gcloud config set project lab-project-id-example
- Se você não se lembrar do ID do projeto:
- É possível listar todos os IDs de projeto com:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
- É possível listar todos os IDs de projeto com:
- Formato:
- Se for preciso autorizar, clique em Autorizar para continuar.
- Você vai receber esta mensagem:
Se você vir umUpdated property [core/project].
WARNING
e for perguntadoDo you want to continue (Y/N)?
, provavelmente inseriu o ID do projeto incorretamente. PressioneN
,Enter
e tente executar o comandogcloud config set project
novamente. - No terminal, defina a variável de ambiente
PROJECT_ID
para ser usada em etapas posteriores.export PROJECT_ID=$(gcloud config get project)
Ativar APIs
No terminal, execute o comando a seguir para ativar as APIs do Google Cloud necessárias:
gcloud services enable sqladmin.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
secretmanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com
Criar uma instância do Cloud SQL para PostgreSQL
O QuantumRoast tem um banco de dados de tíquetes de bugs que contém todos os tíquetes internos. Vamos configurar criando uma instância do Cloud SQL para PostgreSQL.
gcloud sql instances create software-assistant \
--database-version=POSTGRES_16 \
--tier=db-custom-1-3840 \
--region=us-central1 \
--edition=ENTERPRISE \
--enable-google-ml-integration \
--database-flags cloudsql.enable_google_ml_integration=on \
--root-password=admin
Aguarde a criação da instância. Isso pode levar alguns minutos.
Depois de criada, é possível conferir a instância no Console do Cloud aqui.
Criar um banco de dados do Cloud SQL
Crie um banco de dados SQL (tickets-db
) e conceda à conta de serviço do Cloud SQL acesso à Vertex AI para que possamos criar embeddings e realizar pesquisas de similaridade.
gcloud sql databases create tickets-db --instance=software-assistant
SERVICE_ACCOUNT_EMAIL=$(gcloud sql instances describe software-assistant --format="value(serviceAccountEmailAddress)")
echo $SERVICE_ACCOUNT_EMAIL
gcloud projects add-iam-policy-binding $PROJECT_ID --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" --role="roles/aiplatform.user"
Configurar a tabela tickets
No Console do Cloud (Cloud SQL), abra o Cloud SQL Studio para a instância software-assistant
.
Faça login no banco de dados tickets-db
usando o usuário postgres
e admin
como senha.
Abra uma nova guia Editor
.
Em seguida, cole o código SQL a seguir para configurar a tabela e criar embeddings de vetores. Pressione o botão Run
para executar o comando.
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector CASCADE;
GRANT EXECUTE ON FUNCTION embedding TO postgres;
CREATE TABLE tickets (
ticket_id SERIAL PRIMARY KEY, -- PostgreSQL's auto-incrementing integer type (SERIAL is equivalent to INT AUTO_INCREMENT)
title VARCHAR(255) NOT NULL, -- A concise summary or title of the bug/issue.
description TEXT, -- A detailed description of the bug.
assignee VARCHAR(100), -- The name or email of the person/team assigned to the ticket.
priority VARCHAR(50), -- The priority level (e.g., 'P0 - Critical', 'P1 - High').
status VARCHAR(50) DEFAULT 'Open', -- The current status of the ticket (e.g., 'Open', 'In Progress', 'Resolved'). Default is 'Open'.
creation_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, -- Timestamp when the ticket was first created. 'WITH TIME ZONE' is recommended for clarity and compatibility.
updated_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP -- Timestamp when the ticket was last updated. Will be managed by a trigger.
);
A tabela tickets
foi criada. Clique em Clear
para limpar a consulta antiga.
Agora, insira os dados de amostra e clique no botão Run
mais uma vez.
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Login Page Freezes After Multiple Failed Attempts', 'Users are reporting that after 3 failed login attempts, the login page becomes unresponsive and requires a refresh. No specific error message is displayed.', 'samuel.green@example.com', 'P0 - Critical', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Dashboard Sales Widget Intermittent Data Loading Failure', 'The "Sales Overview" widget on the main dashboard intermittently shows a loading spinner but no data. Primarily affects Chrome browser users.', 'maria.rodriguez@example.com', 'P1 - High', 'In Progress');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Broken Link in Footer - Privacy Policy', 'The "Privacy Policy" hyperlink located in the website footer leads to a 404 "Page Not Found" error.', 'maria.rodriguez@example.com', 'P3 - Low', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('UI Misalignment on Mobile Landscape View (iOS)', 'On specific iOS devices (e.g., iPhone 14 models), the top navigation bar shifts downwards when the device is viewed in landscape orientation, obscuring content.', 'maria.rodriguez@example.com', 'P2 - Medium', 'In Progress');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Critical XZ Utils Backdoor Detected in Core Dependency (CVE-2024-3094)', 'Urgent: A sophisticated supply chain compromise (CVE-2024-3094) has been identified in XZ Utils versions 5.6.0 and 5.6.1. This malicious code potentially allows unauthorized remote SSH access by modifying liblzma. Immediate investigation and action required for affected Linux/Unix systems and services relying on XZ Utils.', 'frank.white@example.com', 'P0 - Critical', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Database Connection Timeouts During Peak Usage', 'The application is experiencing frequent database connection timeouts, particularly during peak hours (10 AM - 12 PM EDT), affecting all users and causing service interruptions.', 'frank.white@example.com', 'P1 - High', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Export to PDF Truncates Long Text Fields in Reports', 'When generating PDF exports of reports containing extensive text fields, the text is abruptly cut off at the end of the page instead of wrapping or continuing to the next page.', 'samuel.green@example.com', 'P1 - High', 'Open');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Search Filter "Date Range" Not Applying Correctly', 'The "Date Range" filter on the search results page does not filter records accurately; results outside the specified date range are still displayed.', 'samuel.green@example.com', 'P2 - Medium', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Typo in Error Message: "Unathorized Access"', 'The error message displayed when a user attempts an unauthorized action reads "Unathorized Access" instead of "Unauthorized Access."', 'maria.rodriguez@example.com', 'P3 - Low', 'Resolved');
INSERT INTO tickets (title, description, assignee, priority, status) VALUES
('Intermittent File Upload Failures for Large Files', 'Users are intermittently reporting that file uploads fail without a clear error message or explanation, especially for files exceeding 10MB in size.', 'frank.white@example.com', 'P1 - High', 'Open');
Na QuantumRoast, talvez seja necessário saber quando um bug/ticket foi atualizado pela última vez.
Para isso, podemos criar um gatilho para atualizar o campo updated_time
sempre que um registro for atualizado.
Clique em Clear
e cole o seguinte SQL para implementar um gatilho.
Pressione o botão Run
para executar.
CREATE OR REPLACE FUNCTION update_updated_time_tickets()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_time = NOW(); -- Set the updated_time to the current timestamp
RETURN NEW; -- Return the new row
END;
$$ language 'plpgsql';
CREATE TRIGGER update_tickets_updated_time
BEFORE UPDATE ON tickets
FOR EACH ROW -- This means the trigger fires for each row affected by the UPDATE statement
EXECUTE PROCEDURE update_updated_time_tickets();
Crie embeddings de vetor com base no campo description
. Isso vai permitir que nosso agente faça pesquisas de similaridade no nosso banco de dados. Por exemplo, "Há problemas em aberto relacionados à página inicial do site?".
ALTER TABLE tickets ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',description)) STORED;
Agora você pode consultar o banco de dados para verificar se ele está pronto.
SELECT * FROM tickets;
Você vai ver 10 linhas retornadas semelhantes a estas:
Agora você pode passar para a parte divertida: o código.
4. Configuração do projeto em Python
Antes de começar a criar nosso agente, precisamos garantir que temos uma configuração adequada do projeto Python. Vamos fazer tudo no Cloud Shell.
Primeiro, crie uma pasta quantum-roast
e cd
nela:
mkdir quantum-roast && cd quantum-roast
Agora que temos uma pasta para o projeto, é hora de inicializar e criar os arquivos correspondentes que vamos precisar.
Vamos usar o uv
(gerenciador de projetos e pacotes extremamente rápido do Python), que vem pré-instalado no Cloud Shell para gerenciar nosso projeto e as dependências. O Uv vai ajudar a configurar alguns dos nossos arquivos e gerenciar ambientes virtuais, dependências etc. para que não precisemos fazer isso.
Inicialize um novo projeto com uv init
:
uv init --description "QuantumRoast Software Bug Assistant with ADK" --bare --python 3.10
Depois de executar o comando, teremos um arquivo pyproject.toml
para nosso projeto. Para verificar, execute cat pyproject.toml
no terminal do Cloud Shell:
cat pyproject.toml
A saída será assim:
[project] name = "quantum-roast" version = "0.1.0" description = "QuantumRoast Software Bug Assistant with ADK" requires-python = ">=3.10" dependencies = []
Agora vamos adicionar google-adk
(ADK) como uma dependência ao nosso projeto usando uv add
.
uv add google-adk==1.11.0
Isso adiciona google-adk
à lista dependencies
na nossa pyproject.toml
.
O ADK espera uma determinada estrutura de projeto para alcançar os melhores resultados.
quantum-roast/ software_bug_assistant/ __init__.py agent.py .env
Crie a pasta software_bug_assistant
e os arquivos dentro dela:
mkdir software_bug_assistant && touch software_bug_assistant/__init__.py \
software_bug_assistant/agent.py \
software_bug_assistant/tools.py \
software_bug_assistant/.env
Verifique a criação dos arquivos usando ls
:
ls -a software_bug_assistant/
Você verá o seguinte:
__init__.py . .. .env agent.py tools.py
Agora é hora de preencher o arquivo .env
com as variáveis de ambiente necessárias para que o ADK chame os modelos do Gemini corretamente. Vamos acessar o Gemini pela API Vertex.
echo "GOOGLE_GENAI_USE_VERTEXAI=TRUE" >> software_bug_assistant/.env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> software_bug_assistant/.env \
&& echo "GOOGLE_CLOUD_LOCATION=us-central1" >> software_bug_assistant/.env
Para verificar se o .env
foi preenchido corretamente, execute o seguinte:
cat software_bug_assistant/.env
Você vai ver o seguinte, em que your-project-id
é o ID do projeto:
GOOGLE_GENAI_USE_VERTEXAI=TRUE GOOGLE_CLOUD_PROJECT=your-project-id GOOGLE_CLOUD_LOCATION=us-central1
Agora estamos prontos para começar a criar nosso agente do ADK.
5. Agente do ADK de base
Vamos configurar um agente ADK básico para adicionar ferramentas uma a uma durante este workshop e criar um assistente de bugs eficiente.
Abra agent.py
no editor do Cloud Shell:
cloudshell edit software_bug_assistant/agent.py
Cole o código a seguir em agent.py
e salve o arquivo Ctrl + s
:
from google.adk.agents import Agent
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[],
)
Execute o agente recém-criado iniciando a interface de desenvolvimento do ADK (adk web
). Ao fazer isso com uv run
, um ambiente virtual com o ADK instalado será criado automaticamente.
uv run adk web --port 8080 --reload_agents
No console, você vai ver a inicialização bem-sucedida do servidor da Web do ADK.
INFO: Started server process [1557] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://localhost:8080. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
Abra a visualização da Web do Cloud Shell para conferir a interface.
A interface da Web do ADK vai aparecer.
Tente conversar com o agente do ADK.
Pergunte ao agente What day is it today?
.
Você vai notar na resposta que o agente não consegue responder a essa pergunta básica. Os LLMs são sistemas isolados, treinados com dados anteriores. Eles não têm contexto em tempo real sobre eventos recentes ou até mesmo a data atual, a menos que você dê a eles ferramentas.
É hora de implementar o primeiro tipo de ferramenta do ADK, uma ferramenta de função.
6. Ferramenta de função
O primeiro e mais simples tipo de ferramenta do ADK é a ferramenta de função. É exatamente o que parece ser: uma função em Python que é chamada pelo agente.
As ferramentas de função são muito úteis porque permitem escrever código personalizado para o agente chamar como uma ferramenta, como fazer um cálculo, chamar uma API ou consultar um banco de dados. Elas podem ser funções simples ou complexas, fica a seu critério.
Na QuantumRoast, queremos definir uma função básica para receber a data do dia atual. Assim, mais tarde neste laboratório, poderemos processar consultas como "mostre os bugs da última semana" ou "que dia é hoje?". (acontece com todo mundo).
O arquivo tools.py
na pasta /software_bug_assistant
é onde vamos organizar todas as ferramentas que criaremos ao longo deste laboratório.
Abra um terminal NOVO clicando no ícone +
.
Agora, no novo terminal, defina PROJECT_ID
e abra tools.py
:
cd quantum-roast
export PROJECT_ID=$(gcloud config get project)
cloudshell edit software_bug_assistant/tools.py
Agora defina a função get_current_date
, que será usada como uma ferramenta de função.
from datetime import datetime
# ----- Example of a Function tool -----
def get_current_date() -> dict:
"""
Get the current date in the format YYYY-MM-DD
"""
return {"current_date": datetime.now().strftime("%Y-%m-%d")}
A função agora está definida. Agora é hora de transmitir como uma ferramenta para o agente.
Abra agent.py
no editor do Cloud Shell:
cloudshell edit software_bug_assistant/agent.py
Queremos importar a função get_current_date
de tools.py
e transmitir a função ao argumento tools
do agente.
O agent.py
atualizado fica assim:
from google.adk.agents import Agent
from .tools import get_current_date
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date],
)
Agora, se você voltar para a guia "Visualização na Web" que executa a interface da Web do ADK e perguntar What day is it today?
de novo...
O agente pode informar a data chamando a ferramenta de função get_current_date
. 🎉
Hora de conhecer o próximo tipo de ferramenta do ADK.
7. Ferramenta integrada
Outro tipo de ferramenta do ADK é uma ferramenta integrada. São ferramentas que funcionam com os principais recursos do modelo do Google, como a execução de código dentro do próprio modelo. Podemos anexar a ferramenta integrada Pesquisa Google ao nosso agente assistente de bugs para dar a ele acesso à pesquisa na Web e contextualizar as informações relevantes. Isso permite que o agente colete informações mais atuais sobre um bug ou uma vulnerabilidade conhecida.
Abra o arquivo tools.py
para adicionar suporte à ferramenta integrada da Pesquisa Google.
cloudshell edit software_bug_assistant/tools.py
Adicione o seguinte à parte de baixo de tools.py
:
# ----- Built-in Tool Imports -----
from google.adk.agents import Agent
from google.adk.tools import google_search
from google.adk.tools.agent_tool import AgentTool
# ----- Example of a Built-in Tool -----
search_agent = Agent(
model="gemini-2.5-flash",
name="search_agent",
description="A specialist in Google Search.",
instruction="""
You're a specialist in Google Search.
""",
tools=[google_search],
)
search_tool = AgentTool(search_agent)
Aqui, estamos encapsulando a ferramenta da Pesquisa Google em um agente próprio com instruções de sistema próprias, usando um agente como ferramenta.
Agora podemos importar e transmitir o search_tool
para o agente raiz em agent.py
:
cloudshell edit software_bug_assistant/agent.py
Substitua agent.py
pelo código a seguir para incluir search_tool
:
from google.adk.agents import Agent
from .tools import get_current_date, search_tool
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool],
)
Salve o arquivo e volte para a janela aberta com a interface da Web do ADK em execução.
Na QuantumRoast, queremos garantir que nosso site e software estejam protegidos contra vulnerabilidades e exposições comuns (CVEs), que são vulnerabilidades públicas de segurança cibernética. Podemos usar a nova ferramenta de Pesquisa Google do nosso agente para pesquisar na Web os CVEs descobertos mais recentemente.
Execute a seguinte consulta: Do a web search for 5 of the most recent CVEs?
.
Nosso agente precisa chamar o search_agent
para pesquisar na Web.
Nosso agente agora desbloqueou a capacidade de pesquisar na Web usando a ferramenta integrada do ADK para a Pesquisa Google. 🎉
Vamos para o próximo tipo de ferramenta do ADK.
8. Ferramenta de terceiros
O ADK foi projetado para ser altamente extensível, permitindo que você integre ferramentas de outros frameworks de agentes de IA de terceiros, como CrewAI e LangChain. Essa interoperabilidade é crucial porque permite um tempo de desenvolvimento mais rápido e a capacidade de reutilizar ferramentas atuais.
Para conectar nosso agente de bugs aos dados de perguntas e respostas do StackOverflow, podemos usar a biblioteca de ferramentas da LangChain, especificamente a ferramenta de wrapper da API StackExchange. O ADK é compatível com ferramentas de terceiros, como o LangChain. Por isso, adicionar essa ferramenta ao nosso agente do ADK exige apenas algumas linhas de código.
Primeiro, precisamos adicionar novas dependências para LangChain e StackOverflow (langchain-community
e stackapi
) ao nosso projeto:
uv add langchain-community==0.3.27 stackapi==0.3.1
Abra o arquivo tools.py
para adicionar suporte à ferramenta LangChain StackExchange.
cloudshell edit software_bug_assistant/tools.py
Adicione o seguinte à parte de baixo de tools.py
:
# ----- Example of a Third-Party Tool -----
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import StackExchangeTool
from langchain_community.utilities import StackExchangeAPIWrapper
stack_exchange_tool = StackExchangeTool(api_wrapper=StackExchangeAPIWrapper())
langchain_tool = LangchainTool(stack_exchange_tool)
Agora podemos importar e transmitir o langchain_tool
para o agente raiz em agent.py
:
cloudshell edit software_bug_assistant/agent.py
Substitua agent.py
pelo código a seguir para incluir langchain_tool
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, search_tool
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool],
)
Salve o arquivo e volte para a guia aberta com a interface da Web do ADK.
Pergunte ao agente algo sobre os CVEs anteriores, "Are there similar issues on stack exchange?"
ou algo novo, como "Our database queries with SQLAlchemy seem to be timing out, is there anything on StackExchange relevant to this?"
.
Nosso agente usou uma ferramenta do LangChain no ADK para consultar o StackOverflow. 🥳
Hora do próximo tipo de ferramenta do ADK... Ferramentas do MCP!
9. Ferramenta do MCP (banco de dados)
MCP significa Protocolo de Contexto de Modelo. É um protocolo aberto lançado pela Anthropic em 2024. O MCP fornece uma camada de abstração entre o agente de IA e os "back-ends" de ferramentas (APIs, bancos de dados).
O MCP tem algumas especificações exclusivas. Ao contrário do HTTP padrão, o MCP oferece uma conexão bidirecional com estado entre o cliente e o servidor. Ele tem uma maneira própria de definir ferramentas e mensagens de erro específicas para cada ferramenta. Um provedor de ferramentas pode criar servidores MCP com base nas APIs dele, expondo uma ou mais ferramentas pré-criadas para desenvolvedores e usuários. Em seguida, as estruturas de agentes podem inicializar clientes MCP em um aplicativo de agente para descobrir e chamar essas ferramentas.
Na QuantumRoast, temos um banco de dados do Cloud SQL para PostgreSQL para bugs internos de software. Queremos criar ferramentas do ADK para que nosso agente possa realizar determinadas consultas no nosso banco de dados.
A maneira mais fácil de fazer isso é com o MCP Toolbox for Databases (link em inglês), um servidor MCP de código aberto para bancos de dados. A caixa de ferramentas é compatível com mais de 15 bancos de dados, incluindo o Cloud SQL.
A caixa de ferramentas oferece:
- Desenvolvimento simplificado: integre ferramentas ao seu agente em menos de 10 linhas de código, reutilize ferramentas entre vários agentes ou frameworks e implante novas versões de ferramentas com mais facilidade.
- Melhor desempenho: práticas recomendadas, como pooling de conexões, autenticação e muito mais.
- Segurança aprimorada: autenticação integrada para acesso mais seguro aos seus dados
- Observabilidade de ponta a ponta: métricas e rastreamento prontos para uso com suporte integrado ao OpenTelemetry.
O ADK oferece suporte ao MCP Toolbox for Database tools, o que facilita a integração.
Implantar o servidor da caixa de ferramentas MCP para bancos de dados no Cloud Run
Primeiro, vamos implantar a caixa de ferramentas do MCP para servidores de banco de dados no Cloud Run e apontar para nossa instância do Cloud SQL.
A caixa de ferramentas exige um arquivo YAML para configuração, em que você descreve a origem do banco de dados e as ferramentas a serem configuradas.
Crie um arquivo tools.yaml
para a implantação.
cloudshell edit tools.yaml
Cole o conteúdo a seguir em tools.yaml
:
sources:
postgresql:
kind: cloud-sql-postgres
project: ${PROJECT_ID}
region: us-central1
instance: software-assistant
database: tickets-db
user: postgres
password: admin
tools:
search-tickets:
kind: postgres-sql
source: postgresql
description: Search for similar tickets based on their descriptions.
parameters:
- name: query
type: string
description: The query to perform vector search with.
statement: |
SELECT ticket_id, title, description, assignee, priority, status, (embedding <=> embedding('text-embedding-005', $1)::vector) as distance
FROM tickets
ORDER BY distance ASC
LIMIT 3;
get-ticket-by-id:
kind: postgres-sql
source: postgresql
description: Retrieve a ticket's details using its unique ID.
parameters:
- name: ticket_id
type: string
description: The unique ID of the ticket.
statement: SELECT * FROM tickets WHERE ticket_id = $1;
get-tickets-by-assignee:
kind: postgres-sql
source: postgresql
description: Search for tickets based on assignee (email).
parameters:
- name: assignee
type: string
description: The email of the assignee.
statement: SELECT * FROM tickets WHERE assignee ILIKE '%' || $1 || '%';
update-ticket-priority:
kind: postgres-sql
source: postgresql
description: Update the priority of a ticket based on its ID.
parameters:
- name: priority
type: string
description: The priority of the ticket. Can be one of 'P0 - Critical', 'P1 - High', 'P2 - Medium', or 'P3 - Low'.
- name: ticket_id
type: string
description: The ID of the ticket.
statement: UPDATE tickets SET priority = $1 WHERE ticket_id = $2;
update-ticket-status:
kind: postgres-sql
source: postgresql
description: Update the status of a ticket based on its ID.
parameters:
- name: status
type: string
description: The new status of the ticket (e.g., 'Open', 'In Progress', 'Closed', 'Resolved').
- name: ticket_id
type: string
description: The ID of the ticket.
statement: UPDATE tickets SET status = $1 WHERE ticket_id = $2;
get-tickets-by-status:
kind: postgres-sql
source: postgresql
description: Search for tickets based on their current status.
parameters:
- name: status
type: string
description: The status of the tickets to retrieve (e.g., 'Open', 'In Progress', 'Closed', 'Resolved').
statement: SELECT * FROM tickets WHERE status ILIKE '%' || $1 || '%';
get-tickets-by-priority:
kind: postgres-sql
source: postgresql
description: Search for tickets based on their priority.
parameters:
- name: priority
type: string
description: The priority of the tickets to retrieve (e.g., 'P0 - Critical', 'P1 - High', 'P2 - Medium', 'P3 - Low').
statement: SELECT * FROM tickets WHERE priority ILIKE '%' || $1 || '%';
create-new-ticket:
kind: postgres-sql
source: postgresql
description: Create a new software ticket.
parameters:
- name: title
type: string
description: The title of the new ticket.
- name: description
type: string
description: A detailed description of the bug or issue.
- name: assignee
type: string
description: (Optional) The email of the person to whom the ticket should be assigned.
- name: priority
type: string
description: (Optional) The priority of the ticket. Can be 'P0 - Critical', 'P1 - High', 'P2 - Medium', or 'P3 - Low'. Default is 'P3 - Low'.
- name: status
type: string
description: (Optional) The initial status of the ticket. Default is 'Open'.
statement: INSERT INTO tickets (title, description, assignee, priority, status) VALUES ($1, $2, $3, COALESCE($4, 'P3 - Low'), COALESCE($5, 'Open')) RETURNING ticket_id;
get-tickets-by-date-range:
kind: postgres-sql
source: postgresql
description: Retrieve tickets created or updated within a specific date range.
parameters:
- name: start_date
type: string
description: The start date (inclusive) for the range (e.g., 'YYYY-MM-DD').
- name: end_date
type: string
description: The end date (inclusive) for the range (e.g., 'YYYY-MM-DD').
- name: date_field
type: string
description: The date field to filter by ('creation_time' or 'updated_time').
statement: SELECT * FROM tickets WHERE CASE WHEN $3 = 'creation_time' THEN creation_time ELSE updated_time END BETWEEN $1::timestamp AND $2::timestamp;
toolsets:
tickets_toolset:
- search-tickets
- get-ticket-by-id
- get-tickets-by-assignee
- get-tickets-by-status
- get-tickets-by-priority
- get-tickets-by-date-range
- update-ticket-priority
- update-ticket-status
- create-new-ticket
O arquivo YAML define nove ferramentas relacionadas ao banco de dados de tíquetes do QuantumRoast.
Agora vamos configurar uma conta de serviço para o serviço do Cloud Run da caixa de ferramentas, conceder permissão para acessar o Cloud SQL e o Secret Manager e criar um secret do Secret Manager para nosso arquivo tools.yaml
.
O Secret Manager é onde vamos armazenar nosso arquivo tools.yaml
porque ele contém credenciais sensíveis do Cloud SQL.
gcloud iam service-accounts create toolbox-identity
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/secretmanager.secretAccessor
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member serviceAccount:toolbox-identity@$PROJECT_ID.iam.gserviceaccount.com \
--role roles/cloudsql.client
gcloud secrets create tools --data-file=tools.yaml
É hora de implantar a MCP Toolbox for Databases no Cloud Run. Vamos usar a versão de lançamento mais recente da imagem do contêiner da caixa de ferramentas do MCP.
gcloud run deploy toolbox \
--image us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:latest \
--service-account toolbox-identity \
--region us-central1 \
--set-secrets "/app/tools.yaml=tools:latest" \
--set-env-vars="PROJECT_ID=$PROJECT_ID" \
--args="--tools-file=/app/tools.yaml","--address=0.0.0.0","--port=8080" \
--allow-unauthenticated
Aguarde a conclusão da implantação...
Verifique se a caixa de ferramentas está em execução consultando os registros do Cloud Run:
gcloud run services logs read toolbox --region us-central1 --limit 10
Você verá:
2025-08-20 18:03:55 2025-08-20T18:03:55.465847801Z INFO "Initialized 1 sources." 2025-08-20 18:03:55 2025-08-20T18:03:55.466152914Z INFO "Initialized 0 authServices." 2025-08-20 18:03:55 2025-08-20T18:03:55.466374245Z INFO "Initialized 9 tools." 2025-08-20 18:03:55 2025-08-20T18:03:55.466477938Z INFO "Initialized 2 toolsets." 2025-08-20 18:03:55 2025-08-20T18:03:55.467492303Z INFO "Server ready to serve!"
Salve o URL do Cloud Run para o serviço da caixa de ferramentas como uma variável de ambiente para que o agente do ADK saiba onde encontrá-lo.
export MCP_TOOLBOX_URL=$(gcloud run services describe toolbox --region us-central1 --format "value(status.url)")
echo MCP_TOOLBOX_URL=$MCP_TOOLBOX_URL >> software_bug_assistant/.env
Atualizar o agente do QuantumRoast
Em segundo lugar, precisamos adicionar a dependência do SDK da MCP Toolbox for Databases (toolbox-core
) ao nosso projeto:
uv add toolbox-core==0.5.0
Abra o arquivo tools.py
para adicionar suporte às ferramentas da MCP Toolbox.
cloudshell edit software_bug_assistant/tools.py
Adicione o seguinte à parte de baixo de tools.py
:
# ----- Example MCP Toolbox for Databases tools -----
import os
from toolbox_core import ToolboxSyncClient
TOOLBOX_URL = os.getenv("MCP_TOOLBOX_URL", "http://127.0.0.1:5000")
# Initialize Toolbox client
toolbox = ToolboxSyncClient(TOOLBOX_URL)
# Load all the tools from toolset
toolbox_tools = toolbox.load_toolset("tickets_toolset")
Agora podemos importar e transmitir o toolbox_tools
para o agente raiz em agent.py
:
cloudshell edit software_bug_assistant/agent.py
Substitua agent.py
pelo código a seguir para incluir toolbox_tools
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, search_tool, toolbox_tools
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool, *toolbox_tools],
)
Salve o arquivo e volte para a guia aberta com a interface da Web do ADK.
Agora você pode fazer perguntas sobre os tíquetes armazenados no nosso banco de dados interno de tíquetes do Cloud SQL.
Faça uma pergunta como uma destas:
I am seeing an issue with database timeouts, has anyone else seen a similar issue?
How many bugs are assigned to samuel.green@example.com? Show a table.
Can you bump the priority of ticket with ID 6 to to P0 - Critical priority
Create a new ticket
(deixe o agente guiar você na criação de um bug)
Nosso agente do ADK consultou o banco de dados com sucesso usando as ferramentas do MCP Toolbox for Databases!🚀
10. Opcional: ferramenta MCP (API)
E como conectar nosso agente do ADK a ferramentas do MCP que não têm SDK próprio, como o MCP Toolbox for Database?
O ADK oferece suporte a ferramentas genéricas do MCP pela classe MCPToolset
. A classe MCPToolset
é o principal mecanismo do ADK para integrar ferramentas de um servidor MCP.
O MCPToolset
pode ser usado para se conectar a servidores MCP locais ou remotos. No QuantumRoast, queremos conectar nosso agente ao servidor MCP remoto do GitHub para chamar facilmente as APIs do GitHub. Isso permite que nosso agente extraia informações sobre problemas de repositórios de software públicos ou até mesmo de nossas próprias bases de código. O servidor MCP do GitHub expõe diferentes partes da funcionalidade do GitHub, desde problemas e solicitações de envio até notificações e segurança de código.
Token de acesso pessoal (PAT) do GitHub
Para se autenticar com o servidor MCP do GitHub, você precisa de um token de acesso pessoal do GitHub.
Para adquirir um, siga estas etapas:
- Acesse as configurações de desenvolvedor do GitHub.
- Clique em "Tokens de acesso pessoal" -> "Tokens (clássico)".
- Clique em "Gerar novo token" -> "Gerar novo token (clássico)".
- Dê ao token um nome descritivo.
- Defina uma data de validade para o token.
- Importante: para sua segurança, conceda ao token os escopos mais limitados necessários. Para acesso somente leitura a repositórios, os escopos
repo:status
,public_repo
eread:user
geralmente são suficientes. Evite conceder permissões de administrador ou de repositório completo, a menos que seja absolutamente necessário. - Clique em
Generate token
. - Copie o token gerado.
No terminal do Cloud Shell, execute o seguinte comando para definir seu PAT do GitHub para que o agente possa usar. Substitua YOUR_GITHUB_PAT
pelo PAT gerado.
export GITHUB_PAT=YOUR_GITHUB_PAT
Atualizar o agente do QuantumRoast
Para nosso assistente de bugs, vamos expor apenas algumas ferramentas do GitHub somente leitura. Assim, os funcionários da QuantumRoast podem encontrar problemas relacionados a dependências de código aberto e verificar se isso ajuda a identificar a causa raiz dos bugs que estão aparecendo no sistema de tíquetes interno. Vamos usar o MCPToolset
do ADK com um tool_filter
para configurar isso. O tool-filter
expõe apenas as ferramentas do GitHub de que precisamos, o que não apenas oculta as ferramentas que não queremos que os usuários acessem (pense em ações sensíveis do repositório), mas também protege o modelo do agente contra sobrecarga ao tentar escolher a ferramenta certa para o trabalho.
Abra o arquivo tools.py
para adicionar suporte às ferramentas do GitHub.
cloudshell edit software_bug_assistant/tools.py
Adicione o seguinte à parte de baixo de tools.py
:
# ----- Example MCP Tools with MCPToolset (GitHub) -----
from google.adk.tools.mcp_tool import MCPToolset, StreamableHTTPConnectionParams
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://api.githubcopilot.com/mcp/",
headers={
"Authorization": "Bearer " + os.getenv("GITHUB_PAT"),
},
),
# Read only tools
tool_filter=[
"search_repositories",
"search_issues",
"list_issues",
"get_issue",
"list_pull_requests",
"get_pull_request",
],
)
Observe como também precisamos fornecer o token de acesso pessoal (PAT) do GitHub à nossa definição de MCPToolset
, assim como você forneceria um token de autenticação ao configurar um cliente de API padrão no seu código. Esse PAT tem escopo para acessar apenas dados de repositórios públicos, sem escopos relacionados a ações sensíveis de usuários ou repositórios.
Agora podemos importar e transmitir o mcp_tools
para o agente raiz em agent.py
:
cloudshell edit software_bug_assistant/agent.py
Substitua agent.py
pelo código a seguir para incluir mcp_tools
:
from google.adk.agents import Agent
from .tools import get_current_date, langchain_tool, mcp_tools, search_tool, toolbox_tools
# --- Agent Definition (model, instructions, tools) ---
root_agent = Agent(
model="gemini-2.5-flash",
name="software_assistant",
instruction="""
You are a skilled expert in triaging and debugging software issues for a
coffee machine company, QuantumRoast.
""",
tools=[get_current_date, search_tool, langchain_tool, *toolbox_tools, mcp_tools],
)
Salve o arquivo e volte para a guia aberta com a interface da Web do ADK.
Agora temos um conjunto de ferramentas MCP do GitHub que nosso agente pode chamar. Os serviços do QuantumRoast dependem do XZ utils, uma ferramenta de compactação de dados. Nosso sistema interno de tíquetes de bugs está rastreando uma CVE (vulnerabilidade de segurança) do ano passado, que podemos rastrear até o repositório do GitHub do XZ Utils usando as ferramentas do StackOverflow e da Pesquisa Google. Em seguida, podemos usar uma das ferramentas MCP do GitHub, search_issues
, para determinar quando e como essa CVE foi corrigida:
Pergunte ao agente o seguinte:
Find the official XZ Utils GitHub repository
Search the repository for issues related to CVE-2024-3094
Você vai ver as ferramentas do GitHub sendo chamadas pelo agente.
O agente do ADK do QuantumRoast agora pode interagir com as ferramentas do servidor MCP do GitHub. 🤩
11. Parabéns
Parabéns! Você criou o agente assistente de bugs QuantumRoast usando o Kit de Desenvolvimento de Agentes (ADK) e integrou vários tipos de ferramentas para melhorar os recursos dele. Você começou com um agente básico e adicionou progressivamente ferramentas de função, ferramentas integradas, ferramentas de terceiros e ferramentas do MCP.
O que aprendemos
- Como configurar um projeto Python para desenvolvimento do ADK.
- Como criar um agente básico do ADK.
- Como implementar e usar as ferramentas de função.
- Como integrar ferramentas integradas, como a Pesquisa Google.
- Como usar ferramentas de terceiros de frameworks como o LangChain no ADK.
- Como usar as ferramentas do MCP para interagir com bancos de dados (Cloud SQL) e APIs.
Limpeza
É possível excluir seu projeto do Cloud para evitar cobranças adicionais.
O Cloud Run não gera custos quando o serviço não está em uso, mas você ainda pode receber cobranças pelo armazenamento da imagem de contêiner no Artifact Registry. A exclusão do projeto do Cloud interrompe o faturamento de todos os recursos usados nele.
Se quiser, exclua o projeto:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Você também pode excluir recursos desnecessários do disco do Cloud Shell. Você pode:
- Exclua o diretório do projeto do codelab:
rm -rf ~/quantum-roast
- Aviso: Não é possível desfazer a próxima ação. Se você quiser excluir tudo no Cloud Shell para liberar espaço, exclua todo o diretório principal. Verifique se tudo o que você quer manter está salvo em outro lugar.
sudo rm -rf $HOME