Skip to content

思考模型返回400错误(与#3715 #3695 #3670 #3669 #3658根源相同)我已找出问题,含修改后的代码) #3724

@enochday

Description

@enochday

What happened?

问题描述

症状:长会话(对话轮次较多、上下文较长)时,调用启用了 thinking 模式的模型(如 DeepSeek-V4-Pro)会报错:

[API Error: 400 The reasoning_content in the thinking mode must be passed back to the API.]

根因packages/core/src/core/openaiContentGenerator/converter.ts 中存在两处导致 reasoning_content 丢失的缺陷:

1. mergeConsecutiveAssistantMessages 丢弃 reasoning_content

// converter.ts 原 line ~1395
// Combine tool calls
const combinedToolCalls = [...lastToolCalls, ...currentToolCalls];

// Update the last message with combined data
// ❌ 只合并了 content 和 tool_calls,
//    message 上的 reasoning_content 被悄悄丢弃

触发条件cleanOrphanedToolCalls 删除位于两个 assistant 消息之间的孤立 tool message 后,两个 assistant 消息变为相邻。mergeConsecutiveAssistantMessages 将它们合并,第二条消息的 reasoning_content 被丢弃。会话越长、工具调用越多,出现孤立 tool call 的概率越大,越容易触发。

2. cleanOrphanedToolCalls 丢弃仅含 reasoning_content 的消息

第一轮和第二轮清理中,当 assistant 消息的 tool_calls 没有对应响应且 content 为空时,整条消息被移除——即使它含有 reasoning_content。条件仅检查了 message.content 是字符串,没有检查 reasoning_content

What did you expect to happen?

修改方案

(我已经使用qwen code在本地完成了修改,可以运行,问题解决了,但不知道为什么界面的语言变成了英文且无法切换,)

文件:packages/core/src/core/openaiContentGenerator/converter.ts

修改 1:mergeConsecutiveAssistantMessages — 合并时保留 reasoning_content

在合并 content 和 tool_calls 之后,增加 reasoning_content 的拼接:

// Combine reasoning_content (新增)
const lastReasoning =
  'reasoning_content' in lastMessage
    ? ((lastMessage as ExtendedChatCompletionAssistantMessageParam)
        .reasoning_content ?? '')
    : '';
const currentReasoning =
  'reasoning_content' in message
    ? ((message as ExtendedChatCompletionAssistantMessageParam)
        .reasoning_content ?? '')
    : '';
const combinedReasoning = [lastReasoning, currentReasoning]
  .filter(Boolean)
  .join('');

// ...更新 content 和 tool_calls 后...

if (combinedReasoning) {
  (lastMessage as ExtendedChatCompletionAssistantMessageParam)
    .reasoning_content = combinedReasoning;
}

修改 2:cleanOrphanedToolCalls — 两轮清理均检查 reasoning_content

将保留条件从"有文本内容"扩展为"有文本内容或有 reasoning_content":

// 旧:
} else if (
  typeof message.content === 'string' &&
  message.content.trim()
) {

// 新:
} else if (
  (typeof message.content === 'string' && message.content.trim()) ||
  ('reasoning_content' in message &&
    typeof (message as ExtendedChatCompletionAssistantMessageParam)
      .reasoning_content === 'string' &&
    (message as ExtendedChatCompletionAssistantMessageParam)
      .reasoning_content!.trim())
) {

第一轮和最终验证轮均做相同修改。

Client information

Qwen Code: 0.15.4 (b0ed821)
运行环境: Node.js v24.14.0 / npm 11.9.0
操作系统: linux arm64 (6.17.0-PRoot-Distro)
认证: API Key - openai
基础 URL: https://api.deepseek.com
模型: deepseek-v4-pro
快速模型: deepseek-v4-pro
会话 ID: 9271c74a-3ddc-4b8a-9505-a66c7331dabc
沙箱: no sandbox
代理: no proxy
内存使用: 658.8 MB

Login information

API https://api.deepseek.com

Anything else we need to know?

No response

Metadata

Metadata

Assignees

Labels

status/needs-triageIssue needs to be triaged and labeledtype/bugSomething isn't working as expected

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions