Создание агентных рабочих процессов в приложении с облачным бэкендом и ADK

  • PublicPublic
  • 29 Sep, 2026
Создание агентных рабочих процессов в приложении с облачным бэкендом и ADK

Некоторые задачи слишком сложны, чтобы уложиться в одну сессию на устройстве. Собрать полное путешествие под ключ — это согласовать время перелётов, выбрать номера в отелях, забронировать билеты в музеи и спланировать рестораны. Если запускать такой многошаговый процесс прямо на телефоне, есть риск потерять прогресс, когда приложение закроют, а жонглировать кучей шагов и ключами API на портативном устройстве быстро становится неудобно. Для таких долгих рабочих процессов лучше подходит собственный self-hosted бэкенд: он выполняет агентов бронирования в фоне, пока Android-приложение остаётся подключённым к сессии, отображает прогресс и запрашивает у пользователя ввод только тогда, когда это действительно нужно.

В основе всего лежит Agent Development Kit (ADK). В примере на Python определяется специализированный агент flight_agent через Agent(name="Flight Booker", model="gemini-3.1-flash-lite",...) с двумя функциональными инструментами: search_flights(destination, date) и reserve_flight(flight_time). Примечательно, что у reserve_flight задан require_confirmation=True, поэтому ADK приостанавливает работу и ждёт явного одобрения пользователя, прежде чем выполнить этот необратимый шаг. Агент запускается через InMemoryRunner, где run_async(user_id, session_id) ведёт цикл. ADK сам занимается исполнением — отслеживает контекст диалога, маршрутизирует сообщения между пользователем и моделью и вызывает зарегистрированные инструменты, когда модель их запрашивает, — так что вам остаётся писать процедурную логику, а оркестрацией управляет фреймворк.

Чтобы передавать обновления с бэкенда на устройство в реальном времени, сервер использует AG-UI — двунаправленный транспортный протокол, который стандартизирует типы сообщений между агентами и UI-клиентами. Агент может сообщать клиенту о событиях жизненного цикла, текстовых сообщениях, вызовах инструментов и изменениях состояния, а клиент в ответ отправляет пользовательские сообщения, результаты инструментов и кастомные события действий. На сервере AG-UI выдаёт обновления как Server-Sent Events (например, event: TEXT_MESSAGE_CONTENT, несущий JSON-дельту). На Android SDK на Kotlin слушает этот поток и отображает полезную нагрузку на типобезопасные клиентские события: HttpAgent настраивается через HttpAgentConfig, RunAgentInput несёт тред и UserMessage, а runAgentObservable(input).collect {... } позволяет ветвить по TextMessageStartEvent, TextMessageContentEvent и TextMessageEndEvent.

Отрисовка только этих текстовых событий даёт простого чат-бота. Чтобы показывать интерактивные компоненты нативно, A2UI позволяет агентам описывать элементы интерфейса динамически. Клиент объявляет каталог поддерживаемых компонентов, а сервер присылает JSON с раскладкой и свойствами — например, поверхность Flight Reservation, содержащую InteractiveOptionPicker с подсказкой, вариантами вроде "10:00 AM" и "2:00 PM" и кнопкой подтверждения. На бэкенде интеграция A2UI в ADK использует A2uiSchemaManager, чтобы скомпилировать JSON-схемы компонентов и инструкции раскладки в системный промпт через generate_system_prompt(...), — так модель узнаёт точную структуру, которую должна генерировать для валидных payload-ов A2UI, которые клиент сможет отрисовать.

На клиенте добавление A2UI начинается с зависимостей Gradle, таких как androidx.a2ui:a2ui-model, androidx.a2ui.compose:compose-runtime, compose-ui и androidx.compose.material3:material3-a2ui — все версии 1.0.0-alpha01. Класс каждого компонента из каталога отображает JSON-свойства в composable из Jetpack Compose, а кастомный A2uiCatalog, зарегистрированный с catalogId, связывает его с серверным определением. Для стандартных элементов — текста, кнопок, чекбоксов и переключателей даты и времени — готовые Material 3-реализации даёт materialA2uiBasicCatalogV1(...), без написания своего кода. BookingAssistantViewModel подаёт сообщения в A2uiMessageProcessor, чей StateFlow activeSurfaces экран отрисовывает composable-ом A2uiSurface, который берёт на себя отслеживание состояния, индикаторы загрузки, обработку ошибок и анимированные переходы. Обе стороны должны использовать один и тот же ID определения каталога; если вы добавляете или меняете свойства, нужно поднять номер версии и обновить соответствующий класс компонента на Kotlin, чтобы не получить ошибки парсинга.