1. 📖 Введение
В предыдущем практическом занятии вы узнали, как разработать многомодальное взаимодействие с данными в ADK. Теперь мы сделаем следующий шаг и рассмотрим, как разработать многомодальное взаимодействие с данными с помощью MCP Server, используя MCP Toolset. Мы расширим возможности ранее разработанного агента для редактирования фотографий, добавив возможность создания коротких видеороликов с использованием модели Veo и Veo MCP Server.
В ходе выполнения практического задания вы будете использовать следующий пошаговый подход:
- Подготовьте проект Google Cloud и базовый каталог агентов.
- Настройте MCP-сервер, которому требуются файловые данные в качестве входных данных.
- Подготовка агента ADK к подключению к серверу MCP.
- Разработайте стратегию обработки запросов и функцию обратного вызова для изменения запроса на вызов функции к набору инструментов MCP.
- Разработайте функцию обратного вызова для обработки многомодальных данных, поступающих от инструментария MCP.
Обзор архитектуры
Общее взаимодействие в данной практической работе показано на следующей диаграмме.

Предварительные требования
- Уверенно работаю с Python.
- (Необязательно) Базовые практические занятия по работе с комплектом разработки агентов (ADK)
- (Необязательно) Практический урок по использованию мультимодального инструмента ADK, часть 1: goo.gle/adk-multimodal-tool-1
Что вы узнаете
- Как создать короткое видео с помощью Veo 3.1, используя подсказку и изображение в качестве отправной точки.
- Как разработать многомодальный MCP-сервер с использованием FastMCP
- Как настроить ADK для использования MCP Toolset
- Как изменить вызов инструмента MCP Toolset через функцию обратного вызова инструмента?
- Как изменить ответ инструмента от MCP Toolset через функцию обратного вызова инструмента.
Что вам понадобится
- Веб-браузер Chrome
- Аккаунт Gmail
- Облачный проект с включенным платежным аккаунтом.
Этот практический урок, разработанный для разработчиков всех уровней (включая начинающих), использует Python в качестве примера приложения. Однако знание Python не требуется для понимания представленных концепций.
2. 🚀 (Необязательно) Подготовка к настройке процесса разработки.
Шаг 1: Выберите активный проект в облачной консоли.
В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud (см. раздел в левом верхнем углу консоли).

Нажмите на него, и вы увидите список всех ваших проектов, как в этом примере.

Значение, обозначенное красной рамкой, — это идентификатор проекта , и это значение будет использоваться на протяжении всего урока.
Убедитесь, что для вашего облачного проекта включена оплата. Для этого нажмите на значок меню (гамбургер) ☰ в верхнем левом углу панели, где отображается меню навигации, и найдите пункт «Оплата».

Если в разделе «Биллинг / Обзор » ( в верхнем левом углу консоли облачных сервисов ) вы видите пункт «Пробный платёжный аккаунт Google Cloud Platform» , значит, ваш проект готов к использованию в этом руководстве. В противном случае вернитесь к началу руководства и активируйте пробный платёжный аккаунт.

Шаг 2: Ознакомьтесь с Cloud Shell.
В большинстве руководств вы будете использовать Cloud Shell . Нажмите «Активировать Cloud Shell» в верхней части консоли Google Cloud. Если система запросит авторизацию, нажмите «Авторизовать».


После подключения к Cloud Shell нам потребуется проверить, авторизована ли оболочка (или терминал) уже с использованием нашей учетной записи.
gcloud auth list
Если вы видите в своей личной почте Gmail результат, как в приведенном ниже примере, значит, все в порядке.
Credentialed Accounts
ACTIVE: *
ACCOUNT: alvinprayuda@gmail.com
To set the active account, run:
$ gcloud config set account `ACCOUNT`
Если это не поможет, попробуйте обновить страницу в браузере и обязательно нажмите кнопку « Авторизовать» , когда появится соответствующий запрос (возможно, авторизация прервалась из-за проблем с подключением).
Далее нам также необходимо проверить, настроена ли оболочка уже для правильного идентификатора проекта (PROJECT ID ). Если вы видите значение внутри скобок ( ) перед значком $ в терминале (на скриншоте ниже значение — "adk-multimodal-tool" ), это значение показывает настроенный проект для вашей активной сессии оболочки.

