Перейти к основному содержимому

Оркестрация агентов требует планировщика, а не фреймворка

Примитивы управления в стиле Kubernetes — допуск, квоты, вытеснение — переносятся на рои агентов полезнее, чем любой новый DSL для агентов.

Крупный план серверной стойки с подсвеченными светодиодами состояния и структурированной кабельной разводкой, символизирующий инфраструктуру планирования и управляющего слоя.

Почему фреймворки буксуюют при масштабировании

Большинство фреймворков для агентов моделируют один запуск: цикл LLM вызывает инструменты, добавляет записи в транскрипт и завершается при выполнении условия остановки. Эта абстракция достаточна для ноутбука и вводит в заблуждение в продакшене. Продакшен-система — это не один запуск; это множество параллельных запусков, конкурирующих за одни и те же дефицитные ресурсы — лимиты скорости модели, параллелизм инструментов, пропускную способность поиска и внимание операторов, наблюдающих за очередью. Задача фреймворка — описать запуск. Задача системы — решить, какие запуски выполняются, в каком порядке и за чей счёт.

Это задачи планирования, и они были решены для контейнеров десятилетия назад. Контроль допуска решает, будет ли запрос принят, поставлен в очередь или отклонён. Квоты ограничивают ресурсы, которые может потребить арендатор. Вытеснение отменяет менее приоритетную работу, чтобы освободить место для более приоритетной. Обратное давление распространяет перегрузку вверх по потоку, вместо того чтобы поглощать её, пока что-нибудь не рухнет. Ни одна из этих концепций не возникла в Kubernetes, но Kubernetes дал им словарь и API-поверхность, которые инженеры уже понимают.

Сближение видно в инструментах. Открытый оркестратор AX от Google — сигнал, что индустрия рассматривает координацию агентов как задачу управляющего слоя, а не как задачу промптинга. Интересная инженерия — не новый DSL для описания агентов; это планировщик, который решает, когда они запускаются.

Сопоставление примитивов управления

Сопоставление оркестрации контейнеров и оркестрации агентов не метафорично. Оно структурно и полезно.

Контроль допуска

Когда запуск отправляется, планировщик прогнозирует его стоимость: ожидаемое потребление токенов, количество вызовов инструментов по классам и длительность по настенным часам. Если прогноз превышает оставшийся бюджет для этого арендатора или для кластера, запуск отклоняется или ставится в очередь. Прогноз не обязан быть точным; он должен быть консервативным и дешёвым. Простой механизм — оценка стоимости запуска, выведенная из размера промпта, объявленного набора инструментов и исторического множителя для класса инструментов. Планировщик сравнивает эту оценку с корзиной токенов. Если корзина пуста, запуск ждёт.

Это та же логика, что и вебхук допуска Kubernetes, отклоняющий под, запрашивающий больше памяти, чем разрешено пространством имён. Разница в том, что ресурс невзаимозаменяем: токен, потраченный на неудачный запуск, исчез, а вызов инструмента с внешним побочным эффектом нельзя вернуть.

Curving steel girders forming a geometric structure in modern architecture, stock photo

Квоты

Квоты применяются до отправки, а не после. У арендатора три бюджета: токены за окно, вызовы инструментов за окно по классам и параллельные запуски. Планировщик проверяет все три во время допуска. Если какой-либо исчерпан, запуск ставится в очередь, а не запускается. Это намеренно скучно, и это самый эффективный механизм предотвращения того, чтобы вышедший из-под контроля цикл одного арендатора не заморил всех остальных.

Компромисс — задержка. Строгая квота заставляет запуск ждать, даже когда в кластере есть свободная ёмкость, потому что квота на арендатора, а не глобальная. Альтернатива — глобальное планирование с весами справедливого распределения — эффективнее и гораздо сложнее для понимания. Большинству команд следует начать с жёстких квот и ослабить их только при наличии данных.

Вытеснение

Вытеснение — примитив, который фреймворки редко реализуют, а продакшен-системы в конечном итоге требуют. Когда высокоприоритетному запуску нужен инструмент, который в данный момент удерживается низкоприоритетным запуском, планировщик может отменить низкоприоритетный запуск и освободить инструмент. Отменённый запуск возвращается в очередь, а не теряется.

Вытеснение мощно и опасно. Оно безопасно только тогда, когда вытесненный запуск можно возобновить с контрольной точки без повторения побочных эффектов. Это условие выполняется не всегда, поэтому вытеснение следует вводить последним примитивом, а не первым.

Что не переносится

Три свойства запусков агентов нарушают чистое сопоставление с подами.

