1. Введение
В этой лабораторной работе мы рассмотрим реализацию и развёртывание службы клиентского агента. Вам предстоит использовать Agent Development Kit (ADK) для создания ИИ-агента, использующего удалённые инструменты, такие как сервер MCP, созданный в лабораторной работе 1. Ключевым архитектурным принципом, продемонстрированным в работе, является разделение задач: отдельный уровень логики (агент) взаимодействует с отдельным уровнем инструментов (сервер MCP) через защищённый API.
В лабораторной работе 1 вы создали MCP-сервер, предоставляющий данные о животных в вымышленном зоопарке студентам магистратуры (LLM), например, с помощью Gemini CLI. В этой лабораторной работе мы создаём агента-экскурсовода для вымышленного зоопарка. Агент будет использовать тот же MCP-сервер из лабораторной работы 1 для доступа к информации о животных зоопарка, а также использовать Википедию для создания наилучшего опыта работы экскурсовода.

Наконец, мы развернем агента-экскурсовода в Google Cloud Run, чтобы к нему могли получить доступ все посетители зоопарка, а не только он работал локально.
Предпосылки
- Работающий сервер MCP на Cloud Run или связанный с ним URL-адрес службы.
- Проект Google Cloud с включенным биллингом.
Чему вы научитесь
- Как структурировать проект Python для развертывания ADK.
- Как реализовать агент, использующий инструмент, с помощью google-adk.
- Как подключить агента к удаленному серверу MCP для его набора инструментов.
- Как развернуть приложение Python в качестве бессерверного контейнера в Cloud Run.
- Как настроить безопасную аутентификацию между службами с использованием ролей IAM.
- Как удалить облачные ресурсы, чтобы избежать будущих затрат.
Что вам понадобится
- Учетная запись Google Cloud и проект Google Cloud
- Веб-браузер, такой как Chrome
2. Зачем развертывать решение в Cloud Run?
Cloud Run — отличный выбор для хостинга агентов ADK, поскольку это бессерверная платформа, позволяющая вам сосредоточиться на коде, а не на управлении базовой инфраструктурой. Мы берём на себя все операционные задачи.
Представьте себе временный магазин: он открывается и использует ресурсы только при поступлении клиентов (заявок). Когда клиентов нет, он полностью закрывается, и вам не нужно платить за пустой магазин.
Ключевые особенности
Запускает контейнеры где угодно:
- Вы переносите контейнер (образ Docker), содержащий ваше приложение.
- Cloud Run работает на инфраструктуре Google.
- Никаких проблем с обновлением ОС, настройкой виртуальных машин или масштабированием.
Автоматическое масштабирование:
- Если вашим приложением пользуются 0 человек → запускается 0 экземпляров (масштабируется до нуля экземпляров, что экономически эффективно).
- Если поступает 1000 запросов → он создает столько копий, сколько необходимо.
Без сохранения состояния по умолчанию:
- Каждый запрос может быть направлен в отдельный экземпляр.
- Если вам необходимо сохранить состояние, используйте внешний сервис, например Cloud SQL, Firestore или Memorystore.
Поддерживает любой язык или фреймворк:
- Пока Cloud Run работает в контейнере Linux, ему неважно, какой язык программирования используется: Python, Go, Node.js, Java или .Net.
Платите за то, что используете:
- Тарификация на основе запросов : оплата за запрос + время вычислений (до 100 мс).
- Тарификация на основе экземпляров : оплата взимается за весь срок службы экземпляра (без платы за запрос).
3. Настройка и требования
Настройка среды для самостоятельного обучения
- Войдите в Google Cloud Console и создайте новый проект или используйте существующий. Если у вас ещё нет учётной записи Gmail или Google Workspace, вам необходимо её создать .



