Паттерн супервизора упирается в потолок
Агент-супервизор элегантно выглядит на диаграмме. Планировщик получает цель, декомпозирует её на подзадачи и направляет каждую подзадачу исполнителю. Исполнители возвращают результаты, супервизор их объединяет, и система выдаёт ответ. Для трёх-четырёх исполнителей этот паттерн работает. Для тридцати параллельных запусков это однопоточный маршрутизатор в распределённом костюме.
Ломается сразу две вещи. Первая — сериализация: каждая подзадача проходит через один шаг рассуждения, прежде чем достичь исполнителя, поэтому задержка супервизора добавляется к каждому переходу в графе зависимостей. Вторая — рост промпта. Супервизор, который должен различать N ролей исполнителей, несёт в своём контексте N описаний, N схем инструментов и N примеров маршрутизации. Точность маршрутизации — это задача внимания, а внимание деградирует по мере роста множества кандидатов. Супервизор не отказывает громко; он начинает ошибочно маршрутизировать пограничные случаи, затем обычные.
Что на самом деле даёт аналогия с ОС
Аналогия — не украшение. Она называет три механизма, которые промпт супервизора не может выразить.
Контроль допуска. Прежде чем запуск начнётся, диспетчер проверяет, допускают ли это бюджет, квота инструментов и граф зависимостей. Запуск, чей родитель не завершён, не допускается. Запуск, который превысил бы оставшийся бюджет токенов для своего тенанта, не допускается. Запуск, которому нужен инструмент, уже насыщенный другими запусками, не допускается. Контроль допуска превращает перегруженную систему из той, что деградирует непредсказуемо, в ту, что отказывает в работе на определённой границе.
Вытеснение. Долгосрочный запуск должен быть приостанавливаемым и возобновляемым без потери рабочего состояния. Это означает, что состояние запуска не может жить в буфере диалога, который существует только пока жив процесс. Оно должно быть материализовано: частичный план, завершённые шаги, созданные артефакты, уже оплаченные результаты инструментов. Вытеснение — это то, что позволяет короткому интерактивному запросу получить приоритет над пакетным анализом, не отбрасывая пакетный анализ.

Справедливость между тенантами. Когда пакетная задача одной команды может заморить голодом интерактивного агента другой команды, проблема больше не в качестве рассуждений. Это распределение. Планировщик с очередями для каждого тенанта и определённой политикой долей делает голодание решением политики, а не эмерджентной случайностью.
Честный компромисс: планировщик добавляет плоскость управления, которую нужно эксплуатировать. Состояние очереди, истечение аренды и логика вытеснения вводят новые режимы отказа, а плохо настроенный диспетчер может добавить задержку запускам, которые прекрасно завершились бы при наивном супервизоре. Планировщик оправдывает свою стоимость только тогда, когда параллелизм достаточно высок, чтобы конкуренция была реальной. Ниже этого порога супервизор проще и дешевле.
Правила проектирования
Отделите планировщик от диспетчера. Планировщик выдаёт DAG: узлы — это шаги агента, рёбра — зависимости по данным, и каждый узел объявляет свои требования к ресурсам. Планировщик не знает, сколько существует исполнителей. Диспетчер владеет ёмкостью, порядком и допуском. Это разделение позволяет улучшать качество маршрутизации и качество планирования независимо, а не обменивать их друг на друга внутри одного промпта.
plan -> DAG { node: { role, inputs, tools, budget } }
|
v
dispatcher: admit(node) if deps_done && budget_ok && quota_ok
enqueue(node) by priority and tenant share
lease(node) -> worker
on timeout or preempt: release lease, persist state
Сделайте каждый шаг агента идемпотентным. Шаг, который может быть вытеснен и повторён, должен давать тот же результат при повторном выполнении с теми же входными данными или уметь обнаружить, что его эффект уже произошёл. Идемпотентность — это то, что делает вытеснение безопасным по построению, а не безопасным благодаря аккуратной обработке. Вызовы инструментов с побочными эффектами нуждаются в
трономического времени.

Сделайте глубину очереди и время ожидания телеметрией первого класса. Если единственное место, где появляется состояние очереди, — это строка лога, операторы не могут отличить медленную модель от насыщенного диспетчера. Глубина очереди, время ожидания, отказы в допуске и количество вытеснений должны быть на том же дашборде, что и использование токенов и частоты ошибок.
Сохраняйте рабочее состояние на границах шагов. Единица приостановки — это шаг, а не запуск. Запуск, завершивший четыре из семи шагов, должен быть возобновляем с пятого шага без повторной оплаты шагов с первого по четвёртый.
Что измерять
Время в очереди против времени в рассуждении, отслеживаемые отдельно. Это разные проблемы с разными решениями. Рост времени рассуждения указывает на изменения модели или промпта; рост времени в очереди указывает на ёмкость или политику допуска. Агрегирование их в одно число сквозной задержки скрывает, какое из них изменилось.
Частота вытеснений и точность возобновления на фиксированной нагрузке. Воспроизведите фиксированный набор запусков, принудительно вызовите вытеснения на границах шагов и проверьте, что возобновлённые запуски создают те же конечные артефакты, что и непрерывные. Точность возобновления — это тест корректности для планировщика.
Смена рамки
Оркестрация, ориентированная на супервизора, рассматривает рой как задачу рассуждения и надеется, что рассуждение масштабируется. Оркестрация, ориентированная на планировщика, рассматривает его как задачу ресурсов и делает единицы рассуждения независимыми, возобновляемыми и подотчётными. Первая рамка создаёт системы, которые работают в демо и застревают в продакшене. Вторая создаёт системы, чьи режимы отказа читаемы: запуск ждёт, и причина в состоянии очереди.
Работа не исчезает. Она перемещается из промпт-инжиниринга в инжиниринг плоскости управления, где ей и место, как только параллелизм становится ограничением.
