60 秒回答模板

我会把流式输出设计成有会话状态的生成任务,而不是一次不可控的 HTTP 流。每次生成要有 requestId、messageId、序列号和任务状态,服务端记录已提交给用户的增量片段、模型生成状态、取消状态和 token 使用。断点续传时,客户端带上最后收到的序列号,服务端优先补发已确认生成但客户端未收到的片段;如果模型任务仍在运行,可以继续挂载到同一流;如果任务已结束,则返回完整结果或结束状态。停止生成时,要从前端事件传到服务端调度器,取消模型流和正在执行的工具,标记任务为 cancelled,并保证重复停止是幂等的。计费上要以服务端实际生成或已结算 token 为准,明确 prompt token、completion token、取消前 token、失败重试 token 和补发片段的关系,补发不能重复计费。关键是把流、状态、取消和计费用同一套任务记录串起来。

考点 任务状态
难度 真实面经题
回答目标 讲清机制、训练与评估取舍

深入解析

01

先建立生成任务模型

流式输出不应只是一条临时连接。服务端应有 requestId、用户、输入摘要、任务状态、输出序列、token 计数、开始结束时间和错误原因。这样断线、取消、重试和计费才能对齐。

02

增量片段要可排序和去重

每个输出 chunk 应带序列号或 offset,客户端记录最后确认位置。重连时服务端根据位置补发缺失片段,客户端按序合并并去重,避免网络抖动造成重复文本或丢字。

03

断点续传分三种状态

如果任务仍在生成,客户端可以重新订阅并继续接收;如果任务已成功结束,服务端返回最终结果和 done;如果任务失败或取消,服务端返回明确状态和已生成内容。不要把所有重连都重新发起模型请求。

04

停止生成要端到端取消

停止事件要传到模型调用层和工具执行层,并更新任务状态。取消后应尽快关闭流、停止 token 消耗、释放 KV 或任务资源;重复点击停止应返回同一 cancelled 状态,而不是触发多次取消或新任务。

05

计费边界由服务端定义

前端看到多少字不是可靠计费依据。计费应基于服务端模型调用返回或流式统计的 prompt/completion token,并定义取消、超时、失败、重试和补发是否计费。补发历史片段只是传输恢复,不能重复记 token。

06

观测和审计保证一致性

需要记录连接断开、重连、取消、模型结束、工具结束、token 统计和结算事件。线上排查时可以回答用户是否真的停止、是否多扣费、是否重复生成,以及哪一段输出丢失。

易错点

  • 把流式输出当成纯 SSE/WebSocket 传输问题,忽略任务状态。
  • 断线后直接重新调用模型,造成重复输出和重复成本。
  • 停止生成只关闭客户端连接,后端仍继续生成。
  • chunk 没有序列号,重连后无法去重和补发。
  • 计费用前端展示字数估算,无法处理取消、失败和补发。
  • 缺少审计日志,用户投诉丢字或多扣费时无法定位。

面试官追问

断线重连时要不要重新请求模型?

优先不要。先根据 requestId 和最后序列号恢复已有任务;只有任务不存在或明确选择重新生成时,才创建新模型请求。

用户点停止后还产生 token 怎么办?

要检查取消信号是否传到模型流和工具层。计费规则也要明确取消请求到实际停止之间已生成 token 是否计入。

客户端收到重复 chunk 如何处理?

用序列号或 offset 做幂等合并,已确认片段不再追加。服务端补发也应从客户端确认位置之后开始。

失败重试会不会重复扣费?

要看规则。一般同一生成任务内的传输补发不重复计费;真正重新调用模型产生的新 token 才可能计费,并应在账单事件里可追溯。