Appearance
DeepSeek 思考模式多轮对话报 reasoning_content 错误
问题
使用 DeepSeek v4 系列模型并开启思考模式(thinking: {type: "enabled"} 或 interleaved)时,第一轮对话正常,从第二轮开始报错:
The `reasoning_content` in the thinking mode must be passed back to the API.报错后会话卡死,无法继续对话。涉及模型:deepseek-v4-pro、deepseek-v4-flash 等。
原因
DeepSeek API 要求对话历史中所有 assistant 消息都必须包含 reasoning_content 字段(即使为空字符串)。OpenCode 在将历史消息回传时,涉及工具调用的助手消息被 normalizeMessages() 中的条件跳过,导致 reasoning_content 丢失。
解决方案
临时绕过
等待官方 patch。可以关注 PR/修复进度。
社区临时修复(fork 分支)
社区用户 fkyah3 提供了修复分支,已有用户验证有效:
仓库:fkyah3/opencode-fkyah3
分支:fix/permission-reasoning-truncation
关键文件:packages/opencode/src/provider/transform.ts修复思路:将 hasReasoningContent 检查从只覆盖 interleaved 模型扩展为所有带 capabilities.reasoning 的模型,同时移除了跳过历史回放中 assistant 消息的窄条件。
配置层绕过
如果不方便编译 fork,可以临时禁用思考模式:
jsonc
// opencode.json
{
"model": "opencode/deepseek-v4-pro",
"modelConfig": {
"thinking": { "type": "disabled" }
}
}关闭思考模式后多轮对话恢复正常,但会失去 Chain-of-Thought 推理能力。
社区补充方法
transformRequestBody 手动补全缺失字段(#24122)
社区用户 AutumnSun1996 提供了一种更通用的 workaround,通过 transformRequestBody 钩子在请求发出前补全缺失字段,兼容工具调用场景:
javascript
// 在自定义 provider 的 options 中添加:
transformRequestBody: (body) => {
if (body.messages) {
for (const msg of body.messages) {
if (msg.role === 'assistant') {
if (msg.tool_calls && msg.tool_calls.length > 0) {
if (!msg.content) msg.content = 'call tool';
if (!msg.reasoning_content) msg.reasoning_content = 'call tool';
} else {
if (!msg.content) msg.content = '';
if (!msg.reasoning_content) msg.reasoning_content = '';
}
}
}
}
return body;
}这个方法比 fork 分支更轻量,不需要重新编译,适合等待官方 patch 期间的临时应对。
补充来源:GitHub #24122