Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Bystrye i nadezhnye vychisleniya s pomoschyu klientskih funktsiy a2ui
Dev48
info@dev48.org+375 29 320-40-96WhatsApp@isky_by

© 2026 · Все права защищены.

Быстрые и надежные вычисления с помощью клиентских функций A2UI

Источник: Flutter•27 сентября 2026 г. в 07:37

Быстрые и надежные вычисления с помощью клиентских функций A2UI

Узнайте, как клиентские функции позволяют агенту делегировать локальные операции непосредственно коду Dart, выполняющемуся на устройстве пользователя.

Узнайте, как клиентские функции позволяют агенту делегировать локальные операции непосредственно коду Dart, выполняющемуся на устройстве пользователя.

28 августа 2026 г. · Время чтения: 5 мин

Генеративный пользовательский интерфейс (GenUI) меняет подход к разработке интерфейсов во Flutter. Вместо жесткого кодирования фиксированных экранов для каждого сценария, GenUI позволяет ИИ-агенту динамически генерировать и настраивать компоненты пользовательского интерфейса во время выполнения. Используя JSON-сообщения интерфейса «Агент-пользователь» (A2UI) и пакет genui, приложение на Flutter может «на лету» отображать динамические карточки и поверхности на базе ИИ.

Однако по мере создания реальных агентских приложений я столкнулся с необходимостью снизить задержку и уменьшить количество возможностей для ошибок со стороны моделей. При разработке с использованием больших языковых моделей (LLM) возникает соблазн полагаться на модель во всем. Но если просить LLM выполнять задачи, для которых она изначально не предназначена (например, арифметику), это может увеличить задержку и создать больше предпосылок для ошибок.

Именно здесь на помощь приходят клиентские функции A2UI.

В этой статье я расскажу, как клиентские функции позволяют агенту делегировать локальные операции непосредственно коду Dart на устройстве пользователя, сокращая количество обращений туда и обратно и обеспечивая более предсказуемые результаты в приложениях Flutter GenUI.

Для чего нужны клиентские функции

Отправка сырых промптов туда и обратно в LLM для простых математических вычислений неэффективна: это увеличивает задержку на круг связи и расходует лишние токены. Вместо этого клиентские функции позволяют агенту вычислять такие значения, как стоимость ингредиентов, итоговая сумма налога или конвертация единиц измерения, локально на самом устройстве.

Клиентские функции решают эту проблему, создавая четкое разделение труда:

  • Клиент Flutter объявляет доступные клиентские функции в каталоге GenUI, сообщая агенту, какие локальные операции могут быть вызваны, какие параметры они ожидают и в каком формате возвращают результат.
  • Агент LLM определяет, когда и где должен быть отображен компонент, и выдает выражение A2UI, вызывающее клиентскую функцию с необходимыми аргументами (например, ID товара и количество).
  • Клиент Flutter вычисляет выражение локально и выполняет математические операции синхронно в коде Dart, сразу же отображая чистый, отформатированный результат на экране.

Перекладывая вычисления на клиентское устройство, ваше приложение избегает ненужных сетевых расходов, добивается единообразного форматирования и снижает общее потребление токенов.

dart

Давайте рассмотрим, как я реализовал этот паттерн в примере приложения под названием Commis — интеллектуального помощника, созданного для коммерческих кухонь и кейтеринговых команд.

Анатомия класса CalculateCostFunction

Готовясь к предстоящему мероприятию, шеф-повар может задавать вопросы об ингредиентах, используемых в меню. Чтобы надежно рассчитывать и отображать стоимость ингредиентов без ожидания ответов от сервера, я создал клиентскую функцию CalculateCostFunction.

В пакете genui синхронные клиентские функции расширяют SynchronousClientFunction. Вот полная реализация из client_functions.dart:

dart

Давайте разберем ключевые части этого класса:

  • name: Уникальный идентификатор (calculateCost), который ИИ-агент использует при генерации вызовов функций внутри полезной нагрузки A2UI.
  • description: Краткое пояснение, отправляемое в LLM, чтобы она знала, когда и зачем вызывать эту функцию и какого формата вывода ожидать.
  • returnType: Указывает тип данных, возвращаемый функцией (в данном случае строку).
  • argumentSchema: Эта схема, созданная с помощью json_schema_builder, точно сообщает LLM, какие параметры необходимы (ingredient_id и quantity).
  • executeSync: Основной метод Dart, выполняемый на устройстве пользователя при отрисовке интерфейса. Он разбирает входящие аргументы, вызывает мой локальный CostService и возвращает отформатированную строку с суммой в долларах.

Если вы только что заметили, что этот паттерн очень похож на тот, что используется для записей каталога компонентов пользовательского интерфейса, вы абсолютно правы! И то, и другое предоставляет метаданные для рассуждений агента в паре с логикой Dart, которая делает что-то полезное: либо создает виджеты, либо, как в данном случае, вычисляет значение.

Регистрация в каталоге и интеграция с системным промптом

Чтобы сделать calculateCost доступным для агента, я регистрирую его в каталоге GenUI моего приложения.

При создании экземпляра Catalog я передаю CalculateCostFunction() в список functions вместе с компонентами интерфейса:

dart

При инициализации сеанса беседы PromptBuilder из genui проверяет каталог и автоматически извлекает все объявления клиентских функций, включая их имена, описания и схемы в системный промпт, предоставляемый Gemini.

Благодаря этому, когда шеф-повар спрашивает о стоимости рецепта, Gemini не пытается угадать или вычислить общую сумму в долларах. Вместо этого он выдает сообщение A2UI, содержащее вызов calculateCost (в данном случае для цены трех банок фасоли):

json

Обратите внимание, как значение для свойства call в сообщении A2UI совпадает с именем функции (calculateCost), зарегистрированной в каталоге. Когда SurfaceController получает это сообщение, он вычисляет calculateCost локально на устройстве с помощью executeSync и сразу выводит на экран точную долларовую строку (например, $2.97).

Быстрая итерация для разработчиков с функцией Flutter Hot Reload

Поскольку клиентские функции не завязаны на бэкенд-микросервис или развертывание облачных функций, работа с ними по-прежнему ощущается как старый добрый Dart.

Если я захочу обновить форматирование валюты (например, добавить логику оптовой скидки или переключиться с $4.50 на USD 4.50), я могу просто отредактировать executeSync в Dart, сохранить файл и наблюдать, как hot reload обновляет мое приложение с новым результатом.

Резюме и следующие шаги

Готовы попробовать GenUI и клиентские функции в собственных приложениях?

  • Ознакомьтесь с официальным руководством Intro to GenUI Codelab, чтобы изучить основы генеративного интерфейса.
  • Изучите , чтобы узнать подробности об API и определениях каталога.
  • Просмотрите flutter/demos repository on GitHub, чтобы ознакомиться с полным исходным кодом Commis и других примеров Dart GenUI.

Успешной разработки!

← Все статьи

О чём эта статья