1. Обзор
ИИ-агенты быстро набирают популярность, революционизируя автоматизацию задач и принятие решений благодаря своей способности работать автономно, учиться и взаимодействовать с окружающей средой для достижения целей.
Эта практическая работа поможет вам начать работу с мультиагентными системами. Вы создадите сервер MCP для валют, агента для валют, который использует сервер MCP и доступен по протоколу Agent2Agent (A2A), агента для путешествий с внутрипроцессным субагентом для погоды, который использует агента для валют по протоколу A2A, и развернете все сервисы в Cloud Run.

Базовые технологии
Model Context Protocol (MCP)
Model Context Protocol (MCP) – это открытый протокол, который стандартизирует то, как приложения предоставляют контекст и инструменты большим языковым моделям. MCP можно сравнить с портом USB-C для ИИ-приложений: он предоставляет стандартизированный способ подключения ИИ-моделей к внешним источникам данных, API и инструментам.
В этой практической работе currency_mcp_server предоставляет инструмент get_exchange_rate через Streamable HTTP (/mcp) на основе общедоступного Frankfurter API.
Agent Development Kit (ADK)
Agent Development Kit (ADK) – это гибкий фреймворк оркестрации для разработки и развертывания ИИ-агентов. ADK не зависит от модели и развертывания и совместим с другими фреймворками. С ADK разработка агентов похожа на стандартную разработку ПО, что упрощает создание, тестирование и оркестрацию сложных агентных рабочих процессов.
ADK обрабатывает разговоры пользователей, обслуживает интерактивный веб-интерфейс, подключается к инструментам MCP через McpToolset и управляет взаимодействием между агентами.
Протокол Agent2Agent (A2A)
Протокол Agent2Agent (A2A) – это открытый стандарт, разработанный для обеспечения связи и взаимодействия между ИИ-агентами. Подобно тому, как MCP стандартизирует связи между агентами и инструментами, A2A стандартизирует взаимодействие между агентами. В мире, где агенты создаются на основе разных фреймворков, в разных средах хостинга и разными организациями, A2A предоставляет общий язык для обнаружения и делегирования задач.
ADK предоставляет currency_agent как сервис A2A (to_a2a) и позволяет travel_agent использовать его удаленно как AgentTool (RemoteA2aAgent).
Локальные субагенты и удаленные A2A-агенты
Эта архитектура подчеркивает важный паттерн в проектировании мультиагентных систем:
- Инструмент Local Agent (
weather_agent). Выполняется в процессе в оркестраторе какAgentTool, без задержки сети или накладных расходов на сериализацию протокола. - Инструмент удаленного агента (
currency_agent). Работает как независимый микросервис, вызываемый по сети через протокол A2A.
Что вы узнаете
- Как создать и протестировать локальный MCP-сервер с помощью FastMCP через Streamable HTTP
- Как создать агента с помощью ADK, который использует инструменты MCP (
McpToolset) - Как сделать агент ADK сервером A2A (
to_a2a) - Как протестировать сервер A2A с помощью клиента A2A Python (
a2a.client) - Как создать агента-оркестратора, который объединяет локальные инструменты субагентов с удаленными A2A-агентами.
- Как запустить и протестировать мультиагентную систему локально с помощью веб-интерфейса ADK.
- Как контейнеризовать и развернуть все три компонента в Google Cloud Run
Что вам понадобится
- Браузер, например Chrome.
- Проект Google Cloud с включенными платежными функциями.
2. Подготовка
Как создать проект
Если у вас нет проекта Google Cloud, создайте его.
В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud.
Также убедитесь, что для вашего облачного проекта включены платежные функции. Подробнее о том, как проверить, включены ли платежные функции для проекта…
Активировать Cloud Shell
Google Cloud Shell – это интерактивная среда разработки на основе браузера, доступная непосредственно в консоли Google Cloud. Это самый простой способ начать работу с Google Cloud без необходимости устанавливать инструменты локально.
Активируйте Cloud Shell, нажав на эту ссылку. Вы можете переключаться между терминалом Cloud Shell (для выполнения облачных команд) и редактором (для просмотра файлов), нажимая соответствующую кнопку в Cloud Shell.
После подключения к Cloud Shell убедитесь, что вы прошли аутентификацию:
gcloud auth list
Убедитесь, что команда gcloud знает о вашем проекте:
gcloud config list project
Укажите идентификатор проекта:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
gcloud config set project $PROJECT_ID
Как включить Cloud API
Включите необходимые API для Cloud Run, Cloud Build, Artifact Registry и Vertex AI:
gcloud services enable run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
aiplatform.googleapis.com
Как получить код
Клонируйте хранилище и перейдите в каталог python:
git clone https://github.com/meteatamel/getting-started-mcp-a2a-adk.git
cd getting-started-mcp-a2a-adk/python
Установите зависимости с помощью uv
uv – это быстрый менеджер пакетов и проектов Python. Он предустановлен в Cloud Shell. Если вы запускаете его локально, установите его следующим образом:
# 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"
Каталог Python структурирован как единый uv.
Workspace. Установите все зависимости для всех участников рабочей области (currency_mcp_server, currency_agent и travel_agent) в единую виртуальную среду, выполнив следующую команду:
uv sync
Настройте переменные среды
Настройте переменные среды в файле .env в каталоге python:
Вариант А. 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
Вариант Б. Google AI Studio (локальный ключ API)
Если вы хотите использовать ключ API из Google AI Studio:
echo "GOOGLE_API_KEY=<your_api_key_here>"<>>/span> .env \
&& echo "GOOGLE_GENAI_USE_ENTERPRISE=FALSE" >> .env
3. Создайте MCP-сервер для конвертации валют
Прежде чем создавать агентов, вы изучите MCP-сервер, который предоставляет инструмент конвертации валют.
MCP-сервер позволяет создавать простые программы, чтобы использовать их возможности как инструменты. Один или несколько агентов могут получить доступ к этим инструментам с помощью стандартизированного протокола Model Context Protocol.
Пакет Python FastMCP можно использовать для создания MCP-сервера, который предоставляет один инструмент под названием get_exchange_rate. Инструмент get_exchange_rate вызывает Frankfurter API, чтобы получить текущий обменный курс между двумя валютами.
Код MCP-сервера находится в 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,
)
)
Запустите MCP-сервер локально
Запустите MCP-сервер в терминале:
uv run python currency_mcp_server/server.py
Сервер запускается на порте 8080, а конечная точка Streamable HTTP доступна по адресу /mcp (http://localhost:8080/mcp).
Протестируйте MCP-сервер
Откройте второе окно терминала (не закрывая первое, в котором запущен MCP-сервер), перейдите в папку python (cd getting-started-mcp-a2a-adk/python) и запустите тестовый скрипт:
uv run python currency_mcp_server/test_server.py
Тестовый скрипт подключается к конечной точке MCP с помощью Client FastMCP, выводит список инструментов и вызывает 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}} ---
Здорово! У вас есть работающий MCP-сервер, на котором размещен инструмент для конвертации валют. Не закрывайте терминал. Он понадобится вам на следующих этапах.
4. Создание агента для конвертации валют с помощью ADK
Теперь создайте агента для конвертации валют с помощью Agent Development Kit (ADK).
ADK предоставляет встроенную поддержку инструментов MCP через класс McpToolset. Агент валют подключается к нашему MCP-серверу с помощью StreamableHTTPConnectionParams.
Посмотрите на определение агента валют в 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
)
)
],
)
Обратите внимание, что McpToolset автоматически обнаруживает и загружает инструмент get_exchange_rate непосредственно с работающего MCP-сервера по протоколу HTTP.
Тестирование агента для конвертации валют в веб-интерфейсе ADK
Вы можете протестировать агент отдельно, используя веб-интерфейс разработки ADK. Во втором терминале выполните следующую команду:
uv run adk web --allow_origins "*" currency_agent
Откройте в браузере страницу http://localhost:8000 (или нажмите Web Preview (Предварительный просмотр) в Cloud Shell).

