Herramientas para crear un agente: De cero a asistente con el ADK

1. Introducción

En este lab, compilarás un agente con el Kit de desarrollo de agentes (ADK). Aprenderás a compilar un agente asistente para errores de software con el ADK y varios tipos de herramientas. Comenzarás con un agente básico y, de forma progresiva, agregarás herramientas para mejorar sus capacidades, incluidas las herramientas de funciones, las herramientas integradas, las herramientas de terceros y las herramientas del Protocolo de contexto del modelo (MCP).

Herramientas para crear un agente

Qué aprenderás

  • Cómo configurar un proyecto de Python para el desarrollo del ADK
  • Cómo crear un agente básico del ADK
  • Cómo implementar y usar las herramientas de funciones
  • Cómo integrar herramientas integradas, como la Búsqueda de Google
  • Cómo aprovechar las herramientas de terceros de frameworks como LangChain dentro de ADK
  • Cómo usar las herramientas de MCP para interactuar con bases de datos (Cloud SQL) y APIs

2. Descripción general

Imagina que eres gerente de proyectos en QuantumRoast, una empresa global de máquinas de café.

Quantum Roast

Ayudas a tus compañeros de equipo a navegar por un mar de hojas de ruta de ingeniería, cambios repentinos de estrategia (¡ahora hacemos matcha!) y tickets entrantes de los clientes, desde sistemas de facturación con errores hasta una máquina de café que emite un ruido agudo las 24 horas del día.

En un día normal, tienes alrededor de cincuenta pestañas del navegador abiertas: el sistema interno de tickets, el correo electrónico, el chat, GitHub, la Búsqueda de Google, StackOverflow y mucho más. Te gusta tu trabajo y tus compañeros de equipo, pero, a veces, te sientes abrumado.

Gerente de proyectos abrumado

¿Qué pasaría si pudiéramos crear un asistente para ayudarte a crear y priorizar tickets de software, y depurar problemas? Un agente de IA hace que esto sea posible.

Agente de IA

Kit de desarrollo de agentes (ADK)

El Kit de desarrollo de agentes (ADK) es un framework flexible y modular para desarrollar e implementar agentes de IA. Si bien está optimizado para Gemini y el ecosistema de Google, el ADK es independiente del modelo y de la implementación, y se creó para ser compatible con otros frameworks. El ADK se diseñó para que el desarrollo de agentes se asemeje más al desarrollo de software, y para que los desarrolladores puedan crear, implementar y coordinar arquitecturas basadas en agentes que abarcan desde tareas simples hasta flujos de trabajo complejos con mayor facilidad.

El ADK es el framework que usaremos para compilar nuestro asistente de errores de software QuantumRoast.

Diagrama del agente

Introducción a las herramientas

Los agentes de IA usan modelos, no solo lógica codificada, para razonar y resolver un problema. Sin embargo, más allá del razonamiento basado en LLM, los agentes de IA tienen la capacidad única de recopilar datos externos y, luego, tomar medidas en nombre del usuario. En lugar de decirte cómo resolver un problema, un agente de IA puede ayudarte a resolverlo. ¿Cómo lo hacemos? ¡Con herramientas!

Una herramienta es una capacidad que ayuda a un agente de IA a interactuar con el mundo. Una herramienta puede ser casi cualquier cosa: una función intercalada, una base de datos alojada, una API de terceros o incluso otro agente. Los frameworks de agentes de IA, como el kit de desarrollo de agentes (ADK), tienen compatibilidad integrada con herramientas, lo que admite una variedad de tipos de herramientas que analizaremos en un momento.

Pero, ¿cómo sabe un agente no solo cuándo llamar a una herramienta determinada, sino también cómo llamarla? El modelo del agente desempeña algunos roles clave aquí.

Cómo funcionan las herramientas

La primera es la selección de herramientas. Le proporcionamos a nuestro agente una lista de herramientas y algunas instrucciones para usarlas. Cuando un usuario le da una instrucción al agente, el modelo del agente ayuda a decidir qué herramientas llamar y por qué, para ayudar al usuario.

El segundo paso clave es la llamada a funciones. El término “llamada a funciones” es un poco engañoso, ya que el modelo no llama a la herramienta, sino que se prepara para llamarla dando formato al cuerpo de la solicitud que el framework usa para llamar a la herramienta.

