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

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

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