Workflow-сценарии
Form-filler и quiz state-machine, вычислимые шаги, отмена workflow, шаблонизация — без LLM-вызова на каждый шаг.
Workflow-сценарии
Иногда чат с агентом — это не «спросил и получил ответ», а сценарий: «зовут как → телефон → удобное время → город → готово, лид в CRM». Делать такое чисто LLM-ом дорого и ненадёжно (модель забывает шаг, путает вопросы, выдумывает). Поэтому в Framix есть workflow-движок: state-machine, которая ведёт диалог по заранее заданным шагам до LLM, без вызова модели на каждом шаге.
LLM подключается только когда сценарий закончен — или когда посетитель явно «выходит» из workflow (например, спрашивает что-то совсем другое).
Зачем это нужно
- Дешевле. Шаг «введите email» проверяется регексом — это бесплатно, не списывается ничего. Целый сценарий из 10 шагов обходится примерно в 1-2 LLM-вызова, а не в 10.
- Надёжнее. Модель не пропустит шаг и не задаст вопрос второй раз.
- Капчурится лид. Шаги пишутся в
project_collectionсо статусомin_progress. Если посетитель бросил сценарий — лид всё равно остался, со всем, что он успел ответить. Это сигнал для оператора, а не баг.
Два типа сценария
Form-filler
Самый простой: серия шагов «вопрос → ответ → валидация → следующий вопрос → … → финал». Финал переводит лид в new.
Пример полей в шагах:
text— свободный текст;email— с regex-валидацией;phone— с regex-валидацией (10-15 цифр, любые разделители);choice— выбор из вариантов (рендерится как quick-reply chips);boolean— да/нет.
Quiz
То же, что form-filler, плюс scoring: каждый ответ может давать баллы (или вычитать), в конце выбирается scoreRange (например, 0-3 → новичок, 4-7 → средний, 8+ → продвинутый) и рендерится персональный результат.
Compute-шаги
Можно вставить вычислимый шаг между вопросами — например, посчитать сумму кредита от введённых параметров. Формула — whitelist-арифметика по полям ответов ({income} * 12 / {rate}), без LLM:
amount = {monthlyPay} * {months}
overpay = amount - {principal}
Хелпер — lib/computeFormula.ts, покрыт тестами на безопасность (нельзя дёрнуть process.env, нельзя выйти за пределы whitelist'а операторов).
Шаблонизация
В текстах шагов можно использовать плейсхолдеры {field} — они резолвятся из ранее введённых ответов:
Спасибо, {name}! На какой email прислать подтверждение?
Помощник — lib/workflowTypes.ts#renderTemplate, покрыт тестами на null/undefined и отсутствующие поля.
Отмена workflow
Если посетитель в середине сценария напишет «отмена / стоп / передумал / не нужно» — regex CANCEL_RE это ловит и возвращает управление LLM. Лид с брошенным сценарием остаётся в in_progress — это ценный сигнал «человек начал, но не закончил», а не баг.
Покрыто тестами: tests/server/utils/workflow-executor.test.ts.
Quick-replies в шагах
Шаги типа choice автоматически рендерятся как quick-reply chips под последним сообщением бота. Клик по чипу отправляет выбранный вариант — это особенно полезно для коротких опросов.
Где это настраивается
/account/agents/<id> → вкладка «Workflow».
- Список сценариев — у одного агента может быть несколько (разные формы для разных лендингов).
- Редактор шагов — drag-and-drop, порядок шагов меняется.
- Reorder через отдельный endpoint, чтобы не пересохранять весь сценарий.
Что хранится
| Таблица | Что |
|---|---|
ai_agent_workflows | Сценарии (определение шагов в JSONB) |
project_collection | Лиды, создаваемые workflow (статус in_progress пока сценарий идёт, new после завершения) |
Совмещение с LLM
В одной сессии могут быть и workflow-шаги, и обычные LLM-ответы:
- Сценарий ведётся, пока шаги не закончились или пока не сработал CANCEL_RE.
- После завершения сценария бот переходит в обычный режим — отвечает по системному промпту + базе знаний.
- Если в середине сценария юзер задал внерелевантный вопрос — он попадает в обычный LLM-ответ (а сценарий ставится на паузу до явного re-engage).
Когда workflow не подходит
- Свободные консультации — лучше LLM с базой знаний.
- Продажи товаров/услуг — этим занимаются commerce-tools и booking-tools (тоже без LLM-цикла на каждый шаг, но через инструменты, а не state-machine).
- Когда шагов меньше двух — проще задать вопрос в обычной LLM-сессии.