NoteExpress

 找回密码
 立即注册
搜索
热搜: NE3 NE 3 已解决
查看: 167|回复: 3

API 请求失败:HTTP 400: The `reasoning_content` in the thinking mode mus...

[复制链接]

46

主题

1495

帖子

4939

积分

论坛元老

Rank: 8Rank: 8

积分
4939
发表于 2026-8-9 17:31:01 | 显示全部楼层 |阅读模式
使用的是 qw3.5 模型
截屏2026-08-09 17.29.04.png
回复

使用道具 举报

46

主题

1495

帖子

4939

积分

论坛元老

Rank: 8Rank: 8

积分
4939
 楼主| 发表于 2026-8-10 19:19:21 | 显示全部楼层
API 请求失败:HTTP 400: The `reasoning_content` in the thinking mode must be passed back to the API.
我看到关键信息了。这个错误跟你的推理模型和部署方式直接相关,我解释一下。

根本原因:你的 qwen3.5-397b-a17b-fp8 是一个推理模型(thinking/reasoning model),部署在 GPUStack(API key 前缀 gpustack_ 就是证据)上。这类后端有个硬性约束:

一旦进入 thinking mode(思考模式),多轮对话中上一条 assistant 消息里的 reasoning_content(思考过程)必须原样传回给 API——丢了就报 HTTP 400。

也就是说,出错的不是单次请求本身,而是在续接历史对话时,Hermes 侧没有把上一轮返回的 reasoning_content 一起回传,导致后端拒绝继续。

为什么会触发这种情况
典型发生在以下场景之一:

触发场景        原因
多轮对话续接        新一轮请求带上下文时,reasoning_content 未被保留回传
上下文压缩 (compression)        Hermes 压缩历史时把 assistant 的思考字段删了
上下文管理/截断        超过阈值后裁剪掉 assistant 消息的 reasoning 部分
中途切换/重试        /retry、模型切换后重发,历史里的 reasoning 没带
你当前的排查方向——怀疑跟之前的会话/上下文处理有关——是对的,但根本锚点在后端对 thinking mode 的强约束。

解决方案(按推荐顺序)
方案 1(最直接,推荐):关闭 thinking mode 既然这是自建 GPUStack 端点,在你的 config.yaml 里针对该模型禁用推理思考,绕开"必须回传"的强制逻辑:

代码
· yaml
model:
  default: qwen3.5
  provider: qwen-custom
  reasoning_effort: none    # 关键:关闭思考模式
方案 2:确认 Hermes 是否支持对该模型透传 reasoning_content 检查 Hermes 配置里有没有针对 "reasoning/thinking" 的透传开关,让历史消息的 reasoning_content 在后端类型为 openai transport 时被保留。

方案 3:验证是不是压缩引起 如果是压缩后必现,临时把 compression 相关的 provider 指向不支持 thinking 的普通模型,或提高压缩阈值,避免触发上下文重写。

我先帮你确认最省事的方案 1 是否生效。要我现在就改 config.yaml 关闭 thinking mode 试试吗?还是你希望先保留思考能力、让我深入查 Hermes 的 reasoning_content 透传支持(方案 2)?

由于涉及你的配置改动,我想先确认你的意图——

这个 400 错误你想怎么处理?
其他 (输入你的答案)
回复 支持 反对

使用道具 举报

46

主题

1495

帖子

4939

积分

论坛元老

Rank: 8Rank: 8

积分
4939
 楼主| 发表于 2026-8-10 19:30:28 | 显示全部楼层
我已经 100% 定位到根因了。信息足够,先给你完整诊断。让我最后确认一下是否有不改核心代码的 config 层开关(查 models_dev 推理模型注册机制):

我现在有了完整的诊断结论。核心问题清楚,我给你完整的分析。

回复 支持 反对

使用道具 举报

46

主题

1495

帖子

4939

积分

论坛元老

Rank: 8Rank: 8

积分
4939
 楼主| 发表于 2026-8-10 19:31:01 | 显示全部楼层
本帖最后由 stanley 于 2026-8-10 19:32 编辑

