You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
症状 一个会话里某个 turn 之后,该会话之后每一轮都立即失败:
This turn failed: Invalid assistant message: content or tool_calls must be set [code: INVALID_REQUEST, status: 400]即使只回 "hi?" 也一样,整会话报废、无法续用。
复现
配置:llm-deepseek 指向平台代理(多厂商网关,Anthropic 兼容),model: deepseek-v4-flash-vision-exp,reasoningEffort: high。
触发:模型某一轮只返回了 reasoning(思维链),没有正文、也没有工具调用(实验版模型 + 高推理时容易出现)。该纯推理轮被当作普通 assistant 消息持久化。
下一轮重放历史时,网关报 content or tool_calls must be set,此后每轮都失败。
根因 packages/llm/llm-deepseek/src/serialize.ts 的 serializeAssistant()(~203 行):
纯推理轮 → content: ""、无 tool_calls,仅带 reasoning_content。把空串当作"未设置 content"的网关(也不把 reasoning_content 映射为可接受内容)→ 直接 400。
对比 同文件多模态路径有兜底:
唯独 serializeAssistant 这条没有——这是明显的不一致。
家族关系(跨引用) 这属于"一条坏消息就永久毒死整会话"的同一失败家族:#967、#3315(未配对 UTF-16 代理对)、#5160(sourceEventSeqs 写盘)、#5439(dsh-storage-json 符号链接)、#5445(tool/result 损坏 + 上游 Content Exists Risk)。 但以上都未覆盖本触发点(reasoning-only 空 content),代理对的 sanitize 修复(hungnnvidia 的 fork PR)也治不到这里。
提案
在序列化层做系统性加固,补上最后一个洞:
serializeAssistant 遇到"无 text 且无 tool-call 的 assistant 轮"(即为纯推理轮)时:从 wire 消息中剔除该轮(它对用户无可见内容,且思维回传规则仅对 tool-call 轮生效),或采用非空兜底。
配套回归测试:tests/serialize.spec.ts 增加 reasoning-only 用例(现有 reasoning 用例都带 text/tool,唯独缺 reasoning-only)。
与代理对 sanitize(sanitizeSurrogates)合并为"序列化层双洞加固"。
请教
这是不是已知且在修?"剔除纯推理轮"这个方案维护者是否接受,还是更倾向给个非空兜底?
从维护者角度,serializeAssistant 这条为啥没像多模态那条加 || '(no output)' 兜底(是否有保真/签名方面的刻意考量)?
All reactions