Разработка пользовательского интерфейса с использованием ADK и A2UI

1. Обзор

Большинство приложений для агентов возвращают обычный текст. A2UI меняет это. Это протокол с 18 декларативными примитивами пользовательского интерфейса, который позволяет вашему агенту создавать многофункциональные интерактивные интерфейсы. Клиент отображает их нативно. Для каждого макета не требуется новый код фронтенда.

В этом практическом занятии для создания агента используется Agent Development Kit (ADK), а для генерации пользовательского интерфейса — A2UI .

Что вы построите

Панель мониторинга облачной инфраструктуры в три этапа:

  1. Стандартный агент , возвращающий данные ресурсов в виде обычного текста.
  2. Агент A2UI , возвращающий те же данные, что и структурированный JSON-файл A2UI.
  3. Агент , отображающий JSON-данные A2UI в виде интерактивных компонентов пользовательского интерфейса в среде разработки ADK.

Агент ADK A2UI

Что вы узнаете

  • Принцип работы A2UI: 18 примитивов, 3 типа сообщений, плоская компонентная модель.
  • Как использовать SDK A2UI для того, чтобы заставить агент ADK сгенерировать JSON-файл A2UI.
  • Как отображать компоненты A2UI в adk web

Что вам понадобится

  • Проект Google Cloud с включенной функцией выставления счетов.
  • Веб-браузер, например Chrome.
  • Python 3.12+

Этот практический урок предназначен для разработчиков среднего уровня, имеющих некоторое представление о Python и Google Cloud.

Выполнение этого практического задания займет приблизительно 15-20 минут.

Стоимость ресурсов, созданных в рамках этого практического занятия, должна составлять менее 5 долларов.

2. Настройте свою среду.

Создайте проект в Google Cloud.

  1. В консоли Google Cloud на странице выбора проекта выберите или создайте проект Google Cloud .
  2. Убедитесь, что для вашего облачного проекта включена функция выставления счетов. Узнайте, как проверить, включена ли функция выставления счетов для проекта .

Запустить редактор CloudShell

Чтобы запустить сеанс Cloud Shell из консоли Google Cloud, нажмите кнопку «Активировать Cloud Shell» в консоли Google Cloud.

Это запустит сессию в нижней панели вашей консоли Google Cloud.

Чтобы запустить редактор, нажмите кнопку «Открыть редактор» на панели инструментов окна Cloud Shell.

Установите переменные среды

На панели инструментов редактора Cloud Shell нажмите «Терминал» и «Новый терминал» , затем выполните следующие команды, чтобы указать свой проект, местоположение и настроить ADK для использования Gemini в Vertex AI.

export GOOGLE_CLOUD_PROJECT=<INSERT_YOUR_GCP_PROJECT_HERE>
export GOOGLE_CLOUD_LOCATION=global
export GOOGLE_GENAI_USE_VERTEXAI=True

Включить API

В терминале выполните следующую команду, чтобы включить необходимые API:

gcloud services enable aiplatform.googleapis.com

Установите зависимости

В терминале выполните следующую команду для установки последней версии Agent Development Kit (ADK):

pip install -U google-adk a2ui-agent-sdk
export PATH="$HOME/.local/bin:$PATH"

3. Создайте агента.

Начните со стандартного агента ADK, который возвращает обычный текст. Именно так выглядит большинство современных приложений-агентов.

Создать папку агента

Создайте папку с именем a2ui_agent , которая будет содержать исходный код вашего агента и инструментов.

Определите инструмент и имитационные данные.

Создайте файл a2ui_agent/resources.py со следующим содержимым. Этот инструмент возвращает список облачных ресурсов с указанием их статуса.

RESOURCES = [
    {
        "name": "auth-service",
        "type": "Cloud Run",
        "region": "us-west1",
        "status": "healthy",
        "cpu": "2 vCPU",
        "memory": "1 GiB",
        "instances": 3,
        "url": "https://auth-service-abc123.run.app",
        "last_deployed": "2026-04-18T14:22:00Z",
    },
    {
        "name": "events-db",
        "type": "Cloud SQL",
        "region": "us-east1",
        "status": "warning",
        "tier": "db-custom-8-32768",
        "storage": "500 GB SSD",
        "connections": 195,
        "version": "PostgreSQL 16",
        "issue": "Storage usage at 92%",
    },
    {
        "name": "analytics-pipeline",
        "type": "Cloud Run",
        "region": "us-west1",
        "status": "error",
        "cpu": "2 vCPU",
        "memory": "4 GiB",
        "instances": 0,
        "url": "https://analytics-pipeline-ghi789.run.app",
        "last_deployed": "2026-04-10T16:45:00Z",
        "issue": "CrashLoopBackOff: OOM killed",
    },
]

