2. Данные между узлами¶
Всё, что знает запуск, лежит в одном месте — во фрейме. Это словарь переменных, который едет вместе с исполнением. Узел читает переменные в свои аргументы и записывает результаты обратно переменными.
Фрейм неизменяемый. Запись его не меняет, а порождает новый. Именно поэтому параллельные ветки дальше окажутся безопасными.
Вторая стадия¶
Боту нужно понять, о чём тикет. ClassifyByRulesStage определяет тему и
срочность по ключевым словам, без сети:
{"id": "rules", "type": "stage", "stage": "ClassifyByRulesStage",
"arguments": {"vars": {"text": "text", "subject": "subject"}},
"outputs": {"topic": "topic", "urgency": "urgency"},
"next": "done"}
Она читает text и subject, которые записал загрузчик на шаге 1, и
добавляет во фрейм topic и urgency. Переводим load.next на неё, а
терминал пусть покажет, что получилось:
{"id": "done", "type": "terminal", "result": {"status": "classified"},
"artifacts": ["subject", "topic", "urgency"]}
result.result # {'status': 'classified'}
result.artifacts # {'subject': 'Charged twice for October', 'topic': 'billing', 'urgency': 'normal'}

Аргументы: переменные и литералы¶
Аргументы лежат в двух корзинах. vars берёт значения из фрейма, const
хранит литералы, записанные прямо в JSON:
"arguments": {
"vars": {"ticket_id": "ticket_id"},
"const": {"queue": "tier-2", "reason": "no article matched"}
}
Обе корзины можно использовать в одном узле. Если имя аргумента есть и там и там, побеждает переменная.
Узел может и убрать переменные, которые больше никому не нужны:
После узла text исчезнет из фрейма. Убираться никто не заставляет, но на
длинном графе это заметно облегчает чтение фрейма в отладчике.
Узел как форма¶
Кликните по узлу в редакторе — панель справа покажет ровно то, что объявлено в докстринге: что стадия получает, что отдаёт, какие аргументы необязательны.

У каждого аргумента есть переключатель: «переменная» (взять из фрейма) или «выражение» (посчитать на CEL). Внизу — выходы стадии, у каждого указана переменная, в которую он идёт.
Объявление типов¶
Переменным можно объявить типы. Объявление необязательное: что не объявлено, то не проверяется.
С ним validate() сверяет ваши объявления с типами из спецификаций стадий.
Объявите topic как int — и пайплайн остановится ещё до запуска:
PipelineValidationError: Pipeline validation failed: rules: output 'topic' of
stage ClassifyByRulesStage has type 'string', but is written to vars.topic
typed 'int'
Та же проверка повторяется во время исполнения на каждую запись, так что стадия, вернувшая не то, что обещала, тоже будет поймана. Весь язык типов — на странице типизации переменных.
Дальше: выбор дороги.