Skip to content

流式输出

通过设置 stream: true 使用 Server-Sent Events(SSE)流式接收响应,降低首字延迟。

请求

bash
curl https://api.aiqizhilian.tech/v1/chat/completions \
  -H "Authorization: Bearer <你的 API Key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.5",
    "messages": [
      {
        "role": "user",
        "content": "用三句话介绍日本东京。"
      }
    ],
    "max_tokens": 512,
    "stream": true
  }'

响应格式

text
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"东京"}}]}
data: {"object":"chat.completion.chunk","choices":[{"delta":{"content":"是"}}]}
...
data: {"object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop"}]}
data: {"object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":12,"completion_tokens":6,"total_tokens":18}}
data: [DONE]

客户端处理方式:

  • 按行读取 data:,每行是一段 JSON。
  • 文本增量在 choices[0].delta.content
  • 收到 finish_reason 时本条 message 已经写完。
  • data: [DONE] 之前的最后一个 chunk 中,choices 为空数组 []usage 字段包含本次请求的 token 用量。
  • 收到 data: [DONE] 表示流结束。

关于 usage chunk

实测行为

本网关在所有流式响应的末尾都会单独返回一个 usage chunk,无需额外参数即可获取 token 用量。已覆盖测试:GPT、Claude、Gemini、Qwen、GLM、DeepSeek、Kimi。

如果直接使用 Anthropic 原生接口 /v1/messages(Claude Code、Claude Desktop 走的就是这条),流末尾会返回标准的 message_deltamessage_stop 事件,message_delta 中携带最终 usagestop_reason

  • 如希望客户端代码同时兼容 OpenAI 官方行为,建议显式传入 "stream_options": {"include_usage": true}。行为与不传一致。
  • OpenAI 官方 Python / Node SDK 已经自动处理 usage chunk,业务代码无需手工解析。
  • 自己解析 SSE 时,注意 choices: [] 是 usage chunk 的标志,不是错误

显式开启 stream_options 的请求:

json
{
  "model": "gpt-5.5",
  "messages": [...],
  "stream": true,
  "stream_options": { "include_usage": true }
}

SDK 示例

Python

python
from openai import OpenAI

client = OpenAI(
    api_key="<你的 API Key>",
    base_url="https://api.aiqizhilian.tech/v1",
)

stream = client.chat.completions.create(
    model="gpt-5.5",
    messages=[{"role": "user", "content": "用三句话介绍东京"}],
    max_tokens=512,
    stream=True,
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
    if chunk.usage:
        print(f"\n[usage] prompt={chunk.usage.prompt_tokens} "
              f"completion={chunk.usage.completion_tokens}")

Node.js

javascript
import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: process.env.AIQIZHILIAN_API_KEY,
  baseURL: 'https://api.aiqizhilian.tech/v1',
})

const stream = await client.chat.completions.create({
  model: 'gpt-5.5',
  messages: [{ role: 'user', content: '用三句话介绍东京' }],
  max_tokens: 512,
  stream: true,
})

for await (const chunk of stream) {
  const text = chunk.choices?.[0]?.delta?.content
  if (text) process.stdout.write(text)
  if (chunk.usage) {
    console.log(
      `\n[usage] prompt=${chunk.usage.prompt_tokens} completion=${chunk.usage.completion_tokens}`,
    )
  }
}

常见问题

1. 流式响应中途断开

可能原因:HTTP/2 空闲超时、客户端读取慢于服务端推送、服务端上游异常。 处理建议:

  • 客户端读取要尽量贴近 SSE 流,避免在单 chunk 上做耗时计算。
  • 自带重试逻辑,但要避免对非幂等业务无脑重试。

2. 拿到的 chunk 解析失败

可能原因:客户端按字符长度切而非按 data: 行边界切。 处理建议:用现成 SSE 库(如 openai SDK、sseclient-pyeventsource-parser),不要自己撸。