Acerca de este codelab
1. Descripción general
Los agentes de IA están aumentando rápidamente su popularidad y revolucionando la automatización de tareas y la toma de decisiones con su capacidad de operar de forma autónoma, aprender e interactuar con su entorno para lograr objetivos.
Pero, ¿cómo se crea un agente? Este codelab te ayudará a comenzar mostrándote cómo compilar un agente de conversión de divisas que pueda convertir entre las monedas de diferentes países. El objetivo es explicar las tecnologías más recientes para ayudarte a comprender esas siglas que quizás hayas visto en Internet (MCP, ADK, A2A).
Protocolo de contexto del modelo (MCP)
El protocolo de contexto del modelo (MCP) es un protocolo abierto que estandariza la forma en que las aplicaciones proporcionan contexto a los LLM. El MCP proporciona una forma estandarizada de conectar modelos de IA a recursos, instrucciones y herramientas.
Agent Development Kit (ADK)
El Kit de desarrollo de agentes (ADK) es un framework de orquestación flexible para desarrollar y, luego, implementar agentes de IA. El ADK es independiente del modelo y de la implementación, y se creó para que sea 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.
Protocolo Agent2Agent (A2A)
El protocolo Agent2Agent (A2A) es un estándar abierto diseñado para permitir la comunicación y la colaboración sin problemas entre los agentes de IA. Del mismo modo que el MCP proporciona una forma estandarizada de darles a los LLM acceso a datos y herramientas, el A2A proporciona una forma estandarizada para que los agentes se comuniquen entre sí. En un mundo en el que los agentes se compilan con diversos frameworks y por diferentes proveedores, A2A proporciona un lenguaje común, rompe los silos y fomenta la interoperabilidad.
Qué aprenderás
- Cómo crear un servidor de MCP local
- Implementa el servidor de MCP en Cloud Run
- Cómo compilar un agente con el kit de desarrollo de agentes que usa herramientas de MCP
- Cómo exponer un agente de ADK como servidor de A2A
- Cómo probar el servidor de A2A con el cliente de A2A
Requisitos
2. Antes de comenzar
Crea un proyecto
- En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.
- Asegúrate de que la facturación esté habilitada para tu proyecto de Cloud. Obtén información para verificar si la facturación está habilitada en un proyecto.
- Haz clic en este vínculo para activar Cloud Shell. Puedes alternar entre la terminal de Cloud Shell (para ejecutar comandos de Cloud) y el editor (para compilar proyectos) haciendo clic en el botón correspondiente de Cloud Shell.
- Una vez que te conectes a Cloud Shell, verifica que ya te autenticaste y que el proyecto se configuró con el ID de tu proyecto con el siguiente comando:
gcloud auth list
- En Cloud Shell, ejecuta el siguiente comando para confirmar que el comando gcloud conoce tu proyecto.
gcloud config list project
- Usa el siguiente comando para configurar tu proyecto:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
- Habilita las APIs requeridas con el siguiente comando. Esto puede tardar algunos minutos.
gcloud services enable cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com \
compute.googleapis.com
- Asegúrate de tener Python 3.10 o versiones posteriores.
Consulta la documentación para ver los comandos y el uso de gcloud.
3. Instalación
- Clona el repositorio:
git clone https://github.com/jackwotherspoon/currency-agent.git
cd currency-agent
- Instala uv (se usa para administrar dependencias):
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (uncomment below line)
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
- Configura las variables de entorno (a través del archivo
.env
):
Crea un archivo .env
ejecutando el siguiente comando:
echo "GOOGLE_GENAI_USE_VERTEXAI=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=us-central1" >> .env
4. Crea un servidor de MCP local
Antes de coordinar tu agente de divisas, primero crearás un servidor de MCP para exponer las herramientas que necesitará tu agente.
Un servidor de MCP te permite escribir programas livianos para exponer capacidades específicas (como recuperar tipos de cambio de divisas) como herramientas. Luego, un agente o incluso varios agentes pueden acceder a estas herramientas con el Protocolo de contexto del modelo (MCP) estandarizado.
El paquete de Python FastMCP se puede aprovechar para crear un servidor de MCP que exponga una sola herramienta llamada get_exchange_rate
. La herramienta get_exchange_rate
realiza una llamada a través de Internet a la API de Frankfurter para obtener el tipo de cambio actual entre dos monedas.
El código del servidor de MCP se puede encontrar en el archivo mcp-server/server.py
:
import logging
import os
import httpx
from fastmcp import FastMCP
# Set up logging
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
mcp = FastMCP("Currency MCP Server 💵")
@mcp.tool()
def get_exchange_rate(
currency_from: str = 'USD',
currency_to: str = 'EUR',
currency_date: str = 'latest',
):
"""Use this to get current exchange rate.
Args:
currency_from: The currency to convert from (e.g., "USD").
currency_to: The currency to convert to (e.g., "EUR").
currency_date: The date for the exchange rate or "latest". Defaults to "latest".
Returns:
A dictionary containing the exchange rate data, or an error message if the request fails.
"""
logger.info(f"--- 🛠️ Tool: get_exchange_rate called for converting {currency_from} to {currency_to} ---")
try:
response = httpx.get(
f'https://api.frankfurter.app/{currency_date}',
params={'from': currency_from, 'to': currency_to},
)
response.raise_for_status()
data = response.json()
if 'rates' not in data:
return {'error': 'Invalid API response format.'}
logger.info(f'✅ API response: {data}')
return data
except httpx.HTTPError as e:
return {'error': f'API request failed: {e}'}
except ValueError:
return {'error': 'Invalid JSON response from API.'}
if __name__ == "__main__":
logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
# Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
asyncio.run(
mcp.run_async(
transport="streamable-http",
host="0.0.0.0",
port=os.getenv("PORT", 8080),
)
)
Para iniciar el servidor de MCP de forma local, abre una terminal y ejecuta el siguiente comando (el servidor se iniciará en http://localhost:8080
):
uv run mcp-server/server.py
Prueba que el servidor de MCP funcione correctamente y que se pueda acceder a la herramienta get_exchange_rate
con el protocolo de contexto del modelo.
En una nueva ventana de terminal (para no detener el servidor local de MCP), ejecuta lo siguiente:
uv run mcp-server/test_server.py
Deberías ver el tipo de cambio actual de 1 USD (dólar estadounidense) a EUR (euro):
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {
"amount": 1.0,
"base": "USD",
"date": "2025-05-26",
"rates": {
"EUR": 0.87866
}
} ---
¡Genial! Ahora tienes un servidor de MCP en funcionamiento con una herramienta a la que podrá acceder tu agente.
Antes de pasar a la siguiente estación, detén el servidor de MCP que se ejecuta de forma local con Ctrl+C
(o Command+C
en Mac) en la terminal en la que lo iniciaste.
5. Implementa tu servidor de MCP en Cloud Run
Ahora puedes implementar el servidor de MCP como un servidor de MCP remoto en Cloud Run 🚀☁️
Beneficios de ejecutar un servidor de MCP de forma remota
Ejecutar un servidor de MCP de forma remota en Cloud Run puede proporcionar varios beneficios:
- 📈Escalabilidad: Cloud Run está diseñado para escalar horizontalmente con rapidez y controlar todas las solicitudes entrantes. Cloud Run ajustará la escala de tu servidor de MCP automáticamente según la demanda.
- 👥Servidor centralizado: Puedes compartir el acceso a un servidor de MCP centralizado con los miembros del equipo a través de privilegios de IAM, lo que les permite conectarse a él desde sus máquinas locales en lugar de ejecutar sus propios servidores de forma local. Si se realiza un cambio en el servidor del MCP, todos los miembros del equipo se beneficiarán de él.
- 🔐Seguridad: Cloud Run proporciona una forma sencilla de forzar solicitudes autenticadas. Esto permite solo conexiones seguras a tu servidor de MCP, lo que evita el acceso no autorizado.
Cambia al directorio mcp-server
con el siguiente comando:
cd mcp-server
Implementa el servidor de MCP en Cloud Run:
gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .
Si tu servicio se implementó correctamente, verás un mensaje como el siguiente:
Service [mcp-server] revision [mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
Cómo autenticar clientes de MCP
Dado que especificaste --no-allow-unauthenticated
para requerir autenticación, cualquier cliente de MCP que se conecte al servidor de MCP remoto deberá autenticarse.
En la documentación oficial sobre cómo alojar servidores de MCP en Cloud Run, se proporciona más información sobre este tema según dónde ejecutes tu cliente de MCP.
Deberás ejecutar el proxy de Cloud Run para crear un túnel autenticado al servidor de MCP remoto en tu máquina local.
De forma predeterminada, la URL de los servicios de Cloud Run requiere que todas las solicitudes se autoricen con el rol de IAM de Cloud Run Invoker (roles/run.invoker
). Esta vinculación de política de IAM garantiza que se use un mecanismo de seguridad sólido para autenticar tu cliente de MCP local.
Debes asegurarte de que tú o cualquier miembro del equipo que intente acceder al servidor de MCP remoto tenga el rol de IAM roles/run.invoker
vinculado a su principal de IAM (cuenta de Google Cloud).
gcloud run services proxy mcp-server --region=us-central1
Deberías ver el siguiente resultado:
Proxying to Cloud Run service [mcp-server] in project [<YOUR_PROJECT_ID>] region [us-central1]
http://127.0.0.1:8080 proxies to https://mcp-server-abcdefgh-uc.a.run.app
Todo el tráfico a http://127.0.0.1:8080
ahora se autenticará y se reenviará al servidor MCP remoto.
Prueba el servidor de MCP remoto
En una terminal nueva, vuelve a la carpeta raíz y vuelve a ejecutar el archivo mcp-server/test_server.py
para asegurarte de que el servidor de MCP remoto funcione.
cd ..
uv run mcp-server/test_server.py
Deberías ver un resultado similar al que obtuviste cuando ejecutaste el servidor de forma local:
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {
"amount": 1.0,
"base": "USD",
"date": "2025-05-26",
"rates": {
"EUR": 0.87866
}
} ---
Puedes consultar los registros del servidor de MCP de Cloud Run implementado si deseas verificar que se haya llamado al servidor remoto:
gcloud run services logs read mcp-server --region us-central1 --limit 5
Deberías ver el siguiente resultado en los registros:
2025-06-04 14:28:29,871 [INFO]: --- 🛠️ Tool: get_exchange_rate called for converting USD to EUR ---
2025-06-04 14:28:30,610 [INFO]: HTTP Request: GET https://api.frankfurter.app/latest?from=USD&to=EUR "HTTP/1.1 200 OK"
2025-06-04 14:28:30,611 [INFO]: ✅ API response: {'amount': 1.0, 'base': 'USD', 'date': '2025-06-03', 'rates': {'EUR': 0.87827}}
Ahora que tienes un servidor de MCP remoto, puedes continuar con la creación de un agente. 🤖
6. Crea un agente con el Kit de desarrollo de agentes (ADK)
Ya tienes un servidor de MCP implementado. Ahora es momento de crear el agente de moneda con el Kit de desarrollo de agentes (ADK).
Recientemente, el Kit de desarrollo de agentes lanzó su versión 1.0.0 estable. Este hito significa que el ADK de Python ya está listo para producción y ofrece una plataforma confiable y sólida para que los desarrolladores creen e implementen sus agentes con confianza en entornos activos.
El ADK hace que la creación de agentes sea extremadamente liviana y permite que se conecten fácilmente a los servidores de MCP con compatibilidad integrada para las herramientas de MCP. El agente de divisas accederá a la herramienta get_exchange_rate
con la clase MCPToolset del ADK.
El código del agente de moneda se encuentra en currency_agent/agent.py
:
import logging
import os
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool import MCPToolset, StreamableHTTPConnectionParams
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
load_dotenv()
SYSTEM_INSTRUCTION = (
"You are a specialized assistant for currency conversions. "
"Your sole purpose is to use the 'get_exchange_rate' tool to answer questions about currency exchange rates. "
"If the user asks about anything other than currency conversion or exchange rates, "
"politely state that you cannot help with that topic and can only assist with currency-related queries. "
"Do not attempt to answer unrelated questions or use tools for other purposes."
)
def create_agent() -> LlmAgent:
"""Constructs the ADK currency conversion agent."""
logger.info("--- 🔧 Loading MCP tools from MCP Server... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")
return LlmAgent(
model="gemini-2.5-flash",
name="currency_agent",
description="An agent that can help with currency conversions",
instruction=SYSTEM_INSTRUCTION,
tools=[
MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
)
)
],
)
root_agent = create_agent()
Para probar rápidamente el agente de divisas, puedes aprovechar la IU para desarrolladores del ADK, a la que se accede ejecutando adk web
:
uv run adk web
En un navegador, ve a http://localhost:8000
para ver y probar el agente.
Asegúrate de que currency_agent
esté seleccionado como el agente en la esquina superior izquierda de la IU web.
Pregúntale a tu agente en el área de chat algo como "¿Cuánto equivalen 250 CAD en USD?". Deberías ver que el agente llama a nuestra herramienta de get_exchange_rate
MCP antes de dar una respuesta.
¡El agente funciona! Puede controlar consultas relacionadas con conversiones de divisas 💸.
7. Protocolo Agent2Agent (A2A)
El protocolo Agent2Agent (A2A) es un estándar abierto diseñado para permitir la comunicación y la colaboración sin problemas entre los agentes de IA. Esto permite que los agentes creados con diversos frameworks y por diferentes proveedores se comuniquen entre sí en un lenguaje común, lo que derriba los silos y fomenta la interoperabilidad.
A2A permite que los agentes hagan lo siguiente:
- Descubrir: Encuentra otros agentes y conoce sus habilidades (AgentSkill) y capacidades (AgentCapabilities) con tarjetas de agente estandarizadas.
- Comunicación: Intercambia mensajes y datos de forma segura.
- Colaborar: Delegar tareas y coordinar acciones para alcanzar objetivos complejos
El protocolo A2A facilita esta comunicación a través de mecanismos como las "tarjetas de agente", que actúan como tarjetas de presentación digitales que los agentes pueden usar para anunciar sus capacidades y la información de conexión.
Ahora es el momento de exponer el agente de moneda con A2A para que otros agentes y clientes puedan llamarlo.
SDK de Python de A2A
El SDK de Python de A2A proporciona modelos de Pydantic para cada uno de los recursos mencionados anteriormente: AgentSkill, AgentCapabilities y AgentCard. Esto proporciona una interfaz para acelerar el desarrollo y la integración con el protocolo A2A.
Un AgentSkill
es la forma en que anunciarás a otros agentes que el agente de moneda tiene una herramienta para get_exchange_rate
:
# A2A Agent Skill definition
skill = AgentSkill(
id='get_exchange_rate',
name='Currency Exchange Rates Tool',
description='Helps with exchange values between various currencies',
tags=['currency conversion', 'currency exchange'],
examples=['What is exchange rate between USD and GBP?'],
)
Luego, como parte de AgentCard
, se enumerarán las habilidades y capacidades del agente junto con detalles adicionales, como los modos de entrada y salida que el agente puede controlar:
# A2A Agent Card definition
agent_card = AgentCard(
name='Currency Agent',
description='Helps with exchange rates for currencies',
url=f'http://{host}:{port}/',
version='1.0.0',
defaultInputModes=["text"],
defaultOutputModes=["text"],
capabilities=AgentCapabilities(streaming=True),
skills=[skill],
)
La interfaz AgentExecutor controla la lógica principal de cómo un agente A2A procesa las solicitudes y genera respuestas o eventos. El SDK de Python de A2A proporciona una clase base abstracta a2a.server.agent_execution.AgentExecutor
que debes implementar.
Llegó el momento de unir todo con el agente de divisas y mostrar el poder de A2A.
8. Servidor de Currency Agent A2A
Ahora, observarás algunas partes del código y verás cómo se unen las diferentes partes que componen un servidor de A2A.
Si observas el archivo currency_agent/agent_executor.py
, verás que tienes la clase ADKAgentExecutor
que hereda de la clase abstracta AgentExecutor
de A2A. Se encarga de llamar al agente de ADK invocando el ejecutor de ADK, procesando solicitudes al agente y realizando conversiones entre google.genai.types
, que usa ADK, y a2a.types
, que usa A2A.
# ... see file for full code
class ADKAgentExecutor(AgentExecutor):
"""An AgentExecutor that runs an ADK agent."""
def __init__(self, runner: Runner, card: AgentCard):
self.runner = runner
self._card = card
self._running_sessions = {}
def _run_agent(
self, session_id, new_message: types.Content
) -> AsyncGenerator[Event, None]:
return self.runner.run_async(
session_id=session_id, user_id="self", new_message=new_message
)
async def _process_request(
self,
new_message: types.Content,
session_id: str,
task_updater: TaskUpdater,
) -> None:
session = await self._upsert_session(
session_id,
)
session_id = session.id
# Run through all events within the request.
async for event in self._run_agent(session_id, new_message):
if event.is_final_response():
parts = convert_genai_parts_to_a2a(event.content.parts)
logger.debug("✅ Yielding final response: %s", parts)
await task_updater.add_artifact(parts)
await task_updater.complete()
break
# If the agent is not making a function call, yield an update.
if not event.get_function_calls():
logger.debug("⏳ Yielding update response")
await task_updater.update_status(
TaskState.working,
message=task_updater.new_agent_message(
convert_genai_parts_to_a2a(event.content.parts),
),
)
else:
logger.debug("➡️ Skipping event")
async def execute(
self,
context: RequestContext,
event_queue: EventQueue,
):
# Run the agent until either complete or the task is suspended.
updater = TaskUpdater(event_queue, context.task_id, context.context_id)
# Immediately notify that the task is submitted.
if not context.current_task:
updater.submit()
updater.start_work()
await self._process_request(
types.UserContent(
parts=convert_a2a_parts_to_genai(context.message.parts),
),
context.context_id,
updater,
)
logger.debug("--- 💵💱💶 [Currency] execute exiting ---")
# ... see file for full code
Dentro de currency_agent/__main__.py
, inicializas AgentSkill y AgentCard, y creas el agente de moneda del ADK. Aquí también configurarás e iniciarás el servidor de A2A.
El SDK de Python de A2A proporciona una clase A2AFastAPIApplication
que simplifica la ejecución de un servidor HTTP compatible con A2A. Utiliza FastAPI para el framework web y, por lo general, se ejecuta con un servidor ASGI como Uvicorn.
# ... see file for full code
@click.command()
@click.option("--host", "host", default="localhost")
@click.option("--port", "port", default=10000)
def main(host: str, port: int):
# Verify one of Google AI Studio or Vertex AI is being used
if os.getenv("GOOGLE_GENAI_USE_VERTEXAI") != "TRUE" and not os.getenv(
"GOOGLE_API_KEY"
):
raise ValueError(
"GOOGLE_API_KEY environment variable not set and "
"GOOGLE_GENAI_USE_VERTEXAI is not TRUE."
)
# A2A Agent Skill definition
skill = AgentSkill(
id="get_exchange_rate",
name="Currency Exchange Rates Tool",
description="Helps with exchange values between various currencies",
tags=["currency conversion", "currency exchange"],
examples=["What is exchange rate between USD and GBP?"],
)
# A2A Agent Card definition
agent_card = AgentCard(
name="Currency Agent",
description="Helps with exchange rates for currencies",
url=f"http://{host}:{port}/",
version="1.0.0",
defaultInputModes=["text"],
defaultOutputModes=["text"],
capabilities=AgentCapabilities(streaming=True),
skills=[skill],
)
# Create the ADK runner and executor.
runner = Runner(
app_name=agent_card.name,
agent=root_agent,
artifact_service=InMemoryArtifactService(),
session_service=InMemorySessionService(),
memory_service=InMemoryMemoryService(),
)
agent_executor = ADKAgentExecutor(runner, agent_card)
request_handler = DefaultRequestHandler(
agent_executor=agent_executor,
task_store=InMemoryTaskStore(),
)
server = A2AFastAPIApplication(
agent_card=agent_card, http_handler=request_handler
)
uvicorn.run(server.build(), host=host, port=port)
# ... see file for full code
Para ejecutar el servidor de A2A, ejecuta lo siguiente en una terminal nueva:
uv run currency_agent/
Si el servidor se inicia correctamente, el resultado se verá de la siguiente manera, lo que indica que se está ejecutando en el puerto 10000:
[INFO]: --- 🔧 Loading MCP tools from MCP Server... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
INFO: Started server process [45824]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://localhost:10000 (Press CTRL+C to quit)
El agente de divisas ahora se ejecuta correctamente como un servidor A2A, con la capacidad de ser llamado por otros agentes o clientes que usan el protocolo A2A.
Cómo probar el servidor de A2A
Ahora puedes probar el servidor enviándole algunas solicitudes con A2A.
El SDK de Python de A2A proporciona una clase a2a.client.A2AClient
que simplifica este proceso.
El archivo currency_agent/test_client.py
contiene código que ejecuta varios casos de prueba diferentes en el servidor de A2A.
# ... see file for full code
# Example test using A2AClient
async def run_single_turn_test(client: A2AClient) -> None:
"""Runs a single-turn non-streaming test."""
send_message_payload = create_send_message_payload(text="how much is 100 USD in CAD?")
request = SendMessageRequest(
id=str(uuid4()), params=MessageSendParams(**send_message_payload)
)
print("--- ✉️ Single Turn Request ---")
# Send Message
response: SendMessageResponse = await client.send_message(request)
print_json_response(response, "📥 Single Turn Request Response")
if not isinstance(response.root, SendMessageSuccessResponse):
print("received non-success response. Aborting get task ")
return
if not isinstance(response.root.result, Task):
print("received non-task response. Aborting get task ")
return
task_id: str = response.root.result.id
print("--- ❔ Query Task ---")
# query the task
get_request = GetTaskRequest(id=str(uuid4()), params=TaskQueryParams(id=task_id))
get_response: GetTaskResponse = await client.get_task(get_request)
print_json_response(get_response, "📥 Query Task Response")
# ----- Main Entrypoint (Create client --> Run tests) -----
async def main() -> None:
"""Main function to run the tests."""
print(f'--- 🔄 Connecting to agent at {AGENT_URL}... ---')
try:
async with httpx.AsyncClient() as httpx_client:
client = await A2AClient.get_client_from_agent_card_url(
httpx_client, AGENT_URL
)
print('--- ✅ Connection successful. ---')
await run_single_turn_test(client)
await run_streaming_test(client)
await run_multi_turn_test(client)
except Exception as e:
traceback.print_exc()
print(f'--- ❌ An error occurred: {e} ---')
print('Ensure the agent server is running.')
Ejecuta las pruebas con el siguiente comando:
uv run currency_agent/test_client.py
Si la prueba se ejecuta correctamente, se obtendrá el siguiente resultado:
--- 🔄 Connecting to agent at http://localhost:10000... ---
--- ✅ Connection successful. ---
--- ✉️ Single Turn Request ---
--- 📥 Single Turn Request Response ---
{"id":"3bc92d7b-d857-4e93-9ff0-b2fb865f6e35","jsonrpc":"2.0","result":{"artifacts":[{"artifactId":"35e89e14-b977-4397-a23b-92c84bc32379","parts":[{"kind":"text","text":"Based on the current exchange rate, 1 USD is equivalent to 1.3704 CAD. Therefore, 100 USD would be 137.04 CAD.\n"}]}],"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","history":[{"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","kind":"message","messageId":"59819269f7d04849b0bfca7d43ec073c","parts":[{"kind":"text","text":"how much is 100 USD in CAD?"}],"role":"user","taskId":"52ae2392-84f5-429a-a14b-8413d3d20d97"},{"contextId":"2d66f277-152c-46ef-881d-7fe32866e9f5","kind":"message","messageId":"286095c6-12c9-40cb-9596-a9676d570dbd","parts":[],"role":"agent","taskId":"52ae2392-84f5-429a-a14b-8413d3d20d97"}],"id":"52ae2392-84f5-429a-a14b-8413d3d20d97","kind":"task","status":{"state":"completed"}}}
// ...
--- ⏩ Single Turn Streaming Request ---
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"state":"submitted"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"state":"working"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","final":false,"kind":"status-update","status":{"message":{"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","kind":"message","messageId":"25f5f972-9475-4e4a-a08d-e13f521d7462","parts":[],"role":"agent","taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"},"state":"working"},"taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
--- ⏳ Streaming Chunk ---
{"id":"21239a5f-abbf-4a5e-a249-c101eb1dfbdd","jsonrpc":"2.0","result":{"artifact":{"artifactId":"35e89e14-b977-4397-a23b-92c84bc32379","parts":[{"kind":"text","text":"The current exchange rate is 1 EUR to 164.15 JPY. So, 50 EUR would be 8207.5 JPY.\n"}]},"contextId":"f268ad8c-b3bf-4439-9a64-5e02dfbb9a62","kind":"artifact-update","taskId":"761d2275-d58b-46f8-9c8d-68cd72e0667d"}}
// ...
--- 🚀 First turn completed, no further input required for this test case. ---
¡Funciona! Probaste correctamente que puedes comunicarte con el agente de divisas a través de un servidor de A2A. 🎉
Consulta el repositorio a2a-samples en GitHub para ver casos de uso más avanzados.
¿Quieres implementar tu agente? Vertex AI Agent Engine proporciona una experiencia administrada para implementar agentes de IA en producción.
9. Felicitaciones
¡Felicitaciones! Compilaste e implementaste correctamente un servidor de MCP remoto, creaste un agente de moneda con el Kit de desarrollo de agentes (ADK) que se conecta a herramientas con MCP y expusiste tu agente con el protocolo Agent2Agent (A2A). El agente de divisas ahora está disponible para interactuar con otros agentes de cualquier framework a través de A2A.
Aquí encontrarás un vínculo a la documentación completa del código.
Temas abordados
- Cómo crear un servidor de MCP local
- Implementa el servidor de MCP en Cloud Run
- Cómo compilar un agente con el kit de desarrollo de agentes que usa herramientas de MCP
- Cómo exponer un agente de ADK como servidor de A2A
- Cómo probar el servidor de A2A con el cliente de A2A
Limpia
Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en este lab:
- En la consola de Google Cloud, ve a la página Administrar recursos.
- En la lista de proyectos, elige el proyecto que deseas borrar y haz clic en Borrar.
- En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrarlo.