Ошибка 400 после перехода на Sonnet 5.5: что изменить в API-запросе

Проверьте thinking disabled, принудительные вызовы инструментов, историю диалога и computer use при миграции на Sonnet 5.5. Включён минимальный пример запроса.

Линейная иллюстрация ключа с заголовком Sonnet 5.5 API Migration.

Даже простая замена ID модели может нарушить работу существующей интеграции Sonnet 5. В Sonnet 5.5 изменились допустимые параметры рассуждений, принудительный выбор инструментов, обработка истории рассуждений и совместимость некоторых инструментов. Если после обновления появился HTTP 400, сначала изучите тело ошибки и фактически отправленный запрос, а не меняйте авторизацию и не повторяйте тот же payload.

Основа статьи — руководство по миграции Sonnet 5.5 и описание изменений, проверенные 29 сентября 2026 года. Примеры показывают структуру запросов по документации. Это не утверждение, что Ofox воспроизвёл каждую ошибку на работающем API. Для 401, 429 и специфического для провайдера 404 нужна другая диагностика.

Найдите несовместимое поле

Старая конфигурацияИзменение в Sonnet 5.5Первое действие
thinking.type: disabledОтклоняетсяИспользовать between_tools с effort не выше high
Ручной enabled с budget_tokensОтклоняетсяПерейти на поддерживаемый adaptive thinking или between_tools
tool_choice.type: any или toolОтклоняетсяИспользовать auto и проверять выбор в приложении
Изменённая история с повторной передачей блоков рассужденийМожет нарушить привязку диалогаТолько дополнять историю либо следовать документированному удалению блоков
computer_20251124 в Claude API/Google CloudОтклоняетсяПерейти на поддерживаемый набор computer-инструментов и обновить цикл
Старое сочетание с advisor-модельюНекоторые сочетания отклоняютсяПроверить список поддерживаемых advisor-моделей

Не распространяйте строку computer use на всех провайдеров. На той же официальной странице указано, что Amazon Bedrock принимает старый инструмент computer_20251124. Платформа — часть условий исправления.

Как заменить disabled

Для минимального текстового запроса без инструментов документация допускает такое тело POST /v1/messages в нативном Claude API:

{
  "model": "claude-sonnet-5-5",
  "max_tokens": 1024,
  "thinking": {"type": "between_tools"},
  "output_config": {"effort": "high"},
  "messages": [{"role": "user", "content": "Return a one-sentence summary of this task: verify a CSV total."}]
}

Тело запроса — не полный HTTP-клиент. Добавьте заголовки авторизации и версии API согласно Messages API. Храните учётные данные в своём окружении, а не в копируемых примерах или логах.

between_tools отключает рассуждения перед началом работы, но не гарантирует отсутствие таких блоков во всех сценариях с инструментами. Заметки о ходе работы между инструментами всё ещё могут использовать этот тип блока. Режим поддерживает low, medium и high, но не xhigh и max; дополнительные поля вроде display и budget_tokens не принимаются. Для xhigh или max нужен adaptive thinking. Повтор запроса с несовместимыми параметрами не исправит ошибку валидации.

После отказа от принудительного вызова проверьте поведение

Переход на tool_choice: auto меняет поведение: модель может решать, вызывать ли инструмент. Параметр strict: true в поддерживаемом определении проверяет структуру входных данных инструмента, но не принуждает выбрать его. Приложение должно проверить, произошёл ли ожидаемый вызов. Возможности схем зависят от платформы: согласно руководству, Sonnet 5.5 в Amazon Bedrock не поддерживает structured outputs, включая strict tool use.

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

Сохраняйте историю диалога

Sonnet 5.5 привязывает блоки рассуждений к модели и разговору. Изменение раннего системного промпта, описания инструмента или сообщения при повторной передаче более позднего блока может вызвать ошибку привязки. По умолчанию контроль применяется на указанных платформах к аккаунтам, созданным 31 августа 2026 года в 00:00 UTC или позже. Старые аккаунты и явное включение этой настройки нужно проверять отдельно.

