LLM API и интеграция
Лимит расходов на API-ключ: как не получить огромный счёт
От огромного счёта за API защищают три настройки ключа: отдельный ключ на каждый сценарий, дневной и месячный лимит расходов в рублях и список разрешённых моделей. Величину лимита берут из фактического расхода за неделю — дневной равен самому дорогому дню, умноженному на два, — а ответ 429 key_limit_exceeded код обрабатывает как штатную остановку, а не как сбой. Заодно лимит работает датчиком: ключ, упёршийся в потолок раньше обычного, сообщает о проблеме раньше, чем её увидит бухгалтерия.
Ниже — откуда берутся неожиданные счета, почему баланса мало, как разложить нагрузку по ключам, как посчитать величину лимита по журналу, зачем ограничивать список моделей и что должен делать код, получив отказ по лимиту.
Откуда берётся счёт, которого никто не ждал
Три сценария, и во всех трёх расход идёт без участия человека.
- Зациклившийся агент. Инструмент возвращает ошибку, модель пробует снова, и так по кругу. С каждым кругом растёт история диалога, поэтому каждый следующий запрос дороже предыдущего: он тащит за собой всю переписку. Ночь такого цикла — тысячи запросов с растущим входом.
- Утёкший ключ. Ключ попал в репозиторий, в лог или в переписку, и им пользуется кто-то другой. Чужая нагрузка не экономит: берёт дорогие модели и работает круглосуточно.
- Ошибка в цикле. Повтор при ошибке без паузы и без предела попыток, пакетная задача, запущенная дважды, список, который из-за бага читается заново. Самый скучный сценарий и самый частый.
Общее у всех трёх: человек узнаёт о проблеме по счёту или по остановке сервиса, то есть через часы или дни. Защита должна срабатывать раньше и без него. Как агенты разгоняют расход и из каких множителей складывается их месяц, разобрано в статье сколько стоит ИИ-агент в месяц.
Предоплаченный баланс от этого не спасает. Он ограничивает ущерб суммой на счёте, а когда она заканчивается, останавливаются все сценарии разом: вместе с зациклившимся агентом замолкает бот поддержки, который ни в чём не виноват. Лимит на уровне ключа останавливает один сценарий и на заранее выбранной сумме, остальные ключи продолжают работать.
Зачем отдельный ключ на каждый сценарий
Лимит имеет смысл только у ключа с одной задачей. Если бот поддержки, агент разработчика и тестовый стенд живут на общем ключе, нет правильной величины лимита: любая цифра либо душит рабочий трафик, либо ничего не защищает.
Разумное деление выглядит так:
- по ключу на каждый рабочий сценарий: бот поддержки, разбор заявок, ночная обработка документов;
- отдельный ключ на каждого агента, включая агента в редакторе кода;
- ключ разработки и ключ тестового стенда;
- по ключу на каждого подрядчика, с отзывом по окончании работ.
Побочная польза — учёт. В журнале видно, какой сценарий сколько стоит, без разбора логов. Где хранить ключи, как их ротировать и что делать при утечке, подробно разобрано в статье как хранить API-ключи; здесь речь только про их границы.
Какие ограничения можно поставить на ключ
В KeyDealer у каждого ключа настраиваются четыре границы: дневной лимит расходов в рублях, месячный лимит расходов в рублях, месячный лимит в токенах и список разрешённых моделей. При исчерпании лимита API отвечает 429 key_limit_exceeded, а журнал показывает по каждому запросу ключ, модель, токены входа и выхода и стоимость; тексты запросов не хранятся.
Рублёвые лимиты — основная защита, потому что они считают деньги напрямую, независимо от ставки модели. Лимит в токенах полезен там, где нужно ограничить объём работы, например у тестового стенда или у подрядчика. Список моделей закрывает отдельный риск, о нём ниже.
Как выбрать величину лимита
Лимит берут из фактического расхода, а не наугад. Угаданный низко лимит останавливает рабочий трафик, и через неделю его снимают совсем. Угаданный высоко не защищает ни от чего.
Порядок такой:
- Первую неделю сценарий работает с месячным лимитом, заведомо выше ожиданий, но конечным.
- По журналу считается расход по дням: сколько ушло в каждый день и какой день был самым дорогим.
- Дневной лимит — самый дорогой день недели, умноженный на два.
- Месячный лимит — недельный расход, умноженный на 4,3, плюс треть запаса на рост нагрузки.
Пример расчёта для четырёх ключей одной компании:
| Ключ | Расход за неделю | Самый дорогой день | Дневной лимит | Месячный лимит |
|---|---|---|---|---|
| Бот поддержки | 1 400 ₽ | 250 ₽ | 500 ₽ | 8 000 ₽ |
| Ночная обработка документов | 700 ₽ | 180 ₽ | 400 ₽ | 4 000 ₽ |
| Агент разработчика | 2 100 ₽ | 650 ₽ | 1 300 ₽ | 12 000 ₽ |
| Тестовый стенд | 150 ₽ | 60 ₽ | 150 ₽ | 900 ₽ |
Суммы расхода в таблице условные, лимиты округлены вверх, коэффициенты рабочие. Пересматривать лимит стоит раз в месяц и при каждом изменении сценария: новая модель, новый канал, рост числа пользователей. Как переводить токены в рубли для любой позиции, показано в материале про стоимость миллиона токенов.
Зачем нужен дневной лимит, если есть месячный
Они ловят разные беды, и ставить нужно оба.
Дневной лимит ловит всплеск. Зациклившийся агент или повтор без паузы выбирают месячный лимит за одну ночь, и дальше сценарий стоит до конца месяца или до ручного вмешательства. С дневным лимитом ущерб ограничен сутками, а на следующий день ключ снова работает.
Месячный лимит ловит ползучий рост. Утёкший ключ, которым пользуются умеренно, не упрётся в дневной потолок ни разу. За месяц он при этом наберёт сумму, которую вы не планировали. Месячный лимит превращает такую утечку в остановку, а не в счёт.
Лимит не заменяет ограничителей внутри самого агента — потолка числа шагов и расхода на одну сессию. Это разные уровни: ограничитель агента срабатывает на одной задаче, лимит ключа — на всём сценарии. Как ставить первые, разобрано в статье как сделать ИИ-агента.
Зачем ограничивать список моделей
Ключ под классификацию обращений не должен уметь вызывать флагман. Ставки в каталоге различаются в десятки раз, и одна строка в конфигурации превращает копеечный сценарий в дорогой.
Ставки на 25 сентября 2026 года, в базовом каталоге одинаковые на вход и на выход:
| Позиция | ₽ за 1 млн токенов | Каким ключам разрешать |
|---|---|---|
deepseek-v4-flash | 1 | классификация, разбор заявок |
qwen-3-7-plus | 3 | короткие ответы |
gemini-3-flash | 6 | бот поддержки |
sonnet-5 | 30 | тексты, агент разработчика |
opus-5 | 30 | сложные задачи, отдельный ключ |
gpt-6-astra | 60 | многошаговые задачи, отдельный ключ |
Список разрешённых моделей закрывает два сценария. Первый — ошибка своих: разработчик поменял модель в конфигурации «проверить, будет ли лучше» и забыл вернуть. Второй — чужие руки: утёкший ключ с доступом к одной дешёвой позиции стоит злоумышленнику мало, и ущерб от него растёт медленно.
Список заодно фиксирует решение о модели: смена модели в сценарии превращается из правки конфигурации в осознанное изменение настроек ключа.
Что происходит, когда лимит исчерпан
API отвечает статусом 429 с кодом key_limit_exceeded в теле ошибки. Сервис при этом исправен: сработала граница, которую вы поставили сами.
Главное — не путать его с rate_limit_exceeded. Статус у них одинаковый, смысл противоположный. Отказ по частоте лечится паузой и повтором, как описано в статье лимиты запросов и что делать. Отказ по лимиту ключа от повторов не проходит: бюджет не восстановится через секунду, а повторы только засорят журнал.
В документации есть важная деталь: key_limit_exceeded приходит, когда остатка лимита не хватает на активные запросы и на максимальный вывод нового запроса. Значит, отказ возможен до того, как лимит списан целиком. Разумный max_tokens у запроса помогает использовать остаток до конца, а максимальный без нужды делает отказ более ранним.
Как обработать key_limit_exceeded в коде
Код разбирает поле code в теле ошибки и на этом коде останавливает задачу, а не повторяет её.
import os
from openai import OpenAI, RateLimitError
client = OpenAI(base_url="https://api.keydealer.ru/v1",
api_key=os.environ["KD_KEY_SUPPORT"])
def answer(messages):
try:
return client.chat.completions.create(
model="gemini-3-flash", messages=messages, max_tokens=800)
except RateLimitError as e:
if e.code == "key_limit_exceeded":
notify_team("Ключ поддержки упёрся в лимит") # ваш канал оповещений
raise BudgetStopped() # штатная остановка, без повторов
raise # rate_limit_exceeded: пауза и повтор выше по стеку
Что должно произойти после остановки:
- Состояние задачи сохраняется. Пакетная обработка запоминает, на каком документе остановилась, и продолжит с него, а не с начала.
- Пользователь видит понятный текст. Бот поддержки отвечает, что сейчас подключит человека, а не показывает техническую ошибку.
- Команда получает оповещение. Сигнал об исчерпании лимита приходит в ваш код в виде ответа 429, поэтому оповещение строится на вашей стороне: первый key_limit_exceeded за день пишет в рабочий канал.
Остальные коды ошибок и реакция на каждый собраны в таблице в статье ошибки API нейросетей.
Что значит, если ключ упёрся раньше обычного
Лимит, выбранный от фактического расхода, в нормальный день не срабатывает. Значит, срабатывание — это сигнал разобраться, а не повод поднять потолок.
Журнал показывает по каждому запросу модель, токены входа и выхода и стоимость, и по этим полям видны типовые причины:
- вход растёт от запроса к запросу — агент крутится в цикле и таскает за собой всю историю;
- одинаковые запросы подряд с интервалом в доли секунды — повтор без паузы;
- резко вырос выход — у запроса нет max_tokens, и модель пишет, пока не упрётся в свой предел;
- запросы в нерабочее время при обычной нагрузке днём — повод проверить, не утёк ли ключ.
Порядок действий при подозрении на утечку — сначала отозвать ключ, потом разбираться — разобран в материале крадут API-ключи: что нашла разведка Google. Поднимать лимит, не поняв причину, — значит платить за ту же ошибку дважды.
Как настроить всё за пятнадцать минут
- Выпишите сценарии, которые сейчас ходят в API, и заведите по ключу на каждый.
- Каждому ключу оставьте в списке разрешённых только те модели, которые он реально вызывает.
- Поставьте временный месячный лимит в рублях, заведомо выше ожиданий, и неделю соберите расход.
- По журналу посчитайте дневной и месячный лимит по формулам выше.
- Добавьте в код разбор key_limit_exceeded и оповещение команды.
- Отзовите старый общий ключ.
Чего мы не утверждаем
Лимит не защищает ключ от кражи. Он ограничивает ущерб и ускоряет обнаружение. Хранение, ротация и отзыв — отдельная работа.
Коэффициенты в формулах — рабочие, а не универсальные. У сценария с сильной недельной сезонностью запас нужен больше, у ровного фонового процесса — меньше.
Мы не видим тексты ваших запросов. Журнал показывает модель, токены и стоимость, поэтому смысловой разбор инцидента — какой шаг агента зациклился — делается по вашим собственным логам.
Что нужно, чтобы попробовать
Ключ заводится на keydealer.ru/login, оплата российской картой в рублях, без зарубежной карты. Один ключ открывает каталог: на 25 сентября 2026 года это 56 позиций, из них 44 доступны, 46 текстовых с рублёвой ставкой и 10 генерируют изображения.
Лимиты и список моделей задаются у каждого ключа отдельно, поэтому разложить нагрузку можно сразу: дешёвый ключ под классификацию, отдельный под агента, отдельный под тесты. Две позиции сейчас в режиме проверки — gemini-3-6-flash и fable-5, и включать их в список разрешённых для рабочего сценария пока рано.
Что держать в голове
Неожиданный счёт почти никогда не бывает атакой из ниоткуда. Чаще это собственный агент, собственный цикл повторов или ключ, забытый в репозитории. Во всех трёх случаях расход идёт без человека, поэтому и защита должна работать без него.
Защита складывается из слоёв. Отдельный ключ даёт сценарию собственную границу, дневной лимит режет всплеск, месячный — ползучий рост, список моделей не даёт дешёвому сценарию стать дорогим. Код отличает key_limit_exceeded от отказа по частоте и останавливается, а не повторяет.
И главное: лимит — это ещё и датчик. Если ключ упёрся раньше обычного, сначала журнал и причина, потом решение о потолке. Как мы проверяем факты и что храним из запросов — на странице о проекте. Завести ключи с лимитами под свои сценарии: keydealer.ru/login.
Частые вопросы
Зачем ставить лимит расходов на API-ключ?
Чтобы ошибка стоила одного дня работы сценария, а не всего баланса. Зациклившийся агент, утёкший ключ или повтор без паузы тратят деньги быстрее, чем это замечает человек. Лимит останавливает расход сам, без вашего участия и в любое время суток.
Какой лимит поставить, если непонятно, сколько нужно?
Неделю поработать с высоким, но конечным лимитом и посмотреть фактический расход по дням в журнале. Дневной лимит — самый дорогой день недели, умноженный на два. Месячный — недельный расход, умноженный на четыре с третью, плюс запас на рост.
Что делать при ошибке 429 key_limit_exceeded?
Остановить задачу и не повторять запрос с паузой. Это не перегрузка, и от повторов лимит не восстановится. Дальше сохранить состояние задачи, показать пользователю понятный текст, оповестить команду и посмотреть в журнале, почему ключ упёрся раньше обычного.
Чем key_limit_exceeded отличается от rate_limit_exceeded?
Первый означает, что закончился бюджет ключа, который задали вы. Второй — что запросы идут чаще допустимого, и его лечат паузой и повтором. Оба приходят со статусом HTTP 429, поэтому код должен разбирать поле code в теле ошибки, а не только статус.
Зачем ограничивать список моделей на ключе?
Чтобы ключ под простую задачу не мог уйти на дорогую позицию из-за ошибки в конфигурации или в чужих руках. Ставки дешёвых и флагманских позиций различаются в десятки раз, и список разрешённых моделей закрывает этот разрыв одной настройкой.
Нужен ли дневной лимит, если уже стоит месячный?
Да. Месячный лимит зациклившийся агент может выбрать за одну ночь, и сценарий простоит до конца месяца или до ручного вмешательства. Дневной ограничивает ущерб сутками и оставляет бюджет на остальные дни.