Por último, el modelo ayuda a interpretar la respuesta de esa herramienta (por ejemplo, una lista de errores abiertos de la base de datos) y decide si debe tomar más medidas o responderle al usuario con esa información.

Para ver todo esto en acción, es hora de compilar el agente asistente de errores de QuantumRoast con el ADK de Python.

Asistente de errores de QuantumRoast

3. Antes de comenzar

Configuración del proyecto de Google Cloud

  1. Si aún no tienes una Cuenta de Google, debes crear una.
    • Usa una cuenta personal en lugar de una cuenta de trabajo o institución educativa. Es posible que las cuentas de trabajo y de instituciones educativas tengan restricciones que te impidan habilitar las APIs necesarias para este lab.
  2. Accede a la consola de Google Cloud.
  3. Habilita la facturación en la consola de Cloud.
    • Completar este lab debería costar menos de USD 1 en recursos de Cloud.
    • Puedes seguir los pasos al final de este lab para borrar recursos y evitar cargos adicionales.
    • Los usuarios nuevos pueden acceder a la prueba gratuita de USD 300.
  4. Crea un proyecto nuevo o elige reutilizar uno existente.

Abre el editor de Cloud Shell

  1. Navega al Editor de Cloud Shell.
  2. Si la terminal no aparece en la parte inferior de la pantalla, ábrela:
    • Haz clic en el menú de hamburguesa Ícono de menú de hamburguesa.
    • Haz clic en Terminal.
    • Haz clic en Terminal nueva. Abre una terminal nueva en el editor de Cloud Shell
  3. En la terminal, configura tu proyecto con este comando (reemplaza YOUR_PROJECT_ID):
    • Formato:
      gcloud config set project YOUR_PROJECT_ID
      
    • Ejemplo:
      gcloud config set project lab-project-id-example
      
    • Si no recuerdas el ID de tu proyecto, haz lo siguiente:
      • Puedes enumerar todos los IDs de tus proyectos con el siguiente comando:
        gcloud projects list | awk '/PROJECT_ID/{print $2}'
        
      Establece el ID del proyecto en la terminal del editor de Cloud Shell
  4. Si se te solicita autorización, haz clic en Autorizar para continuar. Haz clic para autorizar Cloud Shell
  5. Deberías ver el siguiente mensaje:
    Updated property [core/project].
    
    Si ves un WARNING y se te pregunta Do you want to continue (Y/N)?, es probable que hayas ingresado el ID del proyecto de forma incorrecta. Presiona N, presiona Enter y vuelve a intentar ejecutar el comando gcloud config set project.
  6. En la terminal, configura la variable de entorno PROJECT_ID para usarla en pasos posteriores.
    export PROJECT_ID=$(gcloud config get project)
    

Habilita las APIs

En la terminal, ejecuta el siguiente comando para habilitar las APIs de Google Cloud necesarias:

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

Crea una instancia de Cloud SQL para PostgreSQL

QuantumRoast tiene una base de datos de tickets de errores que contiene todos los tickets internos. Vamos a configurarlo creando una instancia de 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

Espera a que se cree la instancia (puede tardar unos minutos).

Una vez creada, puedes ver tu instancia en la consola de Cloud aquí.

Crea una base de datos de Cloud SQL

Crea una base de datos de SQL (tickets-db) y otorga acceso a la cuenta de servicio de Cloud SQL a Vertex AI (para que podamos crear embeddings y realizar búsquedas por similitud).

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"

Configura la tabla tickets

En Cloud Console (Cloud SQL), abre Cloud SQL Studio para la instancia software-assistant.

Accede a la base de datos tickets-db con el usuario postgres y admin como contraseña.

Cloud SQL Studio

Abre una pestaña nueva de Editor.

Editor de Cloud SQL Studio

Luego, pega el siguiente código SQL para configurar la tabla y crear embeddings de vectores. Presiona el botón Run para ejecutar el 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.
);

Se creó la tabla tickets. Haz clic en Clear para borrar la consulta anterior.

Ahora, inserta los datos de muestra y presiona el botón Run una vez más.

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');

En QuantumRoast, es posible que queramos saber cuándo se actualizó por última vez un error o un ticket.

Para ello, podemos crear un activador que actualice el campo updated_time cada vez que se actualice un registro.

Haz clic en Clear y, luego, pega el siguiente código SQL para implementar un activador.

Presiona el botón Run para ejecutar.

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();