Спросите агента:
"Сколько будет 250 долларов США в евро?"
Вы увидите, как агент вызывает инструмент MCP get_exchange_rate и возвращает конвертированную сумму. Прежде чем продолжить, остановите процесс adk web с помощью Ctrl+C.
5. Протокол Agent2Agent (A2A)
Протокол Agent2Agent (A2A) – это открытый стандарт, разработанный для обеспечения связи и взаимодействия между ИИ-агентами.
В современных мультиагентных системах агенты часто создаются с помощью разных фреймворков (ADK, LangChain, CrewAI, AutoGen) и развертываются в разной инфраструктуре. A2A устраняет эти барьеры, определяя стандартизированный контракт на обмен данными.

Основные понятия A2A
- Обнаружение агентов (карточка агента). Каждый агент, соответствующий стандарту A2A, сообщает о своих возможностях, поддерживаемых режимах I/O, требованиях к аутентификации и навыках через стандартный JSON-файл, размещенный по адресу
/.well-known/agent-card.json. - Навыки агента (
AgentSkill). Определенные возможности или инструменты, которые может использовать агент. Другие агенты читают эти навыки, чтобы решить, когда делегировать задачи. - Обмен данными JSON-RPC. Агенты обмениваются структурированными сообщениями, задачами и артефактами по стандартным транспортным протоколам, таким как HTTP JSON-RPC 2.0.

На следующем шаге вы сделаете агент ADK Currency Agent доступным в качестве сервера A2A, чтобы другие агенты могли находить его и делегировать ему задачи по конвертации валют.
6. Как предоставить доступ к агенту валют в качестве сервера A2A
С помощью служебной функции to_a2a() ADK позволяет легко превратить любой LlmAgent в сервер, совместимый с A2A.
Проверьте нижнюю часть 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)
Помощник to_a2a() автоматически:
- Проверяет инструменты и инструкции
LlmAgent. - Генерирует
AgentCardA2A с описанием навыков (например,currency_agent-get_exchange_rate). - Оборачивает агент в приложение FastAPI (
a2a_app), поддерживающее конечные точки JSON-RPC. - Динамически настраивает рекламируемый
urlв карточке агента на основеAGENT_URL(или localhost).
Запустите сервер агента валют A2A
Во втором терминале запустите агент валют:
uv run python currency_agent/agent.py
Сервер запускается на порте 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)
Проверьте карточку агента
В браузере перейдите к конечной точке карточки агента: http://localhost:8081/.well-known/agent-card.json.
Вы увидите автоматически сгенерированные метаданные JSON:
{
"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"
]
}
]
}
Тестирование с помощью клиента A2A
Откройте третий терминал, перейдите в папку python (cd getting-started-mcp-a2a-adk/python) и протестируйте конечную точку A2A с помощью специального тестового клиентского скрипта A2A:
uv run python currency_agent/test_a2aclient.py
Клиент разрешает карточку агента с помощью A2ACardResolver и отправляет сообщение 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...
Агент валют теперь работает как полноценный сервер A2A!
7. Создание турагентства
Теперь вы создадите управляющего турагента. Этот агент демонстрирует, как агент ADK может легко комбинировать две разные парадигмы инструментов:
- Инструмент Local Agent (
weather_agent). Внутрипроцессный субагент ADK, работающий в той же среде выполнения Python, что позволяет избежать задержек, связанных с сетью или сериализацией. - Инструмент удаленного агента (
currency_agent). Внешний агент, подключенный по сети через протокол A2A с помощьюRemoteA2aAgent.
+-----------------------------+
| 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. Субагент "Местный прогноз погоды"
Посмотрите на 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],
)
Агент погоды – это LlmAgent с инструментом-функцией, который получает данные о погоде в реальном времени от wttr.in с надежным резервным вариантом.
2. Управляющий агент для турагентства
Теперь посмотрите на 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)
Основные моменты:
RemoteA2aAgentполучает карточку агента по валютам изhttp://localhost:8081/.well-known/agent-card.json.- И
currency_remote_agent, иweather_agentупакованы с помощьюAgentToolADK. - При непосредственном запуске
travel_agent/agent.pyзагружается веб-интерфейс ADK на порте8082с использованиемget_fast_api_app(web=True).
8. Запуск и тестирование мультиагентной системы локально
Теперь у вас есть все три компонента. Давайте запустим и протестируем всю систему локально.
Запуск всех трех сервисов
Убедитесь, что сервисы запущены в трех отдельных окнах терминала (из каталога getting-started-mcp-a2a-adk/python) в следующем порядке:
Терминал 1 (MCP-сервер для валют):
uv run python currency_mcp_server/server.py
(Running on port 8080)
Терминал 2 (A2A-агент по обмену валюты):
uv run python currency_agent/agent.py
(Работает на порту 8081)
Терминал 3 (турагентство с веб-интерфейсом)
uv run python travel_agent/agent.py
(работает на порту 8082)
Тестирование в веб-интерфейсе ADK
Откройте в браузере страницу http://localhost:8082 (или используйте Web Preview на порте 8082 в Cloud Shell).
Задайте турагенту составной вопрос, требующий использования обоих инструментов:
"Я планирую поездку в Лондон. Какая сейчас погода и сколько будет 200 евро в фунтах стерлингов?"
Посмотрите, как выполняется код:
- Турагент получает запрос в веб-интерфейсе.
- Оно передает вопрос о погоде локальному
weather_agent, который получает текущие условия отwttr.in. - Он делегирует конвертацию валюты по протоколу A2A агенту
currency_agentна порту 8081. currency_agentвызываетcurrency_mcp_serverчерез порт 8080 по протоколу MCP, чтобы получить обменный курс.- Все результаты будут обобщены и представлены в виде единого полезного ответа.

Тестирование с помощью командной строки
Вы также можете тестировать запросы непосредственно из CLI, не открывая браузер:
uv run adk run travel_agent "What is the weather in London and how much is 100 USD in EUR?"
Теперь, когда все работает на вашем локальном компьютере, давайте развернем всю систему в Google Cloud Run.
9. Развертывание системы из нескольких агентов в Cloud Run
У каждого компонента есть собственный файл Dockerfile и автономный файл pyproject.toml, поэтому его можно создать и развернуть в Cloud Run независимо от других.
С помощью gcloud вы развернете каждый сервис и автоматически свяжете их URL.
Как настроить переменные среды
Укажите идентификатор проекта Cloud и целевой регион:
export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
export REGION=us-central1
Шаг 1. Разверните MCP-сервер Currency
Разверните MCP-сервер непосредственно из источника:
# 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"
Шаг 2. Разверните агент валют
Поскольку общедоступный URL сервиса currency-agent назначается при его первом развертывании, сначала разверните сервис, скопируйте его URL и обновите переменную среды AGENT_URL, чтобы в карточке A2A-агента был указан правильный общедоступный HTTPS-адрес.
# 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"
Шаг 3. Разверните Travel Agent
Теперь разверните турагента, настроив его с помощью 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. Тестирование системы из нескольких агентов в Cloud Run
После развертывания всех трех микросервисов давайте проверим каждый уровень в Cloud Run.
1. Протестируйте удаленный MCP-сервер
Протестируйте развернутый MCP-сервер Cloud Run из командной строки:
MCP_SERVER_URL="$MCP_SERVER_URL" uv run python currency_mcp_server/test_server.py
Вы должны увидеть инструмент в списке и сообщение о том, что он успешно вызван в Cloud Run.
2. Протестируйте валютного агента через A2A
Протестируйте развернутый агент валют с помощью тестового клиента A2A:
AGENT_URL="$CURRENCY_AGENT_URL" uv run python currency_agent/test_a2aclient.py
Клиент получит удаленную карточку агента из Cloud Run и будет обмениваться сообщениями по протоколу HTTPS JSON-RPC.
3. Тестирование веб-интерфейса турагентства в Cloud Run
Откройте $TRAVEL_AGENT_URL в браузере.
Веб-интерфейс ADK полностью обслуживается Cloud Run. Примеры вопросов:
"Я планирую поездку в Токио. Какая там погода и сколько будет 500 долларов США в японских иенах?"
[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)
Все три сервиса масштабируются независимо друг от друга в бессерверной инфраструктуре и взаимодействуют по открытым протоколам.
11. Поздравления и уборка
Что вы сделали
Поздравляем! Вы создали и развернули систему из нескольких агентов, готовую к использованию в рабочей среде:
- Model Context Protocol (MCP). Создан сервер FastMCP, который предоставляет доступ к инструментам API через Streamable HTTP.
- Agent Development Kit (ADK). Создание модульных агентов с помощью
LlmAgent, подключение инструментов MCP с помощьюMcpToolsetи размещение веб-интерфейса ADK. - Протокол Agent2Agent (A2A). Вы предоставили доступ к агенту как к сервису A2A (
to_a2a), опубликовали карточки агентов (agent-card.json) и использовали удаленных агентов с помощьюRemoteA2aAgent. - Мультиагентная архитектура. Объединение локальных внутрипроцессных субагентов (
weather_agent) с распределенными удаленными агентами (currency_agent). - Бессерверное развертывание Cloud Run. Контейнеризация и развертывание всех трех сервисов с автоматической настройкой конфигурации.
Полный код (включая реализации на Python и Java) и будущие обновления доступны в репозитории getting-started-mcp-a2a-adk.
Организовать
Чтобы избежать списания средств с вашего аккаунта Google Cloud за сервисы Cloud Run, созданные в этой практической работе, выполните следующие действия:
Удалите развернутые сервисы Cloud Run:
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
Если вы создали отдельный проект для этой практической работы, вы можете удалить его целиком.
gcloud projects delete $PROJECT_ID