Самый простой подход — история только с добавлением новых сообщений. Сохраняйте возвращённые блоки без изменений и применяйте документированные механизмы для изменений внутри диалога. При намеренном редактировании истории следуйте правилам обработки затронутых блоков и beta-параметров. Не удаляйте все блоки рассуждений из каждого запроса как универсальное исправление: это меняет диалог и может привести к потере полезного контекста.

Переключение моделей имеет отдельные правила. Блок, который целевая модель не может прочитать, может быть отброшен; это не то же самое, что ошибка привязки из-за изменённого префикса. Записывайте конкретную ошибку или метаданные преобразования, а не называйте любую проблему «invalid signature». Для прежних случаев есть руководство по ошибке подписи thinking block.

Проверяйте и успешные HTTP-ответы

Некоторые регрессии не возвращают HTTP-ошибку. Длинные заметки между вызовами инструментов могут поступать в блоках рассуждений, текст которых скрыт при стандартном отображении adaptive. Интерфейс, показывающий только текстовые блоки, выглядит молчащим, хотя запрос допустим. Проверьте поведение thinking.display для adaptive thinking либо поддерживаемый режим between_tools.

Отказ также отличается от транспортной ошибки. Документация описывает HTTP 200 с stop_reason: refusal и дополнительными деталями. Успешный HTTP-статус не доказывает, что задача выполнена. Обрабатывайте результат явно вместо повторной отправки того же отклонённого задания.

Воспроизведите один запрос отдельно от цикла агента

До изменения рабочей интеграции сохраните запрос, удалив секреты и закрытые входные данные. Запишите хост endpoint, точный ID модели, версию SDK, HTTP-статус, поля ошибки type и message, а также request ID, если он доступен. Исходный ответ оставьте локально. Одной строки «400 Bad Request» недостаточно, чтобы отличить несовместимые настройки thinking от неверной последовательности сообщений. На время диагностики отключите автоматические повторы приложения: десять одинаковых невалидных запросов не исправляют конфигурацию.

Сохраните приведённый выше минимальный JSON в request.json и начните новый диалог. Следующая команда обращается к нативному endpoint Anthropic; её выполнение расходует API-ресурсы. Предполагается разрешённая учётная запись и уже заданная переменная ANTHROPIC_API_KEY. Не вписывайте ключ прямо в команду и не публикуйте сохранённый ответ. Это инструкция по диагностике, а не запись нашего успешного запуска модели.

curl --silent --show-error \
  --dump-header response.headers \
  --output response.json \
  --write-out 'HTTP %{http_code}\n' \
  https://api.anthropic.com/v1/messages \
  --header "x-api-key: $ANTHROPIC_API_KEY" \
  --header 'anthropic-version: 2023-06-01' \
  --header 'content-type: application/json' \
  --data-binary @request.json

Проверьте отдельно HTTP-статус в терминале и JSON ответа. Нулевой код завершения curl означает завершение передачи; без специальной обработки HTTP-ошибок он не подтверждает принятие запроса API. Если минимальный вариант работает, возвращайте исходный system prompt, инструменты и историю по одной группе. Первая группа, после которой возвращается ошибка, сужает поиск лучше, чем одновременная замена модели, SDK и схем инструментов.

Если 400 остаётся, сравните фактически сериализованный JSON с примером. Обёртка SDK может снова добавить thinking.type: disabled, ручной token budget или принудительный tool choice, уже удалённые из конфигурации приложения. Смотреть нужно на отправленное тело, а не только на объект настроек. Для шлюза проверьте заявленную совместимость с нативным API: нельзя предполагать, что все поля передаются без изменений.

Меняйте запрос и разбор ответа вместе

Сравнение до и после должно учитывать не только валидность JSON, но и поведение.

ДоПослеДополнительный критерий приёмки
thinking: {"type":"disabled"}thinking: {"type":"between_tools"}Нет неподдерживаемых полей; effort — low, medium или high
tool_choice: {"type":"tool","name":"record_expense"}tool_choice: {"type":"auto"}Различаются отсутствие вызова, один вызов и неожиданный вызов
Чтение только первого content blockРазбор по типам блоковtext, thinking и tool_use обрабатываются; неизвестные инструменты не исполняются
HTTP 200 считается успехомСтатус, stop_reason и бизнес-проверкиОтказ, обрыв и незавершённая работа не записываются как успешные операции