def get_resources() -> list[dict]:
    """Get all cloud resources in the current project.
    Returns a list of cloud infrastructure resources including their
    name, type, region, status, and type-specific details.
    Status is one of: healthy, warning, error. Resources with
    warning or error status include an 'issue' field describing
    the problem.
    """
    return RESOURCES

Определите агента

Создайте a2ui_agent/agent.py со следующим содержимым:

from google.adk.agents import Agent
from .resources import get_resources

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that reports on project resources.",
    instruction=(
        "You are a cloud infrastructure assistant. When users ask about their "
        "cloud resources, use the get_resources tool to fetch the current state. "
        "Summarize the results clearly in plain text."
    ),
    tools=[get_resources],
)

4. Проверьте агента.

ADK включает в себя пользовательский интерфейс для разработчиков, который можно использовать для взаимодействия с агентом и отправки ему запросов в браузере для тестирования.

Запуск пользовательского интерфейса разработчика ADK

В терминале Cloud Shell Editor выполните следующую команду, чтобы запустить пользовательский интерфейс разработчика ADK:

adk web --port 8080 --allow_origins "*" --reload_agents

Вы должны увидеть сообщение, похожее на следующее:

+-----------------------------------------------------------------------------+
| ADK Web Server started                                                      |
|                                                                             |
| For local testing, access at http://127.0.0.1:8080.                         |
+-----------------------------------------------------------------------------+

Откройте пользовательский интерфейс разработчика ADK.

Вы можете открыть пользовательский интерфейс разработчика ADK в браузере, щелкнув по локальному тестовому URL-адресу с помощью клавиши Ctrl или Cmd , или нажав кнопку « Предварительный просмотр веб-страницы» и выбрав «Предварительный просмотр на порту 8080» .

После того, как вы откроете пользовательский интерфейс разработчика ADK, выберите a2ui_agent из выпадающего меню.

Пришлите примеры подсказок

Отправьте агенту пример голосового сообщения:

What's running in my project?

Теперь попробуйте другой пример запроса, и вы получите больше текстового вывода:

Does anything need my attention?

Ваш диалог должен выглядеть примерно так:

ADK Текстовый Агент

Вы получите сплошной текст. Точный, но не очень удобный для пользователя.

5. Сгенерировать JSON-файл A2UI

Что если бы агент мог описывать пользовательский интерфейс вместо того, чтобы просто выводить текст? A2UI — это протокол, позволяющий агентам создавать интерактивные интерфейсы из каталога из 18 примитивов. Клиент отображает их нативно.

В состав A2UI Python SDK входит менеджер схем, который генерирует для вас системные подсказки. Он обучает LLM полному каталогу компонентов A2UI, правильным именам и типам свойств, а также структуре JSON.

Обновите агента

Замените содержимое файла a2ui_agent/agent.py следующим:

from google.adk.agents import Agent
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.basic_catalog.provider import BasicCatalog
from .resources import get_resources

schema_manager = A2uiSchemaManager(
    version="0.8",
    catalogs=[BasicCatalog.get_config("0.8")],
)

instruction = schema_manager.generate_system_prompt(
    role_description=(
        "You are a cloud infrastructure assistant. When users ask about "
        "their cloud resources, use the get_resources tool to fetch the "
        "current state."
    ),
    workflow_description=(
        "Analyze the user's request and return structured UI when appropriate."
    ),
    ui_description=(
        "Use cards for resource summaries, rows and columns for comparisons, "
        "icons for status indicators, and buttons for drill-down actions. "
        "Do NOT use markdown formatting in text values. Use the usageHint "
        "property for heading levels instead. "
        "Respond ONLY with the A2UI JSON array. Do NOT include any text "
        "outside the JSON. Put all explanations into Text components."
    ),
    include_schema=True,
    include_examples=True,
)

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that renders rich A2UI interfaces.",
    instruction=instruction,
    tools=[get_resources],
)

Метод generate_system_prompt() объединяет описание вашей роли с полной JSON-схемой A2UI и несколькими примерами, поэтому LLM точно знает, как форматировать свой вывод. Вам не нужно писать каталог компонентов вручную.

6. Проверьте вывод в формате JSON.

Если у вас всё ещё запущен пользовательский интерфейс разработчика ADK, созданный ранее, он должен автоматически перезагрузить изменения, внесённые вами в агент.

Выберите a2ui_agent , начните новую сессию, нажав кнопку «+Новая сессия» в правом верхнем углу пользовательского интерфейса разработчика ADK, затем отправьте тот же запрос, что и раньше:

What's running in my project?

На этот раз агент отвечает JSON-данными A2UI вместо обычного текста. В выводе чата вы увидите структурированные сообщения, содержащие beginRendering , surfaceUpdate и dataModelUpdate .

ADK A2UI JSON

JSON-файл описывает многофункциональный пользовательский интерфейс с карточками, иконками и кнопками, но adk web отображает его как обычный текст. На следующем шаге вы настроите его на отображение в виде реальных компонентов пользовательского интерфейса.

