DeepSeek API: tool_choice, reasoning и диагностика ошибки 400
Запрос «DeepSeek API tool_choice reasoning ошибка 400» требует не подбора случайных параметров, а короткой диагностики контракта. Сведите запрос к синтетическому минимуму, проверьте собственную схему и остановите побочное действие до ясного результата. RussiaAPI — независимый сторонний API gateway: эта статья не представляет DeepSeek и не обещает поддержку конкретного поля.
Сначала отделите 400 от сетевой неопределённости
HTTP 400 обычно означает, что приложение получило ответ о форме входа, а не что нужно повторять запрос. Зафиксируйте локальную категорию input_or_contract, покажите понятное сообщение разработчику и остановите очередь конкретной операции. Не ставьте 400 в общий retry-пул: повтор того же тела может создать шум в журнале и скрыть причину.
Если клиент получил timeout, ситуация другая: клиент не подтвердил итог и не должен считать операцию неисполненной. Сначала сверяйте локальный operation ID и безопасный статус. Различение этих двух веток важно, когда tool call мог запустить сохранение, публикацию или другой side effect.
Сведите запрос к минимальному fixture
Создайте один короткий синтетический сценарий без пользовательских данных. Отправляйте только документированную форму сообщения, один инструмент с локально проверяемой JSON Schema и один режим выбора инструмента, который разрешён текущим контрактом. Меняйте по одному элементу: так вы увидите, что именно вызвало отказ, а не получите случайный набор различий.
Не копируйте в тест полный production prompt, реальный файл, upstream credential или тело чужого ответа. Для диагностики достаточно версии адаптера, выбранного route alias, даты и сокращённой категории ошибки. Если неизвестное поле или тип не проходит локальную схему, не отправляйте его «на удачу» и не утверждайте, что другой маршрут ведёт себя так же.
Проверьте границу между reasoning и инструментом
Текст рассуждения, промежуточное поле или часть ответа не являются разрешением на действие. Приложение должно отдельно валидировать аргументы инструмента, связывать их с локальной операцией и требовать подтверждение там, где этого требует продукт. Это помогает пережить изменение формата без попытки интерпретировать недокументированные поля как команду.
Не храните лишние промежуточные данные ради отладки. Сохраните разрешённые поля, безопасный хэш структуры и итог локальной проверки; не записывайте весь prompt, потенциально чувствительный reasoning или заголовки. Политика хранения и доступ к журналу определяются вашим проектом, а не этой страницей или предполагаемым поведением поставщика.
Сделайте ветку 400 объяснимой
Хорошая обработка возвращает разработчику конкретное локальное состояние: неверный тип, отсутствующее обязательное поле, неподдержанный режим или неизвестная форма. Пользователю не нужен сырой ответ маршрута. Так интерфейс не раскрывает технические детали и не привязывает логику к нестабильному тексту сообщения.
Для каждого состояния задайте действие: исправить вход, остановить адаптер, повторить позже только временную операцию или передать случай на review. Не обещайте универсальную таблицу ошибок: параметры и ответ зависят от актуального контракта, модели, аккаунта и настройки приложения.
Проведите повторный тест после исправления
После изменения адаптера прогоните прежний отрицательный fixture и один корректный синтетический fixture. Успех означает только то, что эти сценарии сработали в зафиксированный день и конфигурации. Перед расширением охвата сохраните rollback и проверьте, что side effect не запускается без валидных аргументов.
Продолжите с совместимостью DeepSeek и OpenAI-формата, проверкой аргументов tool use и диагностикой ошибок по request ID. Эти материалы помогают построить проверку, но не заменяют текущий контракт.
Зафиксируйте границу проверки
До отправки запроса запишите, что именно должна подтвердить проверка: форму входа, локальную схему, обработку финального статуса или решение оператора. Не расширяйте вывод одного теста. Успешный ответ не доказывает постоянную совместимость, доступность другой модели, срок хранения или условия использования.
Для воспроизводимого теста берите синтетические и обезличенные данные. В fixture не должно быть пользовательского prompt, вложения, cookie, заголовка Authorization или чужого ключа. В техническом журнале обычно достаточно времени, версии адаптера, локального operation ID, хэша нормализованной структуры и итоговой категории.
Проверяйте сценарий на staging
Начинайте с staging и минимального allowlist. Разделите успешный путь, ошибку валидации, отсутствие разрешения, временную сеть и неизвестный итог. Для каждого состояния заранее определите остановку, ручной review или безопасное повторение. Бесконечный retry не исправляет неверный контракт и не заменяет проверку статуса.
Сравнивайте только данные, которые ваше приложение вправе обрабатывать. Не угадывайте скрытые возможности, не перебирайте параметры и не включайте функцию только по имени модели. Дата проверки, версия клиента и условия теста полезнее общего обещания: команда сможет повторить ровно наблюдаемый сценарий.
Сделайте решение обратимым
Конфигурация должна позволять отключить новый маршрут или отложить публикацию без изменения пользовательских данных. Сохраните прежний безопасный путь, короткий журнал решения и явный критерий остановки. Если результат неясен, маркируйте операцию для review вместо повторной отправки.
Разделяйте интерфейсный эксперимент и внешнее действие. Сначала покажите оператору диагностический результат или дайте его малой группе, затем расширяйте охват. Такой порядок не обходит правила поставщика и не гарантирует результат; это обычная дисциплина управления риском в собственном приложении.
Минимальный набор доказательств
Для выпуска сохраните описание входа, нормализованный ожидаемый выход, список разрешённых полей, локальный результат и ссылку на текущий контракт. При изменении SDK, каталога или формата повторите тест. Не подменяйте документацию поставщика заявлением о функции RussiaAPI: фактическая доступность зависит от выбранного маршрута и вашего аккаунта.
Проверьте отдельно, что лог не содержит секретов и что пользователю не показывается техническое тело ошибки. Внешний источник объясняет общий принцип, но не заменяет контрактный тест. Никакой пример на этой странице не просит upstream key: используйте только собственный ключ RussiaAPI на сервере и храните его в механизме секретов.
Безопасный server-side пример
Пример ниже выполняет только локальную проверку. Он не делает сетевой вызов, не содержит реальных ключей и не доказывает поддержку endpoint. Перед подключением маршрута сверяйте актуальный контракт, каталог и условия своего аккаунта.
export function classifyToolRequest(input) {
if (!input?.tool || !Array.isArray(input.tool.required)) return { ok: false, action: 'stop' };
if (input.reasoning === true && input.tool.sideEffect === true) return { ok: false, action: 'review' };
return { ok: true, action: 'send_after_contract_test' }; // no network call
}Источники и границы
DeepSeek API documentation · OWASP Input Validation Cheat Sheet
Источники объясняют общие инженерные принципы. Они не подтверждают, что конкретная возможность включена у RussiaAPI или у вашего аккаунта. Соблюдайте применимые правила и используйте только собственный ключ RussiaAPI на сервере.
FAQ
Нужно ли retry после 400?
Обычно нет. Ошибка формы или контракта требует локальной проверки входа и актуальной документации. Повтор допустим только для отдельно подтверждённого временного состояния и не должен создавать побочный эффект.
Можно ли использовать reasoning как команду?
Нет. Любой промежуточный текст или поле требует отдельной локальной валидации. Инструмент запускается только по разрешённой схеме и правилам вашего приложения.
Где держать ключ?
Только на сервере в хранилище секретов. Пример не содержит настоящего ключа и не запрашивает upstream credential.
Следующий шаг
Откройте RussiaAPI, подтвердите доступный маршрут и протестируйте сценарий на staging. Затем продолжите с материалами: Совместимость DeepSeek и OpenAI · Проверка аргументов tool use · Диагностика ошибок по request ID.