流式响应
流式传输会在生成过程中逐步返回部分结果,让你的应用可以增量地显示文本,而无需等待完整响应。这能带来更好的用户体验,尤其是对于较长的响应。
流式传输的工作原理
当你设置 stream: true 时,API 会返回一个 Server-Sent Events(SSE) 流。每个事件都包含生成过程中的一小段响应。
使用 cURL
curl https://openapi.linkwo.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek/deepseek-v4-pro",
"messages": [{"role": "user", "content": "Write a haiku about coding"}],
"stream": true
}'响应是一连串的 data: 行:
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"content":"Silent"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1719000000,"model":"deepseek/deepseek-v4-pro","choices":[{"index":0,"delta":{"content":" keys"},"finish_reason":null}]}
data: [DONE]使用 Python(OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://openapi.linkwo.ai/v1",
api_key="YOUR_API_KEY"
)
stream = client.chat.completions.create(
model="deepseek/deepseek-v4-pro",
messages=[{"role": "user", "content": "Explain quantum computing in simple terms"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="", flush=True)使用 Node.js(OpenAI SDK)
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://openapi.linkwo.ai/v1',
apiKey: 'YOUR_API_KEY',
});
const stream = await client.chat.completions.create({
model: 'deepseek/deepseek-v4-pro',
messages: [{ role: 'user', content: 'Explain quantum computing in simple terms' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
}流式分片格式
流中每个分片的结构如下:
{
"id": "chatcmpl-abc123",
"object": "chat.completion.chunk",
"created": 1719000000,
"model": "deepseek/deepseek-v4-pro",
"choices": [
{
"index": 0,
"delta": {
"content": "partial text"
},
"finish_reason": null
}
]
}Delta 与 Message
| 字段 | 非流式 | 流式 |
|---|---|---|
| 内容位置 | choices[].message.content | choices[].delta.content |
| 内容 | 完整响应 | 增量片段 |
finish_reason | 始终存在 | 在最后一个分片之前为 null |
第一个分片通常包含 delta.role: "assistant"。后续分片包含 delta.content 片段。最后一个分片的 finish_reason 为 "stop",且 delta 为空。
何时使用流式传输
| 使用场景 | 是否流式? |
|---|---|
| 聊天界面 | 是 —— 边生成边显示文本 |
| 批量处理 | 否 —— 收集完整响应后再处理 |
| API 集成 | 视情况而定 —— 若延迟敏感则使用 |
| 函数调用 | 否 —— 需要完整的结构化输出 |
最佳实践
- 务必处理
[DONE]标记 —— 它标志着流的结束 - 设置超时 —— 网络问题可能导致流挂起
- 缓冲小分片 —— 出于显示考虑,可缓冲后再渲染,避免过度重绘
- 处理断连 —— 为断开的连接实现重试逻辑