Как научить нейросетевых агентов собирать интерфейсы без дыр в безопасности
Когда создаешь чат-бота или автономного агента на базе LLM, быстро упираешься в границы обычного текста. Пользователю неудобно вводить дату бронирования, выбирать категорию или настраивать фильтры через бесконечную переписку. Гораздо проще нажать пару кнопок в карточке, подвигать ползунок или кликнуть по дате в календаре.
Часто разработчики пытаются решить это в лоб: просят модель сгенерировать кусок HTML или React-компонент прямо в ответе. Но выполнять сгенерированный нейросетью код на клиенте через dangerouslySetInnerHTML или динамический eval — верный способ получить XSS и сломать безопасность приложения. Модели к тому же периодически ошибаются в синтаксисе верстки и ломают рендеринг страницы.
В проекте A2UI подошли к задаче с другой стороны. Это открытый протокол и набор библиотек, которые превращают генеративный UI в структурированные данные.
Что под капотом
Главная идея A2UI предельно проста: жестко отделить намерение построить интерфейс от непосредственного рендеринга. Агент не присылает готовый JavaScript, CSS или сырую разметку. Вместо этого он формирует плоский JSON-документ со списком абстрактных компонентов и их параметров.
Фронтенд заранее объявляет каталог доверенных элементов. В этот каталог входят карточки, текстовые поля, кнопки, переключатели и списки. Когда приложение получает JSON от LLM, специальный рендерер сопоставляет типы из сообщения с реальными виджетами вашей дизайн-системы.
Если модель попытается вставить вредоносный скрипт или вызовет несуществующий тег, клиентское приложение не упадет и не выполнит опасный код. Оно просто проигнорирует некорректные поля.
Архитектура и особенности формата
В структуре A2UI заметно несколько продуманных решений, ориентированных именно на особенности работы больших языковых моделей.
- Плоское дерево компонентов. LLM тяжело справляются с глубокими вложенными структурами и часто ошибаются в закрывающих скобках. В A2UI компоненты лежат в плоском списке и ссылаются друг на друга по строковым ID.
- Инкрементальный стриминг. Агенту не нужно пересылать весь экран целиком при каждом ответе. Он умеет точечно обновлять отдельные узлы интерфейса прямо в процессе диалога.
- Полная независимость от платформы. Один и тот же JSON с описанием формы можно отрисовать на вебе через веб-компоненты, на мобильном устройстве через Flutter или в десктопном приложении.
- Механизм Smart Wrappers. Если базовых кнопок и карточек не хватает, разработчик может зарегистрировать собственную обертку. Это помогает безопасно встраивать даже legacy-виджеты или изолировать сложные элементы внутри iframe с изолированным контекстом.
Где это пригодится на практике
Формат закрывает типовые сценарии, где обычного Markdown в чате уже недостаточно:
- Динамические формы сбора данных. Агент на лету генерирует форму под конкретную ситуацию. Например, при заказе столика в ресторане выводятся поля для количества гостей, выбора даты и пожеланий к рассадке.
- Фоновые субагенты. Главный бот передает задачу специализированному сервису, а тот возвращает интерактивный блок прямо в текущий тред.
- Ситуативные панели мониторинга. Корпоративный ассистент строит графики и таблицы по запросу аналитика без необходимости заранее верстать десятки отдельных страниц.
- Пошаговые сценарии согласования. Интерфейс перестраивает кнопки действий в зависимости от прав текущего сотрудника и стадии заявки.
Как запустить демо локально
Пощупать концепцию можно на готовом примере с поиском ресторанов. Для запуска понадобятся Node.js 18+ с включенным Corepack, пакетный менеджер uv для Python и ключ от Gemini API.
Склонируйте репозиторий и запустите проект:
git clone https://github.com/a2ui-project/a2ui.git
cd a2ui
export GEMINI_API_KEY="ваш_ключ_gemini"
corepack enable
yarn install
cd samples/client/lit
yarn demo:restaurant
Скрипт соберет рендереры, запустит локального Python-агента и откроет веб-клиент на порту 5173.
Если не хочется возиться с терминалом, авторы выложили интерактивные песочницы Composer и Theater. В них можно визуально собирать экраны и смотреть, какой JSON генерируется на выходе.
Для создания собственного проекта на базе существующих фреймворков вроде LangGraph или CrewAI есть стартер:
npx create-ag-ui-app@latest
Текущее состояние и ограничения
Проект находится на этапе публичного превью. Основная рабочая ветка сейчас имеет версию v0.9.1, а спецификация v1.0 пока в статусе кандидата на релиз. Это означает, что структура некоторых полей в JSON еще может измениться.
Пока официальные рендереры из коробки написаны преимущественно для Lit и Flutter (в рамках проекта GenUI SDK). Поддержка React, SwiftUI для iOS и Jetpack Compose для Android находится в планах сообщества либо доступна через сторонние интеграции вроде CopilotKit. Если вам нужен чистый React без внешних надстроек, часть маппинга придется набросать вручную.
Стоит ли пробовать
A2UI решает фундаментальную проблему генеративного интерфейса: дает агентам гибкость в визуализации данных, но оставляет контроль за выполнением кода на стороне клиента.
Если вы проектируете сложные сценарии взаимодействия с LLM, где текст стал узким местом, изучить проект точно имеет смысл. Начать проще всего с официальной веб-песочницы, чтобы оценить структуру JSON и прикинуть, насколько легко формат впишется в архитектуру вашего фронтенда.
