Sobre este codelab
1. Visão geral
Os agentes de IA estão ganhando popularidade rapidamente, revolucionando a automação de tarefas e a tomada de decisões com a capacidade de operar de forma autônoma, aprender e interagir com o ambiente para alcançar metas.
Mas como criar um agente? Este codelab vai ajudar você a começar mostrando como criar um agente de moeda que pode converter entre as moedas de diferentes países. O objetivo é apresentar as tecnologias mais recentes para ajudar você a entender as siglas que podem ter aparecido na Internet (MCP, ADK, A2A).
Protocolo de contexto do modelo (MCP)
O Protocolo de Contexto de Modelo (MCP) é um protocolo aberto que padroniza como os aplicativos fornecem contexto para LLMs. O MCP oferece uma maneira padronizada de conectar modelos de IA a recursos, comandos e ferramentas.
Kit de desenvolvimento de agentes (ADK)
O Agent Development Kit (ADK) é um framework de orquestração flexível para desenvolver e implantar agentes de IA. O ADK é independente de modelo e implantação e foi criado para ser compatível com outros frameworks. O ADK foi projetado para fazer com que o desenvolvimento de agentes pareça mais com o desenvolvimento de software, facilitando a criação, a implantação e a organização de arquiteturas de agentes que variam de tarefas simples a fluxos de trabalho complexos.
Protocolo Agent2Agent (A2A)
O protocolo Agent2Agent (A2A) é um padrão aberto projetado para permitir a comunicação e a colaboração perfeitas entre agentes de IA. Assim como o MCP oferece uma maneira padronizada de dar aos LLMs acesso a dados e ferramentas, o A2A oferece uma maneira padronizada para os agentes conversarem entre si. Em um mundo em que os agentes são criados usando diversos frameworks e por diferentes fornecedores, o A2A oferece uma linguagem comum, quebra os silos e promove a interoperabilidade.
O que você vai aprender
- Como criar um servidor MCP local
- Como implantar o servidor MCP no Cloud Run
- Como criar um agente com o Agent Development Kit que usa ferramentas do MCP
- Como expor um agente do ADK como um servidor A2A
- Testar o servidor A2A usando o cliente A2A
O que é necessário
2. Antes de começar
Criar um projeto
- No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Verifique se o faturamento está ativado para seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto.
- Clique neste link para ativar o Cloud Shell. Clique no botão correspondente no Cloud Shell para alternar entre o terminal do Cloud Shell (para executar comandos da nuvem) e o editor (para criar projetos).
- Depois de se conectar ao Cloud Shell, verifique se sua conta já está autenticada e se o projeto está configurado com seu ID do projeto usando o seguinte comando:
gcloud auth list
- Execute o comando a seguir no Cloud Shell para confirmar se o comando gcloud sabe sobre seu projeto.
gcloud config list project
- Use o comando a seguir para definir seu projeto:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
- Ative as APIs necessárias usando o comando a seguir. Isso pode levar alguns 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
- Verifique se você tem o Python 3.10 ou uma versão mais recente.
Consulte a documentação para ver o uso e os comandos gcloud.
3. Instalação
- Clone o repositório:
git clone https://github.com/jackwotherspoon/currency-agent.git
cd currency-agent
- Instale o uv (usado para gerenciar dependências):
# 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"
- Configure as variáveis de ambiente (pelo arquivo
.env
):
Crie um arquivo .env
executando o seguinte:
echo "GOOGLE_GENAI_USE_VERTEXAI=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=us-central1" >> .env
4. Criar um servidor MCP local
Antes de orquestrar seu agente de moeda, crie um servidor MCP para expor as ferramentas que ele vai precisar.
Um servidor MCP permite escrever programas leves para expor recursos específicos (como buscar taxas de câmbio) como ferramentas. Um ou vários agentes podem acessar essas ferramentas usando o Protocolo de contexto de modelo (MCP, na sigla em inglês) padronizado.
O pacote Python FastMCP pode ser usado para criar um servidor MCP que expõe uma única ferramenta chamada get_exchange_rate
. A ferramenta get_exchange_rate
faz uma chamada pela Internet para a API Frankfurter e recebe a taxa de câmbio atual entre duas moedas.
O código do servidor MCP pode ser encontrado no arquivo 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 o servidor MCP localmente, abra um terminal e execute o seguinte comando (o servidor será iniciado em http://localhost:8080
):
uv run mcp-server/server.py
Teste se o servidor MCP está funcionando corretamente e se a ferramenta get_exchange_rate
está acessível usando o protocolo de contexto do modelo.
Em uma nova janela de terminal (para não interromper o servidor MCP local), execute o seguinte:
uv run mcp-server/test_server.py
Você vai ver a taxa de câmbio atual de 1 USD (dólar americano) para 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
}
} ---
Incrível! Você tem um servidor MCP funcionando com uma ferramenta que seu agente pode acessar.
Antes de passar para a próxima estação, pare o servidor do MCP em execução localmente executando Ctrl+C
(ou Command+C
no Mac) no terminal em que você o iniciou.
5. Implantar o servidor MCP no Cloud Run
Agora você pode implantar o servidor MCP como um servidor MCP remoto no Cloud Run 🚀☁️
Benefícios de executar um servidor MCP remotamente
Executar um servidor MCP remotamente no Cloud Run pode oferecer vários benefícios:
- 📈Escalonabilidade: o Cloud Run foi criado para escalonar rapidamente para lidar com todas as solicitações de entrada. O Cloud Run vai escalonar automaticamente seu servidor MCP com base na demanda.
- 👥Servidor centralizado: é possível compartilhar o acesso a um servidor MCP centralizado com membros da equipe usando privilégios do IAM. Assim, eles podem se conectar a ele nas máquinas locais em vez de executar os próprios servidores localmente. Se uma mudança for feita no servidor do MCP, todos os membros da equipe vão se beneficiar dela.
- 🔐Segurança: o Cloud Run oferece uma maneira fácil de forçar solicitações autenticadas. Isso permite apenas conexões seguras com o servidor MCP, evitando o acesso não autorizado.
Mude para o diretório mcp-server
:
cd mcp-server
Implante o servidor MCP no Cloud Run:
gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .
Se o serviço tiver sido implantado, você verá uma mensagem como esta:
Service [mcp-server] revision [mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.
Autenticar clientes do MCP
Como você especificou --no-allow-unauthenticated
para exigir autenticação, qualquer cliente do MCP que se conectar ao servidor MCP remoto precisará se autenticar.
A documentação oficial sobre Como hospedar servidores MCP no Cloud Run fornece mais informações sobre esse tópico, dependendo de onde você está executando o cliente MCP.
Você precisará executar o proxy do Cloud Run para criar um túnel autenticado para o servidor MCP remoto na sua máquina local.
Por padrão, o URL dos serviços do Cloud Run exige que todas as solicitações sejam autorizadas com o papel do IAM Invocador do Cloud Run (roles/run.invoker
). Essa vinculação de política do IAM garante que um mecanismo de segurança forte seja usado para autenticar seu cliente MCP local.
Verifique se você ou qualquer membro da equipe que esteja tentando acessar o servidor MCP remoto tem o papel roles/run.invoker
do IAM vinculado ao principal do IAM (conta do Google Cloud).
gcloud run services proxy mcp-server --region=us-central1
Você verá esta resposta:
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 o tráfego para http://127.0.0.1:8080
agora será autenticado e encaminhado para o servidor MCP remoto.
Testar o servidor MCP remoto
Em um novo terminal, volte para a pasta raiz e execute novamente o arquivo mcp-server/test_server.py
para garantir que o servidor MCP remoto esteja funcionando.
cd ..
uv run mcp-server/test_server.py
Você vai ver uma saída semelhante à que apareceu quando executou o servidor localmente:
--- 🛠️ 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
}
} ---
É possível consultar os registros do servidor MCP do Cloud Run implantado se quiser verificar se o servidor remoto foi realmente chamado:
gcloud run services logs read mcp-server --region us-central1 --limit 5
Você vai ver o seguinte nos 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}}
Agora que você tem um servidor MCP remoto, é possível criar um agente. 🤖
6. Criar um agente com o Agent Development Kit (ADK)
Agora que você tem um servidor do MCP implantado, é hora de criar o agente de moeda usando o Kit de desenvolvimento de agentes (ADK).
O Agent Development Kit lançou recentemente a versão estável 1.0.0. Esse marco significa que o ADK do Python agora está pronto para produção, oferecendo uma plataforma confiável e robusta para que os desenvolvedores criem e implementem agentes em ambientes ativos com confiança.
O ADK facilita a criação de agentes extremamente leves e permite que eles se conectem facilmente aos servidores MCP com suporte integrado para as ferramentas do MCP. O agente de moeda vai acessar a ferramenta get_exchange_rate
usando a classe MCPToolset do ADK.
O código do agente de moeda está em 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 testar rapidamente o agente de moeda, use a interface de desenvolvimento do ADK. Para acessar, execute adk web
:
uv run adk web
Em um navegador, acesse http://localhost:8000
para ver e testar o agente.
Verifique se currency_agent
está selecionado como o agente no canto superior esquerdo da interface da Web.
Pergunte ao agente na área de chat algo como "Quanto é 250 CAD em USD?". O agente vai chamar nossa ferramenta get_exchange_rate
MCP antes de dar uma resposta.
O agente funciona! Ele pode lidar com consultas relacionadas a conversões de moeda 💸.
7. Protocolo Agent2Agent (A2A)
O protocolo Agent2Agent (A2A) é um padrão aberto projetado para permitir a comunicação e a colaboração perfeitas entre agentes de IA. Isso permite que agentes criados usando diversos frameworks e por diferentes fornecedores se comuniquem em uma linguagem comum, eliminando silos e promovendo a interoperabilidade.
Com o A2A, os agentes podem:
- Descobrir:encontre outros agentes e conheça as habilidades (AgentSkill) e capacidades (AgentCapabilities) deles usando os cards de agente padronizados.
- Comunicação:troque mensagens e dados com segurança.
- Colaborar:delegue tarefas e coordene ações para alcançar metas complexas.
O protocolo A2A facilita essa comunicação por mecanismos como "Cartões de agente", que funcionam como cartões de visita digitais que os agentes podem usar para anunciar suas capacidades e informações de conexão.
Agora é hora de expor o agente de moeda usando A2A para que ele possa ser chamado por outros agentes e clientes.
SDK do Python A2A
O SDK do Python A2A oferece modelos Pydantic para cada um dos recursos mencionados: AgentSkill, AgentCapabilities e AgentCard. Isso fornece uma interface para acelerar o desenvolvimento e a integração com o protocolo A2A.
Um AgentSkill
é como você vai anunciar para outros agentes que o agente de moeda tem uma ferramenta 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?'],
)
Em seguida, como parte do AgentCard
, ele vai listar as habilidades e capacidades do agente, além de outros detalhes, como modos de entrada e saída que o agente pode processar:
# 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],
)
A interface AgentExecutor processa a lógica principal de como um agente A2A processa solicitações e gera respostas/eventos. O SDK Python A2A fornece uma classe base abstrata a2a.server.agent_execution.AgentExecutor
que você precisa implementar.
Chegou a hora de juntar tudo com o agente de moeda e mostrar o poder do A2A.
8. Servidor A2A do agente de moeda
Agora, vamos analisar algumas partes do código e ver como as diferentes partes que compõem um servidor A2A se unem.
Dentro do arquivo currency_agent/agent_executor.py
, você tem a classe ADKAgentExecutor
, que herda da classe abstrata AgentExecutor
do A2A. Ele lida com a chamada do agente do ADK invocando o executor do ADK, processando solicitações ao agente e convertendo entre google.genai.types
, que o ADK usa, e a2a.types
, que o A2A usa.
# ... 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
, você inicializa o AgentSkill, o AgentCard e cria o agente de moeda do ADK. É também onde você configura e inicia o servidor A2A.
O SDK do Python A2A fornece uma classe A2AFastAPIApplication
que simplifica a execução de um servidor HTTP compatível com A2A. Ele usa o FastAPI para o framework da Web e geralmente é executado com um servidor ASGI, como o 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 executar o servidor A2A, em um novo terminal, execute o seguinte:
uv run currency_agent/
Se o servidor for iniciado corretamente, a saída será semelhante a esta, indicando que ele está sendo executado na porta 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)
O agente de moeda agora está sendo executado como um servidor A2A, com a capacidade de ser chamado por outros agentes ou clientes usando o protocolo A2A.
Testar o servidor A2A
Agora é possível testar o servidor enviando algumas solicitações usando o A2A.
O SDK do Python A2A fornece uma classe a2a.client.A2AClient
que simplifica esse processo.
O arquivo currency_agent/test_client.py
contém código que executa vários casos de teste diferentes no servidor 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.')
Execute os testes usando o seguinte comando:
uv run currency_agent/test_client.py
Uma execução de teste bem-sucedida vai resultar no seguinte:
--- 🔄 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. ---
Funcionou! Você testou com sucesso a comunicação com o agente de moeda em um servidor A2A. 🎉
Confira o repositório a2a-samples no GitHub para ver casos de uso mais avançados.
Quer implantar seu agente? O Vertex AI Agent Engine oferece uma experiência gerenciada para implantar agentes de IA em produção.
9. Parabéns
Parabéns! Você criou e implantou um servidor MCP remoto, criou um agente de moeda usando o Kit de Desenvolvimento de Agentes (ADK) que se conecta a ferramentas usando o MCP e expôs seu agente usando o protocolo Agent2Agent (A2A). O agente de moeda já está disponível para interagir com outros agentes de qualquer framework usando A2A.
Aqui está um link para a documentação completa do código.
O que aprendemos
- Como criar um servidor MCP local
- Como implantar o servidor MCP no Cloud Run
- Como criar um agente com o Agent Development Kit que usa ferramentas do MCP
- Como expor um agente do ADK como um servidor A2A
- Testar o servidor A2A usando o cliente A2A
Limpar
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados neste laboratório, siga estas etapas:
- No console do Google Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
- Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.