大模型应用面试里,流式输出很容易被说成“前端体验更好”。这当然是一个原因,但只说到这里不够。后端接入流式接口后,要面对的是长连接、模型超时、用户取消、网络断开、部分结果、敏感内容拦截和资源占用。
换句话说,流式输出不是 UI 动效,而是后端链路从一次性请求变成了持续传输。这个变化会影响接口设计、线程模型、连接池和错误处理。
SSE 和 WebSocket 要按场景选
很多问答类场景用 SSE 就够了。服务端不断向浏览器推送文本片段,浏览器按事件流接收,协议简单,天然适合服务器到客户端的单向输出。WebSocket 更适合双向实时交互,比如多人协作、语音对话、客户端频繁发控制消息的场景。
不要为了显得高级就默认 WebSocket。面试里可以说:如果只是模型回答逐步返回,SSE 简单稳定;如果需要双向控制、实时中断、多路事件或复杂会话,再考虑 WebSocket。技术选择要和交互模式匹配。
客户端取消要传到模型侧
用户关闭页面、点击停止生成、网络断开时,后端不能继续傻等模型完整输出。否则用户已经走了,服务端还在消耗模型额度、连接和线程资源。正确做法是感知客户端断开或停止信号,取消上游请求,释放资源,并记录这次会话是被用户取消而不是模型失败。
这点在成本治理里很重要。大模型调用按 token、时长或请求计费,取消传播做不好,浪费会非常隐蔽。监控上要能区分正常完成、用户取消、模型超时、内容拦截和网络错误。
超时不能只有一个总超时
流式接口至少有几类时间需要关注:模型首 token 等待时间、连续 token 间隔、总生成时间、客户端连接存活时间。如果只设置一个很长的总超时,用户可能在空白页面等很久;如果超时太短,又可能误杀复杂问题。
更合理的方式是设置首包超时和空闲超时。首包太慢,说明模型排队、检索或路由可能有问题;中间长时间没有片段,可能是上游卡住;总时长太长,则需要停止生成或提示用户缩小问题范围。
背压不是只有消息队列才有
模型输出快,客户端网络慢,或者前端处理慢,服务端就会积压数据。简单把 chunk 写到响应流里,不代表系统一定安全。大量慢连接会占住资源,影响其他用户。
后端需要限制并发流式请求数、单用户连接数、响应缓冲大小和最大输出长度。必要时对低优先级请求排队或拒绝。流式输出看起来温和,实际上每个请求都可能占用较长时间,容量规划不能按普通短接口估算。
部分结果也要有语义
流式回答可能生成一半就失败。页面上留下的半段内容,是草稿、失败结果,还是可继续追问的上下文?如果涉及知识库问答,还要考虑引用证据是否已经完整返回。否则用户看到一段看似完整、实则缺证据的回答,会误以为系统已经完成。
可以在事件里区分 token、引用、状态、错误和结束标记。前端不要只拼字符串,后端也不要只返回裸文本。一个清晰的事件协议,能让 UI、日志和恢复逻辑都更可靠。
面试里的高分表达
可以这样总结:大模型流式输出提升体验,但后端要把它当成长连接系统设计。协议选择、取消传播、首包超时、空闲超时、背压控制、部分结果语义和调用成本都要考虑。能讲到这些,说明你不是只接过一个 SDK,而是真的理解 AI 应用后端的工程边界。