Crea embeddings de vectores a partir del campo description. Esto le dará a nuestro agente la capacidad de realizar búsquedas de similitud en nuestra base de datos. Por ejemplo, "¿Hay problemas abiertos relacionados con la página principal de los sitios web?".

ALTER TABLE tickets ADD COLUMN embedding vector(768) GENERATED ALWAYS AS (embedding('text-embedding-005',description)) STORED;

Ahora puedes consultar la base de datos para verificar que esté lista.

SELECT * FROM tickets;

Deberías ver 10 filas que se parezcan a las siguientes:

Verifica la base de datos de Cloud SQL

Ahora puedes pasar a la parte divertida: el código.

4. Configuración del proyecto de Python

Antes de comenzar a compilar nuestro agente, debemos asegurarnos de tener configurado un proyecto de Python adecuado. Haremos todo en Cloud Shell.

Primero, crea una carpeta quantum-roast y cd en ella:

mkdir quantum-roast && cd quantum-roast

Ahora que tenemos una carpeta para nuestro proyecto, es momento de inicializarlo y crear los archivos correspondientes que necesitaremos.

Usaremos uv (el administrador de proyectos y paquetes extremadamente rápido de Python), que viene preinstalado en Cloud Shell para administrar nuestro proyecto y las dependencias. Uv nos ayudará a configurar algunos de nuestros archivos y a administrar entornos virtuales, dependencias, etcétera. ¡Así no tendremos que hacerlo nosotros!

Inicializa un proyecto nuevo con uv init:

uv init --description "QuantumRoast Software Bug Assistant with ADK" --bare --python 3.10

Después de ejecutar el comando, deberíamos tener un archivo pyproject.toml para nuestro proyecto. Para verificarlo, ejecuta cat pyproject.toml en la terminal de Cloud Shell:

cat pyproject.toml

Deberías ver el siguiente resultado:

[project]
name = "quantum-roast"
version = "0.1.0"
description = "QuantumRoast Software Bug Assistant with ADK"
requires-python = ">=3.10"
dependencies = []

Es hora de agregar google-adk (ADK) como dependencia a nuestro proyecto con uv add.

uv add google-adk==1.11.0

Esto agrega google-adk a la lista dependencies en nuestro pyproject.toml.

El ADK espera una determinada estructura del proyecto para lograr los mejores resultados.

quantum-roast/
    software_bug_assistant/
        __init__.py
        agent.py
        .env

Crea la carpeta software_bug_assistant y los archivos dentro de ella:

mkdir software_bug_assistant && touch software_bug_assistant/__init__.py \
software_bug_assistant/agent.py \
software_bug_assistant/tools.py \
software_bug_assistant/.env

Verifica la creación de los archivos con ls:

ls -a software_bug_assistant/

Deberías ver lo siguiente:

__init__.py	 .  ..	 .env	 agent.py    tools.py

Es hora de propagar el archivo .env con las variables de entorno necesarias para que el ADK llame correctamente a los modelos de Gemini. Accederemos a Gemini a través de la API de 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 que .env se haya propagado correctamente, ejecuta lo siguiente:

cat software_bug_assistant/.env

Deberías ver lo siguiente, en el que your-project-id es el ID de tu proyecto:

GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=us-central1

Ahora sí, podemos comenzar a crear nuestro agente del ADK.

5. Agente de ADK base

Configuraremos un agente básico del ADK al que podremos agregar herramientas una por una durante este taller para crear un asistente de errores potente.

Abre agent.py en el Editor de Cloud Shell:

cloudshell edit software_bug_assistant/agent.py

Pega el siguiente código en agent.py y guarda el archivo 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=[],
)

Ejecuta el agente que acabas de crear iniciando la IU para desarrolladores del ADK (adk web). Si lo haces con uv run, se creará automáticamente un entorno virtual con el ADK instalado.

uv run adk web --port 8080 --reload_agents

En la consola, deberías ver el inicio exitoso del servidor web del 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)

Abre la vista previa en la Web de Cloud Shell para ver la IU.

Vista previa en la Web de Cloud Shell

Deberías ver la IU web del ADK.

IU web del ADK

Adelante, prueba chatear con el agente de ADK.

Pregúntale al agente What day is it today?.

Ejemplo web del ADK

