流式响应
使用 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
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();生产检查清单
- 设置连接超时和总时长上限。
- 客户端断开时及时取消上游请求。
- 将已完成内容与“生成中”状态分开存储。
- 区分正常结束、用户取消、网络中断和服务端错误。
- 对流式请求重试时避免重复向用户展示已经输出的内容。