# 流式输出

> 用 stream: true 打开 SSE 流式输出,逐 token 返回,把首字延迟从数秒降到数百毫秒。

在请求体里加 `"stream": true`,响应变成 `text/event-stream`,每个事件是一行 `data: {json}`,
最后一个事件是 `data: [DONE]`。

```bash
curl https://api.tokrouter.dev/v1/chat/completions \
  -H "Authorization: Bearer $TOKROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4-mini",
    "messages": [{"role": "user", "content": "写一首四行诗"}],
    "stream": true
  }'
```

```
data: {"id":"...","choices":[{"delta":{"content":"春"}}]}

data: {"id":"...","choices":[{"delta":{"content":"眠"}}]}

data: [DONE]
```

## 用 SDK 读取

绝大多数 SDK 的 `stream=True` 已经处理了 SSE 分帧、keep-alive 与 `[DONE]`:

```python
for chunk in client.chat.completions.create(..., stream=True):
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

## 自己解析 SSE 时注意三点

1. **按 `\n\n` 切事件**,不要按行处理 —— 一个事件可能跨多个网络包(半包)
2. 忽略以 `:` 开头的注释行(keep-alive 心跳)
3. 收到 `[DONE]` 后关闭连接,不要等 EOF

## 什么时候不该用流式

- 需要一次性拿到完整 JSON(结构化输出)—— 流式只会让解析更麻烦
- 服务端要缓存整段结果且对首字延迟不敏感
- `/v1/systemone` 这类非 chat 端点**不支持流式**,请求带 `stream` 不会生效

<Callout type="warn" title="流式与计费">
流式请求同样按实际生成的 token 计费。客户端中途断开时,已生成的部分仍然计费。
</Callout>
