BazaarLinkBazaarLink
登入
文件API 参考SDK 参考Agent 应用AI Skills
章节导航

串流

串流

设定 stream: true 以接收 Server-Sent Events (SSE) 串流。每个事件包含一个回应片段。

from openai import OpenAI

client = OpenAI(
    base_url="https://api.bazaarlink.ai/v1",
    api_key="sk-bl-YOUR_API_KEY",
)

stream = client.chat.completions.create(
    model="anthropic/claude-sonnet-4.6",
    messages=[{"role": "user", "content": "Count to 10 slowly."}],
    stream=True,
)

for chunk in stream:
    content = chunk.choices[0].delta.content
    if content:
        print(content, end="", flush=True)

SSE 格式

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"Hello"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":" world"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{"prompt_tokens":10,"completion_tokens":4,"total_tokens":14}}

data: [DONE]
串流中的使用量
串流时,使用量资料会在 [DONE] 讯息之前的最后一个区块中返回,该区块的 choices 阵列带有一个空 delta 与 finish_reason: "stop"。

Keep-alive 与收尾行为

流式响应可能包含 SSE 注释行及未知或 ping keep-alive 事件;请忽略这些内容并解析 data 帧。最后一个 data 帧可能在 data: [DONE] 前携带 usage。

: keepalive          <- SSE comment line — ignore, do NOT JSON.parse

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"Hi"},"index":0}]}

data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{},"finish_reason":"stop","index":0}],"usage":{...}}

data: [DONE]

流取消

流式请求可以通过关闭客户端连接来取消 — 例如调用 AbortController.abort() 或关闭 stream 对象。BazaarLink 收到取消信号后会立即停止转发后续内容,并中止对上游供应商的请求。

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.bazaarlink.ai/v1",
  apiKey: "sk-bl-YOUR_API_KEY",
});

const controller = new AbortController();

const stream = await client.chat.completions.create(
  {
    model: "anthropic/claude-sonnet-4.6",
    messages: [{ role: "user", content: "Write a long story." }],
    stream: true,
  },
  { signal: controller.signal }
);

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}

// e.g. on a "Stop" button click:
controller.abort();
被中断的流不收费
如果流在最后的 usage chunk 到达前就结束 — 包括客户端主动取消的情况 — 这次请求就没有可信的 token 用量依据,BazaarLink 会全额退还预扣的额度。取消前已发送到你客户端的内容不会计费。
不保证上游立即停止
关闭连接会让 BazaarLink 立即停止转发并停止为后续 token 计费,但上游供应商是否会在自己的服务器上瞬间停止生成,取决于该供应商本身 — 有些供应商断线后仍会短暂继续运算。

串流中途出错

错误帧没有 choices 字段
如果串流已经开始后才发生失败(例如上游连接中断),您会收到一个 {error:{message,type,code}} 形状的 SSE 数据帧,而不是通常的 {choices:[...]} —— HTTP 状态不会变化,因为 header 早就发送了。读取 choices[0].delta 前请先检查是否有 error 字段;计费只会算到已经串流出去的 token(适用部分计费)。
data: {"id":"85e6f35c71a31f19-SJC","choices":[{"delta":{"content":"The capital of "},"index":0}]}

data: {"error":{"message":"The request could not be completed.","type":"upstream_error","code":502}}

data: [DONE]
客服
您好!有什么可以协助?
请留下消息,我们会尽快回复。
串流 | BazaarLink