En la respuesta, notarás que el agente no puede responder esta pregunta básica. Recuerda que los LLM son sistemas aislados, entrenados con datos históricos. No tienen contexto en tiempo real sobre eventos recientes ni siquiera sobre la fecha actual… a menos que les proporciones herramientas.

Es hora de implementar el primer tipo de herramienta del ADK, una herramienta de función.

6. Herramienta de función

El primer y más simple tipo de herramienta de ADK es la herramienta de función. Es exactamente lo que parece: una función de Python a la que llama el agente.

Herramienta de función

Las herramientas de funciones son muy potentes, ya que te permiten escribir código personalizado para que el agente lo llame como una herramienta, por ejemplo, para realizar un cálculo, llamar a una API o consultar una base de datos. Pueden ser funciones simples o complejas, todo depende de ti.

En QuantumRoast, queremos definir una función básica para obtener la fecha del día actual, de modo que, más adelante en este lab, podamos controlar consultas como "Muéstrame los errores de la semana pasada" o "¿Qué día es hoy?". (a todos nos pasa).

El archivo tools.py dentro de la carpeta /software_bug_assistant es donde organizaremos todas las herramientas que compilaremos a lo largo de este lab.

Haz clic en el ícono + para abrir una terminal NUEVA.

Terminal nueva

Ahora, en la nueva terminal, configura PROJECT_ID y abre tools.py:

cd quantum-roast
export PROJECT_ID=$(gcloud config get project)
cloudshell edit software_bug_assistant/tools.py

Ahora, define la función get_current_date que se usará como herramienta de función.

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")}

Ahora se define la función. Es hora de pasarlo como herramienta al agente.

Abre agent.py en el Editor de Cloud Shell:

cloudshell edit software_bug_assistant/agent.py

Queremos importar la función get_current_date de tools.py y pasar la función al argumento tools del agente.

El elemento agent.py actualizado se ve de la siguiente manera:

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],
)

Ahora, si vuelves a la pestaña de vista previa en la Web que ejecuta la IU web del ADK y vuelves a preguntar What day is it today?

Herramienta de función web del ADK

El agente puede indicar la fecha correctamente llamando a la herramienta de función get_current_date. 🎉

Es hora de explorar el siguiente tipo de herramienta del ADK.

7. Herramienta integrada

Otro tipo de herramienta del ADK es la herramienta integrada. Estas son herramientas que funcionan con las funciones del modelo insignia de Google, como la ejecución de código dentro del propio modelo. Podemos adjuntar la herramienta integrada Búsqueda de Google a nuestro agente asistente de errores para fundamentar al agente en un contexto pertinente, ya que le permite buscar en la Web. Esto permitirá que el agente recopile información más actual sobre un error o una vulnerabilidad conocida.

Herramienta integrada

Abre el archivo tools.py para agregar compatibilidad con la herramienta integrada de la Búsqueda de Google.

cloudshell edit software_bug_assistant/tools.py

Agrega lo siguiente a la parte inferior 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)

Aquí, en realidad, estamos encapsulando esa herramienta de la Búsqueda de Google en su propio agente con sus propias instrucciones del sistema, lo que equivale a usar un agente como herramienta.

Ahora podemos importar y pasar el search_tool al agente raíz en agent.py:

cloudshell edit software_bug_assistant/agent.py

Puedes reemplazar agent.py por el siguiente código 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],
)

Guarda el archivo y vuelve a la ventana abierta en la que se ejecuta la IU web del ADK.

En QuantumRoast, queremos asegurarnos de que nuestro sitio web y software estén protegidos contra las vulnerabilidades y exposiciones comunes (CVE), que son vulnerabilidades públicas de seguridad cibernética. Podemos usar la nueva herramienta de Búsqueda de Google de nuestro agente para buscar en la Web los CVE descubiertos más recientemente.

Ejecuta la siguiente consulta: Do a web search for 5 of the most recent CVEs?.

Nuestro agente debe llamar a search_agent para buscar en la Web.

Ejemplo de herramienta integrada en la Web del ADK

Nuestro agente ahora desbloqueó correctamente la capacidad de buscar en la Web a través de la herramienta integrada de la ADK para la Búsqueda de Google. 🎉

Pasemos al siguiente tipo de herramienta del ADK.

8. Herramienta de terceros

