Lovely Router文档
获取密钥
模型 API

流式输出

在三种 API 格式中,都能在 token 生成的同时流式接收。了解网关如何隐藏早期失败、卡顿和流中途的错误如何呈现,以及取消的流如何计费。

流式输出使用厂商自己格式的服务器发送事件(SSE)。你收到的字节就是模型产生的字节;网关只是监听它们,用于计量用量并保护你免受故障影响。

开启流式输出#

API如何开启流式输出流的结束标志
Anthropic Messages请求体中设置 "stream": trueevent: message_stop
OpenAI Chat Completions请求体中设置 "stream": truedata: [DONE]
GeminiPOST /v1beta/models/{model}:streamGenerateContent?alt=sse一个候选结果带有 finishReason 的事件

各 SDK 指南中有示例代码:Anthropic、OpenAI、Gemini。

流的样子#

SSE
event: message_start
data: {"type":"message_start","message":{"id":"msg_01HCz7","type":"message","role":"assistant","model":"claude-sonnet-5-5","content":[],"stop_reason":null,"usage":{"input_tokens":14,"cache_creation_input_tokens":0,"cache_read_input_tokens":0,"output_tokens":1}}}

event: content_block_start
data: {"type":"content_block_start","index":0,"content_block":{"type":"text","text":""}}

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"One, two, three."}}

event: content_block_stop
data: {"type":"content_block_stop","index":0}

event: message_delta
data: {"type":"message_delta","delta":{"stop_reason":"end_turn","stop_sequence":null},"usage":{"output_tokens":8}}

event: message_stop
data: {"type":"message_stop"}

早期失败会自动重试#

有时渠道接受了请求,却在产生任何输出之前失败,例如先发送 message_start,随后返回过载错误。网关会暂存每个流的开头,直到第一个内容 token(文本、思考或工具调用)到达。如果渠道在此之前失败,此时还没有任何内容到达你这里,因此网关会在另一个渠道上重试请求,你会从头收到一个干净的流。

启动过慢的渠道同样如此:对于未开启扩展思考的 Claude 模型,如果某个渠道在 10 秒内(提示词每 1 万 token 多 1 秒)还没有产生第一个 token,网关会改用另一个渠道,除非它已是最后一个可用渠道。开启思考的请求可以按模型思考所需的时间等待。非流式请求遵循同样的规则。

这对你的客户端意味着:

  • HTTP 状态码和响应头会与第一个 token 一起到达,因此首字节时间等于首 token 时间。
  • 如果所有渠道都在第一个 token 之前失败,你会收到一个采用你所用 API 错误格式的普通 HTTP 错误响应,而不是一个中断的流。
  • 暂存最长持续 15 秒。如果模型静默思考超过这个时间,流会在此刻开始输出,从那以后请求就固定在该渠道上。
  • 请为响应开始预留至少 30 秒。请求还可能先等待几秒钟以获得容量;请参阅限流与故障转移。

流中途的卡顿和错误#

一旦 token 开始流动,请求就固定在一个渠道上,无法再转移。仍有两种情况可能让它提前结束。

卡顿。 如果渠道 3 分钟内没有发送任何内容,网关会以你所用 API 格式的错误事件结束流,并关闭连接:

SSE
event: error
data: {"type":"error","error":{"type":"api_error","message":"Upstream stopped responding mid-stream"}}

渠道返回的错误。 渠道可能在运行中的流里报告错误,例如模型过载。你收到的是一个采用你所用 API 格式的通用错误事件,而不是渠道自己的文本:渠道繁忙时为 overloaded_error(OpenAI 为 rate_limit_exceeded,Gemini 为 RESOURCE_EXHAUSTED),其他情况为 api_error(Gemini 为 UNAVAILABLE),消息为 The model provider returned an error. Please retry.

这两种情况下,流结束时都没有正常的最后一个事件(message_stop、data: [DONE] 或 finishReason)。请把缺少该事件就结束的流视为不完整:保留或丢弃部分输出,如果需要完整的回答,再重试整个请求。Anthropic 和 OpenAI SDK 收到错误事件时会抛出异常。

取消流#

关闭连接即可停止生成,例如跳出循环,或调用 stream.close() / controller.abort()。网关会停止模型,并对截至当时已生成的内容计费:

  • 输入使用流已经报告的 token 数(Anthropic 在流开始时就会报告);如果尚未报告,则按你的请求大约每 4 个字符 1 个 token 估算。
  • 输出取流截至当时报告的数量与按已发送给你的文本大约每 4 个字符 1 个 token 的估算值中的较大者。被提前切断的流很少会报告最终的输出 token 数,因此通常适用的是估算值。

以卡顿错误结束的流也按同样方式,对你收到的内容计费。每个被取消或卡顿的流都会连同其扣费显示在日志中。请参阅模型与价格。