Перейти к содержимому
16 июн. 2025 г.·7 мин чтения

Лимиты LLM между командами: схема квот без простоев

Лимиты LLM между командами: как раздать квоты по продуктам, средам и часам суток, чтобы прод не простаивал, а тесты и батчи не съедали общий пул.

Лимиты LLM между командами: схема квот без простоев

Почему общий пул быстро ломается

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

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

Сначала это выглядит как мелкая неприятность. Где-то выросла задержка, где-то пошли повторы запросов, потом появляются 429. Команды редко связывают эти симптомы в одну проблему, потому что сбой не похож на одну большую аварию. Он расползается по разным сервисам и маскируется под частные ошибки.

Сценарий обычно очень простой. Команда поиска запускает пакетную обработку 200 тысяч описаний товаров. В это же время чат поддержки отвечает клиентам, а команда разработки гоняет нагрузочные тесты на staging. Если у всех один лимит, побеждает самый шумный поток, а не самый важный.

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

Даже единый OpenAI-совместимый шлюз сам по себе это не исправляет. AI Router, например, дает один совместимый эндпоинт для доступа к разным моделям, но спор за токены при общем пуле никуда не исчезает. Нужны границы: кто сколько может тратить, в какой среде и в какие часы. Иначе работает простое правило - кто успел, тот и съел.

По каким осям делить лимиты

Один лимит на всю компанию почти всегда съедает самый шумный потребитель. Поэтому квоты лучше делить сразу по нескольким осям. Тогда чат поддержки не проиграет ночному пакетному прогону, а прод не встанет из-за экспериментов в dev.

Сначала зафиксируйте все продукты, которые ходят в модели, и назначьте владельца для каждого. Это не бюрократия, а способ быстро понять, кто отвечает за расход, пики нагрузки и пересмотр квоты. Если продукта нет в списке или у него нет владельца, он обычно начинает тратить лимит тихо, пока не случится сбой.

Потом разделите трафик по средам. Прод, stage, dev и песочницы не должны жить в одном коридоре. У прода должен быть свой гарантированный лимит и самый высокий приоритет. У stage лимиты ниже, но стабильные, чтобы релизы проходили без ручной борьбы за ресурс. Dev и песочницы лучше ограничивать жестче, иначе один неудачный тест быстро съест запас всей команды.

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

Есть смысл делить запросы и по типу трафика:

  • интерактивный трафик с ответом за секунды
  • пакетные задачи без жесткого SLA
  • внутренние эксперименты и тесты
  • аварийный резерв для критичных сервисов

На практике схема выглядит просто. Допустим, у вас есть чат поддержки, внутренний помощник для сотрудников и ночная обработка документов. Чат получает отдельную квоту в проде днем и резерв на пиковые часы. Помощник сотрудников делит лимит с офисной активностью и может немного подождать. Ночная обработка документов получает большой лимит после 22:00, но днем уступает интерактивным сервисам.

Хороший порядок такой: сначала продукт, потом среда, потом время, потом тип трафика. В таком виде квоты живут дольше и ломаются реже.

Квоты по продуктам

Лимиты удобнее считать не по людям, а по продуктам. Один внутренний помощник переживет очередь и замедление, а клиентский чат нет. Если всем дать общий пул, самый шумный сервис быстро съест запас, и пострадают те, у кого есть SLA.

Сначала задайте каждому продукту гарантированный минимум. Это не желаемый объем, а нижняя планка, которой хватает на обычный день. Удобно фиксировать ее в двух числах: токены в сутки и допустимый всплеск в минуту. Тогда сервис не голодает в рабочее время и не падает от короткого наплыва запросов.

Потом поставьте потолок. Он нужен даже успешным продуктам. Без потолка один запуск, ошибка в клиенте или неудачный batch-процесс могут съесть весь общий запас за час. Для внутренних инструментов потолок лучше делать жестким. Для сервисов с клиентским трафиком можно оставить небольшой запас сверху, но только в пределах отдельного резерва.

На старте часто работает такая пропорция: 50-60% пула закрепляют за продуктами с внешними пользователями и SLA, 20-30% отдают внутренним сервисам, 10-15% держат в резерве на клиентский трафик и аварийные пики, еще 5-10% выделяют пилотам и экспериментам отдельно от продовых сервисов.

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

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

Квоты по средам

Один из самых частых сбоев начинается не в проде, а рядом с ним. Если прод, stage и dev берут токены из общего пула, тесты и эксперименты легко съедают запас, который нужен боевому трафику.

Прод должен жить отдельно. Для него задают основной лимит и небольшой буфер на всплески: утренний пик, маркетинговую рассылку, рост числа обращений в поддержку. Буфер не нужен огромный. Достаточно объема, который перекрывает короткий скачок, а не любой возможный рекорд.

Stage обычно не требует большого объема, но ему нужна предсказуемость. Команда должна знать, что nightly-тесты, ручная проверка перед релизом и прогон новых промптов точно поместятся в выделенный предел. Если stage каждый раз конкурирует с продом, релизная дисциплина быстро ломается.

Dev и песочницы лучше держать под жестким потолком. Именно там чаще всего гоняют длинные промпты, пробуют новые модели и забывают выключить циклы. Мягкие ограничения здесь почти не работают. Жесткий лимит работает честнее: дошли до потолка, дождались следующего окна или запросили временное повышение.

В релизные дни stage почти всегда нужно больше обычного. Не делайте это постоянной настройкой. Лучше поднимать лимит вручную на несколько часов и потом возвращать назад. Так вы не оставите лишний объем открытым на всю неделю.

Простое правило звучит так: прод должен пережить чужую ошибку, stage должен спокойно провести релиз, а dev должен быть дешевым и управляемым. Если одна среда может опустошить весь пул, схема еще не работает.

Квоты по времени суток

Поставьте лимиты по ключу
В AI Router можно задать лимиты на уровне ключа для prod и dev.

Одинаковый лимит в 11 утра и в 2 ночи почти всегда дает сбой. Нагрузка разная, и цена задержки для бизнеса тоже разная. Поэтому квоты стоит делить не только по сервисам, но и по часам.

Днем защищайте все, что работает в реальном времени: чаты поддержки, поиск по базе знаний, подсказки оператору, внутренние ассистенты для сотрудников. Если такой сервис ждет токены в очереди из-за фоновой задачи, пользователи замечают это сразу.

Обычно помогает простое правило: в рабочие часы держать отдельный запас пропускной способности для интерактивных сценариев, а для фоновых задач ставить более низкий burst. Суточный объем у них может остаться тем же, но в часы пика они не должны резко забирать весь канал.

В качестве отправной точки часто хватает такой схемы:

  • с 9:00 до 20:00 приоритет у чатов, поиска и операторских инструментов
  • ночью идут батчи, переиндексация, массовая обработка документов и тестовые прогоны
  • в интервалы вроде 11:00-14:00 и 16:00-18:00 неприоритетные задачи получают более жесткий burst
  • на выходных открывается окно для тяжелых прогонов, которые днем мешали бы проду

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

Есть и типичная ловушка - конец месяца. В этот период внезапно растут отчеты, сверки, выгрузки и внутренние проверки. Если такие исключения не описаны заранее, команды начинают просить ручное повышение лимита, и схема ломается в самый неудобный момент.

Лучше сразу определить, кто и на сколько часов получает расширенное окно. Не для всех, а только для задач с понятным сроком и владельцем. Тогда ночные и выходные квоты остаются предсказуемыми.

Как собрать схему по шагам

Начните не с цифр, а со списка всех, кто вообще ходит в LLM API. Обычно там быстро всплывают не только продовые сервисы, но и тестовые стенды, внутренние боты, batch-задачи и ручные скрипты аналитиков. У каждого потребителя должен быть владелец. Иначе в момент дефицита никто не сможет быстро решить, что резать первым.

Потом снимите профиль нагрузки хотя бы за неделю. Смотрите не только общий объем, но и часы пиков, длину всплесков и долю ошибок на лимитах. Один сервис может давать ровный фон весь день, а другой - выстреливать каждые 15 минут после массовой рассылки или запуска очереди.

Сначала задайте базовую защиту

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

Удобно держать три уровня приоритета:

  • критичный для выручки или клиентского пути
  • внутренний рабочий сервис с понятным SLA
  • фоновая или экспериментальная нагрузка

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

Проверьте схему на старых пиках

Не вводите квоты вслепую. Возьмите 2-3 самых тяжелых дня из истории и прогоните схему как тест. Смотрите, где прод начнет отказывать, где тест съест лишнее и сколько резерва реально остается в пиковые часы.

После такой проверки чаще всего правят три вещи:

  • повышают минимум для сервисов с жестким SLA
  • урезают burst для тестовых и dev-сред
  • переносят фоновую обработку на ночные часы

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

Пример распределения для трех сервисов

Соберите один слой доступа
Подключите AI Router как один OpenAI-совместимый эндпоинт для разных моделей и команд.

Возьмем суточный бюджет 10 млн токенов и 200 запросов в минуту. На живом примере такие правила обсуждать проще.

СервисСредаВремяБазовая квотаПравило перераспределения
Чат поддержкиprod08:00-22:004 млн токенов в день, 120 rpmСначала забирает общий резерв
Аналитический батчprod22:00-08:00, выходные3 млн токенов, 60 rpm ночьюДнем почти не работает, резерв получает после чата
R&D-песочницаdev/stage10:00-19:001 млн токенов, 20 rpmДнем выше потолка не поднимается
Общий резервобщийвесь день2 млн токеновПриоритет: чат, потом батч, потом эксперименты

Днем правила лучше держать жесткими. Чат поддержки получает гарантированный пул, потому что там любая пауза сразу видна клиенту. Даже если аналитика или тесты внезапно выросли, они не должны съедать дневной запас чата.

Батч лучше сдвигать на ночь и выходные. Для него задержка на пару часов обычно не так болезненна, как для живого диалога с пользователем. Днем ему можно оставить маленький лимит только на срочные задачи, чтобы команда не ждала до ночи из-за каждой правки.