El ADK está diseñado para ser altamente extensible, lo que te permite integrar sin problemas herramientas de otros frameworks de agentes de IA de terceros, como CrewAI y LangChain. Esta interoperabilidad es fundamental porque permite un tiempo de desarrollo más rápido y la capacidad de reutilizar herramientas existentes.

Herramienta de terceros

Para conectar nuestro agente de errores a los potentes datos de preguntas y respuestas de StackOverflow, podemos extraer información de la extensa biblioteca de herramientas de LangChain, específicamente, la herramienta de wrapper de la API de StackExchange. El ADK admite herramientas de terceros, como LangChain, por lo que agregar esta herramienta a nuestro agente de ADK solo requiere unas pocas líneas de código.

Primero, debemos agregar nuevas dependencias para LangChain y StackOverflow (langchain-community y stackapi) a nuestro proyecto:

uv add langchain-community==0.3.27 stackapi==0.3.1

Abre el archivo tools.py para agregar compatibilidad con la herramienta LangChain StackExchange.

cloudshell edit software_bug_assistant/tools.py

Agrega lo siguiente a la parte inferior 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)

Ahora podemos importar y pasar el langchain_tool al agente raíz en agent.py:

cloudshell edit software_bug_assistant/agent.py

Puedes reemplazar agent.py por el siguiente código 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],
)

Guarda el archivo y regresa a la pestaña abierta con la IU web del ADK.

Intenta preguntarle al agente sobre las CVE anteriores, "Are there similar issues on stack exchange?" o algo nuevo como "Our database queries with SQLAlchemy seem to be timing out, is there anything on StackExchange relevant to this?".

Ejemplo de herramienta externa para la Web del ADK

Nuestro agente ahora aprovechó con éxito una herramienta de LangChain en el ADK para consultar StackOverflow. 🥳

Es hora de ver el siguiente tipo de herramienta del ADK… Herramientas de MCP

9. Herramienta de MCP (base de datos)

MCP significa Model Context Protocol (Protocolo de contexto del modelo). Es un protocolo abierto que Anthropic presentó en 2024. El MCP proporciona una capa de abstracción entre tu agente de IA y los "backends" de herramientas (APIs, bases de datos).

Cómo funciona el MCP

El MCP tiene algunas especificaciones únicas. A diferencia del protocolo HTTP estándar, MCP proporciona una conexión bidireccional con estado entre el cliente y el servidor. Tiene su propia forma de definir herramientas y mensajes de error específicos de cada herramienta. Luego, un proveedor de herramientas puede compilar servidores de MCP sobre sus APIs, lo que expone una o más herramientas prediseñadas para desarrolladores y usuarios. Luego, los frameworks de agentes pueden inicializar clientes de MCP dentro de una aplicación de agente para descubrir y llamar a esas herramientas.

En QuantumRoast, tenemos una base de datos de Cloud SQL para PostgreSQL para errores de software internos. Queremos crear herramientas del ADK para que nuestro agente pueda realizar ciertas consultas en nuestra base de datos.

Base de datos de herramientas de MCP

La forma más sencilla de hacerlo es con MCP Toolbox for Databases , un servidor de MCP de código abierto para bases de datos. Toolbox admite más de 15 bases de datos, una de las cuales es Cloud SQL.

Toolbox proporciona lo siguiente:

  • Desarrollo simplificado: Integra herramientas a tu agente con menos de 10 líneas de código, reutiliza herramientas entre varios agentes o frameworks, y, luego, implementa nuevas versiones de herramientas con mayor facilidad.
  • Mejor rendimiento: Prácticas recomendadas, como la agrupación de conexiones, la autenticación y mucho más.
  • Seguridad mejorada: Autenticación integrada para un acceso más seguro a tus datos
  • Observabilidad de extremo a extremo: Métricas y seguimiento listos para usar con compatibilidad integrada para OpenTelemetry

El ADK admite herramientas de MCP Toolbox for Databases, lo que agiliza la integración.

MCP Toolbox for Databases

Implementa el servidor de MCP Toolbox for Databases en Cloud Run

Primero, implementaremos el servidor de MCP Toolbox for Databases en Cloud Run y lo dirigiremos a nuestra instancia de Cloud SQL.

Toolbox requiere un archivo YAML para la configuración, en el que se describe la fuente de la base de datos y las herramientas que se deben configurar.

Crea un archivo tools.yaml para la implementación.

cloudshell edit tools.yaml

Pega el siguiente contenido en 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

