AIAPIZZ 登录 免费注册

流式输出(SSE)

共 14 篇

怎么开

请求体里带上 "stream": true 即可,返回 Content-Type: text/event-stream:

curl -N https://aiapizz.com/v1/chat/completions \
  -H "Authorization: Bearer sk-你的密钥" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","stream":true,"messages":[{"role":"user","content":"数到 10"}]}'
stream = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "数到 10"}],
    stream=True,
    stream_options={"include_usage": True},   # 想拿到 token 用量就加上
)
for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

curl 一定要加 -N(禁用本地缓冲),否则看起来像「一次性返回」。

数据格式

标准 OpenAI SSE:每行以 data: 开头,块之间空行分隔,最后以 data: [DONE] 结束。

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"向"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

请求里带 "stream_options": {"include_usage": true} 时,结束前还会多一个 choices 为空、usage 有值的块(网关对 OpenAI 渠道会自动补上这个参数,保证流式也能准确计费)。

两条不同的链路(很重要)

网关有两种流式实现,行为不一样:

情况实现表现
请求格式 == 上游格式真流式直通,边收边发首字延迟低,逐字吐出
请求格式 != 上游格式先拿到完整响应,再按你的格式切块包装成 SSE首字延迟 = 整段生成时间,之后一次性刷出(看着「像」流式)

三种格式(OpenAI / Anthropic / Gemini)都能包装,请客户端用哪个格式,包装出来就是哪个格式的事件流,不用避开任何组合。

所以:要真流式(首字快),就选一个上游格式与你请求格式一致的模型(模型广场里详细页会写明支持的格式);跨格式能用,只是首字要等整段生成完。

部署侧要注意的(流式中断/卡住九成在这里)

  1. Nginx 缓冲:宝塔默认会缓冲上游响应,流式会变成「憋一大坨」。网关已经发了 X-Accel-Buffering: no,但部分配置下仍被覆盖,建议在站点配置里对 PHP 加上:
fastcgi_buffering off;
fastcgi_read_timeout 600s;
# 客户端(AI 工具)中途关掉时,不要让 nginx 替你掐断后端 ——
# 掐断了网关就没机会走完结算,上游已经算的这笔钱就白亏了。
fastcgi_ignore_client_abort on;
  1. PHP 超时:长回答可能超过 max_execution_time。网关在收到上游响应前就已调 set_time_limit(0),若 php.ini 里开了 disable_functions 或 max_execution_time 被硬限制,仍需在宝塔「PHP 设置」里放宽。另外把 request_terminate_timeout 设得比最长回答更长(或设 0),它到点会直接杀进程,那种情况下网关的兜底结算也来不及跑;
  2. PHP-FPM 并发:客户端断开后网关会继续把这次调用读完(见下一条),所以这种请求会占住一个 worker 直到读完。用 AI 工具的用户比较多时,把 pm.max_children 调大一些;
  3. 反向代理/CDN:套了 CDN 的话,确认它不缓冲 SSE(多数 CDN 需要单独配置白名单);
  4. 客户端断开:你在生成中途 Ctrl+C,网关仍会把这次调用跑完并按实际用量计费(上游已经产出的 token 是要付钱的),日志里能看到完整的用量,并带一句「客户端提前断开」的备注。上游流到一半自己断了的话,按已经收到的那部分用量结算,不会记成一笔 0 元的调用。

关于计费

流式与非流式的计价方式完全一致,按最终 usage 结算;上游没返回 usage 时,网关按「1 token ≈ 4 字符」估算并计费。

输入侧的口径是「输入量含缓存命中的部分」,各家格式(OpenAI 的 prompt_tokens、Anthropic 的 input_tokens + cache_read_input_tokens、Gemini 的 promptTokenCount)在网关里统一成了这一种算法,所以同一个提示词用不同格式、流式或非流式请求,日志里的输入量应该在同一量级。

Anthropic 系模型还会额外报一项「缓存写入」(cache_creation_input_tokens,把这段提示词写进缓存的那部分)。这一路单独计量、单独计价,因为上游对写缓存本来就收得比普通输入贵。OpenAI 与 Gemini 的协议里没有这个概念,它们的缓存写入量恒为 0。

你的接口地址是 https://aiapizz.com/v1。 注册后即可在控制台创建密钥。
AIAPIZZ  · 模型广场  · 接口文档  · 服务条款  · 隐私政策
This website is independently developed and operated by the AIAPIZZ team. It is not affiliated with, authorized by, endorsed by, or otherwise associated with any other AI website, platform, brand, or service provider.
© 2026 AIAPIZZ