Ollama API 流式响应
2026-10-29 19:01 更新
/api/generate、/api/chat 这类端点默认就是流式。它返回的不是一个 JSON,而是一串按行分隔的 JSON(NDJSON,Content-Type 为 application/x-ndjson)。这个格式理解错了,解析就会出问题。
版本基线 v0.40.12,官方
docs.ollama.com/api/streaming。
一、流式响应长什么样
{"model":"gemma4","created_at":"2025-10-26T17:15:24.097767Z","response":"That","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.109172Z","response":"'","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.121485Z","response":"s","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.132802Z","response":" a","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.143931Z","response":" fantastic","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.155176Z","response":" question","done":false}
{"model":"gemma4","created_at":"2025-10-26T17:15:24.166576Z","response":"!","done":true, "done_reason": "stop"}
三个要点:
- 每行一个完整 JSON,不是数组,不需要逗号分隔
response是增量片段,要自己拼接(注意" a"前面带空格)- 最后一行
done: true,同时带done_reason
别把
response当成整句去替换——它是累加的碎片,直接+=拼接。
二、关掉流式
请求体里加 {"stream": false},返回就变成普通 JSON(application/json):
{"model":"gemma4","created_at":"2025-10-26T17:15:24.166576Z","response":"That's a fantastic question!","done":true}
三、什么时候用哪种
用流式(默认):
- 需要实时显示生成过程
- 想让用户感知延迟更低
- 长文本生成——边生成边展示,体验差别很大
用非流式:
- 处理逻辑更简单
- 短响应
- 结构化输出(JSON schema)——一次性拿到完整对象更安全
- 需要精确的用量统计(流式下指标在最后一个 chunk)
四、代码里的处理方式
Shell(逐行读)
curl http://localhost:11434/api/generate -d '{
"model": "gemma4",
"prompt": "Why is the sky blue?"
}' | while IFS= read -r line; do
echo "$line" | python -c "import sys,json; print(json.load(sys.stdin).get('response',''), end='')"
done
echo
Python(非流式取整句)
import requests
r = requests.post("http://localhost:11434/api/generate", json={
"model": "gemma4",
"prompt": "Why is the sky blue?",
"stream": False,
})
print(r.json()["response"])
Python(流式逐块)
import json, requests
with requests.post("http://localhost:11434/api/generate", json={
"model": "gemma4",
"prompt": "Why is the sky blue?",
}, stream=True) as r:
for line in r.iter_lines():
if not line:
continue
chunk = json.loads(line)
if "error" in chunk:
raise RuntimeError(chunk["error"])
print(chunk.get("response", ""), end="", flush=True)
if chunk.get("done"):
break
注意到里面有个 if "error" in chunk —— 流式过程中出错不会改 HTTP 状态码(响应已经开始发了),错误是作为一行 JSON 出现的。细节见 13.5 Ollama API 错误。
五、几个实操细节
| 细节 | 说明 |
|---|---|
| 空行 | NDJSON 里可能出现空行,解析前先跳过 |
| 拼接方式 | 字符串累加即可,不需要处理重叠 |
done_reason |
常见值 stop(正常结束)、length(达到 token 上限) |
| 用量指标 | 只在 done: true 的那一行里 |
| 中断 | 客户端断开连接,服务端停止生成 |
动手试
一条命令看清流式的原始形态:
curl http://localhost:11434/api/generate -d '{
"model": "gemma4",
"prompt": "Count from 1 to 5"
}'
会看到一行一行的 JSON 陆续刷出。再把 "stream": false 加进去跑一次,对比返回结构的差别——这个对比比读文档更直观。
以上内容是否对您有帮助:

TRAE-AI编程


更多建议: