流式响应

使用 Server-Sent Events 接收模型的增量输出,并正确处理中断与结束事件。

流式响应会在模型生成过程中持续返回增量内容,通常可以降低用户感知到的首字延迟。OpenAI compatible 请求通过 stream: true 开启。

数据格式

响应的 Content-Type 通常为 text/event-stream。每个事件以 data: 开头,流结束时会收到结束标记。

data: {"choices":[{"delta":{"content":"你"}}]}

data: {"choices":[{"delta":{"content":"好"}}]}

data: [DONE]

浏览器或 Node.js Fetch

stream.ts
const response = await fetch(
  'https://api.sublyx.org/v1/chat/completions',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer sk-sublyx-example',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model: 'gpt-5.6-terra',
      stream: true,
      messages: [{ role: 'user', content: '解释流式响应。' }],
    }),
  },
);

if (!response.ok || !response.body) {
  throw new Error(`请求失败:${response.status}`);
}

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { value, done } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const events = buffer.split('\n\n');
  buffer = events.pop() ?? '';

  for (const event of events) {
    const line = event
      .split('\n')
      .find((item) => item.startsWith('data:'));
    if (!line) continue;

    const data = line.slice(5).trim();
    if (data === '[DONE]') continue;

    const chunk = JSON.parse(data);
    process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
  }
}

不要按网络分片直接解析 JSON

一个网络分片可能包含半个事件,也可能同时包含多个事件。先按 SSE 事件边界缓冲,再解析每个 data: 字段。

取消请求

const controller = new AbortController();

const response = fetch('https://api.sublyx.org/v1/chat/completions', {
  method: 'POST',
  signal: controller.signal,
  headers: {
    Authorization: 'Bearer sk-sublyx-example',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gpt-5.6-terra',
    stream: true,
    messages: [{ role: 'user', content: '生成一个长回答。' }],
  }),
});

controller.abort();

生产检查清单

  • 设置连接超时和总时长上限。
  • 客户端断开时及时取消上游请求。
  • 将已完成内容与“生成中”状态分开存储。
  • 区分正常结束、用户取消、网络中断和服务端错误。
  • 对流式请求重试时避免重复向用户展示已经输出的内容。

本页目录