Claude API 400 «prompt is too long»: причины и исправление
Вы вызываете /v1/messages и получаете HTTP 400 invalid_request_error, начинающуюся с prompt is too long. Ниже описано, что учитывается в контекстном окне, как работает правило «входные данные + max_tokens» в текущих моделях, а также как измерить и сократить промпт.
Краткий ответ
«prompt is too long» означает, что только входные данные — системный промпт, каждое сообщение, определения инструментов, изображения и документы — превышают контекстное окно модели. Запрос отклоняется до начала генерации, поэтому повторный вызов или уменьшение max_tokens не помогут; поможет только уменьшение объема входных данных. Измерьте запрос с помощью POST /v1/messages/count_tokens, а затем удалите или суммируйте старые реплики, сократите результаты работы инструментов или разбейте задачу на части. В Claude 4.5 и более новых моделях большое значение max_tokens само по себе не вызывает эту ошибку.
Симптомы и значение ошибки
В официальном API Messages от Anthropic тело ответа выглядит так:
{
"type": "error",
"error": {
"type": "invalid_request_error",
"message": "prompt is too long: 1048213 tokens > 1000000 maximum"
},
"request_id": "req_011CSHoEeqs5C35K2UUqR7Fy"
}В документации Anthropic эта ошибка упоминается, но полный шаблон сообщения не публикуется; хвост N tokens > M maximum — это формат, который можно встретить в публичных отчетах об ошибках, а числа выше приведены для примера. В коде проверяйте префикс prompt is too long, а не числа.
В моделях старше Claude 4.5 вы можете столкнуться с проверкой входных данных плюс выходных. В сообщениях сообщества она описывается так:
input length and `max_tokens` exceed context limit: 198882 + 21333 > 200000, decrease input length or `max_tokens` and try againНе путайте её с похожими ошибками:
- 413
request_too_large— тело HTTP-запроса содержит слишком много байт, а не токенов. См. 413 request too large. max_tokensбольше лимита вывода модели — другая ошибка 400, касающаяся лимита вывода. См. max_tokens too large.stop_reason: "model_context_window_exceeded"— это вообще не ошибка: успешный ответ (200), который остановился, потому что генерация заполнила окно.
Как учитывается контекстное окно
Согласно документации Anthropic, учитывается всё, что есть в запросе: system промпт, каждая запись в messages (включая результаты инструментов, изображения и документы) и определения ваших инструментов — плюс вывод для текущего шага, включая «размышления» (thinking). При использовании кэширования промптов учитываются input_tokens, cache_read_input_tokens и cache_creation_input_tokens.
Claude Opus 5.5, Sonnet 5.5 и Haiku 5.5 (и другие текущие модели) по умолчанию имеют окно 1 млн токенов без необходимости использования бета-заголовков, с поддержкой до 128 тыс. токенов вывода. У более старых моделей, включая Claude Sonnet 4.5, лимит составляет 200 тыс. В запросе может быть не более 600 изображений или страниц PDF (100 для моделей с окном 200 тыс.).
Правило «входные данные + max_tokens»
Поведение изменилось с выходом Claude 4.5:
| Ситуация | Claude 4.5 и новее | Более старые модели |
|---|---|---|
| Входные данные превышают окно | 400 «prompt is too long» | 400 «prompt is too long» |
Входные данные помещаются, но сумма с max_tokens превышает окно | Запрос принимается; если генерация достигает лимита, она останавливается с stop_reason: "model_context_window_exceeded" | Ошибка валидации 400 (можно включить новое поведение через бета-заголовок model-context-window-exceeded-2025-08-26) |
Таким образом, в текущих моделях можно задавать max_tokens с запасом, не вычисляя его заранее — но нужно проверять stop_reason и обрабатывать model_context_window_exceeded как усеченный ответ.
Скрытый рост: блоки размышлений и новый токенизатор
- Сохраняемые блоки размышлений. В Claude Opus 4.5 и более поздних моделях Opus, Sonnet 4.6 и более поздних моделях Sonnet, а также Haiku 5.5, блоки размышлений (thinking blocks) из предыдущих реплик остаются в контексте и учитываются как входные данные, поэтому сессии агентов растут быстрее, чем кажется по видимому тексту.
- Изменение токенизатора. По заявлению Anthropic, в Claude 4.7 и более новых моделях используется токенизатор, который создает примерно на 30% больше токенов для того же текста. Промпт, который помещался в старую модель, может переполнить новую после миграции; пересчитайте токены для той модели, которую вы используете.
Исправление 1: измеряйте перед отправкой
Эндпоинт для подсчета токенов принимает те же входные данные, что и запрос Messages, и возвращает input_tokens. Его использование бесплатно, и он имеет собственный лимит частоты запросов, отдельный от создания сообщений.
curl https://api.anthropic.com/v1/messages/count_tokens \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5-5",
"system": "You are a code reviewer.",
"messages": [{"role": "user", "content": "Review this diff: ..."}]
}'
# => {"input_tokens": 1234}Проверка перед отправкой на Python:
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-sonnet-5-5"
CONTEXT_LIMIT = 1_000_000 # из страницы модели в документации Anthropic
HEADROOM = 0.9 # подсчет — это оценка; оставьте место для вывода
def fits(system, messages, tools=None):
kwargs = {"model": MODEL, "system": system, "messages": messages}
if tools:
kwargs["tools"] = tools
n = client.messages.count_tokens(**kwargs).input_tokens
return n, n < CONTEXT_LIMIT * HEADROOMПомните об ограничениях: результат — это оценка, а эндпоинт отклоняет серверные инструменты, коннектор MCP и блоки image/document с источником url или file (для их подсчета отправляйте данные в base64). В продакшене также логируйте usage из каждого ответа, чтобы видеть, насколько близко каждый диалог подходит к лимиту.
Исправление 2: обрезайте историю, не ломая её
Удаление самых старых реплик — очевидное решение, но здесь есть две ловушки.
Ловушка 1: осиротевшие результаты инструментов. Если вы разрежете историю между tool_use (вызов инструмента) ассистента и tool_result (результат инструмента) пользователя, который на него отвечает, вы получите ошибку tool_use without tool_result. Всегда обрезайте историю на обычной реплике пользователя.
Ловушка 2: подписи блоков размышлений. В Claude Opus 5.5, Sonnet 5.5 и Haiku 5.5 повторно отправленный блок размышлений должен соответствовать префиксу, в котором он был создан. Anthropic указывает, что обрезка на стороне клиента, сохраняющая недавние размышления в неизменном виде, является причиной ошибки 400 Invalid signature in thinking block; задокументированное решение — удаление этих блоков.
def is_plain_user(msg):
if msg["role"] != "user":
return False
c = msg["content"]
return isinstance(c, str) or not any(b.get("type") == "tool_result" for b in c)
def trim_history(messages, keep_last=20):
trimmed = messages[-keep_last:]
# 1. Начинайте с обычной реплики пользователя, чтобы ни один tool_result не потерял свой tool_use
while trimmed and not is_plain_user(trimmed[0]):
trimmed = trimmed[1:]
# 2. Сохраненные блоки размышлений больше не соответствуют укороченному префиксу: удалите их
out = []
for m in trimmed:
if m["role"] == "assistant" and isinstance(m["content"], list):
m = {**m, "content": [b for b in m["content"]
if b.get("type") not in ("thinking", "redacted_thinking")]}
out.append(m)
return outЭтот код предполагает, что сообщения представлены в виде словарей (для SDK-объектов используйте .model_dump()). Обрезайте историю только перед добавлением новой реплики пользователя, никогда не делайте этого в середине цикла работы с инструментами.
Чтобы не заниматься этим самостоятельно, используйте сжатие на стороне сервера от Anthropic (бета, Claude 4.6 и новее), которое суммирует ранние реплики, или редактирование контекста, которое удаляет старые результаты инструментов и блоки размышлений. Согласно документации, ни один из этих методов не вызывает ошибку подписи.
Исправление 3: сокращайте отправляемые данные
Часто промпты становятся слишком большими из-за нескольких огромных блоков, а не из-за длинного диалога:
- Результаты инструментов. Дампы логов, чтение целых файлов и «сырой» HTML — обычные виновники в агентах. Обрезайте или суммируйте их перед отправкой, либо позвольте редактированию контекста очищать старые данные.
- Документы. Извлекайте соответствующие фрагменты вместо передачи всего корпуса текстов; разбивайте плотные PDF-файлы по разделам.
- Определения инструментов. Схема каждого инструмента является входными данными при каждом запросе. Удаляйте инструменты, которые не нужны для задачи, или откладывайте их использование с помощью инструмента поиска инструментов Anthropic.
- Саммари. Заменяйте старые реплики коротким сообщением-сводкой; один дополнительный вызов позволит держать историю небольшой в дальнейшем.
Исправление 4: знайте, что делает кэширование промптов
Кэширование не исправляет проблему с контекстом. Anthropic заявляет, что кэшированные префиксы по-прежнему занимают место в контекстном окне; кэширование меняет только стоимость этих токенов, а не то, учитываются ли они. Это может снизить счет при использовании длинных, стабильных префиксов, но есть нюанс: запись в кэш оплачивается по повышенной ставке, поэтому кэширование контента, который не используется повторно в ближайшее время, стоит дороже, чем отказ от кэширования.
И напоследок: обрабатывайте случай, который не является ошибкой: когда приходит ответ с stop_reason == "model_context_window_exceeded". Это означает, что ответ был обрезан из-за окна, а не из-за max_tokens — сократите историю (Исправление 2) перед тем, как просить модель продолжить.
Если вы вызываете Claude через byesu
byesu — это шлюз AI API с OpenAI-совместимым эндпоинтом (https://byesu.com/v1) и Anthropic-родным эндпоинтом (/v1/messages на том же хосте), с оплатой по факту использования и без подписки. Для этой ошибки важны два момента:
- Окно принадлежит модели. Шлюз не может его увеличить:
claude-opus-5-5,claude-sonnet-5-5иclaude-haiku-5-5(которые также можно вызывать по точечным псевдонимам, напримерclaude-opus-5.5) имеют те же лимиты, которые публикует Anthropic. В/v1/chat/completionsта же ошибка может прийти упакованной в объект ошибки в стиле OpenAI, поэтому ориентируйтесь на текст «prompt is too long», а не на структуру JSON. - Обрезка — это еще и экономия. При оплате по факту использования каждая реплика истории, которую вы переотправляете, снова оплачивается как входные данные. В Claude Code (
ANTHROPIC_BASE_URL=https://byesu.com, без/v1) запускайте/compactдо того, как сессия приблизится к лимиту, вместо того чтобы ждать ошибки 400.
Чтобы начать, создайте токен в консоли и укажите SDK соответствующий эндпоинт. Полная настройка: Quick Start.
FAQ
Что означает «prompt is too long» в Claude API?
Это ошибка 400 invalid_request_error, которая возвращается, когда входные данные (системный промпт, сообщения, определения инструментов, изображения и документы) превышают контекстное окно модели. Запрос отклоняется до начала генерации, поэтому повторный вызов или уменьшение max_tokens не помогут; нужно отправить меньше входных токенов.
Входит ли max_tokens в контекстное окно Claude?
Генерируемый Claude вывод учитывается в окне, но в Claude 4.5 и более новых моделях API больше не отклоняет запрос только потому, что входные данные плюс max_tokens превышают окно. Запрос принимается, и если генерация достигает лимита, она останавливается со статусом stop_reason «model_context_window_exceeded». Более старые модели вместо этого возвращают ошибку валидации, если только вы не отправляете бета-заголовок model-context-window-exceeded-2025-08-26.
Как подсчитать токены перед отправкой запроса в Claude API?
Отправьте те же параметры (модель, system, сообщения и инструменты) в POST /v1/messages/count_tokens; ответ будет содержать input_tokens. Эндпоинт бесплатный и имеет собственный лимит частоты запросов, но результат является оценочным. Он отклоняет серверные инструменты, коннектор MCP и изображения/документы по url или file, поэтому для подсчета медиа отправляйте данные в формате base64.
Помогает ли кэширование промптов при ошибке «prompt is too long»?
Нет. Кэшированные префиксы все равно занимают место в контекстном окне — кэширование меняет только стоимость этих токенов, а не то, учитываются ли они. Чтобы исправить ошибку, удалите или сократите контент. Кэширование может снизить расходы при частом использовании длинного, стабильного префикса, но запись в кэш оплачивается выше обычной ставки за ввод, поэтому кэширование контента, который вы не используете повторно, стоит дороже.
Почему мой промпт перестал работать после перехода на новую модель Claude?
Anthropic отмечает, что в Claude 4.7 и более новых моделях используется новый токенизатор, который создает примерно на 30% больше токенов для того же текста, а текущие модели Opus и Sonnet также сохраняют предыдущие блоки размышлений (thinking blocks) в контексте. Промпт, который подходил для старой модели, может переполнить новую. Пересчитайте токены с помощью count_tokens для той модели, которую вы фактически вызываете.