7. Разберитесь в A2UI

Посмотрите на JSON-код, который только что сгенерировал ваш агент. Вы заметите, что он содержит три типа сообщений. Каждый ответ A2UI имеет такую ​​же структуру:

1. beginRendering

Создаёт поверхность для отрисовки и присваивает имя корневому компоненту:

{"beginRendering": {"surfaceId": "default", "root": "main-column"}}

2. surfaceUpdate

Отправляет дерево компонентов в виде плоского списка с идентификаторами (не вложенными):

{"surfaceUpdate": {"surfaceId": "default", "components": [
  {"id": "main-column", "component": {"Column": {"children": {"explicitList": ["title", "card1"]}}}},
  {"id": "title", "component": {"Text": {"text": {"literalString": "My Resources"}, "usageHint": "h1"}}},
  {"id": "card1", "component": {"Card": {"child": "card1-content"}}},
  {"id": "card1-content", "component": {"Text": {"text": {"path": "service_name"}}}}
]}}

3. Обновление модели данных

Отправляет данные отдельно от структуры:

{"dataModelUpdate": {"surfaceId": "default", "contents": [
  {"key": "service_name", "valueString": "auth-service"},
  {"key": "status", "valueString": "healthy"}
]}}

Компоненты привязываются к данным с помощью {"path": "key"} . Вы можете обновлять данные, не отправляя повторно дерево компонентов.

18 примитивов

Категория

Компоненты

Макет

Карточка, Столбец, Строка, Список, Вкладки, Разделитель, Модальное окно

Отображать

Текст, Изображение, Значок, Видео, Аудиоплеер

Вход

Текстовое поле, поле ввода даты и времени, поле выбора нескольких вариантов, флажок, ползунок.

Действие

Кнопка

Агент создает различные макеты из одного и того же каталога. Подробную информацию о каждом примитиве см. в справочнике компонентов . Представление просмотра, панель приоритетов и форма конфигурации используют одни и те же 18 примитивов. Новые компоненты для интерфейса не требуются.

8. Отображение компонентов A2UI

Агент генерирует корректный JSON-файл A2UI, но adk web отображает его как необработанный текст. Для отображения его в виде реальных компонентов пользовательского интерфейса необходима небольшая утилита, которая преобразует вывод JSON-файла A2UI от агента в формат, ожидаемый встроенным рендерером adk web .

Создайте утилиту рендеринга A2UI.

Создайте a2ui_agent/a2ui_utils.py со следующим содержимым:

import json
import re
from google.genai import types
from google.adk.agents.callback_context import CallbackContext
from google.adk.models.llm_response import LlmResponse

def _wrap_a2ui_part(a2ui_message: dict) -> types.Part:
    """Wrap a single A2UI message for rendering in adk web."""
    datapart_json = json.dumps({
        "kind": "data",
        "metadata": {"mimeType": "application/json+a2ui"},
        "data": a2ui_message,
    })
    blob_data = (
        b"<a2a_datapart_json>"
        + datapart_json.encode("utf-8")
        + b"</a2a_datapart_json>"
    )
    return types.Part(
        inline_data=types.Blob(
            data=blob_data,
            mime_type="text/plain",
        )
    )

def a2ui_callback(
    callback_context: CallbackContext,
    llm_response: LlmResponse,
) -> LlmResponse | None:
    """Convert A2UI JSON in text output to rendered components."""
    if not llm_response.content or not llm_response.content.parts:
        return None
    for part in llm_response.content.parts:
        if not part.text:
            continue
        text = part.text.strip()
        if not text:
            continue
        if not any(k in text for k in ("beginRendering", "surfaceUpdate", "dataModelUpdate")):
            continue
        # Strip markdown fences
        if text.startswith("```"):
            text = text.split("\n", 1)[-1]
            if text.endswith("```"):
                text = text[:-3].strip()
        # Find where JSON starts (skip conversational prefix)
        json_start = None
        for i, ch in enumerate(text):
            if ch in ("[", "{"):
                json_start = i
                break
        if json_start is None:
            continue
        json_text = text[json_start:]
        # raw_decode parses JSON and ignores trailing text
        try:
            parsed, _ = json.JSONDecoder().raw_decode(json_text)
        except json.JSONDecodeError:
            # Handle concatenated JSON objects: {"a":1} {"b":2}
            try:
                fixed = "[" + re.sub(r'\}\s*\{', '},{', json_text) + "]"
                parsed, _ = json.JSONDecoder().raw_decode(fixed)
            except json.JSONDecodeError:
                continue
        if not isinstance(parsed, list):
            parsed = [parsed]
        a2ui_keys = {"beginRendering", "surfaceUpdate", "dataModelUpdate", "deleteSurface"}
        a2ui_messages = [msg for msg in parsed if isinstance(msg, dict) and any(k in msg for k in a2ui_keys)]
        if not a2ui_messages:
            continue
        new_parts = [_wrap_a2ui_part(msg) for msg in a2ui_messages]
        return LlmResponse(
            content=types.Content(role="model", parts=new_parts),
            custom_metadata={"a2a:response": "true"},
        )
    return None

