从协议机制、响应结构、教学交互设计到稳定性治理,系统拆解 DeepSeek API 流式输出的实现路径与工程要点。
大模型应用体验的分水岭,往往不在模型能力本身,而在第一个字返回的时间。在 AI 指导老师这类强互动场景中,学员提问后若对着空白界面等待十几秒才看到整段回答,注意力早已涣散,追问的节奏也被打断。流式输出把一次性的完整响应拆解为持续抵达的增量片段,让生成过程变成可感知的渐进呈现,既缩短了首字等待,也让学习者能够跟随推理步骤同步思考。然而真正把流式用稳、用好,并不只是把参数改成 stream 为 true 那么简单,它牵涉协议底座、分片结构、前端渲染节奏以及整条代理链路的配合。下面从四个层面展开解析。
1. 从 SSE 到增量 token:流式输出的协议底座
DeepSeek API 在接口形态上兼容 OpenAI 的对话补全规范,流式能力通过请求体中的 stream 参数开启。开启之后,服务端不再等待整段文本生成完毕再返回,而是将响应头设置为 text/event-stream,走 Server-Sent Events 通道,并配合 HTTP 分块传输编码持续推送数据。每一帧以 data: 开头,后接一段 JSON,帧与帧之间以两个换行分隔,全部内容推送完成后发送 data: [DONE] 作为终止标记。这种单向、基于普通 HTTP 的长连接设计,相比 WebSocket 更容易穿透企业防火墙和常见反向代理,客户端实现成本也更低,代价是它只支持服务端到客户端的单向推送,交互指令仍需另发请求。
理解协议之后,还需理解数据产生的粒度。模型在解码阶段逐个 token 生成内容,服务端在积累到一定数量或达到刷新阈值时就把当前片段推送出去,因此一个分片里可能包含一个字、一个词,也可能是半句话。首 token 延迟主要消耗在预填充阶段,也就是对输入上下文做注意力计算的过程,输入越长、并发越高,这段等待越明显。DeepSeek 官方对上下文缓存做了专门优化,命中缓存的部分可以显著压低预填充耗时,这也是为什么在长文档问答类教学场景中,把稳定的系统提示词和教材原文放在前部、把学员的临时提问放在后部,往往能获得更稳定的首字响应。中文场景下还需注意 token 与字符并非一一对应,一个汉字通常对应一到两个 token,按字符估算用量会产生偏差。
2. 请求参数与响应分片的结构化解读
流式请求的响应体与普通请求存在结构差异,最直接的体现是 choices 数组中的字段由 message 变为 delta。首个分片通常只携带 role 信息,content 为空;中间分片逐步给出 content 的增量文本;最后一个内容分片会带上 finish_reason,取值为 stop、length 或 content_filter,用于判断是自然结束、触达最大长度还是被安全策略截断。若使用具备思维链能力的模型版本,还会出现 reasoning_content 字段,它与正文内容分离推送,教学场景中可以据此把思考过程和最终答案分层展示,避免学员把推理草稿误当作结论。
工程上最容易踩的坑是忽略增量语义而做整段覆盖。正确做法是在客户端维护一个累积缓冲区,每收到一个分片就追加 delta.content,同时用该缓冲区驱动界面刷新,而不是把每个分片当成完整答案替换。另一个细节是用量统计。默认情况下流式响应不返回 token 消耗,需要在请求中显式设置 stream_options 并把 include_usage 置为 true,服务端会在终止帧之前额外推送一个 choices 为空、usage 字段完整的分片,其中包含输入、输出及缓存命中的 token 数。这一帧是后续做成本核算与配额管理的唯一可靠依据,缺少它就只能靠字符数粗估,误差在长对话中会不断累积。此外,max_tokens 在流式下依然是硬性上限,一旦触达,finish_reason 会变为 length,前端应当据此提示内容被截断,而不是让学员误以为回答已经完整。
3. 面向教学场景的流式交互设计
AI 指导老师的核心诉求不是把答案尽快倒给学员,而是让讲解节奏可跟随。流式输出天然适合分步呈现,但若不做渲染节流,高频分片会导致界面反复重排,长文本下甚至出现明显卡顿。实践中通常按帧合并更新,把若干毫秒内到达的分片聚合成一次渲染,既保持了打字机效果,又控制了重绘频率。Markdown 的增量渲染是另一个难点,代码块和公式在未闭合时按完整语法解析会报错或闪烁,稳妥的做法是对未闭合的围栏做占位处理,待闭合后再整体高亮。
交互层面还有几处必须提前设计。其一是中断能力,学员看到思路跑偏时应当能立即停止生成,客户端通过中止请求关闭连接,服务端随之停止解码,这 simultaneously 节省了输出 token 的成本,已生成的内容则要保留在界面上并可写入对话历史。其二是历史拼接,多轮对话中必须把完整的累积文本作为助手消息回传,若误传单个分片,上下文会立刻错乱。其三是与语音播报的衔接,口语化辅导场景可以让合成引擎消费增量文本,按句子边界切分后送入语音通道,实现边生成边朗读。其四是内容审核,流式环境下无法等全文生成后再过滤,需要采用滑动窗口对增量文本做实时检测,一旦命中敏感内容立即终止并回退已展示片段。
4. 稳定性、代理链路与成本治理
很多流式故障并不出在模型侧,而在中间链路。Nginx 默认开启响应缓冲,会把分片攒成整段再下发,前端看到的效果与关闭流式几乎没有区别,必须在对应 location 中关闭 proxy_buffering,并把 proxy_read_timeout 调至明显大于最长生成时长,否则长回答会在中途被切断。CDN 与部分企业网关同样存在缓冲和空闲超时策略,上线前应逐跳验证是否真正做到了逐帧透传。移动网络下的断连更为常见,客户端需要记录已接收内容与最后的分片序号,重连后由业务层决定是重新请求还是提示学员续问,切忌在已输出部分内容后对整个请求做无脑重试,否则会出现答案重复或语义断裂。
治理层面,流式并不改变计费口径,费用仍按输入与输出 token 结算,但流式让提前终止成为可能,学员主动停止生成能够实打实减少输出消耗。限流错误在流式下表现为连接建立阶段直接返回错误码,这类失败发生在首包之前,适合用指数退避重试;而连接已建立后再出错,重试就需谨慎。监控指标应当围绕首 token 延迟、分片间隔与中断率构建,前者反映预填充与排队状况,后者能暴露链路缓冲或网络抖动。把这些指标与 include_usage 返回的用量数据结合,才能既保证教学过程中讲解的流畅呈现,又把单位会话的成本控制在可预期范围内。

