1. Panoramica
Gli agenti AI stanno diventando sempre più popolari, rivoluzionando l'automazione delle attività e il processo decisionale grazie alla loro capacità di operare in modo autonomo, apprendere e interagire con l'ambiente per raggiungere gli obiettivi.
Questo codelab ti aiuterà a iniziare creando un sistema multi-agente end-to-end. Creerai un server MCP per le valute, un agente per le valute che utilizza il server MCP ed è esposto tramite il protocollo Agent2Agent (A2A), un'agenzia viaggi con un subagente meteo in-process che utilizza l'agente per le valute tramite A2A e, infine, eseguirai il deployment di tutti i servizi su Cloud Run.

Tecnologie di base
Model Context Protocol (MCP)
Model Context Protocol (MCP) è un protocollo aperto che standardizza il modo in cui le applicazioni forniscono contesto e strumenti agli LLM. Pensa a MCP come a una porta USB-C per le applicazioni di AI: fornisce un modo standardizzato per connettere i modelli di AI a origini dati, API e strumenti esterni.
In questo codelab, currency_mcp_server espone uno strumento get_exchange_rate su Streamable HTTP (/mcp), supportato dall'API Frankfurter pubblica.
Agent Development Kit (ADK)
Agent Development Kit (ADK) è un framework di orchestrazione flessibile per lo sviluppo e il deployment di agenti AI. ADK è indipendente dal modello e dal deployment ed è progettato per essere compatibile con altri framework. ADK rende lo sviluppo di agenti simile alla progettazione software standard, semplificando la creazione, il test e l'orchestrazione di Agentic Workflows complessi.
ADK gestisce le conversazioni degli utenti, fornisce l'interfaccia utente web interattiva, si connette agli strumenti MCP tramite McpToolset e gestisce le comunicazioni A2A.
Protocollo A2A (Agent2Agent)
L'Agent2Agent (A2A) Protocol è uno standard aperto progettato per consentire la comunicazione e la collaborazione tra agenti AI. Proprio come l'MCP standardizza le connessioni tra agenti e strumenti, l'A2A standardizza la collaborazione tra agenti. In un mondo in cui gli agenti vengono creati su diversi framework, ambienti di hosting e organizzazioni, A2A fornisce un linguaggio comune per l'individuazione e la delega delle attività.
ADK espone currency_agent come servizio A2A (to_a2a) e consente a travel_agent di utilizzarlo da remoto come AgentTool (RemoteA2aAgent).
Subagenti locali e agenti A2A remoti
Questa architettura evidenzia un pattern cruciale nella progettazione multi-agente:
- Strumento agente locale (
weather_agent): viene eseguito in-process all'interno dell'orchestratore comeAgentTool, con latenza di rete o overhead di serializzazione del protocollo pari a zero. - Remote Agent Tool (
currency_agent): viene eseguito come microservizio indipendente, chiamato sulla rete tramite il protocollo A2A.
Obiettivi didattici
- Come creare e testare un server MCP locale utilizzando FastMCP su HTTP trasmissibile in streaming
- Come creare un agente con ADK che utilizza gli strumenti MCP (
McpToolset) - Come esporre un agente ADK come server A2A (
to_a2a) - Come testare un server A2A utilizzando il client Python A2A (
a2a.client) - Come creare un agente orchestratore che combina strumenti di subagenti locali con agenti A2A remoti
- Come eseguire e testare l'intero sistema multi-agente localmente con l'interfaccia utente web ADK
- Come containerizzare ed eseguire il deployment di tutti e tre i componenti in Google Cloud Run
Che cosa ti serve
- Un browser, ad esempio Chrome.
- Un progetto Google Cloud con la fatturazione abilitata.
2. Prima di iniziare
Crea un progetto
Se non hai un progetto Google Cloud, creane uno.
Nella console Google Cloud, nella pagina di selezione del progetto, seleziona o crea un progetto Google Cloud.
Verifica inoltre che la fatturazione sia abilitata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata per un progetto.
Attiva Cloud Shell
Google Cloud Shell è un ambiente di sviluppo interattivo basato su browser fornito direttamente all'interno della console Google Cloud. È il modo più semplice per iniziare a utilizzare Google Cloud senza dover installare strumenti localmente.
Attiva Cloud Shell facendo clic su questo link. Puoi passare dal terminale Cloud Shell (per eseguire i comandi cloud) all'editor (per visualizzare i file) facendo clic sul pulsante corrispondente in Cloud Shell.
Una volta eseguita la connessione a Cloud Shell, verifica che il tuo account sia autenticato:
gcloud auth list
Verifica che il comando gcloud riconosca il tuo progetto:
gcloud config list project
Imposta l'ID progetto:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
gcloud config set project $PROJECT_ID
Abilita le API Cloud
Abilita le API richieste per Cloud Run, Cloud Build, Artifact Registry e Vertex AI:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
Ottieni il codice
Clona il repository e vai alla directory python:
git clone https://github.com/meteatamel/getting-started-mcp-a2a-adk.git
cd getting-started-mcp-a2a-adk/python
Installa le dipendenze con uv
uv è un gestore di progetti e pacchetti Python veloce. È preinstallato in Cloud Shell. Se l'esecuzione avviene localmente, puoi installarlo nel seguente modo:
# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh
# Windows (PowerShell)
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
La directory Python è strutturata come un uv unificato
Workspace. Installa tutte le dipendenze in tutti i membri dell'area di lavoro (currency_mcp_server, currency_agent e travel_agent) in un unico ambiente virtuale eseguendo:
uv sync
Configura le variabili di ambiente
Configura le variabili di ambiente in un file .env nella directory python:
Opzione A: Gemini Enterprise (Google Cloud / Cloud Shell)
echo "GOOGLE_GENAI_USE_ENTERPRISE=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=global" >> .env
Opzione B: Google AI Studio (chiave API locale)
Se preferisci utilizzare una chiave API di Google AI Studio:
echo "GOOGLE_API_KEY=<your_api_key_here>"<>>/span> .env \
&& echo "GOOGLE_GENAI_USE_ENTERPRISE=FALSE" >> .env
3. Crea il server MCP per le valute
Prima di creare gli agenti, esplorerai il server MCP che espone lo strumento di conversione di valuta.
Un server MCP ti consente di scrivere programmi leggeri per esporre le funzionalità come strumenti. Un agente (o più agenti) può quindi accedere a questi strumenti utilizzando il Model Context Protocol standardizzato.
Il pacchetto Python FastMCP può essere utilizzato per creare un server MCP che espone un singolo strumento chiamato get_exchange_rate. Lo strumento get_exchange_rate chiama l'API Frankfurter per ottenere il tasso di cambio attuale tra due valute.
Il codice per il server MCP si trova in currency_mcp_server/server.py:
import asyncio
import logging
import os
import httpx
from fastmcp import FastMCP
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.dev/v1/{currency_date}",
params={"from": currency_from, "to": currency_to},
)
response.raise_for_status()
data = response.json()
if "rates" not in data:
logger.error(f"❌ rates not found in response: {data}")
return {"error": "Invalid API response format."}
logger.info(f"✅ API response: {data}")
return data
except httpx.HTTPError as e:
logger.error(f"❌ API request failed: {e}")
return {"error": f"API request failed: {e}"}
except ValueError:
logger.error("❌ Invalid JSON response from API")
return {"error": "Invalid JSON response from API."}
if __name__ == "__main__":
port = int(os.getenv("PORT", 8080))
logger.info(f"🚀 MCP server started on port {port}")
# Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
asyncio.run(
mcp.run_async(
transport="http",
host="0.0.0.0",
port=port,
)
)
Avvia il server MCP localmente
Avvia il server MCP nel terminale:
uv run python currency_mcp_server/server.py
Il server si avvia sulla porta 8080 con l'endpoint HTTP Streamable disponibile all'indirizzo /mcp (http://localhost:8080/mcp).
Testa il server MCP
Apri una seconda finestra del terminale (lasciando il server MCP in esecuzione nella prima), vai alla cartella python (cd getting-started-mcp-a2a-adk/python) ed esegui lo script di test:
uv run python currency_mcp_server/test_server.py
Lo script di test si connette all'endpoint MCP utilizzando Client di FastMCP, elenca gli strumenti e richiama get_exchange_rate:
Connecting to MCP server at: http://localhost:8080/mcp
--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
--- ✅ Success: {"amount":1.0,"base":"USD","date":"2026-09-29","rates":{"EUR":0.84919}} ---
Fantastico! Hai un server MCP funzionante che espone uno strumento di conversione di valuta in tempo reale. Tieni aperto questo terminale per i passaggi successivi.
4. Crea l'agente di conversione di valuta con ADK
Ora è il momento di creare l'agente di conversione di valuta utilizzando l'Agent Development Kit (ADK).
ADK fornisce il supporto integrato per gli strumenti MCP tramite la classe McpToolset. L'agente di conversione di valuta si connette al nostro server MCP utilizzando StreamableHTTPConnectionParams.
Dai un'occhiata alla definizione dell'agente di conversione di valuta in currency_agent/agent.py:
import logging
import os
from urllib.parse import urlparse
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.a2a.utils.agent_to_a2a import to_a2a
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."
)
mcp_server_url = os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
if not mcp_server_url.endswith("/mcp"):
mcp_server_url = f"{mcp_server_url.rstrip('/')}/mcp"
logger.info(f"--- 🔧 Loading MCP tools from MCP Server at {mcp_server_url}... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")
root_agent = LlmAgent(
model="gemini-3.8-flash",
name="currency_agent",
description="An agent that can help with currency conversions",
instruction=SYSTEM_INSTRUCTION,
tools=[
McpToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url
)
)
],
)
Nota come McpToolset rileva e carica automaticamente lo strumento get_exchange_rate direttamente dal server MCP in esecuzione su HTTP.
Testa l'agente di conversione di valuta con l'interfaccia utente web di ADK
Puoi testare l'agente in isolamento utilizzando l'interfaccia web di sviluppo di ADK. Nel secondo terminale, esegui:
uv run adk web --allow_origins "*" currency_agent
Apri il browser all'indirizzo http://localhost:8000 (o fai clic su Anteprima web in Cloud Shell).