Эта утилита выполняет две функции:

  1. Извлекает JSON-данные A2UI из текстового вывода агента.
  2. Оборачивает каждое сообщение A2UI в формат, ожидаемый встроенным рендерером A2UI в adk web .

Обновите агента

Замените содержимое файла a2ui_agent/agent.py следующим содержимым. Единственное изменение по сравнению с предыдущим шагом — это импорт функции a2ui_callback и параметра after_model_callback для агента:

from google.adk.agents import Agent
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.basic_catalog.provider import BasicCatalog
from .resources import get_resources
from .a2ui_utils import a2ui_callback

schema_manager = A2uiSchemaManager(
    version="0.8",
    catalogs=[BasicCatalog.get_config("0.8")],
)

instruction = schema_manager.generate_system_prompt(
    role_description=(
        "You are a cloud infrastructure assistant. When users ask about "
        "their cloud resources, use the get_resources tool to fetch the "
        "current state."
    ),
    workflow_description=(
        "Analyze the user's request and return structured UI when appropriate."
    ),
    ui_description=(
        "Use cards for resource summaries, rows and columns for comparisons, "
        "icons for status indicators, and buttons for drill-down actions. "
        "Do NOT use markdown formatting in text values. Use the usageHint "
        "property for heading levels instead. "
        "Respond ONLY with the A2UI JSON array. Do NOT include any text "
        "outside the JSON. Put all explanations into Text components."
    ),
    include_schema=True,
    include_examples=True,
)

root_agent = Agent(
    model="gemini-3-flash-preview",
    name="cloud_dashboard",
    description="A cloud infrastructure assistant that renders rich A2UI interfaces.",
    instruction=instruction,
    tools=[get_resources],
    after_model_callback=a2ui_callback,
)

9. Проверьте отрисованный пользовательский интерфейс.

Если у вас всё ещё запущен пользовательский интерфейс разработчика ADK, созданный ранее, он должен автоматически перезагрузить изменения, внесённые вами в агент.

Обновите вкладку браузера, выберите a2ui_agent , затем начните новую сессию, нажав кнопку «+Новая сессия» в правом верхнем углу пользовательского интерфейса разработчика ADK, и отправьте тот же запрос, что и раньше:

What's running in my project?

На этот раз adk web отображает компоненты A2UI как реальный пользовательский интерфейс: карточки с индикаторами состояния, подробной информацией о ресурсах и кнопками действий.

Агент ADK A2UI

Попробуйте другой вариант командной строки, чтобы увидеть, как агент создаст другой пользовательский интерфейс из того же набора примитивов:

Does anything need my attention?

Наконец, попробуйте другой вариант ввода, чтобы сгенерировать другой пользовательский интерфейс для развертывания новой службы:

I need to deploy a new service

Каждый запрос отправляется одному и тому же агенту, одному и тому же инструменту и одним и тем же 18 примитивам. Но каждый запрос приводит к разному пользовательскому интерфейсу для разных целей.

10. Уборка

Чтобы избежать работы локальных серверов, очистите ресурсы:

  • В терминале, где запущена adk web , нажмите Ctrl+C , чтобы остановить сервер-агент.

Если вы создали проект специально для этого практического занятия, вы можете удалить весь проект:

gcloud projects delete ${GOOGLE_CLOUD_PROJECT}

11. Поздравляем!

Вы создали агент ADK, который генерирует насыщенный интерактивный пользовательский интерфейс с помощью A2UI.

Что вы узнали

  • A2UI — это протокол, содержащий 18 декларативных примитивов и 3 типа сообщений.
  • SDK A2UI генерирует системные подсказки, которые обучают LLM каталогу компонентов.
  • Один и тот же агент, инструмент и примитивы позволяют создавать различные пользовательские интерфейсы для разных целей.
  • Компоненты A2UI могут отображаться непосредственно в adk web во время разработки.

Создайте производственный интерфейс пользователя.

В этом практическом задании вы отобразили A2UI внутри adk web для разработки и тестирования.

Для использования в продакшене вам потребуется создать фронтенд, используя один из официальных рендереров A2UI:

Платформа

Рендерер

Установить

Веб (React)

@a2ui/react

npm install @a2ui/react

Веб (литература)

@a2ui/lit

npm install @a2ui/lit

Веб (Angular)

@a2ui/angular

npm install @a2ui/angular

Мобильные/настольные устройства

Flutter GenUI SDK

Начиная

Справочная документация