DeepSeek V4 多轮 Tool-Calling 报 reasoning_content 400?原因、排查与本地中继方案

DeepSeek V4 迁移过程中,如果 Agent 使用 thinking mode + 多轮 Tool-Calling,一个比较隐蔽的问题是 reasoning_content 在轮次之间丢失,最终触发 400。

典型错误类似:

text 复制代码
The reasoning_content in the thinking mode must be passed back to the API

这个问题不一定是业务 tool 写错了,也不一定是某个 tool result 有问题。很多时候,它发生在 多轮 messages 传递过程 中:上游框架或 agent loop 把 DeepSeek provider-specific 字段丢掉了。

本文从消息链路出发,梳理这个问题的原因、排查方法,以及一种迁移期可用的本地中继缓解方案。

1. 问题背景

在普通 Chat Completion 场景里,请求和响应通常围绕这些字段展开:

json 复制代码
{
  "role": "assistant",
  "content": "..."
}

而在 Tool-Calling 场景里,assistant message 可能包含:

json 复制代码
{
  "role": "assistant",
  "tool_calls": [
    {
      "id": "call_xxx",
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{\"city\":\"Shanghai\"}"
      }
    }
  ]
}

到了 DeepSeek thinking mode,assistant message 里还可能出现 provider-specific 字段:

json 复制代码
{
  "role": "assistant",
  "reasoning_content": "...",
  "tool_calls": [
    {
      "id": "call_xxx",
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{\"city\":\"Shanghai\"}"
      }
    }
  ]
}

问题就出在这里:很多上游框架会把 message 规范化成通用 OpenAI-compatible 结构,在下一轮请求里只保留 rolecontenttool_calls 等字段,而丢掉 reasoning_content

2. 最小问题链路

可以把问题简化成下面这个链路:

text 复制代码
Turn 1 response:
  assistant message has:
    - tool_calls
    - reasoning_content

Turn 2 request:
  assistant message keeps:
    - tool_calls
  assistant message drops:
    - reasoning_content

DeepSeek API:
  HTTP 400

也就是说,tool call 本身可能是对的,tool result 也可能是对的,但 assistant message 的 provider-specific 状态在多轮传递时丢了。

这类问题的难点在于,它不是一个单点错误,而是跨轮次状态错误。

3. 排查清单

遇到这个错误时,可以按下面顺序排查。

3.1 找上一轮 assistant response

先找到失败前一轮模型返回的 assistant message,看它是否同时包含:

  • tool_calls
  • reasoning_content

如果上一轮 response 本身没有 reasoning_content,那就要先确认当前模型模式、请求参数和 DeepSeek thinking mode 是否符合预期。

3.2 找下一轮 request

再看下一轮发送给 DeepSeek 的 request。

重点检查同一个 assistant tool-call message 是否还保留:

  • 原来的 tool_calls
  • 原来的 reasoning_content

如果 tool_calls 还在,但 reasoning_content 没了,就高度可疑。

3.3 对 tool_call id

检查 tool_call_id 是否能对应上:

text 复制代码
assistant.tool_calls[0].id == tool.tool_call_id

如果 id 对不上,可能是另一个 Tool-Calling 链路问题,不一定是 reasoning_content 丢失。

3.4 检查 strict schema

DeepSeek strict schema 也容易被误判。

常见要求:

  • object 的所有 properties 应该进入 required
  • object 应该设置 additionalProperties: false
  • minLengthmaxLengthminItemsmaxItems 这类限制不适合直接放进 strict schema

同时不要把支持项误报成不支持。例如:

  • pattern
  • format
  • minimum
  • maximum
  • multipleOf

这些字段在 JSON Schema 工具链里很常见,如果 linter 写得不准,很容易把排查方向带偏。

4. 长期修复方案

长期看,最合理的修复位置是上游框架或 agent loop。

框架在多轮 Tool-Calling 中应该保证:

  • assistant message 的 provider-specific 字段不被无意丢弃
  • tool_calls 和后续 tool message 的 tool_call_id 稳定对应
  • message role 顺序符合模型 API 要求
  • strict schema 生成器不会输出 DeepSeek 不支持的字段

如果问题出现在 LangChain、LlamaIndex、OpenClaw、Hermes Agent 等框架里,比较好的方式是整理一个最小可复现 fixture,然后给上游提 issue。

长期方案应该是上游正确保留状态,而不是业务侧一直维护兼容补丁。

5. 迁移期缓解:本地 OpenAI-compatible 中继

但在迁移期,很多团队需要先做三件事:

  • 快速判断问题是不是 reasoning_content 丢失
  • 尽快恢复本地调试链路
  • 生成可复现材料给上游框架提 issue

这时可以考虑在本地加一层 OpenAI-compatible 中继:

text 复制代码
OpenAI-compatible client -> local relay -> DeepSeek API

已有代码通常只需要改 baseURL

text 复制代码
http://127.0.0.1:8787/v1

中继可以做这些事:

  1. 第一轮 response 经过中继时,记录 tool_call id 对应的 reasoning_content
  2. 后续 request 经过中继时,检查 assistant tool-call message 是否丢失 reasoning_content
  3. 如果上下文完整、tool_call id 能对应上,在转发给 DeepSeek 前补回
  4. 输出诊断日志,指出哪一轮 message 被修复