Chiedi all'agente:
"A quanto corrispondono 250 USD in EUR?"
Vedrai l'agente richiamare lo strumento MCP get_exchange_rate e restituire l'importo convertito. Interrompi il processo adk web utilizzando Ctrl+C prima di procedere.
5. Protocollo A2A (Agent2Agent)
L'Agent2Agent (A2A) Protocol è uno standard aperto progettato per consentire la comunicazione e la collaborazione tra agenti AI.
Nei moderni sistemi multi-agente, gli agenti vengono spesso creati utilizzando framework diversi (ADK, LangChain, CrewAI, AutoGen) e ne viene eseguito il deployment su un'infrastruttura diversa. A2A abbatte questi silos definendo un contratto di comunicazione standardizzato.

Concetti chiave di A2A
- Rilevamento degli agenti (scheda dell'agente): ogni agente conforme ad A2A pubblicizza le sue funzionalità, le modalità di I/O supportate, i requisiti di autenticazione e le skill tramite un file JSON standard ospitato all'indirizzo
/.well-known/agent-card.json. - Skill dell'agente (
AgentSkill): funzionalità o strumenti specifici che l'agente può eseguire. Altri agenti leggono queste competenze per decidere quando delegare le attività. - Comunicazione JSON-RPC: gli agenti scambiano messaggi, attività e artefatti strutturati tramite trasporti standard come HTTP JSON-RPC 2.0.

Nel passaggio successivo, esporrai il nostro ADK Currency Agent come server A2A in modo che altri agenti possano rilevarlo e delegargli le attività di conversione di valuta.
6. Esponi l'agente di conversione di valuta come server A2A
ADK semplifica la trasformazione di qualsiasi LlmAgent in un server compatibile con A2A grazie alla funzione di utilità to_a2a().
Esamina la parte inferiore di currency_agent/agent.py:
# Make the agent A2A-compatible
PORT = int(os.getenv("PORT", 8081))
AGENT_URL = os.getenv("AGENT_URL")
if AGENT_URL:
parsed = urlparse(AGENT_URL)
protocol = parsed.scheme or "https"
host = parsed.hostname
port = parsed.port or 443
else:
protocol = "http"
host = "localhost"
port = PORT
a2a_app = to_a2a(root_agent, host=host, port=port, protocol=protocol)
if __name__ == "__main__":
import uvicorn
logger.info(f"🚀 Starting currency_agent on port {PORT}")
uvicorn.run(a2a_app, host="0.0.0.0", port=PORT)
L'assistente to_a2a() esegue automaticamente le seguenti operazioni:
- Ispeziona gli strumenti e le istruzioni di
LlmAgent. - Genera un A2A
AgentCardche descrive le sue competenze (ad es.currency_agent-get_exchange_rate). - Aggrega l'agente in un'applicazione FastAPI (
a2a_app) che supporta gli endpoint JSON-RPC. - Configura dinamicamente l'
urlannunciato nella scheda dell'agente in base aAGENT_URL(o localhost).
Avvia il server A2A dell'agente di conversione di valuta
Nel secondo terminale, avvia l'agente di conversione di valuta:
uv run python currency_agent/agent.py
Il server si avvia sulla porta 8081:
[INFO]: --- 🔧 Loading MCP tools from MCP Server at http://localhost:8080/mcp... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
[INFO]: 🚀 Starting currency_agent on port 8081
INFO: Started server process
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)
Esamina la scheda dell'agente
Nel browser, visita l'endpoint della scheda dell'agente: http://localhost:8081/.well-known/agent-card.json
Vedrai i metadati JSON generati automaticamente:
{
"name": "currency_agent",
"description": "An agent that can help with currency conversions",
"supportedInterfaces": [
{
"url": "http://localhost:8081",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"version": "0.0.1",
"capabilities": {
"streaming": true
},
"defaultInputModes": [
"text/plain"
],
"defaultOutputModes": [
"text/plain"
],
"skills": [
{
"id": "currency_agent",
"name": "model",
"description": "An agent that can help with currency conversions",
"tags": [
"llm"
]
},
{
"id": "currency_agent-get_exchange_rate",
"name": "get_exchange_rate",
"description": "Use this to get current exchange rate.",
"tags": [
"llm",
"tools"
]
}
]
}
Esegui il test con il client A2A
Apri un terzo terminale, vai alla cartella python (cd getting-started-mcp-a2a-adk/python) e testa l'endpoint A2A utilizzando lo script client di test A2A dedicato:
uv run python currency_agent/test_a2aclient.py
Il client risolve la scheda dell'agente utilizzando A2ACardResolver e invia un messaggio JSON-RPC:
🔄 Fetching the agent card at http://localhost:8081
✅ Successfully fetched the agent card
====================================================
AgentCard
====================================================
Name : currency_agent
Description : An agent that can help with currency conversions
Interfaces : [0] http://localhost:8081 (JSONRPC 1.0)
Skills : currency_agent, currency_agent-get_exchange_rate
====================================================
🔄 Initializing a non-streaming client
Sending request: "how much is 100 USD in GBP?"
Response:
100 USD is currently equal to approximately 73.37 GBP...
L'agente di conversione di valuta ora funziona come un server A2A completamente operativo.
7. Crea l'agente di viaggio
Ora creerai l'agenzia viaggi di orchestrazione. Questo agente mostra come un agente ADK può combinare facilmente due diversi paradigmi di strumenti:
- Strumento agente locale (
weather_agent): un subagente ADK in-process in esecuzione nello stesso runtime Python, che evita qualsiasi latenza di rete o di serializzazione. - Remote Agent Tool (
currency_agent): un agente esterno connesso alla rete tramite il protocollo A2A utilizzandoRemoteA2aAgent.
+-----------------------------+
| travel_agent |
| (Orchestrator with Web UI) |
+--------------+--------------+
|
+---------------------+---------------------+
| (In-process call) | (A2A Network Hop)
v v
+-------------------------+ +-------------------------+
| weather_agent | | currency_agent |
| (Local AgentTool) | | (Remote A2A Agent) |
| Calls wttr.in API | | Calls Currency MCP Svc |
+-------------------------+ +-------------------------+
1. Subagente Meteo locale
Dai un'occhiata a travel_agent/subagents/weather_agent.py:
import logging
import httpx
from google.adk.agents import LlmAgent
logger = logging.getLogger(__name__)
SYSTEM_INSTRUCTION = (
"You are a specialized assistant for providing weather forecasts and conditions for travel destinations. "
"Your sole purpose is to use the 'get_weather' tool to fetch weather information. "
"Provide clear, concise summaries of current weather conditions, temperatures, and forecasts to help travelers pack and plan."
)
def get_weather(location: str = "London") -> dict:
"""Gets the current weather and forecast for a given location or city."""
logger.info(f"--- 🌤️ Tool: get_weather called for {location} ---")
try:
response = httpx.get(
f"https://wttr.in/{location}?format=j1",
headers={"User-Agent": "curl/7.68.0"},
timeout=8.0,
)
response.raise_for_status()
data = response.json()
current = data["current_condition"][0]
return {
"location": location,
"condition": current.get("weatherDesc", [{}])[0].get("value", "Unknown"),
"temperature_celsius": f"{current.get('temp_C', 'N/A')}°C",
"temperature_fahrenheit": f"{current.get('temp_F', 'N/A')}°F",
"humidity": f"{current.get('humidity', 'N/A')}%",
"wind_speed_kmph": f"{current.get('windspeedKmph', 'N/A')} km/h",
}
except Exception as e:
logger.warning(f"⚠️ Weather lookup failed: {e}. Returning simulated estimate.")
return {
"location": location,
"condition": "Partly Cloudy",
"temperature_celsius": "20°C",
"temperature_fahrenheit": "68°F",
"humidity": "55%",
"wind_speed_kmph": "10 km/h",
"note": f"Live data unavailable ({e}); showing estimated conditions.",
}
weather_agent = LlmAgent(
model="gemini-3.8-flash",
name="weather_agent",
description="A local specialist agent that provides current weather reports and forecasts for travel destinations.",
instruction=SYSTEM_INSTRUCTION,
tools=[get_weather],
)
L'agente meteo è un LlmAgent con uno strumento di funzione che recupera il meteo in tempo reale da wttr.in con un fallback resiliente.
2. L'orchestratore di agenzie viaggi
Ora guarda travel_agent/agent.py:
import logging
import os
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.tools.agent_tool import AgentTool
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent, AGENT_CARD_WELL_KNOWN_PATH
try:
from travel_agent.subagents.weather_agent import weather_agent
except ImportError:
from subagents.weather_agent import weather_agent
logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
load_dotenv()
SYSTEM_INSTRUCTION = (
"You are a helpful travel assistant. You help users plan trips, recommend places, "
"and answer travel-related questions.\n\n"
"- Whenever a user asks about currency exchange rates or money conversions, "
"delegate the request to the 'currency_agent' tool.\n"
"- Whenever a user asks about the weather, climate, or forecasts for a destination, "
"delegate the request to the 'weather_agent' tool."
)
CURRENCY_AGENT_URL = os.getenv("CURRENCY_AGENT_URL", "http://localhost:8081").rstrip("/")
logger.info(
"--- 🔗 Connecting to Remote A2A Currency Agent at %s... ---",
CURRENCY_AGENT_URL,
)
currency_remote_agent = RemoteA2aAgent(
name="currency_agent",
agent_card=f"{CURRENCY_AGENT_URL}{AGENT_CARD_WELL_KNOWN_PATH}",
description="An agent that can help with currency conversions and exchange rates.",
)
logger.info("--- 🤖 Creating ADK Travel Agent... ---")
root_agent = LlmAgent(
model="gemini-3.8-flash",
name="travel_agent",
description="A travel assistant that can help plan trips, check weather forecasts via the local weather agent, and convert currencies via the remote currency agent.",
instruction=SYSTEM_INSTRUCTION,
tools=[
AgentTool(agent=currency_remote_agent),
AgentTool(agent=weather_agent),
],
)
if __name__ == "__main__":
import uvicorn
from google.adk.cli.fast_api import get_fast_api_app
PORT = int(os.getenv("PORT", 8082))
logger.info(f"🚀 Starting travel_agent Web UI on port {PORT}")
app = get_fast_api_app(web=True, allow_origins=["*"], agents_dir=os.path.dirname(__file__) or ".")
uvicorn.run(app, host="0.0.0.0", port=PORT)
Principali punti di forza:
RemoteA2aAgentrecupera la scheda dell'agente di conversione dahttp://localhost:8081/.well-known/agent-card.json.- Sia
currency_remote_agentcheweather_agentsono aggregati utilizzandoAgentTooldi ADK. - L'esecuzione di
travel_agent/agent.pyavvia direttamente l'interfaccia utente web di ADK sulla porta8082utilizzandoget_fast_api_app(web=True).
8. Esegui e testa il sistema multi-agente in locale
Ora hai tutti e tre i componenti pronti. Eseguiamo e testiamo l'intero sistema in locale.
Esecuzione di tutti e tre i servizi
Assicurati che i servizi siano in esecuzione in tre finestre del terminale separate (dalla directory getting-started-mcp-a2a-adk/python) nel seguente ordine:
Terminale 1 (server MCP di conversione di valuta):
uv run python currency_mcp_server/server.py
(In esecuzione sulla porta 8080)
Terminale 2 (agente A2A di valuta):
uv run python currency_agent/agent.py
(Running on port 8081)
Terminal 3 (agenzia viaggi con UI web):
uv run python travel_agent/agent.py
(Running on port 8082)
Esegui il test tramite l'interfaccia utente web di ADK
Apri il browser all'indirizzo http://localhost:8082 (o utilizza Anteprima web sulla porta 8082 in Cloud Shell).
Fai all'agenzia viaggi una domanda complessa che richiede l'utilizzo di entrambi gli strumenti:
"Sto pianificando un viaggio a Londra. Che tempo fa e quanto sono 200 EUR in GBP?"
Guarda il flusso di esecuzione:
- L'agenzia viaggi riceve la richiesta nell'interfaccia utente web.
- Delega la domanda sul meteo in-process al
weather_agentlocale, che recupera le condizioni attuali dawttr.in. - Delega la conversione di valuta tramite il protocollo A2A a
currency_agentsulla porta 8081. currency_agentchiamacurrency_mcp_serversulla porta 8080 tramite MCP per recuperare il tasso di cambio.- Tutti i risultati vengono sintetizzati e restituiti in una risposta unificata e utile.

Esegui i test dalla riga di comando
Puoi anche testare le query direttamente dall'interfaccia a riga di comando senza aprire un browser:
uv run adk run travel_agent "What is the weather in London and how much is 100 USD in EUR?"
Ora che tutto funziona perfettamente sulla tua macchina locale, eseguiamo il deployment dell'intero sistema su Google Cloud Run.
9. Esegui il deployment del sistema multi-agente in Cloud Run
Ogni componente ha il proprio Dockerfile e un pyproject.toml autonomo, in modo da poter essere creato e distribuito in modo indipendente su Cloud Run.
Utilizzando gcloud, eseguirai il deployment di ogni servizio e collegherai automaticamente i relativi URL.
Imposta le variabili di ambiente
Imposta l'ID progetto Cloud e la regione di destinazione:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
export REGION=us-central1
Passaggio 1: esegui il deployment del server MCP Currency
Esegui il deployment del server MCP direttamente dall'origine:
# 1. Deploy MCP server
gcloud run deploy currency-mcp-server \
--source currency_mcp_server \
--region $REGION \
--allow-unauthenticated
# 2. Capture the deployed MCP server URL
MCP_SERVER_URL=$(gcloud run services describe currency-mcp-server --region $REGION --format='value(status.url)')/mcp
echo "MCP Server URL: $MCP_SERVER_URL"
Passaggio 2: esegui il deployment dell'agente di conversione di valuta
Poiché l'URL pubblico di currency-agent viene assegnato al primo deployment, esegui prima il deployment del servizio, acquisisci il relativo URL e aggiorna la variabile di ambiente AGENT_URL in modo che la scheda dell'agente A2A annunci l'indirizzo HTTPS pubblico corretto:
# 1. Deploy Currency Agent connected to the deployed MCP Server
gcloud run deploy currency-agent \
--source currency_agent \
--region $REGION \
--allow-unauthenticated \
--update-env-vars MCP_SERVER_URL="$MCP_SERVER_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"
# 2. Capture its assigned Cloud Run URL
CURRENCY_AGENT_URL=$(gcloud run services describe currency-agent --region $REGION --format='value(status.url)')
echo "Currency Agent URL: $CURRENCY_AGENT_URL"
# 3. Update AGENT_URL so the agent advertises its public HTTPS endpoint in its Agent Card
gcloud run services update currency-agent \
--region $REGION \
--update-env-vars AGENT_URL="$CURRENCY_AGENT_URL"
Passaggio 3: esegui il deployment dell'agente di viaggio
Ora esegui il deployment dell'agente di viaggio, configurandolo con CURRENCY_AGENT_URL:
# 1. Deploy Travel Agent (with ADK Web UI) connected to Currency Agent
gcloud run deploy travel-agent \
--source travel_agent \
--region $REGION \
--allow-unauthenticated \
--update-env-vars CURRENCY_AGENT_URL="$CURRENCY_AGENT_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"
# 2. Capture its assigned Cloud Run URL
TRAVEL_AGENT_URL=$(gcloud run services describe travel-agent --region $REGION --format='value(status.url)')
echo "Travel Agent URL: $TRAVEL_AGENT_URL"
10. Testa il sistema multi-agente in Cloud Run
Dopo aver eseguito il deployment di tutti e tre i microservizi, verifichiamo ogni livello in Cloud Run.
1. Testa il server MCP remoto
Testa il server MCP Cloud Run di cui hai eseguito il deployment dalla riga di comando:
MCP_SERVER_URL="$MCP_SERVER_URL" uv run python currency_mcp_server/test_server.py
Dovresti vedere lo strumento elencato e richiamato correttamente su Cloud Run.
2. Testa l'agente di conversione di valuta tramite A2A
Testa l'agente di conversione di valuta di cui è stato eseguito il deployment utilizzando il client di test A2A:
AGENT_URL="$CURRENCY_AGENT_URL" uv run python currency_agent/test_a2aclient.py
Il client recupererà l'Agent Card remota da Cloud Run e scambierà messaggi tramite HTTPS JSON-RPC.
3. Testa l'interfaccia utente web dell'agenzia viaggi in Cloud Run
Apri $TRAVEL_AGENT_URL nel browser.
L'interfaccia utente web ADK completa viene fornita direttamente da Cloud Run. Prova a chiedere:
"Sto pianificando un viaggio a Tokyo. Che tempo fa e quanto sono 500 $ in ¥?"
[Browser]
│
▼ (HTTPS)
[Cloud Run: travel-agent]
├──> Local in-process tool: weather_agent (wttr.in)
└──> A2A JSON-RPC (HTTPS)
│
▼
[Cloud Run: currency-agent]
└──> MCP Streamable HTTP (HTTPS)
│
▼
[Cloud Run: currency-mcp-server] (Frankfurter API)
Tutti e tre i servizi scalano in modo indipendente su un'infrastruttura serverless, comunicando senza problemi tramite protocolli aperti.
11. Congratulazioni e pulizia
I tuoi risultati
Complimenti! Hai creato ed eseguito il deployment di un sistema multi-agente di livello di produzione:
- Model Context Protocol (MCP): ho creato un server FastMCP che espone strumenti API in tempo reale tramite HTTP trasmissibile in streaming.
- Agent Development Kit (ADK): hai creato agenti modulari utilizzando
LlmAgent, hai collegato gli strumenti MCP conMcpToolsete hai ospitato l'interfaccia utente web ADK. - Protocollo Agent2Agent (A2A): hai esposto un agente come servizio A2A (
to_a2a), pubblicato schede agente (agent-card.json) e utilizzato agenti remoti utilizzandoRemoteA2aAgent. - Architettura multi-agente: Combinazione di sub-agenti locali in-process (
weather_agent) con agenti remoti distribuiti (currency_agent). - Deployment serverless di Cloud Run: containerizzazione e deployment di tutti e tre i servizi con collegamento di configurazione automatizzato.
Per il codice completo (incluse le implementazioni Python e Java) e gli aggiornamenti futuri, visita il repository getting-started-mcp-a2a-adk.
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi ai servizi Cloud Run creati in questo codelab:
Elimina i servizi Cloud Run di cui hai eseguito il deployment:
gcloud run services delete currency-mcp-server --region $REGION --quiet
gcloud run services delete currency-agent --region $REGION --quiet
gcloud run services delete travel-agent --region $REGION --quiet
In alternativa, se hai creato un progetto dedicato per questo codelab, puoi chiudere l'intero progetto:
gcloud projects delete $PROJECT_ID