- Название проекта — отображаемое имя участников проекта. Это строка символов, не используемая API Google. Вы можете изменить её в любой момент.
- Идентификатор проекта уникален для всех проектов Google Cloud и неизменяем (нельзя изменить после установки). Cloud Console автоматически генерирует уникальную строку; обычно вам не важно, какой именно. В большинстве практических работ вам потребуется указать идентификатор проекта (обычно обозначаемый как
PROJECT_ID). Если вам не нравится сгенерированный идентификатор, вы можете сгенерировать другой случайный идентификатор. Вы также можете попробовать использовать свой собственный идентификатор и посмотреть, доступен ли он. После этого шага его нельзя будет изменить, и он останется на протяжении всего проекта. - К вашему сведению, существует третье значение — номер проекта , который используется некоторыми API. Подробнее обо всех трёх значениях можно узнать в документации .
- Далее вам нужно включить биллинг в Cloud Console для использования облачных ресурсов/API. Выполнение этой лабораторной работы не потребует больших затрат, если вообще потребует. Чтобы отключить ресурсы и избежать списания средств за пределами этого руководства, вы можете удалить созданные вами ресурсы или проект. Новые пользователи Google Cloud могут воспользоваться бесплатной пробной версией стоимостью 300 долларов США .
Запустить Cloud Shell
Перейдите в редактор Cloud Shell.
Если терминал не отображается внизу экрана, откройте его:
- Нажмите «Терминал»
- Нажмите «Новый терминал».

В терминале настройте свой проект с помощью этой команды. Если вы выполнили лабораторную работу 1, убедитесь, что вы используете тот же идентификатор проекта:
gcloud config set project [YOUR-PROJECT-ID]
Если вы не можете вспомнить идентификатор своего проекта, вы можете вывести список всех идентификаторов своих проектов с помощью:
gcloud projects list | awk '/PROJECT_ID/{print $2}'
4. Если будет предложено авторизоваться, нажмите «Авторизовать» , чтобы продолжить.

5. Вы должны увидеть это сообщение:
Updated property [core/project].
If you see a `WARNING` and are asked `Do you want to continue (Y/n)?`,
then you have likely entered the project ID incorrectly. Press `n`,
press `Enter`, and try to run the `gcloud config set project` command again.
4. Прежде чем начать
Включить API и задать переменные среды
Включите все необходимые службы:
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
cloudbuild.googleapis.com \
aiplatform.googleapis.com \
compute.googleapis.com
Ожидаемый результат
Operation "operations/acat.p2-[GUID]" finished successfully.
5. Создайте папку проекта.
Создайте каталог проекта.
Эта команда создает основную папку лаборатории для исходного кода агента.
cd && mkdir zoo_guide_agent && cd zoo_guide_agent
Создайте файл requirements.txt . В этом файле перечислены библиотеки Python, необходимые вашему агенту. Следующая команда создаёт этот файл и заполняет его.
cloudshell edit requirements.txt
google-adk==1.14.0
langchain-community==0.3.27
wikipedia==1.4.0
Задайте переменные для текущего проекта, региона и пользователя. Это более надёжный способ выполнения этих команд.
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export SERVICE_ACCOUNT="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
Создайте и откройте файл .env для аутентификации агента в каталоге zoo_guide_agent .
cloudshell edit .env
Команда редактирования Cloudshell откроет файл .env в редакторе над терминалом. Введите в .env следующее и вернитесь в терминал.
MODEL="gemini-2.5-flash"
SERVICE_ACCOUNT="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
Добавление URL-адреса сервера MCP . Если вы выполнили лабораторную работу 1, выполните следующие действия, чтобы использовать созданный в ней сервер MCP:
- Предоставьте удостоверению службы Cloud Run разрешение на вызов удаленного сервера MCP.
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT" \
--role="roles/run.invoker"
- Сохраните URL-адрес сервера MCP из лабораторной работы 1 в переменной среды.
echo -e "\nMCP_SERVER_URL=https://zoo-mcp-server-${PROJECT_NUMBER}.europe-west1.run.app/mcp" >> .env
Если вы используете ссылку на публичный сервер MCP, выполните следующую команду и замените PROJECT_NUMBER на предоставленный адрес.
echo -e "\nMCP_SERVER_URL=https://zoo-mcp-server-${PROJECT_NUMBER}.europe-west1.run.app/mcp" >> .env
6. Создание рабочего процесса агента
Создать файл init .py
Создайте файл init .py. Этот файл сообщает Python, что каталог zoo_guide_agent — это пакет.
cloudshell edit __init__.py
Приведённая выше команда открывает редактор кода. Добавьте следующий код в файл __init__.py :
from . import agent
Создать основной файл agent.py
Создайте основной файл agent.py. Эта команда создаст файл Python и вставит в него полный код вашей многоагентной системы.
cloudshell edit agent.py
Шаг 1: Импорт и начальная настройка
Этот первый блок подключает все необходимые библиотеки из ADK и Google Cloud. Он также настраивает ведение журнала и загружает переменные среды из вашего файла .env , что критически важно для доступа к вашей модели и URL-адресу сервера.
Добавьте следующий код в файл agent.py:
import os
import logging
import google.cloud.logging
from dotenv import load_dotenv
from google.adk import Agent
from google.adk.agents import SequentialAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StreamableHTTPConnectionParams
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.langchain_tool import LangchainTool
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
import google.auth
import google.auth.transport.requests
import google.oauth2.id_token
# --- Setup Logging and Environment ---
cloud_logging_client = google.cloud.logging.Client()
cloud_logging_client.setup_logging()
load_dotenv()
model_name = os.getenv("MODEL")
Шаг 2: Определение инструментов (возможностей агента)

Эффективность агента напрямую зависит от инструментов, которые он может использовать. В этом разделе мы определим все возможности нашего агента, включая специальную функцию сохранения данных, инструмент MCP, подключающийся к нашему защищённому серверу MCP, и инструмент Wikipedia.
Добавьте следующий код в конец agent.py:
# Greet user and save their prompt
def add_prompt_to_state(
tool_context: ToolContext, prompt: str
) -> dict[str, str]:
"""Saves the user's initial prompt to the state."""
tool_context.state["PROMPT"] = prompt
logging.info(f"[State updated] Added to PROMPT: {prompt}")
return {"status": "success"}
# Configuring the MCP Tool to connect to the Zoo MCP server
mcp_server_url = os.getenv("MCP_SERVER_URL")
if not mcp_server_url:
raise ValueError("The environment variable MCP_SERVER_URL is not set.")
def get_id_token():
"""Get an ID token to authenticate with the MCP server."""
target_url = os.getenv("MCP_SERVER_URL")
audience = target_url.split('/mcp/')[0]
request = google.auth.transport.requests.Request()
id_token = google.oauth2.id_token.fetch_id_token(request, audience)
return id_token
"""
# Use this code if you are using the public MCP Server and comment out the code below defining mcp_tools
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url
)
)
"""
mcp_tools = MCPToolset(
connection_params=StreamableHTTPConnectionParams(
url=mcp_server_url,
headers={
"Authorization": f"Bearer {get_id_token()}",
},
),
)
# Configuring the Wikipedia Tool
wikipedia_tool = LangchainTool(
tool=WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
)
Объяснение трех инструментов
-
add_prompt_to_state📝
Этот инструмент запоминает вопросы посетителей зоопарка. Когда посетитель спрашивает: «Где львы?», инструмент сохраняет этот вопрос в памяти агента, чтобы другие агенты в рабочем процессе знали, что исследовать.
Как: Это функция Python, которая записывает запрос посетителя в общий словарь tool_context.state . Этот контекст инструмента представляет собой кратковременную память агента для отдельного диалога. Данные, сохранённые в состоянии одним агентом, могут быть прочитаны следующим агентом в рабочем процессе.
-
MCPToolset🦁
Он используется для подключения агента-гида к серверу MCP зоопарка, созданному в Лабораторной работе 1. На этом сервере имеются специальные инструменты для поиска конкретной информации о наших животных, например, их имени, возрасте и номере вольера.
Как: он безопасно подключается к URL-адресу частного сервера зоопарка. Он использует get_id_token для автоматического получения защищённой «карты-ключа» (токена идентификатора учётной записи сервиса) для подтверждения личности и получения доступа.
-
LangchainTool🌍
This gives the tour guide agent general world knowledge. When a visitor asks a question that isn't in the zoo's database, like "What do lions eat in the wild?", this tool lets the agent look up the answer on Wikipedia.
Как: Он действует как адаптер, позволяя нашему агенту использовать готовый инструмент WikipediaQueryRun из библиотеки LangChain.
Ресурсы:
Шаг 3: Определение специализированных агентов
Далее мы определим агента-исследователя и агента форматирования ответов. Агент-исследователь — это «мозг» нашей операции. Этот агент получает запрос пользователя из общего State , анализирует его мощные инструменты (инструмент MCP Server от Zoo и инструмент Wikipedia) и решает, какие из них использовать для поиска ответа.
Роль агента форматирования ответов заключается в представлении информации. Он не использует инструменты для поиска новой информации. Вместо этого он берёт необработанные данные, собранные агентом-исследователем (переданные через состояние), и, используя языковые навыки магистра права (LLM), преобразует их в понятный, разговорный ответ.
Добавьте следующий код в конец agent.py :
# 1. Researcher Agent
comprehensive_researcher = Agent(
name="comprehensive_researcher",
model=model_name,
description="The primary researcher that can access both internal zoo data and external knowledge from Wikipedia.",
instruction="""
You are a helpful research assistant. Your goal is to fully answer the user's PROMPT.
You have access to two tools:
1. A tool for getting specific data about animals AT OUR ZOO (names, ages, locations).
2. A tool for searching Wikipedia for general knowledge (facts, lifespan, diet, habitat).
First, analyze the user's PROMPT.
- If the prompt can be answered by only one tool, use that tool.
- If the prompt is complex and requires information from both the zoo's database AND Wikipedia,
you MUST use both tools to gather all necessary information.
- Synthesize the results from the tool(s) you use into preliminary data outputs.
PROMPT:
{{ PROMPT }}
""",
tools=[
mcp_tools,
wikipedia_tool
],
output_key="research_data" # A key to store the combined findings
)
# 2. Response Formatter Agent
response_formatter = Agent(
name="response_formatter",
model=model_name,
description="Synthesizes all information into a friendly, readable response.",
instruction="""
You are the friendly voice of the Zoo Tour Guide. Your task is to take the
RESEARCH_DATA and present it to the user in a complete and helpful answer.
- First, present the specific information from the zoo (like names, ages, and where to find them).
- Then, add the interesting general facts from the research.
- If some information is missing, just present the information you have.
- Be conversational and engaging.
RESEARCH_DATA:
{{ research_data }}
"""
)
Шаг 4: Агент рабочего процесса
Агент рабочего процесса выступает в роли менеджера «бэк-офиса» для экскурсии по зоопарку. Он принимает запрос на исследование и следит за тем, чтобы два агента, которых мы определили выше, выполняли свои задачи в правильном порядке: сначала исследование, затем форматирование. Это обеспечивает предсказуемый и надёжный процесс ответа на вопрос посетителя.
Как: Это SequentialAgent — особый тип агента, который не мыслит самостоятельно. Его единственная задача — запускать список sub_agents (исследователь и форматировщик) в фиксированной последовательности, автоматически передавая общую память от одного к другому.
Добавьте этот блок кода в конец agent.py :
tour_guide_workflow = SequentialAgent(
name="tour_guide_workflow",
description="The main workflow for handling a user's request about an animal.",
sub_agents=[
comprehensive_researcher, # Step 1: Gather all data
response_formatter, # Step 2: Format the final response
]
)
Последний шаг: сборка основного рабочего процесса 
Этот агент обозначается как root_agent , и фреймворк ADK использует его в качестве отправной точки для всех новых диалогов. Его основная роль — координировать весь процесс. Он выступает в роли начального контроллера, управляя первым этапом диалога.
Добавьте этот последний блок кода в конец agent.py :
root_agent = Agent(
name="greeter",
model=model_name,
description="The main entry point for the Zoo Tour Guide.",
instruction="""
- Let the user know you will help them learn about the animals we have in the zoo.
- When the user responds, use the 'add_prompt_to_state' tool to save their response.
After using the tool, transfer control to the 'tour_guide_workflow' agent.
""",
tools=[add_prompt_to_state],
sub_agents=[tour_guide_workflow]
)
Ваш файл agent.py готов! Создав его таким образом, вы увидите, какую роль каждый компонент — инструменты, рабочие агенты и управляющие агенты — играет в создании конечной интеллектуальной системы. Теперь — развёртывание!
7. Подготовьте заявку к развертыванию.
После подготовки локальной среды следующим шагом станет подготовка проекта Google Cloud к развертыванию. Это включает в себя финальную проверку файловой структуры вашего агента на совместимость с командой развертывания. Что ещё важнее, вы настраиваете критически важное разрешение IAM, которое позволяет вашему развёрнутому сервису Cloud Run действовать от вашего имени и вызывать модели Vertex AI. Выполнение этого шага гарантирует готовность облачной среды к успешному запуску вашего агента.
Загрузите переменные в сеанс оболочки, выполнив команду source.
source .env
Предоставьте учетной записи службы роль пользователя Vertex AI, которая даст ей разрешение делать прогнозы и вызывать модели Google.
# Grant the "Vertex AI User" role to your service account
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:$SERVICE_ACCOUNT" \
--role="roles/aiplatform.user"
8. Разверните агент с помощью ADK CLI.
После того, как ваш локальный код и проект Google Cloud готовы, пришло время развернуть агент. Вы воспользуетесь командой adk deploy cloud_run — удобным инструментом для автоматизации всего процесса развёртывания. Эта команда упаковывает ваш код, создаёт образ контейнера, отправляет его в реестр артефактов и запускает службу в Cloud Run, делая её доступной через веб.
Развертывать
Выполните следующие команды для развёртывания агента. Команда uvx позволяет запускать инструменты командной строки, опубликованные в виде пакетов Python, без необходимости их глобальной установки.
# Run the deployment command
uvx --from google-adk \
adk deploy cloud_run \
--project=$PROJECT_ID \
--region=europe-west1 \
--service_name=zoo-tour-guide \
--with_ui \
. \
-- \
--labels=dev-tutorial=codelab-adk
Принять запросы
Вам может быть предложено следующее:
Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [europe-west1] will be created. Do you want to continue (Y/n)?
Введите Y и нажмите ENTER.
Вам может быть предложено следующее:
Allow unauthenticated invocations to [your-service-name] (y/N)?.
Для этой лабораторной работы мы хотим разрешить неаутентифицированные вызовы для упрощения тестирования, введите y и нажмите Enter.
Получить ссылку на развертывание
После успешного выполнения команда предоставит URL-адрес развёрнутого сервиса Cloud Run. (Он будет выглядеть примерно так: https://zoo-tour-guide-123456789.europe-west1.run.app ). Скопируйте этот URL-адрес для следующей задачи.
9. Протестируйте развернутый агент.
Теперь, когда ваш агент запущен в Cloud Run, вам нужно будет выполнить тест, чтобы убедиться, что развёртывание прошло успешно и агент работает должным образом. Для доступа к веб-интерфейсу ADK и взаимодействия с агентом вам потребуется использовать общедоступный URL-адрес сервиса (например, https://zoo-tour-guide-123456789.europe-west1.run.app/ ).
Откройте URL-адрес общедоступной службы Cloud Run в веб-браузере. Поскольку вы использовали --with_ui flag , вы должны увидеть интерфейс разработчика ADK.
Включите функцию Token Streaming в правом верхнем углу.
Теперь вы можете взаимодействовать с агентом Zoo.
Введите hello и нажмите Enter, чтобы начать новый разговор.
Наблюдайте за результатом. Агент должен быстро отреагировать приветствием:
"Hello! I'm your Zoo Tour Guide. I can help you learn about the amazing animals we have here. What would you like to know or explore today?"
Задайте агенту такие вопросы:
Where can I find the polar bears in the zoo and what is their diet?


Объяснение потока агентов
Ваша система работает как интеллектуальная многоагентная команда. Процесс управляется чёткой последовательностью, обеспечивающей плавный и эффективный переход от вопроса пользователя к окончательному, подробному ответу.
1. Сотрудник зоопарка (стойка регистрации )
Весь процесс начинается с встречающего агента.
Его задача: начать разговор. Его задача — поприветствовать пользователя и спросить, о каком животном он хотел бы узнать.
Его инструмент: когда пользователь отвечает, Greeter использует свой инструмент add_prompt_to_state, чтобы записать точные слова (например, «расскажите мне о львах») и сохранить их в памяти системы.
Передача: после сохранения подсказки управление немедленно передается ее субагенту tour_guide_workflow.
2. Всесторонний исследователь (суперисследователь)
Это первый шаг основного рабочего процесса и «мозг» операции. Вместо большой команды теперь у вас есть один высококвалифицированный агент, имеющий доступ ко всей доступной информации.
Его задача: проанализировать вопрос пользователя и сформировать разумный план. Он использует мощные возможности языковой модели, чтобы определить, необходимо ли:
- Внутренние данные из записей зоопарка (через сервер MCP).
- Общие знания из Интернета (через API Википедии).
- Или, в случае сложных вопросов, и то, и другое.
Действие: выполняет необходимые инструменты для сбора всех необходимых исходных данных. Например, если задать вопрос «Сколько лет нашим львам и чем они питаются в дикой природе?», он обратится к серверу MCP за информацией о возрасте и к инструменту Wikipedia за информацией об их рационе.
3. Форматировщик ответов (Представитель)
После того, как всесторонний исследователь собрал все факты, это последний агент, который нужно запустить.
Его задача: выступать в роли дружелюбного гида зоопарка. Он принимает необработанные данные (которые могут быть получены из одного или обоих источников) и обрабатывает их.
Действие: синтезирует всю информацию в единый, связный и увлекательный ответ. Следуя инструкциям, сначала представляет конкретную информацию о зоопарке, а затем добавляет интересные общие факты.
Конечный результат: текст, сгенерированный этим агентом, представляет собой полный, подробный ответ, который пользователь видит в окне чата.
Если вам интересно узнать больше о строительных агентах, ознакомьтесь со следующими ресурсами:
10. Очистите окружающую среду
gcloud run services delete zoo-tour-guide --region=europe-west1 --quiet
gcloud artifacts repositories delete cloud-run-source-deploy --location=europe-west1 --quiet
11. Поздравления
Поздравляем с завершением лабораторной работы.
Что мы рассмотрели
- Как структурировать проект Python для развертывания с помощью интерфейса командной строки ADK.
- Как реализовать многоагентный рабочий процесс с использованием SequentialAgent и ParallelAgent.
- Как подключиться к удаленному серверу MCP с помощью MCPToolset для использования его инструментов.
- Как дополнить внутренние данные путем интеграции внешних инструментов, таких как API Википедии.
- Как развернуть агент как бессерверный контейнер в Cloud Run с помощью команды adk deploy.
12. Опрос
Выход:
