RussiaAPI

DeepSeek API: как безопасно обрабатывать reasoning_content после tool call

Запрос «DeepSeek API reasoning_content после tool call» появляется, когда приложение строит многошаговый цикл: модель предлагает инструмент, сервер выполняет разрешённую операцию и возвращает результат. Самая опасная ошибка здесь — считать любой дополнительный текст или поле вечной частью контракта и пересылать его без проверки. RussiaAPI — независимый сторонний API gateway. Эта статья описывает границу клиентского приложения: как связать локальную операцию с вызовом инструмента, сократить хранение данных и остановиться при неизвестной структуре. Она не утверждает, что конкретный маршрут, модель или версия SDK поддерживает reasoning_content либо заданный порядок сообщений.

Сначала подтвердите контракт именно вашего маршрута

Названия полей, порядок сообщений и доступность reasoning-режима могут отличаться между моделями, версиями SDK и совместимыми маршрутами. До production соберите минимальный обезличенный сценарий: один допустимый tool call, один предсказуемый результат и один следующий ход. Зафиксируйте дату, имя адаптера, версию теста и наблюдаемые поля. Не переносите пример из старой интеграции или чужого endpoint как универсальное правило.

Если поле отсутствует, изменило тип или появилось неожиданно, не дописывайте его в следующий запрос «на всякий случай». Переведите локальную операцию в состояние requires_review, сохраните только безопасную категорию несовместимости и проверьте документацию или staging. Такой отказ полезнее догадки: он не превращает экспериментальный формат в скрытую зависимость и не заставляет пользователя думать, что действие уже завершилось.

Свяжите инструмент с локальной операцией, а не с текстом модели

Когда сервер получает предложение вызвать инструмент, он создаёт свой operation ID и связывает его с tenant, разрешённым именем инструмента, схемой аргументов и текущим состоянием задачи. Идентификатор не должен содержать prompt, email, ключ, заголовок Authorization или внутренний URL. Результат инструмента возвращается только после проверки прав и сопоставления с этой локальной записью.

Не принимайте tool call как разрешение на побочное действие. Даже валидный JSON не доказывает, что текущий пользователь вправе изменить заказ, отправить письмо или обратиться к чужому документу. До выполнения нужны allowlist инструмента, строгая схема аргументов, авторизация объекта и при необходимости подтверждение человека. Если проверка не прошла, верните нейтральный локальный статус, а не содержимое исключения или секретные детали инфраструктуры.

Храните reasoning и журнал раздельно

Для диагностики обычно достаточно времени, версии адаптера, operation ID, имени разрешённого инструмента, статуса валидации и категории ошибки. Полный prompt, сырое reasoning_content, ответ модели и аргументы инструмента часто содержат лишние персональные или служебные данные. Не помещайте их в обычный лог, тикет, аналитическое событие или клиентский браузер только ради удобства расследования.

Если команде нужен пример для теста, создайте отдельный синтетический fixture с вымышленными значениями и правилами удаления. Минимизация не означает отсутствие наблюдаемости: можно считать число несовпадений схемы, запретов инструментов и ручных эскалаций. Эти метрики показывают регрессию адаптера, но не доказывают доступность модели, правила хранения поставщика, скорость или SLA.

Проверяйте следующий ход как новый недоверенный вход

После результата инструмента заново проверяйте сообщение, а не предполагаете, что модель продолжит тот же формат. Разрешите только ожидаемые роли и типы блоков, ограничьте размер данных, удалите поля, не нужные следующему шагу, и проверьте tenant. Инструментальный результат должен быть кратким и предметным: например, локальный статус и безопасный идентификатор, а не дамп записи из базы или ответ внешней системы.

Полезно отделить адаптер формата от доменной логики. Адаптер преобразует подтверждённые поля в собственный малый объект; доменный слой решает, допустимо ли продолжать сценарий. При изменении SDK можно тестировать эти части отдельно. Так обновление сериализации не даёт случайно расширить права, а бизнес-правило не зависит от непроверенного текстового описания модели.

Отдельно обработайте неизвестный и поздний результат

Timeout, обрыв соединения или закрытое окно не доказывают, что вызов инструмента не начался. Не повторяйте side effect по одному таймеру. Сначала ищите operation ID и показывайте честное состояние: не начато, выполняется, завершено, отклонено или требует сверки. Повтор допускается только для операции, которую ваша модель данных доказуемо защищает от дубля.

Если результат приходит позже, worker сверяет текущий статус и версию операции перед записью. Устаревший результат не должен перезаписывать новое решение пользователя. Для рискованных действий оставьте ручную эскалацию: оператор видит безопасные метаданные и выбирает дальнейший шаг. Это клиентская дисциплина, а не обещание отмены или идемпотентности со стороны внешнего API.

Закройте цикл контрактным тестом

В CI добавьте fixtures для неизвестного поля, неверного типа аргумента, запрещённого инструмента, чужого tenant, повторной доставки результата и таймаута. Тест должен подтвердить, что процесс не совершает сетевой side effect, не выдаёт ложный успех и не печатает содержимое входа. Такой набор работает без API-ключа и проверяет именно ваш код.

После изменения модели, маршрута, middleware или схемы повторите staging-проверку на обезличенном сценарии. При расхождении остановите rollout адаптера feature flag и вернитесь к проверенной версии до уточнения контракта. Для базовой совместимости полезно сначала пройти материал о DeepSeek и OpenAI-compatible API, но окончательное решение всё равно принимается по текущему тесту вашего проекта.

Безопасный server-side пример

Этот пример показывает только локальную логику приложения. Он не делает сетевой вызов, не содержит реальных ключей и не доказывает поддержку конкретного endpoint. Перед подключением рабочего маршрута сверяйте актуальный договор и API-контракт.

export function acceptToolResult({ operation, result, viewer }) {
  if (!operation || operation.tenantId !== viewer.tenantId) return { ok: false };
  if (operation.status !== 'running') return { ok: false, reason: 'stale' };
  if (!result || result.operationId !== operation.id) return { ok: false };
  if (typeof result.status !== 'string' || !['ok', 'rejected'].includes(result.status)) return { ok: false };
  return { ok: true, status: result.status }; // no model text or keys are logged
}

Граница ответственности и данных

Не передавайте в браузер, тикет, статью или обычный журнал API-ключи, заголовок Authorization, cookie, ключи поставщиков, полный prompt или персональные данные. Условия обработки данных, права на контент и применимые требования проверяются по политике организации, договору и с ответственным специалистом.

Контроль перед выпуском

Перед release проверьте синтетический сценарий, роли и tenant boundary, запреты на секреты в логах, понятный статус для пользователя и ручную ветку для неизвестного результата. Сохраните дату, версию адаптера и результат теста. После изменения SDK, модели, схемы или маршрута повторите проверку; старый прогон не подтверждает новый контракт.

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

Полезные материалы

DeepSeek API Docs · OWASP: Input Validation Cheat Sheet

FAQ

Нужно ли пересылать reasoning_content в каждом следующем сообщении?

Не предполагайте этого. Требования к полям зависят от текущего маршрута, модели и контракта. Подтвердите минимальный сценарий на staging и храните только данные, необходимые вашему приложению; неизвестное поле не следует автоматически возвращать в следующий ход.

Является ли tool call разрешением выполнить действие?

Нет. Tool call — непроверенный вход для приложения. Сервер обязан проверить allowlist инструмента, схему аргументов, tenant, права на объект и состояние операции. Для заметного side effect может потребоваться отдельное подтверждение пользователя или оператора.

Что логировать при несовместимости?

Сохраняйте время, локальный operation ID, версию адаптера и безопасную категорию ошибки. Не записывайте API-ключи, Authorization, cookie, полный prompt, reasoning или персональные поля. Для воспроизведения используйте синтетический fixture.

Следующий шаг

Продолжите с материалами: DeepSeek и OpenAI-compatible API · Проверка аргументов tool use · Проверка tool call перед действием. Затем проверьте текущие условия и безопасно протестируйте интеграцию на staging перед production-трафиком.