BazaarLinkBazaarLink
เข้าสู่ระบบ
เอกสารAPI ข้อมูลอ้างอิงSDK ข้อมูลอ้างอิงการใช้งาน AgentAI ทักษะ
สารบัญ

Streaming

Streaming

ตั้ง stream: true เพื่อรับ Server-Sent Events (SSE) stream แต่ละเหตุการณ์มีส่วนหนึ่งของการตอบกลับ

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]
การใช้งานใน streaming
เมื่อ streaming ข้อมูลการใช้งานจะถูกส่งคืนในชิ้นสุดท้ายก่อนข้อความ [DONE] พร้อมอาร์เรย์ choices ที่มี delta ว่างและ finish_reason: "stop"

Keep-alive และ chunk สุดท้าย

สตรีมอาจมีบรรทัดคอมเมนต์ SSE และ event unknown หรือ ping เพื่อ keep-alive ให้ข้ามและ parse data frame; data frame สุดท้ายอาจมี usage ก่อน data: [DONE]

: 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]

การยกเลิกสตรีม

คำขอ streaming สามารถยกเลิกได้ด้วยการปิดการเชื่อมต่อฝั่งไคลเอนต์ — เช่น เรียก AbortController.abort() หรือปิดออบเจ็กต์ stream ทันทีที่ BazaarLink ได้รับสัญญาณยกเลิก จะหยุดส่งต่อ chunk ถัดไปและยกเลิกคำขอที่ส่งไปยังผู้ให้บริการ

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();
สตรีมที่ถูกขัดจังหวะไม่มีค่าใช้จ่าย
ถ้าสตรีมจบลงก่อนที่ chunk usage สุดท้ายจะมาถึง — รวมถึงกรณีที่ไคลเอนต์ยกเลิกเอง — จะไม่มีข้อมูลจำนวนโทเค็นที่เชื่อถือได้สำหรับคำขอนั้น BazaarLink จึงคืนเงินที่กันไว้เต็มจำนวน คุณจะไม่ถูกเรียกเก็บเงินสำหรับเนื้อหาที่ส่งถึงไคลเอนต์ไปแล้วก่อนการยกเลิก
ไม่รับประกันว่าผู้ให้บริการจะหยุดทันที
การปิดการเชื่อมต่อทำให้ BazaarLink หยุดส่งต่อและหยุดคิดค่าใช้จ่ายโทเค็นถัดไปทันที แต่ผู้ให้บริการต้นทางจะหยุดการสร้างข้อมูลบนเซิร์ฟเวอร์ของตนเองทันทีที่การเชื่อมต่อขาดหรือไม่นั้น ขึ้นอยู่กับผู้ให้บริการรายนั้น ๆ — บางรายอาจยังประมวลผลต่ออีกสักครู่หลังจากตัดการเชื่อมต่อ

ข้อผิดพลาดกลางสตรีม

เฟรม error ไม่มีฟิลด์ choices
หากเกิดความล้มเหลวหลังจากที่ streaming เริ่มไปแล้ว (เช่น การเชื่อมต่อ upstream หลุด) คุณจะได้รับ SSE data frame รูปแบบ {error:{message,type,code}} แทนที่ {choices:[...]} ตามปกติ — โดยไม่มีการเปลี่ยนสถานะ HTTP เนื่องจาก header ถูกส่งไปแล้ว ให้ตรวจสอบ error key ก่อนอ่าน choices[0].delta และจะเรียกเก็บเงินเฉพาะโทเค็นที่ stream ไปแล้วเท่านั้น (ใช้การเรียกเก็บเงินบางส่วน)
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]
Support
Hi! How can we help you?
Send a message and we'll get back to you soon.