AI-инжиниринг

Паттерны оркестрации: routing, fallback, chain, map-reduce, branching

Цели урока

  • Освоить sequential chain - конвейер обработки с передачей контекста между шагами
  • Реализовать parallel (fan-out) pipeline с concurrency control и rate limiting
  • Построить routing/branching систему с комбинацией rule-based и LLM-based классификации
  • Применять map-reduce для обработки документов, не помещающихся в контекстное окно
  • Реализовать fallback chains с retry, timeout, cascade и hedged requests

Pipeline - это конвейер. Каждый шаг получает вывод предыдущего. Если шаг 3 из 7 провалился - вся цепочка встала. Так работает большинство AI-систем в production прямо сейчас. Orchestration - это про то как не падать, а деградировать грациозно: fan-out вместо последовательных вызовов, map-reduce для 200K документов, hedged requests для P99 latency, BullMQ для того чтобы async задачи не терялись в void.

  • Stripe AI - cascade fallback через 3 LLM-провайдера, 99.99% availability - каждый сбой OpenAI незаметен для клиентов
  • Notion AI - parallel fan-out: анализирует документ одновременно на структуру, тон и ключевые идеи, экономя 60% времени
  • Linear AI - conditional routing: bug-репорт → техническая модель с RAG по документации, feature-реквест → продуктовая модель без RAG
  • Cursor (IDE) - map-reduce для анализа репозиториев: каждый файл суммаризируется отдельно, затем суммаризации объединяются для понимания архитектуры 500K+ токенов
  • LangGraph 0.2 (2024) - state machine для agent orchestration: explicit graph вместо magic chains, checkpoint для human-in-the-loop

Предварительные знания

  • LangChain and LlamaIndex: Orchestrating LLM Pipelines

Anthropic кодифицирует паттерны оркестрации

Первые два года эры LLM-приложений паттерны оркестрации расходились по блогам, докладам и коду фреймворков без единого словаря. 19 декабря 2024 Anthropic опубликовала Building Effective Agents, и этот текст собрал практику в общий язык. Главное разграничение - workflows, где несколько вызовов LLM соединены заранее заданными путями, и agents, где модель сама решает, какие шаги делать. Документ описал базовые строительные блоки: prompt chaining (последовательная цепочка), routing (классификация запроса и направление в нужную ветку), parallelization (параллельный запуск с агрегацией), orchestrator-workers и evaluator-optimizer. Общий совет Anthropic - начинать с простейшего решения и добавлять сложность только когда она реально окупается.

Sequential Chain: конвейер обработки

Pipeline - это конвейер. Каждый шаг получает вывод предыдущего. Если шаг 3 из 7 провалился - вся цепочка встала. Sequential chain - простейший и самый распространённый паттерн, и именно он чаще всего виноват в недоступности AI-фичи в 3 часа ночи.

Где sequential chain работает в production прямо сейчас:

  • **Content moderation pipeline** - классификация → фильтрация → генерация ответа (порядок критичен: нет смысла тратить `0.01` на ответ токсичному запросу)
  • **Translation with quality check** - перевод → оценка качества → исправление
  • **Code review bot** - парсинг diff → анализ по правилам → генерация комментариев
  • **Customer support** - классификация тикета → извлечение сущностей → генерация ответа

Sequential chain - единственный паттерн, где **порядок шагов критичен**. Модерация должна идти до генерации (не тратить деньги на ответ для токсичного запроса). Классификация - до генерации (нужен правильный system prompt). Если шаги независимы - это сигнал использовать parallel pattern.

В sequential chain из 4 шагов третий шаг возвращает ошибку. Что происходит?

Parallel / Fan-Out: параллельная обработка

LLM-вызовы медленные - от 500ms до 30s на запрос. TTFT у GPT-4o в среднем 800ms, у Claude Sonnet - около 1s. Если два шага pipeline независимы и их гнать последовательно - это не архитектура, это потеря времени. **Fan-out** запускает несколько операций одновременно и собирает результаты в fan-in.

Классический пример: анализ резюме кандидата. Оценка skills, culture fit и red flags - три независимых LLM-вызова. Запускать их последовательно (3.6s) когда можно параллельно (1.5s) - это архитектурный долг.

**Promise.allSettled vs Promise.all** - критичный выбор. `Promise.all` падает при первой ошибке, теряя результаты успешных задач. `Promise.allSettled` возвращает все результаты: и успешные, и упавшие. Для production pipeline с LLM - всегда `allSettled`.

Продвинутый вариант - **Fan-Out с Rate Limiting**. 50 параллельных LLM-вызовов без ограничений → API вернёт 429. Решение: concurrency control через `p-limit`.

При fan-out паттерне 3 задачи запускаются параллельно. Задача A выполняется за 200ms, B - за 1500ms, C - за 800ms. Какое общее время выполнения?

Routing / Branching: условное выполнение

Не все запросы должны проходить один и тот же pipeline. Вопрос «Сколько будет 2+2?» не нуждается в RAG-поиске по базе знаний - это выброшенный вызов и деньги впустую. Жалоба клиента требует GPT-4o с empathetic system prompt, а FAQ-запрос спокойно закроет gpt-4o-mini за `0.15/1M`. **Routing** - это условный оператор для AI-архитектуры.

Два подхода к routing: **LLM-based** (классификатор на модели) и **rule-based** (детерминированная логика). В production выигрывает комбинация: правила закрывают 30-40% запросов бесплатно и за 0ms, LLM подключается только для неоднозначных.

Conditional routing - это не только экономия. Это LangGraph state machine в минимальном виде: классификатор определяет следующее состояние графа. LangGraph 0.2 (2024) строит такие графы явно, с persist state между шагами - это тот же паттерн, но с checkpoint и человеческим контролем в точках разветвления.

Почему в routing паттерне часто комбинируют rule-based и LLM-based классификацию?

Map-Reduce: обработка длинных документов

Контекстное окно GPT-4o - 128K токенов. Звучит много. Годовой отчёт Apple - 200K+ токенов. Кодовая база на 50K строк - 500K+. Лог за месяц - миллионы. **Map-Reduce** - это единственный способ обрабатывать данные, которые в принципе не влезают в контекст. Та же идея, что в Hadoop, только вместо MapReduce-задач - LLM-вызовы.

Cursor использует этот паттерн для анализа больших репозиториев: каждый файл суммаризируется отдельно (MAP), затем суммаризации объединяются для понимания архитектуры (REDUCE). Без map-reduce - проект с 1000 файлами невозможно проанализировать в одном prompt.

Map-Reduce имеет несколько вариаций, выбор зависит от задачи:

ВариацияКак работаетКогда использовать
Map-ReduceОбработка каждого chunk → финальный mergeСуммаризация, extraction из длинных документов
Map-RerankОбработка каждого chunk → сортировка по score → лучшийПоиск ответа в длинном тексте
RefineChunk 1 → ответ → chunk 2 + предыдущий ответ → уточнение → ...Когда нужна связность между частями
CollapseРекурсивный reduce: если summaries слишком длинные → reduce ещё разОчень длинные документы (книги, кодовые базы)

Ключевое решение в Map-Reduce - **какую модель использовать для MAP и REDUCE**. MAP обрабатывает десятки chunks - здесь экономия на модели важна (gpt-4o-mini, `0.15/1M`). REDUCE делает один вызов с критичным результатом - здесь оправдана мощная модель (gpt-4o, Claude Sonnet). При 67 chunks разница в стоимости MAP-фазы между gpt-4o и gpt-4o-mini - в 16 раз.

Вариация **Refine** - альтернатива Map-Reduce, когда важна связность:

Документ на 200K токенов нужно суммаризировать. Контекстное окно модели - 128K. Какой паттерн подойдёт?

Fallback Chains: отказоустойчивость pipeline

В марте 2024 года OpenAI API упал на 4 часа. Все приложения, жёстко привязанные к GPT-4, встали. Приложения с fallback chains переключились на Anthropic Claude за секунды - пользователи не заметили. Orchestration - это не про то, как вызвать LLM. Это про то как **не падать, а деградировать грациозно**.

Fallback - это не оптимизация. Это базовое требование для production. BullMQ с retry-стратегией, circuit breaker, cascade через нескольких провайдеров - всё это части одной идеи: система продолжает работать даже когда один компонент недоступен.

Продвинутая стратегия - **Hedged Request**. Вместо ожидания таймаута, запускаем primary и fallback параллельно, возвращаем первый ответ:

Hedged requests **удваивают стоимость** в worst case. Применять только для критических path, где latency важнее стоимости: real-time чатботы, trading signals, live customer support.

Сводная таблица паттернов оркестрации и когда их использовать:

