Композиты и суб-воркфлоу

Когда граф перестаёт помещаться на экран, кусок его можно свернуть в одну карточку — композит. Внутри неё лежит полноценный подграф со своими нодами и рёбрами; снаружи это обычная нода с портами, которые вы сами и назначили. Композит доступен на бесплатном тарифе, как и все остальные ноды.

Как свернуть и как заглянуть внутрь

Композита нет в палитре — его нельзя перетащить, он создаётся только из уже нарисованного куска графа.

  1. Выделите две или больше нод. Над холстом появится плашка с числом выделенных нод и кнопкой Merge (подпись не локализована), тот же результат даёт Ctrl+G.
  2. Выделенные ноды исчезают с холста, на их месте — одна карточка композита.
  3. Двойной клик по ней открывает тело: холст переключается на подграф, а слева вверху появляется цепочка Root › Composite. Клик по звену возвращает на уровень выше.
  4. Обратная операция — кнопка Ungroup над выделенным композитом или Ctrl+Shift+G: ноды тела возвращаются на холст, рёбра восстанавливаются.

Вход и Выход в композит свернуть нельзя — попытка просто ничего не сделает. Это намеренно: точка входа у воркфлоу ровно одна, и спрятать её внутрь означало бы получить граф, у которого снаружи входа нет.

Интерфейсные порты

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

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

Вход
Проверка заявки
Выход
Снаружи композит — обычная нода: у неё столько портов, сколько рёбер пересекало границу.
Вход
Ответ LLM
Выход
Тело того же композита: его собственный Вход отдаёт значения входных портов, Выход собирает выходные.

Тело проверяется как фрагмент, а не как самостоятельный воркфлоу: требование «ровно один Вход» к нему не применяется, точкой входа служит Вход тела. Всё остальное — типы нод, совместимость проводов, циклы — проверяется теми же правилами, а найденные внутри проблемы всплывают наружу с именем композита в начале строки.

Изоляция пространства имён

Тело исполняется в собственном пространстве имён нод. Практически это значит:

  • снаружи {{ nodes.<нода тела>.output }} не работает — движок не видит внутренние ноды; наружу попадает только то, что тело положило на выходные интерфейсные порты;
  • изнутри точно так же не видны ноды внешнего графа: значения входят только через Вход тела;
  • совпадение идентификаторов не страшно: template_1 внутри композита и template_1 снаружи — разные ноды. В отчёте о запуске внутренние ноды показаны с префиксом: composite_1/template_1.

Разделены при этом именно выходы нод. Переменные сессии (нода Установить переменную) общие: то, что тело записало, читается снаружи и наоборот — иначе композит не мог бы накапливать состояние. Тот же принцип — на странице состояние и переменные.

Вложенность и её предел

Композит внутри композита разрешён: тело — обычный подграф, и в нём может лежать ещё один композит. Глубина ограничена — по умолчанию 5 уровней, значение тарифное. Тот же счётчик считает вызовы WF-инструмент и агента, выступающего инструментом другого агента: это один общий предел рекурсии, а не три разных. Превышение останавливает ноду ошибкой бюджета — см. таймауты и бюджеты.

А вот оболочки итерации (Цикл While, Для каждого, Маппинг, Фильтр, WF-инструмент) вкладывать друг в друга нельзя: валидатор отвечает subgraph.nested_iteration_shell. Подробности и обходные пути — на странице циклы и итерации.

У композита нет своего таймаута

Пер-нодовый потолок времени к композиту, WF-инструмент и агенту не применяется намеренно. Их собственное время — это сумма времён нод, которые они запускают, а каждая из тех уже ограничена. Общий потолок для композита означал бы, что внешняя нода падает по таймауту, пока внутренние честно работают, и отказ приходил бы не туда, где причина. Ограничивают такой запуск потолок времени всего запуска и потолки отдельных нод тела.

WF tool: подграф как инструмент агента

WF-инструмент — та же конструкция «оболочка + тело», но включается она не порядком исполнения, а решением модели. Ноду подключают к порту extensions агента проводом link_extension, задают имя, описание и JSON-схему аргументов; когда модель решает вызвать инструмент, аргументы приезжают на выход Data (это старт тела), а значение, вернувшееся на вход Result, уходит модели как результат вызова.

Вход
ИИ-агент
Выход
WF-инструментT
Тело инструмента
  • Исполнение + данные
  • Расширение
WF tool — сателлит агента: фиолетовая связь регистрирует инструмент, тело исполняется по вызову модели.

У ноды нет входа исполнения: как шаг графа она не запускается никогда, а её тело выполняется столько раз, сколько раз модель вызовет инструмент — возможно, ноль. Имя и описание — это всё, чем модель располагает при выборе, так что «сделать полезное действие» инструментом не называют. Поля и ограничения — на странице ноды WF tool, общая картина по инструментам — инструменты агента.

Композит тоже умеет подключаться к агенту проводом link_extension, но смысл у этого другой: он не становится инструментом сам, а отдаёт агенту инструменты и память, лежащие внутри его тела.

Переиспользовать между воркфлоу

Ноды, которая вызывала бы другой сохранённый воркфлоу, во Flow нет. Композит и WF-инструмент переиспользуют кусок графа внутри одного воркфлоу. Между воркфлоу сегодня доступны три пути:

  • скопировать ноды — выделение, Ctrl+C, Ctrl+V в другом воркфлоу; вместе с карточкой композита переезжает и его тело, а вставленный Вход приклеивается к уже существующему, так что второго не появится. Буфер живёт в открытой вкладке: перезагрузка страницы его теряет;
  • начать с шаблона — готовые сборки из раздела шаблоны;
  • вызвать по HTTP — задеплоить второй воркфлоу вебхуком и обращаться к нему нодой HTTP-запрос. Вебхук — платный триггер, на бесплатном тарифе доступны только публичный чат и виджет; см. лимиты тарифов.

Что дальше