Как научить нейросеть рисовать интерфейсы без риска для безопасности
Представьте, что вы пишете чат-бота для бронирования столиков в ресторанах. Обычный текстовый ответ от LLM — это ок, но пользователю было бы гораздо удобнее увидеть красивую карточку заведения с кнопками, выбором даты и слайдером цен. Казалось бы, в чем проблема? Пусть модель просто выплюнет кусок React-кода или HTML.
Но тут начинаются грабли. Во-первых, исполнять сгенерированный нейросетью код на клиенте — это огромная дыра в безопасности (XSS передает привет). Во-вторых, модель может ошибиться в синтаксисе фреймворка. В-третьих, если ваше приложение написано на Flutter, а модель выдает HTML, вам придется городить костыли для рендеринга.
Google выкатил проект A2UI (Agent-to-User Interface), который пытается решить эту проблему элегантно. Это не очередной фреймворк, а протокол и набор библиотек для передачи «намерений» интерфейса от ИИ к вашему приложению.
В чем суть идеи
Разработчики из Google решили разделить генерацию интерфейса и его исполнение. Вместо того чтобы просить модель написать код, мы просим её выдать декларативный JSON. Этот JSON описывает структуру компонентов, которые уже есть в вашем приложении и которым вы доверяете.
Подход напоминает работу с дизайн-системами в Figma или использование Server-Driven UI. У вас на клиенте есть каталог проверенных компонентов: кнопки, текстовые поля, карточки. Агент (LLM) просто говорит: «Положи сюда карточку, а в неё — кнопку с таким-то текстом».
Почему это удобно для разработчика
Я выделил несколько моментов, которые делают A2UI интересным инструментом для тех, кто строит агентские системы.
Безопасность по умолчанию
Поскольку агент присылает только данные (JSON), он физически не может выполнить произвольный JavaScript в контексте вашего приложения. Вы сами определяете список разрешенных компонентов и то, как они реагируют на события. Это снимает головную боль с проверкой безопасности каждого ответа модели.
Дружелюбность к LLM
Нейросетям проще генерировать плоские структуры данных, чем сложные вложенные деревья кода. Формат A2UI оптимизирован для инкрементального обновления. Если пользователь в чате просит «добавить еще один пункт в заказ», агенту не нужно перерисовывать всё окно — он может прислать только изменения для конкретных ID компонентов. Это делает интерфейс отзывчивым, почти как при живом общении.
Один формат для всех платформ
Это, пожалуй, самая сильная сторона. Вы описываете интерфейс один раз в JSON, а рендерить его можете где угодно. Написали админку на Angular, мобилку на Flutter и лендинг на Lit? Один и тот же ответ от Gemini или GPT-4 отобразится нативно в каждом из этих приложений, используя их родные UI-киты.
Как это работает под капотом
Процесс взаимодействия выглядит примерно так:
- Агент генерирует JSON-ответ (A2UI Response).
- Этот JSON летит на клиент через любой удобный транспорт (например, WebSocket или обычный HTTP).
- Рендерер на стороне клиента парсит JSON и сопоставляет абстрактные типы (например,
type: 'text-field') с реальными компонентами вашей библиотеки. - Вуаля — пользователь видит нативный интерфейс.
Кстати, в репозитории уже есть готовые рендереры для веба (на базе Lit) и Flutter. Для остальных фреймворков вроде React или SwiftUI поддержку придется дописывать самим, но архитектура проекта к этому располагает.
Где это реально пригодится
Я вижу несколько сценариев, где без такого подхода будет туго:
- Динамические формы. Когда состав полей зависит от контекста. Например, страховой агент запрашивает разные данные в зависимости от типа происшествия.
- Сложные дашборды. Когда пользователь просит «покажи мне графики продаж за прошлый месяц», и агент на лету собирает панель мониторинга.
- Мультиагентные системы. Когда один главный бот вызывает «под-агента» (например, для поиска авиабилетов), и тот возвращает свой специфичный интерфейс прямо внутрь общего чата.
Как пощупать проект
Проект сейчас находится в стадии публичного превью (версия 0.8), так что API может поменяться. Но запустить демо и посмотреть, как это работает, можно уже сейчас.
Для запуска примера с поиском ресторанов вам понадобится ключ Gemini API и установленный Node.js. Сначала нужно собрать базовые библиотеки:
# Собираем ядро и рендереры
cd renderers/markdown/markdown-it && npm install && npm run build
cd ../../web_core && npm install && npm run build
cd ../lit && npm install && npm run build
Затем запускаем клиентскую часть:
cd samples/client/lit/shell
npm install
npm run dev
После этого можно запускать Python-агента в соседнем терминале и смотреть, как он «рисует» карточки ресторанов в вашем браузере.
A2UI — это попытка стандартизировать то, как ИИ общается с пользователем через графику, а не только через текст. Пока проект выглядит как крепкий фундамент для тех, кто не хочет изобретать свой велосипед для Server-Driven UI в эпоху нейросетей.
Кому стоит присмотреться:
- Разработчикам AI-агентов, которым тесно в рамках текстовых чатов.
- Командам, которые строят кроссплатформенные приложения с динамическим контентом.
- Тем, кто заботится о безопасности и не хочет давать LLM доступ к выполнению кода на фронтенде.
Конечно, документации пока маловато, а список готовых рендереров ограничен. Но сама концепция «UI как данные» кажется единственно верным путем для создания надежных агентских интерфейсов.