DeepSeek 流式输出和普通返回的差别不在“回答内容”,而在“数据怎么回来”:流式输出用 SSE 之类的分块传输,模型边生成边推送增量片段,客户端需要自己拼装;普通返回要等模型生成完,一次性返回完整 JSON。这个差别会直接影响首字等待时间、连接保持时长、超时设置、错误处理和前端渲染方式。如果你的链路里有网关、反向代理或移动端弱网,流式输出能否真正“边到边显示”,取决于中间层有没有做缓冲。
判断方向:更看重首字体验、回答较长、要边生成边展示的,选流式;要严格结构化 JSON、链路中间有不可控缓冲、或客户端不方便做增量拼装的,先用普通返回。操作上把 stream 参数、SSE 解析、代理缓冲、超时与回退这四件事一起改,并用分段到达日志验证;边界是流式与强结构化输出、断线重试和用量统计之间常常有冲突,需要结合环境确认。
先确认当前场景和目标
先把下面几件事确认清楚,再决定要不要改成流式,否则容易只改了参数却没拿到体验收益。
- 回答长度和交互形态:单次回答几百字以上、用户需要边看边判断的,流式收益明显;一问一答的短结果、后台批处理任务,普通返回更省事。
- 客户端能力:前端或调用方能否处理增量片段并做局部渲染,是否已有“先收到再统一展示”的缓冲逻辑。
- 链路中间层:是否有 Nginx、API 网关、CDN、企业出口网关。这些组件默认可能整段缓冲,流式会被“攒成一次性返回”。
- 输出格式要求:如果下游要用严格 JSON Schema 解析,流式片段通常不是合法 JSON,需要额外的拼接与校验步骤。
- 超时与计费:流式下总时长可能更长,超时不能只按“首字节”设置;用量统计字段在流式响应中的位置也需要确认。
按这个顺序处理
第一步,明确目标只选一个:要么改善首字等待体验,要么简化集成。两个都要,通常要先做流式再做兼容回退。

第二步,在请求里切换模式。DeepSeek 接口通常兼容 OpenAI 风格,用 stream 参数控制;具体字段以你接入时的文档为准。先用命令行确认服务端确实在分块返回,-N 用于关闭 curl 自身缓冲:
curl -N https://<你的API地址>/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<模型名>","stream":true,"messages":[{"role":"user","content":"你好"}]}'
第三步,在客户端按行解析 SSE。下面是通用骨架,替换 url、headers、payload 三处即可,不依赖特定 SDK:

import json, requests
resp = requests.post(url, headers=headers, json=payload, stream=True, timeout=(5, 180))
parts = []
for line in resp.iter_lines(decode_unicode=True):
if not line or not line.startswith("data:"):
continue
data = line[5:].strip()
if data == "[DONE]":
break
chunk = json.loads(data)
delta = chunk["choices"][0].get("delta", {}).get("content")
if delta:
parts.append(delta)
text = "".join(parts)
第四步,处理中间层缓冲。Nginx 场景可以先关掉代理缓冲,并让后端带上关闭缓冲的响应头:

proxy_buffering off;
proxy_cache off;
proxy_read_timeout 180s; # 按单次回答最长时长调整
add_header X-Accel-Buffering no;
第五步,保留普通返回作为回退通道:在配置里放一个开关,解析失败或链路不支持分块时切回非流式,避免线上直接不可用。
改完后怎么验证
- 分段到达:用上面的 curl 命令观察输出是不是一段一段出现的。如果等了很久后整段一次性出现,说明中间层仍在缓冲,优先查代理和网关配置。
- 时间打点:在客户端记录首个片段时间和结束时间,两者分开看。只记录总耗时会掩盖流式是否生效。
- 内容一致性:把流式拼装结果和同参数的非流式结果各跑几次,确认拼接没有丢字、漏掉空格或重复片段。
- 异常路径:主动中断连接、让服务端提前结束、发送空内容问题,确认客户端能正确收尾而不是一直挂起。
- 结构化输出:如果下游要解析 JSON,把拼装后的完整文本做一次解析校验,解析失败要有可见的日志,而不是静默返回空结果。
预期信号是:首个片段明显早于结束时间到达,拼装结果与非流式结果语义一致,中断场景能在超时内退出。
容易忽略的边界
- 流式与严格结构化输出常冲突:需要稳定 JSON 时,可以先用流式展示自然语言,或直接回退到普通返回后再统一解析。
- 用量字段位置不确定:流式响应里用量统计可能出现在末尾片段或需要额外参数,统计逻辑不要假设每个片段都有。
- 超时设置要分两层:连接超时按首字节设,读超时按最长回答设;沿用普通返回的短超时容易把长回答截断。
- 重试可能造成重复:流式中途断开后重发整轮请求,前端可能已经渲染了一半内容,需要先清空再重试,或干脆降级为一次性展示。
- 不适用条件:客户端、网关或某些企业出口不支持长连接和分块传输时,不要强上流式,直接用普通返回更稳。回退方式就是关闭 stream 参数,并把前端渲染改回整段替换。