Skip to content

Runs & Traces

Run — одно исполнение процесса. Trace — детализированная история run’а. Пара run + trace — первое место, где вы чините production-проблемы.

queued → planning → running → done
failed | cancelled
СтатусЧто это значит
queuedTrigger пришёл, run создан, scheduler ещё не взял
planningScheduler начал, resolver’ит templates, выбирает первые ноды
runningИдёт исполнение шагов (один или несколько параллельно)
doneВсе terminal-ноды отработали успешно
failedКритическая ошибка на одном из шагов (retry-policy исчерпан)
cancelledОператор вручную отменил в UI или через API

Транзиции — atomic, записываются в trace-event’ы. Скипнуть состояние нельзя (queued → done напрямую невозможно — будет как минимум один trace-event planning_started).

Каждое значимое событие — это trace-event. Типовые:

Event familyЧто пишет
run.*Состояние самого run’а (created / started / completed / failed)
step.*Состояние каждого шага (queued / started / completed / failed / retrying)
template.*Resolver-события (resolved / unresolved)
approval.*Approval-gate события (requested / approved / rejected / expired)
cost.*Cost ledger (LLM-call стоит X, Bitrix-call бесплатен)
policy.*Policy evaluations (rate-limit checked, allowed / denied)

События сохраняются в append-only режиме — нельзя удалить или переписать. Retention настраивается на уровне space’а (default 90 дней).

Сбои классифицируются:

  • Retryable — сетевые таймауты, 5xx от провайдера, rate-limits (429). OPORA ретраит с exponential backoff (1s → 2s → 4s → 8s → fail).
  • Non-retryable400 Bad Request (ваши данные плохие), 401 Unauthorized (token протух), 422 Validation Error, UNRESOLVED_TEMPLATE, наши собственные DomainError’ы. Non-retryable’ы падают сразу в failed.

Per-node-type retry-policies задаются в node-registry:

  • external.http — 5 retries, 1s-60s backoff
  • ai.generate — 3 retries (LLM’ы capricious), 5s-30s
  • telegram.message.send — 2 retries (Telegram dedupe сам)

Override возможен на уровне ноды (editor → Advanced → Retry).

Повторный trigger (Telegram ретраит webhook если вы ответили timeout’ом) не создаёт второй run, если trigger-payload уже виден в last-seen-cache’е:

  • telegram.webhook.trigger — ключ = update_id
  • yookassa.webhook.trigger — ключ = object.id + event
  • bitrix24.webhook.trigger — ключ = event-id в header’е
  • generic webhook.trigger — ключ = SHA256(raw body) + URL

Window кэша — 5 минут (достаточно для всех провайдер-retry-схем’ов, мало чтобы не засорять Redis).

На странице /runs/<id>:

  • Timeline сверху — визуализация всех шагов с durations
  • Steps список — каждый шаг разворачивается
    • Input — что получил
    • Output — что вернул
    • Events — поднятые события
    • Stack — если был fail, stack trace’ом
  • Events tab — raw-stream всех trace-event’ов (для debug’а)
  • Approval tab — если был approval-gate, видно кто когда что

Для production-ошибок основной flow:

  1. Run красный → открываем trace
  2. Находим failed step → смотрим output (там чаще всего DomainError с кодом)
  3. Если код понятный (OAUTH_CONNECTION_REVOKED) — чиним connection
  4. Если не понятный (INTEGRATION_REMOTE_ERROR) — открываем Sentry (если B4 настроен), там видно stack trace + request / response

/runs/<id> → кнопка Re-run. Создаёт новый run с тем же trigger-payload’ом. Полезно если:

  • Провайдер был in-trouble (их API лежал, наш retry-policy исчерпался)
  • Вы пофиксили свой code / data и хотите перепроиграть

Re-run НЕ меняет оригинальный run — он остаётся failed в trace’е навсегда.

/runs → filter (status=failed, date range) → select → Re-run selected. Для массовых recovery’ев после outage’а.

  • P50 run-latency (queued → done) для простых workflow’ов (webhook → amocrm.lead.create) — 400-800ms на current production-tier VM’е
  • P95 — 2-3s (LLM-call’ы тянут длиннее)
  • Scale: 500-1000 runs/min на current tier; для больше — upgrade VM’ы + horizontal scale step-worker’ов (см. deploy.md)
  • Approvals — human-gate’ы между шагами
  • Agents & Processes — откуда вообще run берётся
  • KPIs — агрегация по run’ам