Оркестрация — слой, который решает, в каком порядке выполняются шаги, кто какую часть делает и что происходит при сбое. Без неё мультиагентная схема превращается в набор вызовов без ответственного.
Два подхода
Жёсткий сценарий. Порядок шагов задан кодом, модель применяется внутри отдельных шагов. Предсказуемо, дёшево, легко отлаживается. Подходит, когда процесс известен.
Свободная схема. Порядок определяет сам агент. Гибко, но непредсказуемо по стоимости и времени, и разбирать сбои тяжело.
На практике почти всегда выигрывает смешанный вариант: скелет процесса задан кодом, а свобода модели ограничена рамками конкретного шага. Это и есть главная причина, по которой «полностью автономные» схемы редко доживают до эксплуатации.
Маршрутизация
По умолчанию маршрутизирует код. Явные признаки — канал обращения, тип клиента, наличие номера заказа — дают решение, которое проверяется тестом и не стоит токенов. Выбирать это, пока признак формализуется.
Модель — там, где признак не формализуется. Свободные формулировки, разнородные входы — здесь ставят классификатор или компактную модель маршрутизации. Плата известна: точность ниже ста процентов, а ошибка маршрутизации — это ошибка всей ветви downstream, поэтому точность маршрутизатора меряется отдельно, по разметке, а не «вообще». Подробнее — в статье «Интент».
Решение маршрутизации журналируется с обоснованием. Записывается выбранная ветвь и признак, по которому она выбрана. Без этого разбор «почему обращение ушло не туда» упирается в отсутствие данных.
Что должна обеспечивать оркестрация
Состояние. Где остановились, что уже сделано. Иначе после сбоя процесс начинается заново и повторяет уже выполненные действия.
Повторы без дублей. Сетевые сбои неизбежны, повтор шага должен быть безопасным. Для создания записей и отправки сообщений нужен ключ, по которому дубль распознаётся.
Лимиты. На число шагов, время и стоимость. Без них зациклившийся агент расходует бюджет молча.
Журнал. Все шаги, аргументы и результаты. Основной инструмент разбора.
Поведение при отказе. Что делать, если внешний сервис недоступен: повторить, отложить, передать человеку. Решение принимается заранее, а не в момент аварии.
Механика восстановления — чекпоинты плюс идемпотентность. Гарантия «ровно один раз» в распределённой схеме недостижима; строят «хотя бы один раз» плюс идемпотентные шаги. Чекпоинт пишется после каждого завершённого шага; перезапуск продолжает с последнего чекпоинта. Повторы — два-три, с растущей задержкой: повтор без задержки создаёт шторм запросов на и так лежащий сервис. После исчерпания попыток задача уходит в очередь к человеку с записанной причиной — а не крутится бесконечно.
Поведение при сбое задаёт код, не агент. Если решение «повторить или сдаться» принимает модель в момент аварии, поведение системы в самый нужный момент — самое непредсказуемое. Агент может действовать внутри шага; стратегия отказа — прерогатива оркестратора.
Наблюдаемость
Минимум, без которого система не эксплуатируется: доля успешно завершённых задач, среднее число шагов, стоимость одной задачи, частота передачи человеку, доля повторных обращений по тому же вопросу.
Последний показатель самый честный: если клиент вернулся с тем же вопросом, задача не решена, какой бы успешной она ни выглядела в журнале.
Сквозная трассировка шагов. Каждой задаче — идентификатор, каждому шагу — запись: действие, аргументы, результат, токены, латентность и кто принял решение — код или модель. По такой трассе разбор сбоя превращается из гадания в чтение; без неё метрики показывают «что», но не «почему». Данные для метрик берутся отсюда же — считать отдельно не нужно.
Журнал с персональными данными — сам обработка персональных данных. Аргументы вызовов содержат имена, телефоны, суммы; попадая в трассировку, они образуют массив ПДн с обязательствами по 152-ФЗ: срок хранения, ограничение доступа, удаление по истечении. Где для разбора достаточно структуры, аргументы обезличиваются; полные значения остаются в основной системе, а не в журнале.
Типичные ошибки
Отсутствие сохранения состояния: после сбоя процесс начинается заново и повторяет уже выполненные действия — вплоть до повторной отправки писем.
Повтор шага без ключа идемпотентности. Сетевой сбой при создании записи приводит к дублю, и обнаруживается это в отчётах, а не в логах.
Лимиты заданы в промпте вместо кода. Модель их нарушает при неудачной формулировке запроса.
Журнал без аргументов вызова: видно, что инструмент вызывали, и непонятно с чем.
Мгновенные повторные попытки на лежащий сервис: вместо восстановления — дозагрузка, продлевающая аварию на всю глубину ретраев.
Частые вопросы
Нужен ли отдельный оркестратор для одного агента?
Полноценный — нет, но состояние, лимиты и журнал нужны даже одному. Именно их отсутствие обнаруживается в первый же сбой: непонятно, что успело выполниться, и безопасно ли перезапускать.
Жёсткий сценарий или свободная схема?
Почти всегда смешанный: последовательность шагов задаётся кодом, а модель принимает решения внутри шага. Полностью свободные схемы плохо предсказуемы по стоимости и тяжело отлаживаются, поэтому редко доживают до эксплуатации.
Какие показатели отслеживать?
Долю завершённых задач, среднее число шагов, стоимость задачи, частоту передачи человеку и долю повторных обращений по тому же вопросу. Последний — самый честный: он показывает, решена ли задача на самом деле.
Кому отдать маршрутизацию — коду или модели?
Критерий — формализуемость признака. Формализуется (канал, тип, номер) — код: бесплатно и проверяемо тестами. Не формализуется (свободная формулировка) — модель или классификатор, но с обязательной отдельной метрикой точности маршрутизации: её ошибки не видны в общих цифрах качества, пока не собраны целенаправленно.
Что делать с персональными данными в трассировке?
Считать журнал обработкой ПДн и применять к нему те же требования, что к основной системе: минимально необходимые поля, ограниченный срок хранения, доступ по ролям. Для разбора сбоев чаще всего достаточно структуры вызова без значений — тогда аргументы обезличиваются или замещаются ссылкой на запись в источнике.
Сколько повторов шага делать при сбое?
Два-три с растущей задержкой — этого хватает на кратковременные сетевые сбои, которых большинство. Дальше — отложить задачу или передать человеку: упорные ретраи лишь множат нагрузку. И только на идемпотентных шагах: повтор без ключа идемпотентности при создании записи — гарантированный дубль.