Если отображаемое значение уже верное , вы можете пропустить следующую команду . Однако, если оно неверно или отсутствует, выполните следующую команду.
gcloud config set project <YOUR_PROJECT_ID>
Затем клонируйте рабочую директорию шаблона для этого практического занятия из Github и выполните следующую команду. Она создаст рабочую директорию в каталоге adk-multimodal-tool.
git clone https://github.com/alphinside/adk-mcp-multimodal.git adk-multimodal-tool
Шаг 3: Ознакомьтесь с редактором Cloud Shell и настройте рабочий каталог приложения.
Теперь мы можем настроить наш редактор кода для выполнения некоторых действий по программированию. Для этого мы будем использовать редактор Cloud Shell.
Нажмите кнопку «Открыть редактор» , это откроет редактор Cloud Shell. 
После этого перейдите в верхнюю часть редактора Cloud Shell и нажмите «Файл» -> «Открыть папку», найдите каталог с вашим именем пользователя и найдите каталог adk-multimodal-tool, затем нажмите кнопку «ОК». Это сделает выбранный каталог основным рабочим каталогом. В этом примере имя пользователя — alvinprayuda , поэтому путь к каталогу показан ниже.


Теперь ваша рабочая директория в Cloud Shell Editor должна выглядеть следующим образом (внутри adk-multimodal-tool ):

Теперь откройте терминал для редактора. Это можно сделать, щелкнув «Терминал» -> «Новый терминал» в строке меню, или используя Ctrl + Shift + C — это откроет окно терминала в нижней части браузера.

