Skip to content

[Bug]DeepSeek V4 思考模式下 reasoning-only 截断导致 400 #9035

Description

@lingyun14beta

What happened / 发生了什么

使用 DeepSeek 推理模型(deepseek-v4-pro / deepseek-v4-flash,思考模式默认开启)进行多步工具调用对话时,
如果某一步生成因为撞到 max_tokens 限制被截断(finish_reason="length"),且该步模型只输出reasoning_content(思维链),没有输出 content(正文)也没有输出 tool_calls,AstrBot 会把这条「空壳」
assistant 消息(content 为空、tool_calls 为空)原样存入持久化对话历史。

由于本轮对话中此前已经发生过一次真实的工具调用(req.tool_calls_result 非空),_save_to_history 的判空保护(只检查 completion_text 和 tool_calls_result,未考虑 reasoning_content)被绕过,这条残缺消息被完整写入数据库。

下一轮用户再发消息时,AstrBot 会把这条历史消息一并带上发给 DeepSeek,DeepSeek 服务端校验
(assistant 消息要求 content 或 tool_calls 至少一个非空)失败,返回 400

#8482 同一现象

Reproduce / 如何复现?

  1. 配置一个 DeepSeek 推理模型作为 Provider(deepseek-v4-pro 或 deepseek-v4-flash),保持思考模式为默认开启状态
  2. 关闭"流式输出"
  3. 在该 Provider 的 max_tokens 中设一个相对偏小的数值
  4. 确保注册了至少一个可用的工具/插件
  5. 发送一条需要"多步"工具调用才能完成的复杂指令
  6. 观察日志:当 agent 达到 max_step 被强制收尾,且最后一步的 completion 显示 content=''、tool_calls=None、reasoning_content 非空、finish_reason='length' 时,说明已经复现出残缺消息(这一步本身不会报错,但已被写入持久化历史)。
  7. 再发送任意一条后续消息。
  8. 此时复现 400:"Invalid assistant message: content or tool_calls must be set",且主 provider 和 fallback provider 都会失败(污染源是历史消息本身,跟具体模型无关)。

AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器

v4.26.0-beta.12

OS

Windows

Logs / 报错日志

Are you willing to submit a PR? / 你愿意提交 PR 吗?

  • Yes!

Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:providerThe bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner.bugSomething isn't working

    Type

    No type

    Fields

    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