Воркфлоу
Многошаговый разговор на визуальном холсте — ноды, ветвления, условия и переиспользуемые субагенты
Workflow — это визуальная карта того, что агент делает шаг за шагом: кто говорит первым, о чём спросить, когда разветвиться, когда перевести звонок и когда передать разговор другому агенту. Вы собираете её на холсте из нод и соединяете их.
Workflow нужен, когда одного промпта мало: у звонка есть чёткие этапы («сначала квалифицировать, потом собрать данные, потом записать или перевести»), нужна однозначная маршрутизация по ответам звонящего (а не «ИИ обычно делает правильно») или часть работы стоит отдать отдельному специалисту.
Промпт — одна длинная инструкция. Агент читает её один раз и пользуется ею весь звонок. Workflow — много маленьких инструкций, по одной на ноду, с явными переходами между ними. Звонком управляет граф, а агент в каждой ноде отвечает только за свой кусок.
Если агент и так хорошо работает с одним промптом, workflow не нужен. Берите workflow, когда в промпте копятся правила «если X, то Y» и они перестают надёжно работать.
Редактор
Редактор — это вкладка «Workflow» на странице workflow-агента. Новый workflow начинается с трёх нод: «Старт», «Субагент» и «Завершить звонок». Ноды добавляются через «Добавить ноду» (кнопка + или правый клик по холсту), расставляются перетаскиванием и соединяются рёбрами.
Инструменты холста:
| Инструмент | Что делает |
|---|---|
| «Добавить область» | Обвести группу нод именованной областью и написать в ней комментарий — заметки для себя и команды |
| «Упорядочить» | Автоматически разложить граф — «Разложить сверху вниз» или «Разложить слева направо» |
| «Полный экран» | Отдать холсту всё окно |
| Индикатор сохранения | Изменения сохраняются автоматически; в панели видно «Сохранение…» и «Все изменения сохранены» |
| «Глобальный промпт (действует во всех шагах)» | Инструкции, которые добавляются перед промптом каждого шага, — правила, тон и факты, которые иначе пришлось бы повторять в каждой ноде |
Правая панель меняется в зависимости от выбранного:
- Нажмите на ноду — откроются её настройки (промпт, поля, переменные и т. д.).
- Нажмите на ребро — откроются настройки перехода («Условие выхода» / «По значению» / «Всегда»).
- Панель «Переменные» (кнопка в панели инструментов) перечисляет все переменные workflow и в один клик ведёт к ноде, которая её задаёт или читает.
Кнопка «Тестовый звонок» запускает звонок в браузере прямо из редактора — светящийся «светлячок» показывает, какая нода активна в каждый момент.
Отмена и повтор (v2.8) — редактор хранит историю до 20 шагов, так что неверное действие можно откатить (или повторить), ничего не пересобирая. Удаление ноды сначала просит подтверждения (v2.8) — случайный клик не сотрёт шаг.
Начинать с пустого холста не обязательно. В окне «С чего хотите начать?» вариант «Построить как воркфлоу» предлагает готовые воркфлоу или пустой холст и сразу открывает редактор.
Правки сохраняются автоматически в рабочую копию. Звонящие слышат опубликованную версию, пока вы не опубликуете новую, — см. Пока вы не опубликовали версию, звонки идут по рабочей копии и любая правка сразу работает; после публикации звонящие слышат опубликованную версию, пока вы не опубликуете новую, — см. Версии и публикация. Workflow можно также сохранить как шаблон и использовать у других агентов.
Ноды
Каждая нода — шаг разговора. Разные ноды делают разное: одни говорят, другие слушают, третьи маршрутизируют, четвёртые выполняют действия.
«Добавить ноду» предлагает:
| Нода | Что делает |
|---|---|
| «Субагент» | Шаг разговора со своим промптом, знаниями и инструментами |
| «Сообщение» | Произносит заданную фразу |
| «Условие» | Направляет звонок по переменной или по тому, что сказал звонящий |
| «Собрать ввод» | Задаёт один вопрос и сохраняет ответ |
| «Ввод с клавиатуры» | Звонящий набирает цифры на телефоне (DTMF) |
| «Обновить состояние» | Записывает значения в переменные |
| «Инструмент» | Выполняет действие как шаг графа: переадресация звонка, API-запрос, MCP |
| «Интеграция» | Выполняет действие подключённого сервиса — ваших MCP-серверов |
| «Завершить звонок» | Прощается и кладёт трубку |
В графах, собранных раньше, могут встречаться ноды «Агент», «Перевод звонка», «Знания (RAG)», «Перевод на человека» и «Подворкфлоу». Они по-прежнему загружаются и отображаются, а «Агент» и «Перевод звонка» продолжают работать, но в «Добавить ноду» их больше нет: перевод на номер теперь — «Инструмент» → «Переадресация звонка», а базы знаний подключаются к ноде субагента.
Агент
Нода «Агент» встречается в графах, собранных до того, как разговор стали строить из субагентов; новые шаги добавляются как субагенты. Это сердце этапа workflow: когда граф доходит до этой ноды, агент берёт слово и ведёт разговор, пока что-то не запустит переход.
Личность и задача ноды настраиваются прямо на холсте (вкладка промпта открывается по клику на ноду) — это промпт для этого куска разговора, а не для всего звонка. К каждой ноде можно подключить свои базы знаний и инструменты.
Приветствие — первая фраза. Если это входная нода (первая после «Старта»), её звонящий слышит первой.
Когда звонком управляет граф, промпт активной ноды заменяет основной промпт агента: граф задаёт личность и задачу каждого этапа. Перед промптом каждого шага добавляется только «Глобальный промпт (действует во всех шагах)», а нода без собственного промпта работает на промпте своего агента.
Субагент
Субагент — помощник, который работает внутри разговора: забирает его ради конкретной задачи, а потом возвращает результат тому, кто его вызвал.
Субагенты удобны, когда часть работы повторяется или стоит особняком: «проверить личность звонящего», «собрать адрес доставки», «квалифицировать лида по SPIN». Основной агент вызывает субагента, тот делает своё дело и сообщает результат, основной агент продолжает с того же места.
У ноды субагента те же вкладки, что и у ноды агента (промпт, знания, инструменты, действия) — базы знаний подключаются на вкладке знаний. Редактор сам создаёт скрытого агента для субагента: его не видно в списке агентов, и он не учитывается в лимите агентов тарифа.
Переменная результата — куда сохранить результат субагента (например, identity_verified, lead_score).
Кто говорит первым
По умолчанию субагент, получив слово, сразу говорит — здоровается или задаёт первый вопрос. Два переключателя это меняют:
- «Ждать реплику клиента (не говорить первым)» — субагент молчит и отвечает только после того, как звонящий что-то скажет. Включайте, если субагент — первая остановка звонка и начать должен звонящий (настоящее «Алло?»), или посреди звонка, когда предыдущий шаг уже всё сказал и субагенту нужно только выслушать ответ.
- «Молчаливый шаг (не говорить)» — субагент не говорит вовсе. Он читает разговор, решает, какой результат вернуть, и сразу отдаёт управление. Это невидимый маршрутизатор: «прочитай, о чём спросил звонящий, и реши, какой это отдел» — без слов, только решение для ветвления.
Допустимые значения результата
Обычно субагент завершает работу с тем значением, какое сочтёт нужным. Если дальше вы ветвитесь по результату рёбрами По значению, ограничьте его закрытым списком:
- Перечислите значения в «Допустимые значения результата» (например,
sales,support,billing). - Субагент обязан завершить работу ровно одним из них — придумать новое он не может.
- На каждое значение — своё ребро По значению (
результат = "sales"→ …), и маршрутизация становится чистой и предсказуемой.
Так субагент надёжно решает и направляет: результат гарантированно совпадёт с одной из ваших веток.
Субагент возвращает один результат. Что дальше — задаётся рёбрами По значению или Всегда по этому результату; рёбра Условие выхода на выходе субагента не используются. Поэтому для маршрутизирующего субагента рекомендуем «Допустимые значения результата» + рёбра По значению.
Сообщение
Нода «Сообщение» произносит заданную фразу — без хода ИИ и без импровизации. Подходит для переходов («Секунду, соединяю вас…»), обязательных по закону предупреждений и подтверждений, где важна каждая формулировка.
Текст — что сказать. Поддерживает {{переменные}}, например "Спасибо, {{first_name}}, записала вас на {{appointment_time}}."
Нода «Сообщение» занимает ход целиком — агент ничего не добавит от себя.
Собрать ввод
Нода «Собрать ввод» задаёт один вопрос и сохраняет ответ звонящего в переменную.
Вопрос — что спросить. Поддерживает {{переменные}}.
Переменная — куда сохранить ответ.
«Макс. пауза тишины (сек)» (v2.8) — сколько ждать ответа на этот вопрос, прежде чем идти дальше. Задаётся для каждой ноды: на «да/нет» можно ждать меньше, чем на номер договора, который диктуют вслух.
Используйте, когда перед продолжением нужно конкретное значение — email, номер договора, число гостей, тип проблемы. Следующая реплика звонящего становится значением; сразу за нодой можно ветвиться по нему ребром По значению.
Ввод с клавиатуры
Нода «Ввод с клавиатуры» просит звонящего набрать цифры на клавиатуре телефона (DTMF) и сохраняет нажатое в переменную — добавочный номер, номер клиента, выбор пункта меню.
| Поле | Описание |
|---|---|
| «Сохранить в переменную» | Куда записать цифры, например extension |
| «Вопрос» | Что агент говорит, прежде чем звонящий начнёт набирать |
| «Сколько цифр» | Сколько цифр ожидать (1–32) |
| «Клавиша завершения» | Клавиша, которой ввод можно закончить раньше, например # |
| «Пауза после последней клавиши (сек)» | Сколько ждать после последнего нажатия, прежде чем идти дальше; по умолчанию 4 с |
| «Повторить цифры для подтверждения» | Проговаривает набранные цифры и просит подтвердить |
| «Прервать реплику при нажатии клавиши» | Первое нажатие сразу обрывает фразу — удобно в меню, когда звонящий уже знает нужный пункт |
Обновить состояние
Нода «Обновить состояние» записывает одно или несколько значений в переменные workflow, ничего не говоря и не спрашивая. Подходит, чтобы задать значения по умолчанию, отметить флаги прогресса или сохранить значения, вычисленные на прошлых шагах.
«Переменные» — пары «переменная — значение».
И имена, и значения поддерживают {{переменные}}, так что новые значения можно собирать из существующих.
Условие
Нода «Условие» только маршрутизирует: не говорит, не спрашивает, а отправляет звонок по той исходящей ветке, которая совпала. «Как принимается решение»: «По переменной» (каждая ветка сравнивает одну переменную со значением) или «Решает ИИ» (каждая ветка — фраза, и ИИ выбирает ту, что подходит к сказанному).
Условия задаются на исходящих рёбрах — см. рёбра «По значению» ниже.
Ставьте отдельную ноду «Условие», когда нужна явная точка развилки: много веток от значения одной переменной. Так логику маршрутизации видно на холсте сразу.
Инструмент
Нода «Инструмент» выполняет действие как шаг графа — ИИ не решает, вызывать ли его. Берите её, когда нужен факт или действие, а не разговор: «найди клиента», «проверь остаток», «отправь подтверждение».
Выберите, что делает шаг:
| Инструмент | Что делает |
|---|---|
| «Переадресация звонка» | Переводит звонок на номер в формате E.164 ({{переменные}} работают). Перевод односторонний, поэтому сразу за ним автоматически добавляется «Завершить звонок» |
| «API-запрос» | Вызывает ваш HTTP-эндпоинт (URL, метод, заголовки, параметры, тело) |
| «MCP-серверы» | Запускает инструмент подключённого MCP-сервера |
Окно «Настроить: Инструмент» для API-запроса
В окне «Настроить: Инструмент» для API-запроса стоит знать несколько полей:
| Поле | Описание |
|---|---|
| «Когда выполняется» | «До звонка (предзагрузка)», «Во время звонка» или «После звонка» |
| Тело (поля JSON) | Ваши поля JSON с {{переменными}} |
| «Отправлять только мои поля» | После звонка отправить только тело и параметры этого шага, без полных данных звонка |
| «Повторы при ошибке» | Если ваш сервер не ответил статусом 2xx, запрос уходит снова после каждой паузы. По умолчанию 7 повторов: 1, 5, 30 минут, 2, 6 часов, 1, 2 дня («Всего попыток: 8»). Единицы — минуты, часы, дни; «Добавить повтор», удалить повтор или «Стандартное расписание» — сброс к умолчанию |
Повторы работают только для шагов «После звонка» — запрос во время звонка не повторяется: звонящий не может ждать. Каждая попытка записывается в CRM → «Коммуникации», можно настроить уведомление о сбое. Подробно — на странице Вебхуки и доставка.
Ответ становится доступен всем следующим нодам. Если ответ — JSON-объект, каждое поле верхнего уровня становится отдельной переменной: ответ {"is_known": true, "tier": "gold"} запишет и is_known, и tier, чтобы по ним ветвиться.
Каждое текстовое поле ноды «Инструмент» — URL, значения заголовков, тело — поддерживает {{переменные}}. Подставьте переменную в путь URL, заголовок или тело запроса без кода.
Если вызов упал (HTTP-ошибка, таймаут, сеть), нода записывает сбой, и граф идёт дальше — без данных. Продумайте следующие условия на случай «значения нет».
Запрос во время звонка может занять пару секунд. Чтобы звонящий не сидел в тишине, включите «Голосовой филлер при API-запросах» в разделе «Настройки» → «Звонок» агента: агент коротко скажет «секунду…», пока шаг загружается.
Знания (RAG)
Только в старых графах. Базы знаний теперь подключаются к ноде субагента (вкладка знаний), а не отдельным шагом; существующие ноды RAG по-прежнему загружаются. Нода «Знания (RAG)» — вариант инструмента для поиска по базе знаний: выбранная база, поисковый запрос (можно с {{переменными}}), и нода выполняет поиск как шаг графа.
Используйте её, когда нужно что-то найти до того, как заговорит нода агента: например, достать последний заказ клиента, чтобы следующая нода агента упомянула его, не переспрашивая. Найденное попадает в переменную, которую можно подставлять в промпты и сообщения.
Интеграция
Нода «Интеграция» — вариант инструмента для подключённых сервисов: ваших MCP-серверов. Вы выбираете сервис и конкретное действие (например, check_availability, create_event), задаёте параметры, и нода вызывает интеграцию без участия ИИ.
Если интеграция у этого агента не подключена, нода проходит насквозь, ничего не делая, и граф продолжается. Учитывайте в следующих условиях случай «не выполнилось».
Перевод звонка
Только в старых графах — в новых используется «Инструмент» → «Переадресация звонка», который работает так же. Нода «Перевод звонка» переводит звонок на внешний номер. После успешного перевода звонок покидает ваш workflow — агента на линии больше нет.
Номер — в международном формате с + (например, +74951234567). Поддерживает {{переменные}}, так что номер может прийти из прошлого шага (например, из ответа на «с каким офисом вас соединить?»).
Если перевод не прошёл (неверный номер, не ответили, телефония не настроена), граф откатывается, и текущий агент остаётся на линии. Разговор продолжается — агент может извиниться и предложить другой путь.
Завершить звонок
Нода «Завершить звонок» заканчивает разговор: агент произносит прощание и кладёт трубку. Ставьте её в конец веток «всё сделано» или «помочь не можем, извините». Как сформулировать прощание и как не звучать записью — в разделе Как попрощаться.
Кроме подведённого ребра, настраивать ничего не нужно.
Подворкфлоу
Нода «Подворкфлоу» была зарезервирована для встраивания другого workflow как подграфа. В «Добавить ноду» её больше нет; в старых графах она проходит насквозь, ничего не делая. Чтобы переиспользовать кусок разговора, используйте субагентов.
Рёбра (Connections)
Вы соединяете одну ноду со следующей через ребро. Триггер ребра решает, когда срабатывает переход.
Есть три триггера:
| Триггер | Кто решает | Когда срабатывает |
|---|---|---|
| Условие выхода | AI | Когда разговор делает это естественным следующим шагом. AI получает «инструмент перехода», который он может вызвать. |
| По значению | Рантайм | Когда переменная совпадает с правилом, которое вы написали. Оценивается до того, как AI ответит. |
| Всегда | Рантайм | Безусловно — в тот момент, когда источниковая нода завершилась. Без ввода звонящего, без участия AI. |
Условие выхода (по интенту)
Используйте Условие выхода, когда только AI может определить, когда переключаться — «если звонящий спрашивает про цены, переведи на агента продаж», «если это звучит как жалоба, запусти subagent извинений».
Вы простыми словами описываете, когда шаг завершён (например, «звонящий спрашивает про цены или хочет перейти на тариф выше»). AI видит это как инструмент с этим условием и по ходу разговора решает, вызывать ли его. Если из ноды выходит несколько рёбер Условие выхода, AI выбирает максимум одно за ход.
По значению (детерминированное ветвление)
Используйте По значению, когда хотите, чтобы граф — а не AI — решал на основе известного факта: «если lead_score is more than 7, отправь на closer; иначе — вежливо заверши звонок».
Эти рёбра проверяются до того, как AI ответит, так что в этом ходе они всегда побеждают AI. AI не может переопределить совпавшее значение.
Вы можете строить условие из этих операторов:
| Оператор | Значение | Пример |
|---|---|---|
| is | точное совпадение (регистронезависимо для текста) | intent is "billing" |
| не равно | не совпадает | status is not "active" |
| содержит | совпадение по подстроке (регистронезависимо) | feedback contains "broken" |
| больше | численное > | lead_score is more than 7 |
| меньше | численное < | wait_minutes is less than 5 |
Ветка может принимать и несколько значений: в панели ветки кнопка «Ещё одно значение» добавляет ещё одно — ветка срабатывает, если совпало любое из значений, например один из этих двух номеров.
Вы также можете комбинировать условия через Все (каждое должно совпасть — AND) или Любое (хотя бы одно должно совпасть — OR), и вкладывать их. Так что правило вроде «звонящий известен и его tier — gold или premium» становится:
All:
- is_known is true
- Any:
- tier is gold
- tier is premium
Если вы ссылаетесь на переменную, которая ещё не была установлена (например, AI её так и не собрал), условия на ней всегда не выполняются — они не выдают ошибку, они просто не совпадают. Так что loyalty_tier is "gold" вернёт false, если loyalty_tier никогда не устанавливался. Проектируйте свои ветки так, чтобы обрабатывать это — обычно через ветку else (см. ниже).
Ветка else — когда ни одно условие не совпало
Если из ноды выходит несколько рёбер По значению и ни одно не совпало, звонок уходит на ребро другого типа с самым низким приоритетом («Всегда» или «Условие выхода»). Если fallback нет вообще, AI возвращает себе контроль и может продолжать свободно.
Распространённый паттерн: несколько рёбер По значению для хорошо известных путей плюс ребро Всегда на catch-all (сказать что-нибудь через «Сообщение», затем «Завершить звонок» или перевести).
Always (auto-advance)
Используйте Всегда, когда следующий шаг безусловный — без решения, без ввода звонящего. Два естественных применения:
- Цепочка шагов: Сообщение → Обновить состояние → Сообщение → Инструмент → Условие. Каждый шаг завершается, и ребро Always сразу продвигает дальше.
- Авто-продвижение после того, как агент закончил говорить: нода Agent с исходящим ребром Always означает «как только AI перестанет говорить, двигайся дальше» — без необходимости ответа звонящего. Полезно для монологовых потоков, например агента-презентера, который произносит текст, а затем переходит к следующей секции.
По значению и Всегда (детерминированные) всегда побеждают Условие выхода. Если совпало ребро «По значению», инструменты перехода AI игнорируются в этом ходе. Именно это позволяет вам писать правила, которые AI не может обойти.
Порядок веток
Когда из одной ноды выходит несколько рёбер, редактор позволяет задать приоритет, перетаскивая строки вверх или вниз. Ветки с более низким приоритетом проверяются первыми. Это важно только тогда, когда две ветки могут сработать на одном и том же ходу — обычно два ребра По значению с пересекающимися правилами. Побеждает первая совпавшая ветка.
Перенос контекста — сколько помнит следующий агент
У каждого ребра есть настройка Carry context, которая контролирует, сколько транскрипта разговора видит следующая нода:
- Полный транскрипт (по умолчанию) — следующий агент видит всё, что было сказано до этого.
- Только сводка — платформа суммирует предыдущий разговор и передаёт следующему агенту короткое резюме.
- Ничего — следующий агент начинает с нуля, без предыдущего транскрипта.
Используйте Только сводка, когда передаёте дело специализированному агенту, которому не нужно каждое слово — это экономит токены и держит нового агента сфокусированным. Используйте Ничего для веток, где персона нового агента должна быть отдельной (например, опрос об удовлетворённости в конце звонка).
Переменные
Переменные — это память workflow. Большинство вещей в workflow — это либо установка переменной, либо её чтение.
Объявление переменных
Панель Переменные (кнопка в тулбаре) показывает каждую переменную workflow с шагами, которые её устанавливают или читают. Клик по переменной — переход к сеттеру; это самый быстрый способ найти, где что-то идёт не так.
Вы можете объявить переменную со значением по умолчанию в панели — полезно для флагов вроде escalated=false, которые должны существовать с самого начала, чтобы ваши условия не сваливались тихо на «отсутствии».
Встроенные переменные
Часть переменных заполняется за вас — их не объявляют и не задают, они просто есть. Раздел Встроенные переменные в панели переменных показывает их все; клик копирует токен, который потом можно вставить в любое поле.
Они делятся на четыре группы, и группа важна: от неё зависит, когда значение появляется.
Звонок — известно до того, как агент скажет первое слово:
| Переменная | Что внутри |
|---|---|
{{call_from}} | Номер звонящего |
{{call_to}} | Набранный номер |
{{call_direction}} | inbound или outbound |
{{customer_phone}} | Номер клиента — звонящий на входящем, вызываемый на исходящем |
{{customer_email}} | Почта клиента, если известна |
Поскольку они есть с первого мгновения, ветвиться по ним можно на самом первом узле — условие на call_from, чтобы поздороваться с постоянным клиентом по имени, направить по коду страны или отправить незнакомый номер на проверку прежде всего остального.
Контакт — заполняется, когда звонящий сопоставлен с карточкой:
| Переменная | Что внутри |
|---|---|
{{firstname}} / {{lastname}} | Имя звонящего |
{{email}} | Почта звонящего |
{{phone}} | Телефон звонящего |
{{company}} | Компания звонящего |
Момент — пересчитывается при каждом чтении, поэтому условие на них означает «прямо сейчас»:
| Переменная | Что внутри |
|---|---|
{{current_time}} | Время сейчас, ЧЧ:ММ, в часовом поясе агента |
{{current_date}} | Дата сейчас, ГГГГ-ММ-ДД |
{{current_datetime}} | То и другое вместе |
{{current_hour}} | Час, 00–23 — сравнивайте через «больше/меньше» для логики рабочих часов |
{{current_weekday}} | День недели (Monday…) |
{{session_duration}} | Сколько идёт разговор, м:сс |
{{session_duration_sec}} | То же в секундах — эта для числовых сравнений |
{{current_node}} | Имя шага, который идёт сейчас |
{{previous_node}} | Имя шага, откуда пришли |
Время, дата, час и день недели считаются в часовом поясе агента.
{{current_hour}} и {{session_duration_sec}} — две самые полезные: первая закрывает логику рабочих часов без всякой интеграции, вторая позволяет свернуть затянувшийся разговор — «если прошло больше девяти минут, подводи итог и переводи».
После звонка — эти пусты во время разговора и заполняются только когда он закончится:
| Переменная | Что внутри |
|---|---|
{{call_summary}} | Сводка звонка от ИИ |
{{call_transcription}} | Полный транскрипт |
{{call_sentiment}} | Как прошёл разговор |
{{call_task_achieved}} | Достигнута ли цель (true/false) |
{{call_date}} | Дата начала звонка, DD.MM.YYYY, в часовом поясе агента |
{{call_time}} | Время начала звонка, HH:MM, в часовом поясе агента |
Как переменные устанавливаются
| Источник | Пример |
|---|---|
| Значения по умолчанию (объявленные в панели Variables) | escalated = false, установленное до начала звонка |
| Собрать ввод | Голосовой ответ звонящего захватывается в переменную ноды |
| Обновить состояние | Вы записываете значение (литерал или составленное из {{tokens}}) напрямую |
| Результат Tool / Integration | Весь ответ сохраняется под именем ноды; если ответ — JSON-объект, каждое поле верхнего уровня тоже становится отдельной переменной |
| Return из Subagent | То, чем subagent завершается, сохраняется в return-переменную ноды subagent |
Чтение переменных — {{tokens}}
Везде, где на ноде можно ввести текст, — промпт субагента, текст «Сообщения», вопрос «Собрать ввод», URL / тело / заголовки «Инструмента», номер переадресации, значение «Обновить состояние», значения условий — можно вставить {{переменную}}, и она подставится во время звонка.
Пути с точкой тоже работают для вложенных данных — например, если Tool-ответ был {"customer": {"name": "Anna", "tier": "gold"}}, можно читать {{customer.name}} или {{customer.tier}}.
Если токен ссылается на несуществующую переменную, литеральный текст {{name}} оставляется на месте (он не очищается). Это намеренно — так сломанные шаблоны легко заметить в test call, вместо того чтобы тихо их проглатывать.
Как попрощаться
Узел Завершить звонок закрывает разговор, и то, как он это делает, стоит минуты внимания — это последнее, что слышит звонящий.
Как прощаться предлагает два режима:
| Режим | Что вы пишете | Когда подходит |
|---|---|---|
| Точные слова | Сами фразы | Формулировка важна — юридическая формула, фирменное завершение |
| Указание для ИИ | Что прощание должно сделать, например «поблагодари за время и тепло попрощайся» | Хочется, чтобы звучало естественно и подходило к состоявшемуся разговору |
В режиме точных слов можно написать несколько прощаний, по одному в строке. На каждый звонок берётся случайное. Это та мелочь, которая не даёт агенту с большим потоком звучать как автоответчик: двадцать человек подряд слышат одну фразу и замечают это, а при пяти вариантах — никто.
Оставьте поле пустым — агент попрощается своей фразой по умолчанию.
Перевести на язык звонка автоматически переводит прощание на тот язык, на котором разговор в итоге шёл. Удобно, когда агент работает на нескольких языках и вести список прощаний на каждый не хочется. Выключите, если формулировка должна остаться ровно такой, как написана: переведённая юридическая формула — уже не та формула, которую согласовали.
Распространённые паттерны
Квалификация → Ветвление → Маршрутизация
Start
└─ Субагент (приветствие + квалификация)
└─ Gather input (intent)
└─ По значению: intent == "sales" → Субагент (продажи)
└─ По значению: intent == "support" → Субагент (поддержка)
└─ Всегда (всё остальное) → Сообщение «Соединяю вас» → Инструмент (Переадресация звонка) → Завершить звонок
Поиск → Персонализация
Start
└─ Tool (CRM lookup, writes is_known, name, tier)
└─ По значению: is_known == true → Субагент (тёплое приветствие с {{name}})
└─ Всегда (иначе) → Субагент (обычное приветствие)
Переиспользуемый хелпер (side-trip Subagent)
Субагент (основной разговор)
└─ Условие выхода: "Caller mentions an address" → Subagent (address collector)
└─ on finish: result = full_address
└─ Agent continues with {{full_address}}
Что заблокировано во время workflow-звонка
Некоторые значения по умолчанию меняются, когда звонок управляется графом:
- Язык заблокирован на том, что использует первый агент workflow. AI не может сменить язык посреди звонка. Это предотвращает уход модели не на тот язык на шумном ходу.
- Основной промпт агента заменяется промптом активной ноды. Это правило «граф владеет персоной» — см. warning под Agent.
- Первое сообщение берётся из приветствия входной ноды — у workflow-агента нет вкладки «Модель» с первым сообщением.
Защита от циклов — бюджет шагов
У каждого workflow есть максимальное число переходов на звонок (по умолчанию 100). Каждый раз, когда граф переходит к новой ноде, счётчик уменьшается на единицу. Когда он доходит до нуля, workflow перестаёт прыгать между нодами, чтобы предотвратить неуправляемые циклы.
Вы можете выбрать запасную ноду для этого случая (обычно «Инструмент» с переадресацией или «Завершить звонок») — звонок отклоняется туда, как только бюджет исчерпан. Иначе AI возвращает себе контроль, и граф фактически замораживается на оставшуюся часть звонка.
Об этом очень редко приходится думать — это страховочная сетка для графов, которые случайно зациклились. Если вы попали в неё при обычном использовании, у вас, скорее всего, где-то цикл.
Версии и публикация
Редактор всегда открывает вашу рабочую копию. Пока вы не опубликовали версию, звонки идут по рабочей копии и любая правка сразу работает. Опубликуйте версию, чтобы защитить прод: после этого звонки идут по опубликованной версии, а ваши правки не видны звонящим, пока вы не опубликуете снова.
Панель инструментов показывает, что сейчас в силе:
| Что видно | Что это значит |
|---|---|
| В проде: v3 | Звонящих обслуживает третья версия. Ваши правки их не касаются. |
| В проде: черновик | Ничего не опубликовано: звонки идут по графу, который вы сейчас редактируете, поэтому любая правка сразу работает. |
| Опубликовать | Заморозить рабочую копию как новую версию и вывести её в эфир. |
| Снять с публикации | Убрать опубликованную версию. Звонки перейдут на рабочую копию — удобно для быстрого отката, но помните: рабочая копия это то, что вы последним оставили на холсте. |
Привычка, которая себя оправдывает: строить свободно, сделать тестовый звонок и публиковать только тогда, когда поток делает то, чего вы ждёте. Если опубликованная версия окажется неудачной, вернуть предыдущую — дело секунд, все версии остаются в списке.
Публикация копирует граф таким, каков он в этот момент. Дальнейшие правки живую версию не меняют — нужно опубликовать заново. Так задумано: недоделанная правка никогда не попадёт в живой звонок.
Ветки
Ветка — это вторая рабочая копия того же воркфлоу. Заводите её, когда хотите попробовать другой маршрут: короче квалификацию, другой адрес перевода, — не трогая поток, которому уже доверяете.
Ветка создаётся в панели версий, там же переключается и удаляется. Звонящих достигает только опубликованная версия, поэтому ветка может лежать недоделанной сколько угодно.
Это самый безопасный способ переработать воркфлоу, который уже обслуживает настоящие звонки: ответвиться, перестроить нужную часть, протестировать ветку и опубликовать, когда она окажется лучше исходной.
Экспорт холста
Редактор выгружает граф в PNG, JPG или PDF. Это картинка потока, а не резервная копия — обратно её не загрузить. Она для разговоров вне платформы: согласовать сценарий звонка с коллегой, показать клиенту, как агент обработает обращение, приложить схему к задаче.
Тестирование
Кнопка Тестовый звонок в редакторе открывает браузерный звонок с текущим draft-ом workflow. Пока звонок идёт, светящийся светлячок движется между нодами на холсте, чтобы вы видели, где именно сейчас звонок. Редактор заблокирован во время test call, чтобы правки не рассинхронизировались с живым состоянием.
Проверьте тестовым звонком:
- Ваши условия совпадают со значениями, которых вы ожидаете (следите, не проскакивает ли светлячок мимо ветки, которая, как вы думали, должна сработать).
- Ваши токены подставляются правильно (прислушайтесь к зависшему
{{name}}, если значение ещё не было установлено). - Сбои инструментов деградируют изящно (ваш fallback-маршрут действительно срабатывает).
Режимы сбоев, о которых стоит знать
| Ситуация | Что происходит |
|---|---|
| Вызов Tool / Integration упал | Граф продолжается без данных. Ваши последующие условия должны обрабатывать отсутствующую переменную. |
| Переадресация не удалась (неверный номер, не отвечают, телефония не настроена) | Граф откатывается, текущий агент остаётся на линии, и разговор продолжается как обычно. |
| Subagent не запустился | Побочный заход отменяется, родительский агент остаётся, и произносится короткая фраза о сбое. |
{{missing_variable}} в тексте | Оставляется литералом в выводе — легко заметить во время test call. |
| Нода «Подворкфлоу» (старые графы) | Проходит насквозь, ничего не делая. |
| Бюджет шагов исчерпан | Отклоняется на запасную ноду, если она задана, иначе AI возвращает себе контроль. |
Когда НЕ использовать Workflow
Workflows мощны, но они не правильный ответ для каждого агента. Останьтесь с одним промптом, когда:
- Разговор открытый («отвечать на вопросы звонящего о наших продуктах»).
- У вас нет чёткой логики ветвления — большинство решений — это суждения, с которыми AI хорошо справляется.
- Вы бы написали одну ноду агента и одну «Завершить звонок» — это просто промпт с лишними шагами.
Переходите на workflow, когда:
- Вы можете набросать звонок как блок-схему с тремя или более чёткими этапами.
- Вам нужно хотя бы одно детерминированное ветвление по переменной (ребро По значению).
- Вы хотите переиспользовать кусок разговора между несколькими агентами (subagent).
- Вы уже накапливаете правила «если звонящий говорит X, то делай Y» в промпте, и они ненадёжны.