Запуски агентов не являются stateless. Под можно убить и перепланировать, потому что его состояние живёт в томе или базе данных. Состояние запуска агента живёт в его транскрипте, истории вызовов инструментов и рабочей памяти. Контрольные точки должны захватывать все три, а возобновление должно быть идемпотентным по отношению к уже вызванным инсWide view of an industrial electrical substation with power lines and towers outdoorsNetwork cables data centre

Вызовы инструментов имеют внешние побочные эффекты. Отмена запуска в середине вызова инструмента не отменяет вызов. Платёж, тикет, письмо, запись в базу данных — они сохраняются. Поэтому вытеснение безопасно только для запусков, оставшаяся работа которых не имеет побочных эффектов, или для инструментов, поддерживающих компенсацию. Планировщику нужна классификация по инструментам: безопасно вытеснять, компенсируемо или терминально. Без этой классификации вытеснение — это ошибка корректности, ждущая своего часа.

Наблюдаемость должна захватывать траектории. Оркестратор контейнеров заботится о кодах выхода и использовании ресурсов. Оркестратор агентов заботится о последовательности решений: какой инструмент был вызван, с какими аргументами, что вернулось и почему запуск пошёл по этой ветке. Наблюдаемости по кодам выхода недостаточно, потому что запуск может завершиться успешно, сделав неправильную вещь. Планировщик должен выдавать структурированную запись траектории для каждого запуска, и эта запись должна быть единицей отладки, а не строка лога.

Путь миграции

Командам не нужно внедрять полный планировщик в первый же день. Путь инкрементален и обратим.

Шаг первый: выдавайте запись планирования для каждого запуска. До любого принуждения заставьте систему описывать себя. Каждый запуск выдаёт запись, содержащую приоритет, оценку бюджета, зависимости и классы инструментов. Это наблюдаемость, а не управление, и это безопасно. Это также даёт данные, необходимые для установки не произвольных квот.

Шаг второй: введите квоты до вытеснения. Квоты обратимы: арендатор, достигший лимита, ждёт, и лимит можно поднять. Вытеснение необратимо: отменённый запуск мог уже вызвать побочный эффект. Сначала введите квоты, измерьте поведение очереди и только затем рассмотрите вытеснение для подмножества запусков, которые безопасно отменять.

Шаг третий: относитесь к планировщику как к единственному месту, где встречаются стоимость и политика. Если логика допуска живёт в API-шлюзе, логика квот — в воркере, а логика приоритетов — в промпте, никто не может ответить, почему запуск ждал. Централизация решения делает систему проверяемой и делает изменения политики тестируемыми. Планировщик становится компонентом, который владеет ответом на вопрос «почему этот запуск не начался?»

Честный компромисс

Планировщик добавляет задержку и новый домен отказа. Каждый запуск платит за проверку допуска, и ошибка в планировщике может остановить весь флот. Фреймворки избегают этого, не имея управляющего слоя; они перекладывают проблему на оператора. Это законный выбор для небольших систем. Он перестаёт быть законным, когда количество параллельных запусков, арендаторов или классов инструментов делает ручной арбитраж невозможным. В этот момент выбор не между фреймворком и планировщиком; он между явным планировщиком и случайным, разбросанным по логике повторных попыток, обработке лимитов скорости и суждениям дежурного.

Явный планировщик сложнее построить и проще эксплуатировать. Таков компромисс. Для роёв агентов в продакшене он правильный.

ПоделитьсяXLinkedInПостоянная ссылка5 мин чтения

Связанное чтение

На какие вопросы это отвечает

What is the difference between an agent framework and an agent scheduler?

A framework describes how a single run executes: the loop, the tools, the stop condition. A scheduler decides which runs execute, in what order, and under what resource constraints. Production systems need both, but the scheduler is the component that prevents overload.

Why is preemption harder for agents than for containers?

Containers are stateless and can be killed and rescheduled. Agent runs hold state in their transcript and tool-call history, and tool calls may have external side effects that cannot be undone. Preemption is only safe for runs whose remaining work is side-effect-free or compensable.

Should quotas or preemption be introduced first?

Quotas. They are reversible: a tenant that hits a limit waits, and the limit can be raised. Preemption is not reversible because a cancelled run may already have caused a side effect. Introduce quotas first, observe queue behaviour, then consider preemption for safe runs.

What should a scheduling record contain?

Priority, budget estimate, dependencies, and tool classes. Emitting this record before enforcing any policy gives the data needed to set non-arbitrary quotas and makes the scheduler auditable.