错误信息显示模型返回了空内容。我以为是响应流中断了,但事实并非如此。
我误入的歧途
我的多智能体内容流水线遇到了瓶颈:其中一个生成步骤抛出了"model returned empty content"(模型返回空内容)的错误,导致整个运行过程中止。该错误信息指向输出层,因此我从那里开始排查。
我花了几轮时间来检测流式传输路径——检查服务器发送事件(SSE)连接是否在响应中途断开,服务提供商是否因速率限制而静默关闭套接字,以及我的反序列化过程是否丢失了字节。每次日志看起来都很干净。请求已发出,响应已返回,完成了完整的往返通信,没有超时。唯一缺失的是助手回合中的实际内容。
随后我怀疑是服务提供商端的问题:也许端点返回了一个格式错误的数据块,被我的客户端静默丢弃了。我在超文本传输协议(HTTP)层增加了更多日志记录。仍然一无所获。请求成功完成。finish_reason: "length"(结束原因:长度限制)。内容字段中的令牌数为零。
我完全找错了排查方向。
实际发生的情况
我调用的模型——通过兼容开放人工智能(OpenAI)的通道访问的深求-v4(deepseek-v4)——是一个推理模型。它在编写可见输出之前,内部会运行一个思维链。该推理过程存储在reasoning_content(推理内容)中,而不是content(内容)中。
我设置的令牌预算完全被思维链消耗殆尽。当模型完成思考时,已经没有剩余资源用于生成实际响应。因此,content返回为""——这是真正的空值,而非传输错误。reasoning_content字段中包含大量文本。模型确实进行了工作,只是在能够写出任何一个可见输出令牌之前,就用完了预算。
具有误导性的一点是:我的编排包装器看到content: "",便抛出"model returned empty content"(模型返回空内容)的错误,该错误看起来与网络故障完全一样。错误信息中未提及令牌预算或推理过程。它只提示为空。因此,我去传输层查找内容为空的原因,而真正的答案一直存在于上一层的应用程序接口(API)响应中。
如果我首先查看原始响应,就能发现这一信号。finish_reason: "length"(结束原因:长度限制)结合非空的reasoning_content(推理内容)和空的content(内容),是一个特定的特征标识。这并不意味着流中断,而是意味着模型陷入了过度思考的困境。
解决方案
分为两部分。
第一:提高令牌预算。解决方案并非巧妙的参数拆分,而仅仅是因为对于复杂任务上的推理模型而言,maxTokens(最大令牌数)设置得太低。推理模型消耗令牌的方式与标准聊天模型不同。对于非推理模型而言合适的预算,可能在写出单个输出令牌之前,就被思维链完全消耗殆尽。
第二:让错误信息反映真实情况。更持久的修复方法是更改错误信息的实际内容。我在ChatResult(聊天结果)类型中添加了一个reasoningOnly(仅推理)标志:
reasoningOnly: !content.trim() && hasReasoning
当该标志为真时,错误信息现在会显示类似"reasoning consumed full token budget — no output generated"(推理消耗了全部令牌预算——未生成输出)的内容,而不是
免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。