Ваш текущий активный терминал должен находиться в рабочей директории adk-multimodal-tool . В этом практическом занятии мы будем использовать Python 3.12 и менеджер проектов Python uv для упрощения создания и управления версиями Python и виртуальными средами. Этот пакет uv уже предустановлен в Cloud Shell.
Выполните эту команду, чтобы установить необходимые зависимости в виртуальное окружение в каталоге .venv.
uv sync --frozen
Проверьте файл pyproject.toml , чтобы увидеть объявленные зависимости для этого руководства: google-adk, and python-dotenv .
Теперь нам нужно будет включить необходимые API с помощью команды, показанной ниже. Это может занять некоторое время.
gcloud services enable aiplatform.googleapis.com
После успешного выполнения команды вы должны увидеть сообщение, похожее на показанное ниже:
Operation "operations/..." finished successfully.
Структура шаблона агента уже предоставлена вам в каталоге part2_starter_agent в клонированном репозитории. Теперь нам нужно сначала переименовать его, чтобы он был готов к этому руководству.
mv part1_ckpt_agent product_photo_editor
После этого скопируйте файл product_photo_editor/.env.example в файл product_photo_editor/.env.
cp product_photo_editor/.env.example product_photo_editor/.env
Открыв файл product_photo_editor/.env , вы увидите содержимое, показанное ниже.
GOOGLE_GENAI_USE_VERTEXAI=1
GOOGLE_CLOUD_PROJECT=your-project-id
GOOGLE_CLOUD_LOCATION=global
Затем вам потребуется обновить значение your-project-id , указав правильный идентификатор вашего проекта. Теперь мы готовы к следующему шагу.
3. 🚀 Инициализируйте сервер Veo MCP.
Для начала создадим каталог службы MCP с помощью этой команды.
mkdir veo_mcp
Затем создайте файл veo_mcp/main.py , используя эту команду.
touch veo_mcp/main.py
После этого скопируйте следующий код в файл veo_mcp/main.py.
from fastmcp import FastMCP
from typing import Annotated
from pydantic import Field
import base64
import asyncio
import os
from google import genai
from google.genai import types
from dotenv import load_dotenv
import logging
# Load environment variables from .env file
load_dotenv()
mcp = FastMCP("Veo MCP Server")
@mcp.tool
async def generate_video_with_image(
prompt: Annotated[
str, Field(description="Text description of the video to generate")
],
image_data: Annotated[
str, Field(description="Base64-encoded image data to use as starting frame")
],
negative_prompt: Annotated[
str | None,
Field(description="Things to avoid in the generated video"),
] = None,
) -> dict:
"""Generates a professional product marketing video from text prompt and starting image using Google's Veo API.
This function uses an image as the first frame of the generated video and automatically
enriches your prompt with professional video production quality guidelines to create
high-quality marketing assets suitable for commercial use.
AUTOMATIC ENHANCEMENTS APPLIED:
- 4K cinematic quality with professional color grading
- Smooth, stabilized camera movements
- Professional studio lighting setup
- Shallow depth of field for product focus
- Commercial-grade production quality
- Marketing-focused visual style
PROMPT WRITING TIPS:
Describe what you want to see in the video. Focus on:
- Product actions/movements (e.g., "rotating slowly", "zooming into details")
- Desired camera angles (e.g., "close-up of the product", "wide shot")
- Background/environment (e.g., "minimalist white backdrop", "lifestyle setting")
- Any specific details about the product presentation
The system will automatically enhance your prompt with professional production quality.
Args:
prompt: Description of the video to generate. Focus on the core product presentation
you want. The system will automatically add professional quality enhancements.
image_data: Base64-encoded image data to use as the starting frame
negative_prompt: Optional prompt describing what to avoid in the video
Returns:
dict: A dictionary containing:
- status: 'success' or 'error'
- message: Description of the result
- video_data: Base64-encoded video data (on success only)
"""
try:
# Initialize the Gemini client
client = genai.Client(
vertexai=True,
project=os.getenv("GOOGLE_CLOUD_PROJECT"),
location=os.getenv("GOOGLE_CLOUD_LOCATION"),
)
# Decode the image
image_bytes = base64.b64decode(image_data)
print(f"Successfully decoded image data: {len(image_bytes)} bytes")
# Create image object
image = types.Image(image_bytes=image_bytes, mime_type="image/png")
# Prepare the config
config = types.GenerateVideosConfig(
duration_seconds=8,
number_of_videos=1,
)
if negative_prompt:
config.negative_prompt = negative_prompt
# Enrich the prompt for professional marketing quality
enriched_prompt = enrich_prompt_for_marketing(prompt)
# Generate the video (async operation)
operation = client.models.generate_videos(
model="veo-3.1-generate-preview",
prompt=enriched_prompt,
image=image,
config=config,
)
# Poll until the operation is complete
poll_count = 0
while not operation.done:
poll_count += 1
print(f"Waiting for video generation to complete... (poll {poll_count})")
await asyncio.sleep(5)
operation = client.operations.get(operation)
# Download the video and convert to base64
video = operation.response.generated_videos[0]
# Get video bytes and encode to base64
video_bytes = video.video.video_bytes
video_base64 = base64.b64encode(video_bytes).decode("utf-8")
print(f"Video generated successfully: {len(video_bytes)} bytes")
return {
"status": "success",
"message": f"Video with image generated successfully after {poll_count * 5} seconds",
"complete_prompt": enriched_prompt,
"video_data": video_base64,
}
except Exception as e:
logging.error(e)
return {
"status": "error",
"message": f"Error generating video with image: {str(e)}",
}
def enrich_prompt_for_marketing(user_prompt: str) -> str:
"""Enriches user prompt with professional video production quality enhancements.
Adds cinematic quality, professional lighting, smooth camera work, and marketing-focused
elements to ensure high-quality product marketing videos.
"""
enhancement_prefix = """Create a high-quality, professional product marketing video with the following characteristics:
TECHNICAL SPECIFICATIONS:
- 4K cinematic quality with professional color grading
- Smooth, stabilized camera movements
- Professional studio lighting setup with soft, even illumination
- Shallow depth of field for product focus
- High dynamic range (HDR) for vibrant colors
VISUAL STYLE:
- Clean, minimalist aesthetic suitable for premium brand marketing
- Elegant and sophisticated presentation
- Commercial-grade production quality
- Attention to detail in product showcase
USER'S SPECIFIC REQUIREMENTS:
"""
enhancement_suffix = """
ADDITIONAL QUALITY GUIDELINES:
- Ensure smooth transitions and natural motion
- Maintain consistent lighting throughout
- Keep the product as the clear focal point
- Use professional camera techniques (slow pans, tracking shots, or dolly movements)
- Apply subtle motion blur for cinematic feel
- Ensure brand-appropriate tone and style"""
return f"{enhancement_prefix}{user_prompt}{enhancement_suffix}"
if __name__ == "__main__":
mcp.run()
Следующий код выполняет следующие действия:
- Создает сервер FastMCP, который предоставляет агентам ADK доступ к инструменту генерации видео Veo 3.1.
- Принимает в качестве входных данных изображения, текстовые подсказки и отрицательные подсказки, закодированные в base64.
- Генерирует 8-секундные видеоролики асинхронно, отправляя запросы к API Veo 3.1 и опрашивая систему каждые 5 секунд до завершения процесса.
- Возвращает видеоданные в формате base64 вместе с расширенным запросом.
Для работы этого инструмента Veo MCP потребуется та же переменная среды, что и для нашего агента, поэтому мы можем просто скопировать и вставить файл .env . Для этого выполните следующую команду.
cp product_photo_editor/.env veo_mcp/
Теперь мы можем проверить корректность работы сервера MCP, выполнив следующую команду.
uv run veo_mcp/main.py
И в консоли отобразится примерно следующее:
╭────────────────────────────────────────────────────────────────────────────╮
│ │
│ _ __ ___ _____ __ __ _____________ ____ ____ │
│ _ __ ___ .'____/___ ______/ /_/ |/ / ____/ __ \ |___ \ / __ \ │
│ _ __ ___ / /_ / __ `/ ___/ __/ /|_/ / / / /_/ / ___/ / / / / / │
│ _ __ ___ / __/ / /_/ (__ ) /_/ / / / /___/ ____/ / __/_/ /_/ / │
│ _ __ ___ /_/ \____/____/\__/_/ /_/\____/_/ /_____(*)____/ │
│ │
│ │
│ FastMCP 2.0 │
│ │
│ │
│ 🖥️ Server name: Veo MCP Server │
│ 📦 Transport: STDIO │
│ │
│ 🏎️ FastMCP version: 2.12.5 │
│ 🤝 MCP SDK version: 1.16.0 │
│ │
│ 📚 Docs: https://gofastmcp.com │
│ 🚀 Deploy: https://fastmcp.cloud │
│ │
╰────────────────────────────────────────────────────────────────────────────╯
[10/22/25 08:28:53] INFO Starting MCP server 'Veo MCP Server' with server.py:1502
transport 'stdio'
Теперь завершите процесс службы MCP, используя CTRL+C. Эта команда будет вызвана из набора инструментов ADK MCP позже. Мы можем перейти к следующему шагу, чтобы разрешить нашему агенту использовать эти инструменты MCP.
4. 🚀 Подключите сервер Veo MCP к агенту ADK.
Теперь давайте подключим сервер Veo MCP, чтобы наш агент мог его использовать. Сначала создадим отдельный скрипт для размещения набора инструментов и выполним следующую команду.
touch product_photo_editor/mcp_tools.py
Затем скопируйте следующий код в файл product_photo_editor/mcp_tools.py.
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
from mcp import StdioServerParameters
mcp_toolset = MCPToolset(
connection_params=StdioConnectionParams(
server_params=StdioServerParameters(
command="uv",
args=[
"run",
"veo_mcp/main.py",
],
),
timeout=120, # seconds
),
)
# Option to connect to remote MCP server
# from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
# mcp_toolset = MCPToolset(
# connection_params=StreamableHTTPConnectionParams(
# url="http://localhost:8000/mcp",
# timeout=120,
# ),
# )
Приведённый выше код демонстрирует, как можно подключиться к MCP-серверу с помощью ADK MCPToolset. В этом примере мы подключаемся к MCP-серверу, используя канал связи STDIO. В команде мы указываем, как запустить MCP-сервер, и устанавливаем параметр таймаута.
5. 🚀 Изменение параметров вызова инструмента
В описании инструмента сервера MCP мы разработали инструмент generate_video_with_image , который задает строку base64 в качестве параметров. Мы не можем попросить LLM сделать это за нас, поэтому нам необходимо разработать специальную стратегию для решения этой проблемы.
В предыдущей лабораторной работе мы обрабатывали загруженное пользователем изображение и ответ инструмента в функции before_model_callback для сохранения в качестве артефакта, что также отражалось в ранее подготовленном шаблоне агента. Мы будем использовать это и применять следующие стратегии:
- Укажите LLM всегда отправлять значение artifact_id, если определенные параметры инструмента требуют отправки строковых данных в формате base64.
- Перехватите вызов инструмента в функции
before_tool_callbackи преобразуйте параметр из artifact_id в его байтовое содержимое, загрузив артефакт и перезаписав аргументы инструмента.
См. изображение ниже для визуализации той части, которую мы будем перехватывать.

Для начала подготовим функцию before_tool_callback , создав новый файл product_photo_editor/tool_callbacks.py , выполнив следующую команду.
touch product_photo_editor/tool_callbacks.py
Затем скопируйте следующий код в файл.
# product_photo_editor/tool_callbacks.py
from google.genai.types import Part
from typing import Any
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.mcp_tool.mcp_tool import McpTool
import base64
import logging
import json
from mcp.types import CallToolResult
async def before_tool_modifier(
tool: BaseTool, args: dict[str, Any], tool_context: ToolContext
):
# Identify which tool input should be modified
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
logging.info("Modify tool args for artifact: %s", args["image_data"])
# Get the artifact filename from the tool input argument
artifact_filename = args["image_data"]
artifact = await tool_context.load_artifact(filename=artifact_filename)
file_data = artifact.inline_data.data
# Convert byte data to base64 string
base64_data = base64.b64encode(file_data).decode("utf-8")
# Then modify the tool input argument
args["image_data"] = base64_data
Приведённый выше код демонстрирует следующие шаги:
- Проверьте, является ли вызываемый инструмент объектом McpTool и соответствует ли он целевому вызову инструмента, который мы хотим изменить.
- Получите значение аргумента
image_data, который запрашивается в формате base64, но мы запрашиваем у LLM возврат artifact_id. - Загрузите артефакт, используя службу артефактов в
tool_context - Перезапишите аргументы
image_dataданными в формате base64.
Теперь нам нужно добавить этот коллбэк в агент, а также немного изменить инструкции, чтобы агент всегда заполнял аргументы инструмента в формате base64 идентификатором артефакта.
Откройте файл product_photo_editor/agent.py и измените его содержимое, добавив следующий код.
# product_photo_editor/agent.py
from google.adk.agents.llm_agent import Agent
from product_photo_editor.custom_tools import edit_product_asset
from product_photo_editor.mcp_tools import mcp_toolset
from product_photo_editor.model_callbacks import before_model_modifier
from product_photo_editor.tool_callbacks import before_tool_modifier
from product_photo_editor.prompt import AGENT_INSTRUCTION
root_agent = Agent(
model="gemini-2.5-flash",
name="product_photo_editor",
description="""A friendly product photo editor assistant that helps small business
owners edit and enhance their product photos. Perfect for improving photos of handmade
goods, food products, crafts, and small retail items""",
instruction=AGENT_INSTRUCTION
+ """
**IMPORTANT: Base64 Argument Rule on Tool Call**
If you found any tool call arguments that requires base64 data,
ALWAYS provide the artifact_id of the referenced file to
the tool call. NEVER ask user to provide base64 data.
Base64 data encoding process is out of your
responsibility and will be handled in another part of the system.
""",
tools=[
edit_product_asset,
mcp_toolset,
],
before_model_callback=before_model_modifier,
before_tool_callback=before_tool_modifier,
)
Хорошо, давайте теперь попробуем взаимодействовать с агентом, чтобы протестировать это изменение. Выполните следующую команду, чтобы запустить веб-интерфейс для разработчиков.
uv run adk web --port 8080
Результат будет выглядеть примерно так, как в следующем примере, это означает, что мы уже можем получить доступ к веб-интерфейсу.
INFO: Started server process [xxxx] INFO: Waiting for application startup. +-----------------------------------------------------------------------------+ | ADK Web Server started | | | | For local testing, access at http://127.0.0.1:8080. | +-----------------------------------------------------------------------------+ INFO: Application startup complete. INFO: Uvicorn running on http://127.0.0.1:8080 (Press CTRL+C to quit)
Чтобы проверить это, вы можете нажать Ctrl + Click на URL-адресе или нажать кнопку « Предварительный просмотр веб-страницы» в верхней части редактора Cloud Shell и выбрать «Предварительный просмотр на порту 8080».

Вы увидите следующую веб-страницу, где сможете выбрать доступных агентов в выпадающем списке в верхнем левом углу (в нашем случае это должен быть product_photo_editor ) и взаимодействовать с ботом.
Затем загрузите следующее изображение и попросите агента создать на его основе рекламный ролик.
Generate a slow zoom in and moving from left and right animation

Вы столкнетесь со следующей ошибкой.

Почему? Потому что инструмент возвращает результаты непосредственно в виде строки base64, что превышает максимально допустимое количество токенов. Давайте разберемся с этой ошибкой в следующем разделе.
6. 🚀 Модификация ответа инструмента
В этом разделе мы обработаем ответ инструмента от MCP. Мы выполним следующие действия:
- Сохраните видеоответ от инструмента в службе артефактов.
- Вместо этого верните агенту идентификатор артефакта.
Напоминаем, что мы будем использовать следующую среду выполнения агента.

Для начала реализуем функцию обратного вызова. Откройте файл product_photo_editor/tool_callbacks.py и измените его, добавив реализацию after_tool_modifier
# product_photo_editor/tool_callbacks.py
from google.genai.types import Part
from typing import Any
from google.adk.tools.tool_context import ToolContext
from google.adk.tools.base_tool import BaseTool
from google.adk.tools.mcp_tool.mcp_tool import McpTool
import base64
import logging
import json
from mcp.types import CallToolResult
async def before_tool_modifier(
tool: BaseTool, args: dict[str, Any], tool_context: ToolContext
):
# Identify which tool input should be modified
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
logging.info("Modify tool args for artifact: %s", args["image_data"])
# Get the artifact filename from the tool input argument
artifact_filename = args["image_data"]
artifact = await tool_context.load_artifact(filename=artifact_filename)
file_data = artifact.inline_data.data
# Convert byte data to base64 string
base64_data = base64.b64encode(file_data).decode("utf-8")
# Then modify the tool input argument
args["image_data"] = base64_data
async def after_tool_modifier(
tool: BaseTool,
args: dict[str, Any],
tool_context: ToolContext,
tool_response: dict | CallToolResult,
):
if isinstance(tool, McpTool) and tool.name == "generate_video_with_image":
tool_result = json.loads(tool_response.content[0].text)
# Get the expected response field which contains the video data
video_data = tool_result["video_data"]
artifact_filename = f"video_{tool_context.function_call_id}.mp4"
# Convert base64 string to byte data
video_bytes = base64.b64decode(video_data)
# Save the video as artifact
await tool_context.save_artifact(
filename=artifact_filename,
artifact=Part(inline_data={"mime_type": "video/mp4", "data": video_bytes}),
)
# Remove the video data from the tool response
tool_result.pop("video_data")
# Then modify the tool response to include the artifact filename and remove the base64 string
tool_result["video_artifact_id"] = artifact_filename
logging.info(
"Modify tool response for artifact: %s", tool_result["video_artifact_id"]
)
return tool_result
После этого нам нужно наделить нашего агента этой функцией. Откройте файл product_photo_editor/agent.py и измените его следующим образом.
# product_photo_editor/agent.py
from google.adk.agents.llm_agent import Agent
from product_photo_editor.custom_tools import edit_product_asset
from product_photo_editor.mcp_tools import mcp_toolset
from product_photo_editor.model_callbacks import before_model_modifier
from product_photo_editor.tool_callbacks import (
before_tool_modifier,
after_tool_modifier,
)
from product_photo_editor.prompt import AGENT_INSTRUCTION
root_agent = Agent(
model="gemini-2.5-flash",
name="product_photo_editor",
description="""A friendly product photo editor assistant that helps small business
owners edit and enhance their product photos. Perfect for improving photos of handmade
goods, food products, crafts, and small retail items""",
instruction=AGENT_INSTRUCTION
+ """
**IMPORTANT: Base64 Argument Rule on Tool Call**
If you found any tool call arguments that requires base64 data,
ALWAYS provide the artifact_id of the referenced file to
the tool call. NEVER ask user to provide base64 data.
Base64 data encoding process is out of your
responsibility and will be handled in another part of the system.
""",
tools=[
edit_product_asset,
mcp_toolset,
],
before_model_callback=before_model_modifier,
before_tool_callback=before_tool_modifier,
after_tool_callback=after_tool_modifier,
)
Готово! Теперь вы можете попросить агента не только помочь вам отредактировать фотографию, но и создать для вас видео! Повторите следующую команду ещё раз.
uv run adk web --port 8080
Затем попробуйте создать видео, используя это изображение.
Generate a slow zoom in and moving from left and right animation

Вы увидите сгенерированное видео, как показано в примере ниже, уже сохраненное как артефакт.

7. ⭐ Краткое содержание
Теперь давайте вспомним, что мы уже сделали в ходе этой практической работы. Вот основные выводы:
- Обработка многомодальных данных (ввод/вывод инструмента) : Усилена стратегия управления многомодальными данными (такими как изображения и видео) для ввода и вывода инструментом за счет использования службы артефактов ADK и специализированных обратных вызовов вместо прямой передачи необработанных байтовых данных.
- Интеграция с набором инструментов MCP : Разработан и интегрирован внешний сервер Veo MCP с использованием FastMCP через набор инструментов ADK MCP для добавления возможностей генерации видео в работу агента.
- Модификация входных данных инструмента (before_tool_callback) : Реализован обратный вызов для перехвата вызова инструмента generate_video_with_image, преобразующий artifact_id файла (выбранный LLM) в необходимые данные изображения в кодировке base64 для ввода на сервер MCP.
- Модификация выходных данных инструмента (after_tool_callback) : Реализован обратный вызов для перехвата большого видеоответа в кодировке base64 от сервера MCP, сохранения видео в качестве нового артефакта и возврата чистой ссылки video_artifact_id в LLM.
8. 🧹 Уборка
Чтобы избежать списания средств с вашего аккаунта Google Cloud за ресурсы, использованные в этом практическом задании, выполните следующие действия:
- В консоли Google Cloud перейдите на страницу «Управление ресурсами» .
- В списке проектов выберите проект, который хотите удалить, и нажмите кнопку «Удалить» .
- В диалоговом окне введите идентификатор проекта, а затем нажмите «Завершить» , чтобы удалить проект.