AI 严选AIAICN / API FIELD GUIDE
流式排障

AI 流式输出中断怎么办?从事件到代理逐层排查

把 SSE 连接关闭与生成完成分开处理,检查客户端解析、代理缓冲和服务端终态,并用离线事件夹具验证恢复逻辑。

AI 严选 · 编辑整理(AI 辅助) · 写于 · 资料核对

本文目录
  1. 先识别当前流的协议
  2. 将生成过程拆成明确状态
  3. 先用本地事件验证 UI,而不是重复烧额度
  4. 用三层证据定位中断位置
  5. 恢复时防止重复内容与重复动作
直接回答

连接关了不等于回答完成。先看是否收到协议定义的完成事件,再区分客户端解析、代理缓冲或超时、服务端失败。已经展示的半段文字应保留为“未完成”,重试结果不要直接追加到旧内容。

适用前提

本文以 OpenAI Responses 的 HTTP SSE 为例。Chat Completions 和第三方兼容接口的事件格式可能不同,不能混用解析器;代码只消费本地合成事件,不连接任何模型。

先识别当前流的协议

Responses 的文字增量可见 response.output_text.delta,正常完成事件为 response.completed,错误也可能以事件形式出现。不要拿 Chat 的 choices 增量读取规则套到 Responses 上,更不能只看到 HTTP 200 就把业务状态标成成功。若使用 SDK,让 SDK 负责 SSE 分帧;自行解析时,网络读取块与完整事件不是一一对应。

官方依据:来源 1

将生成过程拆成明确状态

建议在应用中区分等待、接收、完成、失败和中断。官方事件参考还区分 response.failed 与 response.incomplete;收到它们时应检查对应原因,不能当普通完成。某些高级流程存在额外状态变化,下面只示范不启用 steering 等功能的普通文字请求;遇到未处理的终态应显式报告,不猜测成功。

官方依据:来源 2

先用本地事件验证 UI,而不是重复烧额度

保存为 stream-state.mjs 后运行 node stream-state.mjs。两个合成用例都含文字增量,但只有一个结束于完成事件;预期分别输出 completed 与 interrupted。真实项目还要把 SDK 异常接到失败分支,并为输出项分别建缓冲区。

JavaScript · 本地合成示例,不联网、不消耗 API 额度
function consume(events) {
  let text = '', status = 'receiving';
  for (const event of events) {
    if (event.type === 'response.output_text.delta') text += event.delta;
    if (event.type === 'response.completed') status = 'completed';
    if (['response.failed', 'response.incomplete', 'error'].includes(event.type)) {
      status = 'failed'; break;
    }
  }
  return {text, status: status === 'receiving' ? 'interrupted' : status};
}
const delta = {type:'response.output_text.delta', delta:'这是一段演示'};
console.assert(consume([delta]).status === 'interrupted');
console.assert(consume([delta,{type:'response.completed'}]).status === 'completed');
console.log(consume([delta,{type:'response.completed'}]).status);
console.log(consume([delta]).status);

用三层证据定位中断位置

客户端层:查看是否在 JSON 尚不完整时就解析、是否取消了请求、是否把某一种事件当成所有事件。代理层:对照服务端收到事件的时间与前端展示时间;若后端持续收到而前端成批出现,再检查自己控制的代理是否缓冲、是否有空闲超时。服务端层:记录请求 ID、最后事件类型与终态原因。这里是排查顺序,不是已确认某个商家或 CDN 有问题。

  1. 先用本地夹具复现解析逻辑,不包含任何 Key。
  2. 在受控测试环境对比有无自建代理的路径;不得绕过组织必需的网络或数据控制。
  3. 每次只调整一个超时或缓冲参数,并保留原配置以便恢复。

恢复时防止重复内容与重复动作

把首次输出标为未完成,给每次尝试单独编号。只有确认请求可安全重放,才在预算与次数上限内重试;新回答放到新尝试中,不拼到旧字符串后。若流里触发过发邮件、支付等动作,先查询动作状态并按业务幂等键去重。对已获授权且可检索的保存响应,可以依据供应商文档查询状态,但不能假定所有中转都支持断点续传。

来源与适用边界

2026-10-21 阅读下列官方资料。操作步骤为本站编辑归纳,代码与数字为本地合成示例;未调用付费模型,不是服务商实测报告,也不构成接口或性能承诺。

  1. https://developers.openai.com/api/docs/guides/streaming-responses
  2. https://developers.openai.com/api/reference/resources/responses/streaming-events