这种方式的好处是侵入性低:对 OpenAI-compatible client 来说,只需要改 baseURL。

6. 必须强调的边界

本地中继不是万能修复。

它能工作有一个前提:

text 复制代码
相关请求和响应必须从对话开始就经过中继

如果 reasoning_content 在进入中继之前就已经丢了,中继无法凭空恢复,只能诊断。

另外,本地中继更适合:

  • 本地调试
  • 迁移期止血
  • 复现问题
  • 生成 issue fixture

不应该在没有会话隔离、持久化、鉴权、审计的情况下,当作长期生产 LLM Gateway 直接使用。

7. 可复现参考实现

下面这个开源仓库把上述思路整理成了一个参考实现:

GitHub: github.com/xiaoshuo198...

npm: www.npmjs.com/package/dee...

它包含:

  • diagnose:检查 JSONL run 中是否存在 reasoning_content 丢失
  • lint-schema:检查 DeepSeek strict schema 常见问题
  • proxy:启动本地 OpenAI-compatible 中继
  • mock upstream demo:不需要 DeepSeek API key 就能复现修复链路
  • OpenAI JS 多轮 Tool-Calling demo:模拟第二轮丢失 reasoning_content,验证中继补回

无 key 复现:

bash 复制代码
git clone https://github.com/xiaoshuo1988130/deepseek-compat-kit.git
cd deepseek-compat-kit
npm run demo:mock

OpenAI JS SDK 多轮 Tool-Calling 复现:

bash 复制代码
npm run demo:openai-js-tool-calls

终端里会看到类似:

text 复制代码
WARN DSK_REASONING_003 messages[1]: injected cached reasoning_content for 1 tool call(s).
[openai-js-tool-calls] final: mock upstream received repaired reasoning_content

如果只是想启动本地中继:

bash 复制代码
DEEPSEEK_API_KEY=sk-... npx deepseek-compat-kit proxy --port 8787

然后把 OpenAI-compatible client 的 baseURL 指到:

text 复制代码
http://127.0.0.1:8787/v1

8. 生态接入现状

当前比较适合直接验证的是 OpenAI-compatible 链路。

参考实现里目前有这些材料:

  • OpenAI JS SDK:有可运行 mock demo
  • OpenClaw:有 baseURL 配置指南,live e2e 待验证
  • Hermes Agent:有 baseURL 配置指南,live e2e 待验证
  • Claude Code:目前不是 OpenAI-compatible 直连路径,只适合作为兼容性边界说明

这里尤其要注意 Claude Code。它通常走 Anthropic-compatible 配置,而不是 OpenAI-compatible /v1/chat/completions。不能简单把 ANTHROPIC_BASE_URL 指到 OpenAI-compatible 中继地址。

9. 迁移窗口

DeepSeek 官方 changelog 提到 deepseek-chatdeepseek-reasoner 会在 2026-07-24 停用。

如果 Agent 依赖多轮 Tool-Calling,建议提前验证 V4 路径:

  • 多轮 messages 是否保留 provider-specific 字段
  • strict schema 是否符合 DeepSeek 要求
  • 失败时能否导出脱敏 replay fixture
  • 上游框架是否已经修复对应问题

总结

reasoning_content 400 的核心不是"某个 tool 写错了",而是多轮 Tool-Calling 里 assistant message 的 provider-specific 状态在传递过程中丢失。

排查时要看跨轮次 messages,而不是只看最后一次 API 请求。

长期方案应该是框架正确保留 DeepSeek 字段;迁移期可以用本地 OpenAI-compatible 中继做诊断和临时缓解。但中继必须从第一轮对话开始看到完整上下文,否则无法恢复已经丢失的内容。

相关推荐
qcx231 天前
【系统学AI】02 token机制全解:LLM如何‘读懂‘人类语言
人工智能·llm·产品经理·token·费用·deepseek
●VON1 天前
OpenClaw 架构解析:Skill 与 Agent 的设计哲学与实现机制
人工智能·app·agent·skill·豆包·deepseek
Lyon198505281 天前
从临床医疗说起:当一种科学理论走到边界的时候
人工智能·深度学习·算法·deepseek·ai伦理
七夜zippoe1 天前
重构数字人交互体验:魔珐星云+DeepSeek打造情绪陪伴数字人全流程实战测评
重构·交互·数字人·deepseek·魔珐星云
拙野2 天前
【保姆级教程】Claude Code无缝集成DeepSeek V4 Pro
java·人工智能·deepseek·claudecode·ai coding
视觉&物联智能2 天前
【杂谈】-游戏生成数据:人工智能训练中极易被低估的核心资源
人工智能·游戏·ai·chatgpt·openai·agi·deepseek
LingYi_02 天前
安装Claude Code接入Deep Seek
deepseek·claude code
秣厉科技2 天前
【番外】04:Python 和 LabVIEW 对接 DeepSeek API
python·labview·deepseek
fengxin_rou3 天前
【Spring AI 集成 DeepSeek 实现 AI 摘要与 RAG 问答】:从原理到落地实践
数据库·mysql·rag·deepseek