OpenAI "Unsupported parameter: 'max_tokens'" (unsupported_parameter): причины и решения
Вы отправляете запрос Chat Completions в модель рассуждения и получаете HTTP 400 с сообщением о том, что max_tokens не поддерживается и нужно использовать max_completion_tokens. Иногда аналогичные ошибки возникают для temperature или top_p. Ниже описано, что изменилось, как эти три поля ограничения вывода соотносятся между API и как очистить запрос от лишних параметров.
Краткий ответ
Модели рассуждения отклоняют устаревшее поле max_tokens в Chat Completions — OpenAI заменила его на max_completion_tokens. Переименуйте поле. В Responses API этот же лимит называется max_output_tokens. Сопутствующие ошибки для temperature, top_p и logprobs означают, что эти параметры сэмплирования не поддерживаются при текущем уровне рассуждений (reasoning effort): просто удалите их. Все эти ошибки возникают на этапе валидации, до начала генерации.
Симптомы и значение ошибки
Классический ответ, как при использовании Python SDK от OpenAI:
{
"error": {
"message": "Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.",
"type": "invalid_request_error",
"param": "max_tokens",
"code": "unsupported_parameter"
}
}Версия ошибки для параметров сэмплирования выглядит так же:
{
"error": {
"message": "Unsupported parameter: 'temperature' is not supported with this model.",
"type": "invalid_request_error",
"param": "temperature",
"code": "unsupported_parameter"
}
}Некоторые модели принимают имя параметра, но только если оно равно значению по умолчанию, тогда сообщение меняется:
Unsupported value: 'temperature' does not support 0 with this model. Only the default (1) value is supported.Как это интерпретировать:
unsupported_parameter— поле не разрешено для этой модели. Удалите или переименуйте его.unsupported_value— поле разрешено, но не с тем значением, которое вы отправили. Дляreasoning.effortэто отдельная проблема; см. reasoning effort unsupported value.paramуказывает, какое именно поле нужно исправить. Сначала обратите внимание на него, прежде чем менять что-то еще.
Поскольку запрос даже не дошел до этапа генерации, повторная отправка того же тела запроса приведет к такой же ошибке — это не временная проблема.
Почему это происходит
max_tokensустарел в Chat Completions. Справочник API OpenAI помечает его как устаревший в пользуmax_completion_tokensи указывает, что он несовместим с моделями серии o. На практике семейство GPT-5 и более новые модели рассуждения отклоняют его аналогично, поэтому считайте, что для всех моделей рассуждения доступен толькоmax_completion_tokens.- Лимит теперь учитывает рассуждения.
max_completion_tokens(в Chat Completions) иmax_output_tokens(в Responses) включают в себя как токены рассуждения, так и видимый вывод. Переименование делает это изменение смысла явным. - Параметры сэмплирования зависят от reasoning effort. Руководство по миграции на GPT-6 гласит, что нужно убирать
temperature,top_pиtop_logprobsкаждый раз, когда reasoning effort не равноnone, а такжеlogprobsв Chat Completions. - Поле добавляется чем-то другим. Обёртки SDK, агентские фреймворки и CLI часто внедряют
max_tokensили значениеtemperatureпо умолчанию, которое вы явно не задавали. В репозиториях самой OpenAI встречаются подобные проблемы — например, CLI отправляетtemperature/top_pвo3-mini, а библиотека агентов отправляетmax_tokensв модели рассуждения.
Три поля ограничения вывода: краткий обзор
| Chat Completions | Responses API | |
|---|---|---|
| Ограничение вывода | max_completion_tokens (max_tokens устарел) | max_output_tokens (минимум 16) |
| Включает токены рассуждения | Да | Да |
| Поле reasoning effort | reasoning_effort (на верхнем уровне) | reasoning: { "effort": ... } |
| При достижении лимита | finish_reason: "length" | status: "incomplete", incomplete_details.reason: "max_output_tokens" |
Имена полей не взаимозаменяемы: max_completion_tokens относится к Chat Completions, а max_output_tokens — к Responses. Сообщается, что некоторые шлюзы (gateways), совместимые с OpenAI, также отклоняют max_output_tokens, поэтому если вы переключаетесь между провайдерами, перепроверяйте имя поля для каждого эндпоинта.
Исправление 1: переименуйте max_tokens в max_completion_tokens
Прямое исправление для Chat Completions:
curl https://byesu.com/v1/chat/completions \
-H "Authorization: Bearer sk-YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-sol",
"messages": [{"role": "user", "content": "Summarize RFC 9110 in three bullets."}],
"max_completion_tokens": 4000
}'При использовании Python SDK от OpenAI:
from openai import OpenAI
client = OpenAI(api_key="sk-YOUR_TOKEN", base_url="https://byesu.com/v1")
resp = client.chat.completions.create(
model="gpt-6-sol",
messages=[{"role": "user", "content": "Summarize RFC 9110 in three bullets."}],
max_completion_tokens=4000, # не max_tokens
)
print(resp.choices[0].finish_reason, resp.choices[0].message.content)Если ваш код должен поддерживать и старые модели без рассуждений, используйте единую внутреннюю настройку и транслируйте её на уровне отправки, вместо того чтобы отправлять оба поля одновременно.
Исправление 2: в Responses API используйте max_output_tokens
Если вы уже используете (или переходите на) /v1/responses, имя поля снова отличается:
curl https://byesu.com/v1/responses \
-H "Authorization: Bearer sk-YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6.1-sol",
"input": "Summarize RFC 9110 in three bullets.",
"reasoning": {"effort": "low"},
"max_output_tokens": 4000
}'resp = client.responses.create(
model="gpt-6.1-sol",
input="Summarize RFC 9110 in three bullets.",
reasoning={"effort": "low"},
max_output_tokens=4000,
)
if resp.status == "incomplete":
print("Cap reached:", resp.incomplete_details.reason)
else:
print(resp.output_text)Responses API важен для актуальных моделей не только из-за имени поля: согласно страницам моделей OpenAI, вызов инструментов (tool calling) в gpt-6.1-sol и gpt-6-astra требует именно Responses, а gpt-6-sol / gpt-6-luna поддерживают вызов функций в Chat Completions только при reasoning_effort: "none".
Исправление 3: удалите параметры сэмплирования, которые не применяются
Следуйте правилу миграции OpenAI для GPT-6: когда reasoning effort не равно none, удаляйте temperature, top_p и top_logprobs; в Chat Completions также удаляйте logprobs; в Responses удаляйте message.output_text.logprobs из include.
Какие модели могут работать при none (согласно страницам моделей OpenAI):
| Модель | Принимает reasoning.effort: "none" | Можно использовать параметры сэмплирования? |
|---|---|---|
gpt-6.1-sol | Нет | Планируйте никогда их не отправлять |
gpt-6-astra | Нет | Планируйте никогда их не отправлять |
gpt-6-sol | Да | Только при effort none |
gpt-6-luna | Да | Только при effort none |
gpt-5.6-sol | Да | Считайте, что только при effort none |
Небольшой санитайзер поможет исключить эти параметры на местах вызова:
SAMPLING_KEYS = ("temperature", "top_p", "top_logprobs", "logprobs")
def clean_chat_params(params: dict) -> dict:
p = dict(params)
# Устаревший лимит -> текущий лимит
if "max_tokens" in p:
p.setdefault("max_completion_tokens", p.pop("max_tokens"))
# Параметры сэмплирования имеют смысл только при effort "none"
if p.get("reasoning_effort", "medium") != "none":
for k in SAMPLING_KEYS:
p.pop(k, None)
return p
resp = client.chat.completions.create(**clean_chat_params({
"model": "gpt-6-luna",
"messages": [{"role": "user", "content": "ping"}],
"max_tokens": 200,
"temperature": 0.2,
}))По умолчанию используется medium, так как в документации обоих API medium указан как уровень рассуждений по умолчанию. В справочнике API также отмечается, что параметр stop не поддерживается в o3 и o4-mini, поэтому если вы все еще используете их, добавьте stop в список на удаление.
Исправление 4: найдите уровень, который добавляет поле
Если ваш собственный код никогда не задает max_tokens или temperature, значит, это делает что-то посередине. Изучите запрос в момент выхода из процесса:
# openai-python: логирование параметров запроса, включая JSON-тело
OPENAI_LOG=debug python your_script.py 2>&1 | grep -i -E "max_tokens|temperature|top_p"Распространенные источники:
- Настройки модели во фреймворке со значением
max_tokensилиtemperatureпо умолчанию (агентские фреймворки, обёртки в стиле LangChain, оценочные инструменты). - CLI-инструменты, которые подставляют значения по умолчанию при каждом вызове.
- Клиентские приложения со слайдером «max tokens» или «temperature», значения которого отправляются всегда, даже если их не трогали.
Исправляйте там, где происходит внедрение — обычно это объект настроек модели или конфигурация провайдера, — вместо того чтобы «латать» проблему в каждом месте вызова.
Не устанавливайте слишком низкий лимит
Поскольку лимит включает в себя токены рассуждения, жесткое ограничение max_completion_tokens или max_output_tokens может быть полностью поглощено процессом рассуждения. В руководстве по рассуждениям OpenAI предупреждается, что остановка может произойти еще до получения видимого вывода, и рекомендуется резервировать не менее 25 000 токенов на рассуждение и вывод во время экспериментов. Если вы получаете finish_reason: "length" при пустом сообщении, увеличьте лимит или понизьте уровень усилий (effort). Это проблема бюджета токенов, а не превышение контекстного окна — о последнем см. context length exceeded.
Если вы вызываете GPT через byesu
byesu — это AI API-шлюз с эндпоинтом, совместимым с OpenAI, по адресу https://byesu.com/v1. Он поддерживает как Chat Completions, так и Responses, оплата производится по факту использования (pay-as-you-go) без подписки.
- Те же правила, те же поля. Приведенные выше рекомендации по параметрам применимы без изменений:
max_completion_tokensдля/v1/chat/completions,max_output_tokensдля/v1/responsesи никаких параметров сэмплирования приreasoning_effort, отличном отnone. - Точные ID моделей. Копируйте ID моделей, такие как
gpt-6.1-solилиgpt-6-luna, из списка моделей в консоли или черезGET /v1/models, чтобы применяемые вами правила для параметров соответствовали той модели, которую вы вызываете.
Для начала работы следуйте Quick Start.
FAQ
Что означает ошибка "Unsupported parameter: 'max_tokens' is not supported with this model"?
Это ошибка 400 invalid_request_error с кодом unsupported_parameter. Модели рассуждения в Chat Completions не принимают устаревшее поле max_tokens, которое OpenAI заменила на max_completion_tokens. Переименуйте поле, и запрос пройдет; ошибка возникает на этапе валидации, еще до того, как модель начнет генерацию.
В чем разница между max_tokens, max_completion_tokens и max_output_tokens?
max_tokens — это устаревший лимит для Chat Completions. max_completion_tokens — его замена в Chat Completions, которая учитывает как видимый вывод, так и токены рассуждения. max_output_tokens — аналогичный лимит для Responses API (минимум 16), который также включает токены рассуждения.
Почему моя модель рассуждения отклоняет temperature или top_p?
Руководство по миграции OpenAI для GPT-6 предписывает удалять temperature, top_p и top_logprobs каждый раз, когда reasoning_effort не равно none, а также удалять logprobs в Chat Completions. Модели, которые не могут работать при effort none, такие как gpt-6.1-sol и gpt-6-astra, никогда не должны получать эти параметры выборки.
Почему эта ошибка появляется, если я никогда не устанавливал max_tokens или temperature?
Какая-то библиотека, фреймворк или CLI добавляет их за вас. Обёртки SDK и агентские фреймворки часто внедряют max_tokens или значение temperature по умолчанию. Логируйте тело исходящего запроса и удалите поле на том уровне, где оно добавляется.
Можно ли установить слишком низкое значение max_completion_tokens для модели рассуждения?
Да. Этот лимит включает токены рассуждения, поэтому небольшое значение может быть полностью израсходовано на рассуждения еще до появления какого-либо видимого текста. OpenAI рекомендует резервировать не менее 25 000 токенов на рассуждение и вывод при первых экспериментах с моделями рассуждения.