R&D-команда работает в песочнице с дневным потолком не потому, что она менее важна, а потому что ее нагрузка часто рваная. Один неудачный тест с длинным контекстом легко выбивает общий бюджет за час. Фиксированный потолок защищает прод, а после 22:00 этой команде можно отдавать свободный объем для экспериментов.

Представим обычный будний день. В 17:30 в чате поддержки пошел всплеск обращений. Система сначала отдает резерв чату, потом режет ночной батч, если тот уже стартовал раньше времени. Песочница в этот момент не получает ничего сверх своего дневного лимита.

После 22:00 схема меняется. Если чат вернулся к обычному ночному уровню, а батч не выбрал весь свой объем, остаток можно открыть для экспериментов. Но порядок отключения тоже должен быть жестким: сначала останавливаются тесты, потом двигается батч, и только в самом конце трогают чат.

Где команды чаще ошибаются

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

Вторая частая ошибка - один и тот же лимит для prod и dev. Это почти всегда бьет по пользователям. В разработке люди гоняют тесты, меняют промпты, перезапускают сценарии и легко сжигают объем, который в проде нужен для живого трафика. Dev нужен свой потолок, ниже и жестче, особенно в рабочие часы.

Проблемы начинаются и там, где команды смотрят только на суточный лимит. Если сервис потратил половину дневной квоты за первый час после релиза, до вечера он уже будет жить на остатках. Поэтому стоит держать ограничения не только на сутки, но и на короткие окна: 1 минута, 5 минут, 1 час. Тогда всплеск не съест весь дневной пул.

Еще один частый промах - отсутствие резерва. Релиз, авария в смежной системе или рост ретраев после таймаута быстро меняют картину. Если весь объем уже расписан между командами, спасать прод нечем. Нормально держать небольшой нераспределенный запас для инцидентов, отката и дней с необычной нагрузкой.

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

Быстрая самопроверка тут простая: у prod и dev разные лимиты, есть короткие окна кроме суточного, 10-20% объема не распределены заранее, а ретраи, дубли и всплески по ключам видны в логах.

Короткий чек-лист для пересмотра

Проверьте квоты на одном сервисе
Начните с критичного сценария и отдельно дайте запас песочнице.

Пересматривать квоты лучше по одному шаблону. Иначе они быстро превращаются в набор ручных исключений, где никто уже не помнит, почему одному сервису можно больше, а другому меньше.

Перед каждым пересмотром проверьте пять вещей:

  • у каждого сервиса есть один владелец
  • приоритет записан явно, а не держится на договоренностях в чате
  • prod отделен от dev, stage и тестов
  • batch-задачи живут в своем окне, а не спорят с пользовательским трафиком днем
  • резерв существует отдельно от рабочих квот и не занят по умолчанию

После этого посмотрите на 429 не как на саму проблему, а как на сигнал. Иногда они показывают, что квота слишком мала. Но не реже 429 означают, что сервис выбрал неправильное окно, слишком агрессивно ретраит запросы или случайно залез в чужой резерв. Исправлять нужно причину, а не только поднимать лимит.

Что сделать в следующем спринте

Не пытайтесь переделать весь общий пул за один раз. В одном спринте хватит одного критичного продукта и одной песочницы. Так вы увидите, как схема ведет себя под нагрузкой, и не сломаете соседние сервисы.

Хороший первый кандидат - продукт, который уже влияет на выручку, SLA или поддержку. Для него задайте отдельный лимит, а рядом оставьте небольшую песочницу для экспериментов команды. Песочница нужна не для удобства, а чтобы тесты, новые промпты и случайные прогоны не съедали запас продового сервиса.

Дальше разделяйте доступ не по общему аккаунту, а по отдельным ключам. Один ключ на prod, другой на stage, третий на dev или песочницу. Если ключ общий, вы почти всегда поздно замечаете, кто именно съел лимит и в какой среде это произошло.

На один спринт обычно хватает такого плана:

  • выбрать сервис с самым жестким SLA
  • выдать ему отдельные ключи по средам
  • зафиксировать лимиты на prod и более низкий потолок на песочницу
  • включить простые алерты по приближению к порогу

После настройки проверьте схему не в спокойный день, а в двух неприятных режимах. Первый - релизный день, когда команда гоняет smoke и regression, а пользователи уже идут в прод. Второй - пик нагрузки, например утром в будни или во время пакетной обработки. Если при этих двух сценариях приоритетный сервис не проседает, база выбрана правильно.

Полезно заранее записать одно простое правило: какой трафик урезается первым, если лимит подходит к концу. Обычно сначала режут dev, потом stage, и только потом менее важные продовые задачи вроде внутренних помощников.

Если у вас много команд, провайдеров и ключей, AI Router удобно использовать как единый слой контроля: rate limits на уровне ключа и аудит-логи помогают быстро увидеть, кто выбрал квоту и где начался перекос. Это не заменяет политику квот, но заметно упрощает ее исполнение.

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