Настройка инструментов
Инструмент в GenUI — это Action Block, который модель может вызвать по ходу разговора. Он нужен, когда для ответа не хватает данных или требуется что-то сделать.
Обычные задачи:
- запросить API или базу;
- посчитать;
- получить запись по идентификатору;
- преобразовать данные;
- запустить процесс, возвращающий полезный результат.
Блок действий, который ничего не возвращает, инструментом быть не может.
Для каждого инструмента GenUI передаёт модели:
- имя функции;
- описание;
- параметры;
- обязательность;
- описания параметров;
- тип возвращаемого значения;
- описание результата.
Имя и описание блока действий здесь не косметика: именно по ним модель решает, вызывать инструмент или нет.
Если инструмент выбросил исключение, ошибка перехватывается и уходит модели структурированным ответом. Интерфейс при этом не ломается, а модель может объяснить сбой или предложить обходной путь.
Требования
Блок действий обязан возвращать значение
Инструмент устроен по схеме «запрос — ответ». Без возвращаемого значения модели нечего передать.
Поддерживаемые типы
StringintdoubleboolColorDateTimeTimestampRangeLatLngGooglePlaceJSONDataStructEnum- строковые типы путей к медиа:
ImagePath,VideoPath,AudioPath,MediaPath - списки из перечисленных типов
Остальные типы отклоняются при проверке.
Один инструмент — один раз
Настроить один и тот же блок действий дважды на одном виджете GenUI нельзя — это ошибка.
Сообщения загрузки
У каждого инструмента может быть своё сообщение, которое показывается, пока он работает.
- Задали — показывается оно.
- Не задали — показывается
Processing....
Это не то же самое, что сообщение размышления на уровне виджета: оно по умолчанию Thinking... и показывается до вызова инструмента.
Сериализация
Типы данных FlutterFlow превращаются в понятный модели JSON:
- Color — строка CSS:
Color(0xFF4CAF50)→"#4CAF50"; - DateTime — строка ISO 8601:
DateTime(2024, 3, 15)→"2024-03-15T00:00:00.000"; - TimestampRange — начало и конец в миллисекундах через
|:TimestampRange(1700000000000, 1700086400000)→"1700000000000|1700086400000"; - LatLng — строка координат:
LatLng(37.7749, -122.4194)→"37.7749,-122.4194"; - GooglePlace — объект JSON с данными о месте;
- DataStruct — через
toMap():Product(name: "Shoes", price: 99)→{ "name": "Shoes", "price": 99 }; - Enum — строка:
OrderStatus.delivered→"delivered".
Что стоит учесть
Один инструмент — одна задача
Хорошо:
getOrderDetailssearchProductsgetWeatherForLocationcalculateQuote
Плохо:
handleRequestfetchDataprocessWorkflow
Описание пишется для модели
Хорошо:
Retrieves the current order status, tracking number, and ETA for a given order ID.
Плохо:
Looks up an order.
Возвращайте структуры
Если результат можно описать собственным типом данных DataStruct, так и делайте. Структуру проще передать компоненту каталога, чем разбирать склеенную строку.
Согласуйте выход инструмента со входом компонента
Надёжная схема выглядит так:
- инструмент возвращает
OrderStruct; - компонент каталога принимает
OrderStruct.
Тогда от получения данных до их отрисовки не остаётся ни одного места, где что-то может разойтись.
Типичные примеры
Получение данных
getOrderDetails(orderId: String) -> OrderStruct
Модель вызывает инструмент, получает структуру заказа и рисует карточку заказа.
Поиск
searchProducts(query: String, maxPrice: double?) -> List<ProductStruct>
Модель вызывает инструмент и рисует список найденного компонентом каталога.
Расчёт
calculateMonthlyPayment(amount: double, rate: double, termMonths: int) -> PaymentQuoteStruct
Модель объясняет результат и при желании рисует компонент с расчётом.