
Как проверить, что LLM соблюдает лимит токенов в API
Параметр ограничения генерации в запросе к LLM — не то же самое, что гарантия ответа заданной длины в словах или символах. API ограничивает токены, а модели могут завершить ответ раньше, например из-за стоп-последовательности, конца сообщения или отказа. Чтобы проверить лимит токенов LLM, нужно учитывать параметр конкретного API, фактическую статистику ответа и причину завершения.
Ниже — практический тест, который помогает обнаружить превышение лимита, путаницу между входными и выходными токенами и расхождение между локальным счётчиком и данными провайдера. Он подходит для проверки интеграции до запуска, но не заменяет нагрузочные тесты и проверку ошибок на стороне API.
Какие токены ограничивает параметр генерации
В API часто есть отдельные ограничения на размер входа и выходной генерации. Они связаны, но не взаимозаменяемы: большой контекст запроса может исчерпать общий контекст модели, даже если запрошенный ответ короткий.
Названия параметров различаются. В Chat Completions OpenAI исторически использовался `max_tokens`, а актуальная документация для новых моделей описывает `max_completion_tokens`. В Responses API применяется `max_output_tokens`. Перед тестом проверьте документацию именно того endpoint и модели, которые вызываются в приложении: параметр одного API нельзя автоматически переносить на другой.
В Anthropic Messages параметр `max_tokens` задаёт верхнюю границу генерации. Google Gemini также принимает ограничение выходных токенов в параметрах генерации. Во всех случаях это ограничение относится к токенам, а не к словам: один токен может быть частью слова, знаком пунктуации или пробелом. Для русского текста соответствие «токен — слово» особенно ненадёжно.
Практический вывод: формулируйте проверяемое требование как «ответ не превысил N выходных токенов», а не «ответ содержит не больше N слов». Для ограничения слов используйте отдельную проверку текста, понимая, что она проверяет другое свойство.
Что считать превышением лимита
Сравнивать следует значение использованных выходных токенов из ответа API с лимитом, переданным в запросе. Не сравнивайте лимит генерации с общим числом токенов: статистика обычно включает и вход, и выход.
Для каждого тестового вызова сохраните как минимум:
- имя модели и endpoint;
- значение лимита из запроса;
- фактические выходные токены из usage-объекта;
- причину завершения ответа;
- идентификатор запроса и HTTP-статус.
У разных API названия полей отличаются. В ответах OpenAI Chat Completions статистика содержит `completion_tokens`; в Responses API структура usage другая, и её нужно читать согласно документации используемой версии. Anthropic возвращает счётчики входа и выхода в своём формате, Gemini — в своём. Не пишите универсальный парсер, который предполагает одинаковую структуру у всех поставщиков.
Превышением в узком смысле будет ситуация, когда поле выходных токенов больше заданного лимита. Отсутствующее поле — не ноль: это неполная телеметрия, которую стоит отдельно отмечать, а не засчитывать как успешный тест.
Воспроизводимый тест на одном запросе
Сначала выберите небольшой лимит, например 64 токена, и попросите модель продолжить длинный список или объяснение. Запрос должен мотивировать модель писать дальше, но сам по себе не доказывает, что она достигнет границы: генерация может остановиться естественно.
Пример для OpenAI Chat Completions:
python
from openai import OpenAI
client = OpenAI()
limit = 64
response = client.chat.completions.create(
model=»gpt-4.1-mini»,
messages=[
{
«role»: «user»,
«content»: (
«Перечисли много способов организовать заметки. «
«Каждый пункт подробно объясни и продолжай, пока можешь.»
),
}
],
max_completion_tokens=limit,
)
choice = response.choices[0]
usage = response.usage
print(«Причина завершения:», choice.finish_reason)
print(«Выходные токены:», usage.completion_tokens if usage else None)
if usage is None:
raise RuntimeError(«API не вернул статистику использования»)
if usage.completion_tokens > limit:
raise AssertionError(
f»Превышение: {usage.completion_tokens} > {limit}»
)
Имена доступных параметров и моделей зависят от выбранного endpoint и актуального SDK. Если ваш код вызывает Responses API, не подставляйте в него пример для Chat Completions: используйте соответствующие поля запроса и ответа из документации Responses.
Этот тест проверяет одно свойство: учётная статистика не превышает переданный предел. Чтобы проверить, действительно ли модель останавливается у границы, анализируйте также причину завершения. Значение, указывающее на достигнутый лимит, означает, что генерация была ограничена; обычное завершение может означать, что модель закончила раньше.
Почему одного запуска недостаточно
Результат зависит от длины и формы запроса, настроек генерации и конкретной модели. Короткий ответ на тестовый запрос показывает только, что в этом запуске превышения не было. Он не доказывает поведение на длинном контексте или при параллельных вызовах.
Сделайте набор проверок с несколькими лимитами — например, 1, 8, 64 и 256 токенов, если модель и API допускают такие значения. Для каждого лимита используйте несколько видов запросов:
просьба дать короткий ответ;
просьба продолжать длинный перечень;
3. структурированный вывод, например JSON;
4. запрос, на который ожидается отказ или короткое уточнение.
Проведите серии повторов и сохраняйте сырые ответы. Это позволит отличить реальное превышение от случая, когда модель завершила генерацию до лимита. Не требуйте точного равенства лимиту: верхняя граница не обещает, что модель израсходует все доступные токены.
Лимит токенов — не лимит символов
Если продукт обещает пользователю ответ до 500 символов, параметр API с числом токенов эту формулировку напрямую не обеспечивает. Токенизаторы по-разному разбивают русский, английский, код, URL и числа; одинаковое число токенов может соответствовать разному количеству символов.
Для проверки символов посчитайте длину итогового текста после получения ответа. Если превышен продуктовый предел, приложение может запросить сокращение или обрезать ответ — но обрезка способна повредить JSON, Markdown-таблицу или код. Такие случаи проверяйте отдельно, включая валидность результата после любых преобразований.
Для локальной оценки токенизации используйте токенизатор, соответствующий модели. Библиотека `tiktoken` предназначена для моделей OpenAI, но локальный подсчёт не должен подменять статистику API: серверная обработка, специальные токены и обновления моделей могут влиять на итоговые значения. Для других поставщиков применяйте их документацию и инструменты.
Отдельно проверьте вход и общий контекст
Вызов может завершиться ошибкой ещё до генерации, если вход слишком велик для модели или нарушает ограничение общего контекстного окна. Это не превышение лимита выходных токенов: сервер отклонил запрос либо не смог его обработать по другой причине.
Проверяйте оба бюджета:
- сколько токенов занимает история сообщений и приложенные данные;
- сколько токенов запрошено для ответа;
- укладывается ли их сочетание в ограничения конкретной модели.
Не рассчитывайте остаток простым вычитанием без учёта правил endpoint: в системных сообщениях, инструментах, форматировании и мультимодальном вводе могут быть дополнительные токены. Документация провайдера и фактический ответ API — надёжнее предположений по длине текста.
Ошибки, повторы и потоковая выдача
Тест должен фиксировать не только успешные ответы. Добавьте отдельные результаты для таймаута, ошибки валидации, ограничения частоты запросов и отсутствующей статистики. Иначе интеграция может выглядеть исправной, хотя часть вызовов вообще не доходит до генерации.
В потоковом режиме не считайте события или куски текста токенами. После завершения потока используйте итоговую статистику, если endpoint её возвращает; проверьте документацию для конкретной реализации. Если usage недоступен, локальная токенизация даёт оценку, а не подтверждённый серверный счётчик.
При автоматических повторах связывайте каждый ответ с отдельным идентификатором запроса. Не суммируйте usage повторных попыток как будто это один ответ: для контроля лимита важен каждый вызов, а для стоимости — совокупность фактически выполненных запросов.
Минимальные проверки перед выпуском интеграции
Перед запуском зафиксируйте модель, endpoint и название параметра ограничения. Затем проверьте на тестовых запросах, что приложение передаёт ожидаемое значение, корректно извлекает выходные токены и отдельно обрабатывает причину завершения.
В CI полезно хранить проверку вида «ответ API не превышает заданный максимум», но не привязывать её к точному тексту генерации: формулировки модели могут меняться. Если провайдер обновляет модели или SDK, повторите тест на той же конфигурации, что используется в production.
Наконец, проверьте контракт продукта отдельно от контракта API. Лимит токенов защищает бюджет генерации, но сам по себе не гарантирует краткость, число слов, корректный JSON или соблюдение инструкции. Для каждого такого требования нужна собственная измеримая проверка — и журналирование, которое показывает, какое именно ограничение сработало.