证据链(我在你源码里逐行验证)1. 错误是"思考回传"未启用的典型症状
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]Hermes 源码里处理这个错误的专有代码(agent/agent_runtime_helpers.py:3135-3145),注释原文直接对应你的报错:
DeepSeek / Kimi thinking mode: all assistant messages need reasoning_content. Inject a single space to satisfy the provider's requirement... Space (not "") because DeepSeek V4 Pro tightened validation and rejects empty string with HTTP 400 ("The reasoning content in the thinking mode must be passed back to the API"). Refs #17341.
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]Hermes 早就为同款模型修过这个 bug,补丁正是"给历史 assistant 消息补一个 reasoning_content 空格"。
2. 但这个补丁只对特定 provider 生效
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]run_agent.py:6262-6291 的判定函数,靠 provider 名 / 模型名含关键词 / base_url 域名 三重识别,只有三个家族命中:
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]
触发条件
覆盖

_needs_deepseek_tool_reasoning()provider=deepseek / 模型名含 "deepseek" / 域名 api.deepseek.com
_needs_kimi_tool_reasoning()kimi-coding / api.kimi.com / moonshot
_needs_mimo_tool_reasoning()xiaomi / mimo / xiaomimimo

[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]你的 qwen3.5 + noteexpress 端点完全不匹配这三条 → _needs_thinking_reasoning_pad() 返回 False → 补丁不执行 → 报错。
3. 根因是你自建的 noteexpress provider 插件缺了这个方法
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]plugins/model-providers/noteexpress/__init__.py 里,NoteExpressProfile 没有重写 build_api_kwargs_extras()(DeepSeek/Kimi 插件都有),所以 Hermes 不知道这是个思考模型端点,无法启用回传补丁。

解决方案(保留思考能力,3 选 1)✅ 方案 A(推荐,改动最小):给端点域名"认领"回传机制
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]在 Hermes 源码 run_agent.py 的 _needs_thinking_reasoning_pad() 或 _needs_deepseek_tool_reasoning() 里,把你的端点 113.108.154.211:8009(或 gateway.inoteexpress.com)加进宿主匹配。这样 qwen 思考模式会被正确回传。
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]优点:一处改动,全局生效,保留思考。缺点:改了核心源码,hermes update 会被 git 覆盖(需 stash 或重新打补丁)。
✅ 方案 B(最规范):给你的 noteexpress 插件加 build_api_kwargs_extras
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]照 DeepSeek 插件的写法,在 NoteExpressProfile 里重写此方法,当模型是思考型时输出 {"reasoning_effort": "..."} 并让 Hermes 走回传逻辑。 优点:最符合 Hermes 的插件架构,hermes update 不冲突。缺点:要写代码,且要确认 GPUStack 后端接受哪种 wire shape。
⚠️ 方案 C(绕过,但需权衡):回到上一轮你说的"关闭 thinking mode"
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]把 reasoning_effort 设为 none 或关掉 thinking,彻底绕开回传要求。但你说要保留思考能力,所以这个先放一边。

[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]我的建议:走方案 B——它最干净,不污染核心源码,且你的 noteexpress 插件本来就是公司自研的,加个 thinking 支持顺理成章。而且我在上一轮已经摸清了 DeepSeek 插件的参考模板。
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]要我现在动手吗?如果做,我会:
  • 先 curl 你的 qwen 端点,确认它走的是 thinking 字段还是 reasoning_effort(GPUStack 的 wire shape)
  • 照模板给 noteexpress 插件加上回传支持
  • 用一次真实多轮对话验证
[color=color(srgb 0.145098 0.14902 0.160784 / 0.99)][backcolor=color(srgb 0.996235 0.996235 0.996235)][size=16.875px]在动你源码前我想先确认——是你希望我直接改(方案 B),还是你已经在别处有官方/更新的 noteexpress 插件版本不想让我动?
回复 支持 反对

使用道具 举报

*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|NoteExpress

GMT+8, 2026-8-23 18:47 , Processed in 0.142624 second(s), 24 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表