Ferramentas para criar um agente: do zero ao Google Assistente com o ADK

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

Ferramentas para criar um agente

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

Torra Quantum

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.

Gerente de projetos 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.

Agente de IA

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.

Diagrama do agente

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.

Como as ferramentas funcionam

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.

Assistente de bugs do QuantumRoast

3. Antes de começar

Configuração do projeto do Google Cloud

  1. 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.
  2. Faça login no Console do Google Cloud.
  3. 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.
  4. Crie um projeto ou reutilize um projeto existente.

Abrir editor do Cloud Shell

  1. Acesse o editor do Cloud Shell.
  2. Se o terminal não aparecer na parte de baixo da tela, abra-o:
    • Clique no menu de navegação Ícone do menu de navegação.
    • Clique em Terminal.
    • Clique em Novo Terminal.Abrir um novo terminal no editor do Cloud Shell
  3. 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}'
        
      Definir o ID do projeto no terminal do Editor do Cloud Shell
  4. Se for preciso autorizar, clique em Autorizar para continuar. Clique para autorizar o Cloud Shell
  5. Você vai receber esta mensagem:
    Updated property [core/project].
    
    Se você vir um WARNING e for perguntado Do you want to continue (Y/N)?, provavelmente inseriu o ID do projeto incorretamente. Pressione N, Enter e tente executar o comando gcloud config set project novamente.
  6. 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.

Cloud SQL Studio

Abra uma nova guia Editor.

Editor do Cloud SQL Studio

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:

Verificar o banco de dados do Cloud SQL

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.

Visualização da Web do Cloud Shell

A interface da Web do ADK vai aparecer.

Interface da Web do ADK

Tente conversar com o agente do ADK.

Pergunte ao agente What day is it today?.

Exemplo da Web do ADK

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.

Ferramenta de função

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

Novo terminal

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

Ferramenta de função da Web do ADK

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.

Ferramenta integrada

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.

Exemplo de ferramenta integrada da Web do ADK

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.

Ferramenta de terceiros

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?".

Exemplo de ferramenta de terceiros da Web do ADK

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

Como o MCP funciona

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.

Banco de dados de ferramentas do MCP

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.

MCP Toolbox for Databases

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)

Exemplo de ferramenta de banco de dados do MCP

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.

Ferramenta MCP (API)

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.

GitHub da ferramenta MCP

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:

  1. Acesse as configurações de desenvolvedor do GitHub.
  2. Clique em "Tokens de acesso pessoal" -> "Tokens (clássico)".
  3. Clique em "Gerar novo token" -> "Gerar novo token (clássico)".
  4. Dê ao token um nome descritivo.
  5. Defina uma data de validade para o token.
  6. 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 e read:user geralmente são suficientes. Evite conceder permissões de administrador ou de repositório completo, a menos que seja absolutamente necessário.
  7. Clique em Generate token.
  8. 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.

Exemplo do GitHub das ferramentas do MCP

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.

Final do QuantumRoast

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:

  1. Exclua o diretório do projeto do codelab:
    rm -rf ~/quantum-roast
    
  2. 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