快速结论:当通过 Ollama 的 OpenAI 兼容流式接口调用时,finish_reason 字段被错误地返回为空字符串(””)而非 OpenAI 规范要求的 “stop” 或 “length”(截断时)。优先排查 Ollama 版本是否低于修复该问题的 commit。
适用环境:Ollama(任何版本,只要低于包含修复的提交)。涉及 HTTP 流式接口(/v1/chat/completions?stream=true)。
最快修复方案:将 Ollama 升级至包含 commit 61273a96 的版本(例如 0.1.45 之后的版本)。如果无法升级,可手动修改源码中 finish_reason 的处理逻辑(将空字符串改为 nil 或有效值)。
注意事项:该修复仅解决了 finish_reason 为空字符串的问题。后续讨论指出,在响应被 max_tokens/num_predict 截断时,finish_reason 仍可能错误地返回 “stop” 而非 “length”,该问题在此 Issue 中未完全解决,下游项目(如 LiteLLM、LangChain)仍需额外处理。
问题场景
用户使用 Ollama 的 OpenAI 兼容 API(例如 /v1/chat/completions)并开启流式(stream=true)调用,观察到每个数据块中的 finish_reason 字段始终为空字符串。这导致依赖 OpenAI 规范进行流式结束判断的客户端(如 LangChain、LiteLLM、Hermes Agent)无法正确区分正常结束(”stop”)和截断结束(”length”),引发无限续写或停止时机错误。
报错原文
data: {"id":"chatcmpl-693","object":"chat.completion.chunk","created":1715427619,"model":"mistral:latest","system_fingerprint":"fp_ollama","choices":[{"index":0,"delta":{"role":"assistant","content":" Hello"},"finish_reason":""}]}
data: {"id":"chatcmpl-693","object":"chat.completion.chunk","created":1715427619,"model":"mistral:latest","system_fingerprint":"fp_ollama","choices":[{"index":0,"delta":{"role":"assistant","content":"!"},"finish_reason":""}]}
...
原因分析
Ollama 在流式输出时,对 finish_reason 字段的处理不正确:当生成还未结束时,finish_reason 应为 null(即不发送该字段或发送 null),但 Ollama 错误地将其设置为空字符串 ""。当生成结束时,finish_reason 应返回 "stop" 或 "length",但 Ollama 可能在所有 chunk 中都返回空字符串,或者在最后仍返回空字符串。
环境排查
- 确认 Ollama 版本。运行
ollama --version查看。 - 确认调用方式:是否使用了流式接口(
stream=True),并且是通过/v1/chat/completions端点(OpenAI 兼容 API)。 - 检查响应中的
finish_reason字段内容:""、"stop"还是"length"。 - 确认无其他中间件(如代理)修改响应格式。
解决步骤
- 方案一(推荐):升级 Ollama
将 Ollama 更新到包含修复 commit 的版本(例如 0.1.45 之后)。升级命令:# 如果使用官方安装脚本 curl -fsSL https://ollama.com/install.sh | sh # 或手动替换二进制 - 方案二(开发者):手动修改源码
在 Ollama 源码的server/routes.go或对应处理流式响应的位置,将finish_reason字段处理逻辑改为:FinishReason: func(reason string) *string { if len(reason) > 0 { return &reason } return nil }(r.DoneReason),然后重新编译并替换二进制。
- 方案三(客户端临时绕过)
如果无法升级或修改服务端,可在客户端接收流式数据时,忽略finish_reason字段,转而依赖choices[0].delta.content是否为空以及是否有stop/length等信号进行判断(此方案不准确,推荐升级后使用标准判断)。
验证方法
使用 curl 或其他 HTTP 客户端发送流式请求,观察最后一次数据块的 finish_reason 是否不再为空:
curl -N -X POST http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "mistral:latest",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true,
"max_tokens": 10
}'
预期:非最后一个
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