ПаттернLatencyCostUse Case
SequentialSum(steps)Sum(calls)Зависимые шаги, pipeline обработки
ParallelMax(steps)Sum(calls)Независимые задачи, multi-aspect анализ
RoutingClassify + 1 branchClassify + 1 callРазные типы запросов, оптимизация стоимости
Map-ReduceMap (parallel) + ReduceN × map + 1 reduceДокументы > контекстного окна
FallbackPrimary + retry/cascade1-3 callsОтказоустойчивость, multi-provider
HedgedMin(providers)1-2 callsМинимальная latency для critical path

Orchestration - это просто последовательные вызовы LLM

Orchestration - это управление состоянием, ошибками, retry-стратегиями и partial failure в распределённой системе, где каждый узел - LLM-вызов

Последовательный вызов трёх LLM - это не оркестрация, это скрипт. Оркестрация начинается там, где нужно решить: что делать если шаг 2 из 5 упал? Сохранять промежуточный результат? Retry на другой модели? Пропускать шаг? Уведомлять пользователя о деградации? LangGraph хранит explicit state между шагами - именно потому что без state management агент теряет контекст и зацикливается. BullMQ для async orchestration даёт retry, priority queues и dead letter queue - всё то, чего нет в голом Promise.all.

Production AI-чатбот обслуживает 10K пользователей. OpenAI API иногда отвечает за 5+ секунд. Какой fallback-паттерн снизит P99 latency?

Orchestration - это просто последовательные вызовы LLM

Orchestration - это управление состоянием, ошибками, retry и partial failure. Последовательный вызов трёх LLM - скрипт. Оркестрация - когда система решает что делать при падении шага 2 из 5

LangGraph хранит explicit state между шагами именно потому что без него агент теряет контекст и зацикливается. BullMQ для async orchestration даёт retry, priority queues и dead letter queue - всё то чего нет в голом Promise.all. Разница между скриптом и оркестрацией - это ответ на вопрос: что происходит когда что-то идёт не так?

Итоги

  • Sequential chain: конвейер где каждый шаг зависит от предыдущего. Fail on any step - главная уязвимость
  • Parallel (fan-out): независимые задачи параллельно. Latency = max(tasks), не sum(tasks). Без concurrency control → rate limit 429
  • Routing: rule-based закрывает 30-40% запросов бесплатно за 0ms, LLM-based - остальные. Комбинация - золотой стандарт
  • Map-Reduce: единственный способ обработать документ больше контекстного окна. MAP параллельно на gpt-4o-mini, REDUCE на gpt-4o
  • Fallback: cascade + retry + hedged requests. Production без fallback - вопрос времени до инцидента
  • Паттерны комбинируются: routing → sequential с parallel шагами → fallback на каждом LLM-вызове. LangGraph делает это явным графом

Вопросы для размышления

  • Если шаг 4 из 6 в sequential pipeline периодически падает с 503 от OpenAI - как переделать pipeline чтобы он не начинал с шага 1 каждый раз? Подсказка: идемпотентность и checkpoint.
  • Cursor анализирует репозиторий на 2000 файлов через map-reduce. Какой паттерн выбрать для MAP-фазы если файлы очень разного размера - от 10 строк до 2000? Как не потратить лишнее на микро-файлы?
  • Hedged request экономит P99 latency за счёт двойного расхода токенов в 20% случаев. При каком соотношении цены токенов и стоимости плохого UX он перестаёт быть оправданным?

Что дальше

Routing в этом уроке направлял запросы в разные pipeline. Но можно роутить на уровне самой модели - отправлять простые запросы в дешёвую модель, а сложные в мощную. Это Model Routing - следующая тема.

  • Model Routing — Автоматический выбор модели (GPT-4o vs Claude vs local) на основе сложности, стоимости, latency
  • Error Handling в LLM — Retry стратегии, circuit breaker, graceful degradation для AI pipeline
  • Cost Management — Оптимизация расходов: routing, caching, prompt compression

Связанные уроки

  • aie-20-langchain-llamaindex — Фреймворки дают примитивы, которые используют эти паттерны
  • aie-22-model-routing — Роутинг это один из паттернов оркестрации детально
  • aie-32-error-handling-llm — Fallback и retry это паттерны надёжности
  • aie-29-cost-management — Выбор оркестрации напрямую влияет на стоимость
  • alg-19-divide-conquer — Map-reduce по вызовам LLM это разделяй и властвуй
  • sd-09-message-queue — Параллельный fan-out похож на распределение работы через очереди
  • net-55-message-queues
Паттерны оркестрации: routing, fallback, chain, map-reduce, branching

0

1

Войти