Вход и выход воркфлоу
У графа две границы: entry, куда приходит запрос, и exit, откуда уходит ответ. Обе подчиняются жёстким правилам — их нарушение раньше не ломало запуск заметно, а тихо выбрасывало половину работы.
Entry ровно один
Entry — это и есть вход запуска, а не метка старта. Движок разбирает один и тот же входной объект для каждой entry-ноды, поэтому вторая не может принести второй вход: она дублирует первый и запускает вторую, ни с чем не синхронизированную ветку. Обе цепочки выполняются целиком, и обе оплачиваются.
Поэтому два entry — ошибка graph.multiple_entry. Она безусловна: черновика, в
котором две entry ведут к чему-то валидному, не бывает. Сохранить граф ошибка не
мешает, но деплой и запуск блокирует.
Редактор не даст создать вторую entry: перетаскивание из палитры игнорируется, если entry уже есть на холсте, а при вставке готового сниппета его entry подставляется к уже существующей — все рёбра сниппета приходят на неё.
Два выхода entry
output— сообщение. Для чата, Telegram и вебхука это строка, у неё нет полей. Если запуск сделан с произвольным JSON-объектом (ручной запуск, API, вызов из другого воркфлоу), это весь объект целиком.data— контекст триггера фиксированной формы:trigger,workflow_id,execution_id,workspace_id,user_id,chat.session_idи блокиtelegram/webhook/cron.
Exit — хотя бы один, и он должен быть достижим
Граф без exit получает предупреждение graph.no_exit. Хуже другой случай: exit
есть, но до него не доходит ни одного exec- или execute_data-ребра. Такой exit
не выполнится никогда, а запуск закончится пустым результатом — валидатор
отбивает это ошибкой exec.exit_no_exec_trigger.
Ссылка в шаблоне ноду не запускает: {{ nodes.<id>.output }} читает значение, но
не даёт exit сработать.
Что делает exit
- Порт
endпринимает финальное значение. Поле Output Expression (output_mapping) при непустом значении заменяет то, что пришло наend. - Отдельный вход
filesпринимает ссылки на файлы, и они уходят вместе с ответом: в чате картинки, аудио и вложения показываются рядом с сообщением. - Поле Error message (
error_text) задаёт текст, который увидит пользователь при необработанной ошибке. Доступныerror(короткое безопасное описание сбоя),error_code,error_id(код обращения в поддержку),failed_node_idиfailed_node_type. Технических подробностей — ответа провайдера, текста запроса к базе — здесь нет ни при какой настройке: это сообщение читает ваш собеседник, а не вы. Полная картина остаётся в карточке ноды и в логах запуска.
Несколько exit: только для взаимоисключающих ветвей
Все отработавшие exit пишут в один и тот же объект результата. Побеждает не тот, кто закончил позже, а последний в порядке нод внутри определения графа — то есть перестановка списка нод меняет ответ. В чате правило другое: показывается тот exit, который первым начал стримить, токены второго уходят в пустоту.
Поэтому два exit, способные сработать в одном запуске, — это
exec.multi_exit_race: ошибка на деплое и запуске, предупреждение, пока вы
редактируете граф.
- Исполнение + данные
Как чинить гонку
Сведите ветви в один exit. Если они действительно идут параллельно, поставьте
перед ним wait_all и заведите каждую ветвь в его вход
barrier_in. Раздавать каждой параллельной ветке собственный exit — не выход:
это ровно та форма, из-за которой один ответ затирает другой.