Например, приложение учёта расходов не должно создавать запись только потому, что текст говорит «сохранено». Нужны разрешённое имя tool_use, проверенные аргументы и необходимое разрешение на операцию. При возврате результата сохраните assistant content и сопоставьте результат с соответствующим tool-use ID. При нескольких вызовах связывайте результаты по отдельности, а не присоединяйте всё к последнему пришедшему вызову.

Отсутствие вызова при auto становится штатной веткой. Покажите пользователю понятное состояние незавершённости или запросите недостающие сведения. Повтор с tool_choice: any вернёт несовместимость. strict: true на поддерживаемых платформах ограничивает форму аргументов, но не доказывает правильность суммы, получателя или даты. После schema validation нужны бизнес-проверки.

Проверяйте историю отдельно от нового диалога

Предположим, запрос с системной инструкцией A прошёл, затем вы заменили A на B и повторно отправили подписанный thinking, созданный после A. По описанным правилам binding этот блок уже не соответствует предыдущей части диалога. Увеличение max_tokens не восстановит связь. Повторите задачу в новом диалоге без старых блоков. Если он работает, исследуйте изменение истории, а не бюджет токенов.

Храните исходный разговор как неизменяемую запись. Не создавайте поддельные подписи и не копируйте thinking из другой учётной записи. Для намеренного редактирования истории реализуйте официальный порядок обработки затронутых блоков и поддерживаемых параметров. Временная диагностика через новый диалог не должна незаметно превращаться в рабочую политику удаления всего пользовательского контекста. Проверьте и диалог только с добавлением сообщений, и конкретное изменение истории, которое делает приложение.

Переключение модели — отдельный случай. Нечитаемый блок может быть удалён с ответом 200, тогда как нарушение binding способно отклонить запрос. Различайте в журналах «запрос не выполнен» и «выполнен с изменившейся обработкой истории». У возобновлённой и новой задачи могут различаться контексты даже при одинаковых видимых сообщениях пользователя.

Задайте контракт ответа до переключения трафика

Для минимального текстового примера нужны успешный HTTP-ответ, доступный текст, подходящая причина завершения и резюме, соответствующее входу. Для инструментального процесса добавляются имя инструмента, schema, правильное связывание результатов и завершённая бизнес-задача. max_tokens означает достижение лимита. Половину JSON или инструкции нельзя молча считать готовым результатом. Отказ тоже отдельный исход, а не повод использовать повтор для временного сетевого сбоя.

Поддерживайте шесть небольших регрессионных случаев: новый текстовый запрос, допустимая операция инструмента, ответ без вызова, второй ход с добавлением истории, намеренно изменённый префикс и fixture парсера с несколькими типами блоков. Последний можно выполнить локально на синтетическом JSON. Это проверка вашего парсера, а не поведения Sonnet. Сначала выполните локальные проверки, затем ограниченную онлайн-выборку на разрешённых данных и сравните результаты старой и новой версии приложения.

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

Проверка перед production

Общий план развёртывания — в руководстве по переходу с Sonnet 5, выбор модели в CLI — в настройке Claude Code. Здесь разобраны изменения нативного API; сторонний шлюз может добавлять собственный слой преобразования и ошибки.

Часто задаваемые вопросы

Можно оставить disabled?
Это значение не поддерживается Sonnet 5.5. Документированная замена — between_tools с high или ниже. Для более высоких уровней effort используйте adaptive thinking.
Strict tool use гарантирует вызов инструмента?
Нет. Проверка схемы и выбор инструмента — разные требования. Приложение должно обработать ответ без нужного вызова.
Любой 400 означает проблему обновления модели?
Нет. Прочитайте точную ошибку и изолируйте изменённое поле. Некорректные сообщения, адаптация провайдера и другие недопустимые параметры тоже могут давать 400.