问题
在使用 Fireworks.ai (Kimi K2.5) 和 Julius Agent 处理任务时,我们发现工具执行成功后返回的响应为空。这是一个令人沮丧的错误,原因如下:
- 工具循环将成功执行。
- 所有工具调用都将按预期完成。
- 但最终给用户的回复却是空白的。
这使得任务看起来像是失败了,而实际上它们已经成功完成——只是没有任何可见的输出。
根本原因分析
经过调查,我们发现问题出在对话处理代码中的一个特定极端情况。当 LLM 在执行工具后达到FinishReason::Stop状态时,代码会这样提取响应文本:
问题在于 Fireworks.ai 的 Kimi K2.5 模型返回了一个空的“停止”结束原因。 let final_text = response.text.clone().unwrap_or_default();
在所有工具调用执行完毕后, response.text字段会返回一个空字符串作为最终结果,即使对话历史记录中包含来自先前交互的有效助手回复。
修复方案
我们修改了结束处理逻辑,当最终回复文本为空时,会回退到对话历史记录。更新后的代码如下:
- 检查停止状态下的响应文本是否为空
- 如果为空,则从对话历史记录中检索最新的助手消息
- 使用存储的内容作为最终响应
关键在于, ConversationState已经保存了所有消息的完整历史记录,包括助手回复。last_assistant_text last_assistant_text()方法可以访问最新的助手内容。当最终回复为空时,我们会回退到这些已存储的内容,从而确保用户始终收到助手的最后一个实质性回复。
为什么这很重要
此修复确保了不同 LLM 提供商都能可靠地完成任务。不同的模型在发出完成信号的方式上可能略有不同,而我们的系统现在可以很好地处理这些差异。无论使用哪个模型提供商,用户始终都能看到已完成任务的有效输出。
构建验证
该修复方案已通过干净的生产构建进行验证,确保其与现有代码库正确集成,不会引入任何回归问题。
经验教训
-
信任对话历史记录:在使用 LLM API 时,最终响应字段并不总是最终结果。维护和检查对话历史记录可以提供可靠的保障。
-
模型差异至关重要:不同的提供商可能以不同的方式处理完成状态。健壮的代码应该考虑到这些差异。
-
空响应是隐形的失败:对系统而言,空响应看起来像是成功,但对用户而言却是失败。务必验证是否有实际内容可供用户查看。
这项修复,再加上我们之前将max_turns从 10 增加到 50,使得工具执行循环对于复杂的多步骤任务更加稳健。
原文: https://www.tomtunguz.com/2026-02-23-fixing-empty-response-fireworks/