El archivo YAML define 9 herramientas relacionadas con la base de datos de tickets de QuantumRoast.

Es hora de configurar una cuenta de servicio para el servicio de Toolbox Cloud Run, otorgarle permiso para acceder a Cloud SQL y Secret Manager, y crear un secreto de Secret Manager para nuestro archivo tools.yaml.

Almacenaremos nuestro archivo tools.yaml en Secret Manager, ya que contiene credenciales sensibles de 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

Es hora de implementar MCP Toolbox for Databases en Cloud Run. Usaremos la versión de lanzamiento más reciente de la imagen del contenedor de MCP Toolbox.

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

Espera a que finalice la implementación…

Consulta los registros de Cloud Run para verificar que Toolbox se esté ejecutando:

gcloud run services logs read toolbox --region us-central1 --limit 10

Deberías ver lo siguiente:

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!"

Guarda la URL de Cloud Run para el servicio de Toolbox como una variable de entorno para que el agente del ADK sepa dónde encontrarla.

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

Actualiza el agente de QuantumRoast

En segundo lugar, debemos agregar la dependencia del SDK de MCP Toolbox for Databases (toolbox-core) a nuestro proyecto:

uv add toolbox-core==0.5.0

Abre el archivo tools.py para agregar compatibilidad con las herramientas de MCP Toolbox.

cloudshell edit software_bug_assistant/tools.py

Agrega lo siguiente a la parte inferior 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")

Ahora podemos importar y pasar el toolbox_tools al agente raíz en agent.py:

cloudshell edit software_bug_assistant/agent.py

Puedes reemplazar agent.py por el siguiente código 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],
)

Guarda el archivo y regresa a la pestaña abierta con la IU web del ADK.

Ahora puedes hacer preguntas sobre los tickets almacenados en nuestra base de datos interna de tickets de Cloud SQL.

Haz una pregunta como una de las siguientes:

  • 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 (deja que el agente te guíe en la creación de errores)

Ejemplo de herramienta de base de datos de MCP

Nuestro agente de ADK ahora consultó correctamente nuestra base de datos a través de las herramientas de MCP Toolbox for Databases.🚀

10. Opcional: Herramienta de MCP (API)

¿Qué sucede con la conexión de nuestro agente de ADK a las herramientas de MCP que no tienen su propio SDK, como el kit de herramientas de MCP para bases de datos?

El ADK admite herramientas genéricas de MCP a través de su clase MCPToolset. La clase MCPToolset es el mecanismo principal del ADK para integrar herramientas desde un servidor de MCP.

Herramienta de MCP (API)

MCPToolset se puede usar para conectarse a servidores MCP locales o remotos. En QuantumRoast, queremos conectar nuestro agente al servidor MCP remoto de GitHub para llamar fácilmente a las APIs de GitHub. Esto permitirá que nuestro agente extraiga información sobre problemas de repositorios de software públicos o incluso de nuestras propias bases de código. El servidor de MCP de GitHub expone diferentes partes de la funcionalidad de GitHub, desde problemas y solicitudes de extracción hasta notificaciones y seguridad del código.

GitHub de la herramienta de MCP

Token de acceso personal (PAT) de GitHub

Para autenticarte con el servidor de MCP de GitHub, necesitas un token de acceso personal de GitHub.

Para adquirir uno, sigue estos pasos:

  1. Ve a la configuración para desarrolladores de GitHub.
  2. Haz clic en "Tokens de acceso personal" -> "Tokens (clásico)".
  3. Haz clic en “Generate new token” -> “Generate new token (classic)”.
  4. Asigna un nombre descriptivo al token.
  5. Establece una fecha de vencimiento para tu token.
  6. Importante: Por motivos de seguridad, otorga a tu token los permisos más limitados que sean necesarios. Para el acceso de solo lectura a los repositorios, los alcances repo:status, public_repo y read:user suelen ser suficientes. Evita otorgar permisos de administrador o de repositorio completos, a menos que sea absolutamente necesario.
  7. Haz clic en Generate token.
  8. Copia el token generado.

En la terminal de Cloud Shell, ejecuta el siguiente comando para establecer tu PAT de GitHub para que el agente pueda usarlo. Reemplaza YOUR_GITHUB_PAT por tu PAT generada.

export GITHUB_PAT=YOUR_GITHUB_PAT

Actualiza el agente de QuantumRoast

En el caso de nuestro asistente de errores, solo expondremos algunas herramientas de GitHub de solo lectura para permitir que los empleados de QuantumRoast encuentren problemas relacionados con las dependencias de código abierto y vean si eso puede ayudar a determinar la causa raíz de los errores que ven en el sistema interno de tickets. Usaremos el MCPToolset del ADK con un tool_filter para configurar esto. El tool-filter solo expone las herramientas de GitHub que necesitamos, lo que no solo oculta las herramientas a las que no queremos que accedan los usuarios (por ejemplo, acciones sensibles del repositorio), sino que también protege el modelo del agente para que no se sature cuando intenta elegir la herramienta adecuada para el trabajo.

Abre el archivo tools.py para agregar compatibilidad con las herramientas de GitHub.

cloudshell edit software_bug_assistant/tools.py

Agrega lo siguiente a la parte inferior 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",
    ],
)

Ten en cuenta que también debemos proporcionar el token de acceso personal (PAT) de GitHub a nuestra definición de MCPToolset, al igual que proporcionarías un token de autenticación cuando configuras un cliente de API estándar en tu código. Este PAT solo tiene alcance para acceder a los datos de repositorios públicos, sin alcances relacionados con acciones sensibles del usuario o del repositorio.

Ahora podemos importar y pasar el mcp_tools al agente raíz en agent.py:

cloudshell edit software_bug_assistant/agent.py

Puedes reemplazar agent.py por el siguiente código 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],
)

Guarda el archivo y regresa a la pestaña abierta con la IU web del ADK.

Ahora tenemos un conjunto de herramientas de MCP de GitHub a las que nuestro agente puede llamar. Los servicios de QuantumRoast se basan en XZ utils, una herramienta de compresión de datos. Nuestro sistema interno de tickets de errores hace un seguimiento de una CVE (vulnerabilidad de seguridad) del año pasado, que podemos rastrear hasta el repositorio de GitHub de XZ Utils con las herramientas de StackOverflow y la Búsqueda de Google. Luego, podemos usar una de las herramientas de MCP de GitHub, search_issues, para determinar cuándo y cómo se corrigió esa CVE:

Pregúntale al agente lo siguiente:

  • Find the official XZ Utils GitHub repository
  • Search the repository for issues related to CVE-2024-3094

Deberías ver que el agente llama a las herramientas de GitHub.

Ejemplo de herramientas de MCP en GitHub

El agente de QuantumRoast ADK ahora puede interactuar con las herramientas del servidor de MCP de GitHub. 🤩

11. Felicitaciones

¡Felicitaciones! Compilaste correctamente el agente asistente de errores QuantumRoast con el Kit de desarrollo de agentes (ADK) y, luego, integraste varios tipos de herramientas para mejorar sus capacidades. Comenzaste con un agente básico y agregaste progresivamente herramientas de funciones, herramientas integradas, herramientas de terceros y herramientas de MCP.

Temas abordados

  • Cómo configurar un proyecto de Python para el desarrollo del ADK
  • Cómo crear un agente básico del ADK
  • Cómo implementar y usar las herramientas de funciones
  • Cómo integrar herramientas integradas, como la Búsqueda de Google
  • Cómo aprovechar las herramientas de terceros de frameworks como LangChain dentro de ADK
  • Cómo usar las herramientas de MCP para interactuar con bases de datos (Cloud SQL) y APIs

QuantumRoast Final

Limpieza

Puedes borrar tu proyecto de Cloud para evitar que se generen cargos adicionales.

Si bien Cloud Run no cobra cuando el servicio no se usa, es posible que se te cobre por el almacenamiento de la imagen del contenedor en Artifact Registry. Si borras tu proyecto de Cloud, se dejan de facturar todos los recursos que usaste en ese proyecto.

Si quieres, borra el proyecto:

gcloud projects delete $GOOGLE_CLOUD_PROJECT

También puedes borrar los recursos innecesarios de tu disco de Cloud Shell. Puedes hacer lo siguiente:

  1. Borra el directorio del proyecto del codelab:
    rm -rf ~/quantum-roast
    
  2. Advertencia. Esta próxima acción no se puede deshacer. Si quieres borrar todo el contenido de Cloud Shell para liberar espacio, puedes borrar todo el directorio principal. Ten cuidado de guardar en otro lugar todo lo que quieras conservar.
    sudo rm -rf $HOME