API และ SDKคู่มือ
การสตรีมคำตอบใน Python
พิมพ์คำตอบของโมเดลขณะที่มันถูกสร้างด้วยแพ็กเกจ openai อย่างเป็นทางการ — ตัวอย่างแบบ sync และ async เอาต์พุตการให้เหตุผล การใช้โทเคน และการจัดการข้อผิดพลาด

ในหน้านี้
เมื่อใช้สตรีมมิ่ง คำตอบจะมาทีละส่วนในขณะที่โมเดลยังสร้างอยู่ ผู้ใช้จึงเห็นข้อความทันทีแทนที่จะรอทั้งคำตอบ API ใช้รูปแบบสตรีมมิ่งมาตรฐานของ OpenAI (server-sent events) และแพ็กเกจ openai Python อย่างเป็นทางการจัดการให้คุณ
ตัวอย่างด้านล่างทุกตัวอย่างสมบูรณ์: คัดลอกไปวางในไฟล์แล้วรันได้ ตัวอย่างเหล่านี้ตรวจสอบกับ Python 3.10.12 และ openai 3.31.0 กับเซิร์ฟเวอร์ทดสอบภายในที่จำลองรูปแบบสตรีมมิ่งของ API (ไวยากรณ์และการทำงาน)
การตั้งค่า#
pip install openai
export CHEAPTOKENS_API_KEY="paste-your-key-here"ตัวอย่างแบบมินิมอล#
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
stream = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Write a haiku about latency"}],
stream=True,
)
for chunk in stream:
if not chunk.choices: # service chunk without text, e.g. the final usage chunk
continue
text = chunk.choices[0].delta.content
if text:
print(text, end="", flush=True)
print()มีสองรายละเอียดที่สำคัญ:
- ข้ามชังก์ที่ไม่มี
choicesบางชังก์ไม่มีข้อความ เช่นชังก์สุดท้ายที่มีการใช้โทเคน delta.contentอาจว่างเปล่าได้ ชังก์แรกมักมีแค่ role และชังก์สุดท้ายมีแค่finish_reasonพิมพ์ข้อความเฉพาะเมื่อมีอยู่
โมเดลที่ใช้การให้เหตุผล#
zai- ให้เหตุผลก่อนตอบ เหตุผลมาในฟิลด์แยกของ delta คือ reasoning_ และคำตอบอยู่ใน content SDK เก็บฟิลด์ที่ไม่รู้จักไว้ คุณจึงอ่านได้ด้วย getattr นี่คือตัวอย่างสมบูรณ์ที่มีไคลเอนต์และสตรีมของตัวเอง:
import os
import sys
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
stream = client.chat.completions.create(
model="zai-org/GLM-5.3-Flash",
messages=[{"role": "user", "content": "Is 1013 a prime number?"}],
stream=True,
)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
thinking = getattr(delta, "reasoning_content", None)
if thinking:
print(thinking, end="", flush=True, file=sys.stderr) # reasoning → stderr
if delta.content:
print(delta.content, end="", flush=True) # answer → stdout
print()การให้เหตุผลอาจใช้เวลาสักพักก่อนคำแรกของคำตอบจะปรากฏ — อีกเหตุผลหนึ่งที่ควรใช้สตรีมมิ่ง
การใช้โทเคน#
ขอข้อมูลการใช้ด้วย stream_options; มันมาในชังก์สุดท้ายซึ่งไม่มี choices:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
stream = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Explain idempotency in one paragraph"}],
stream=True,
stream_options={"include_usage": True},
)
usage = None
for chunk in stream:
if chunk.usage:
usage = chunk.usage
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if usage:
print(f"\ninput: {usage.prompt_tokens}, output: {usage.completion_tokens}")คูณตัวเลขเหล่านี้ด้วยอัตราของโมเดลเพื่อคำนวณค่าใช้จ่ายของคำขอ — ดู How to estimate the cost of an AI agent
asyncio#
ในโค้ดแบบ async ใช้ AsyncOpenAI และ async for ไคลเอนต์มีชื่อของตัวเองคือ async_client จึงไม่ชนกับ client แบบซิงโครนัสจากตัวอย่างอื่น:
import asyncio
import os
from openai import AsyncOpenAI
async_client = AsyncOpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
async def main() -> None:
stream = await async_client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Name three uses of a message queue"}],
stream=True,
)
async for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
asyncio.run(main())การหยุดก่อนเวลาและ timeout#
ออกจากลูปเพื่อหยุดการสร้าง การเปิดสตรีมด้วย with จะปิดการเชื่อมต่อเมื่อบล็อกจบ timeout ของไคลเอนต์ตั้งไว้อย่างชัดเจน; SDK ยังลองใหม่คำขอที่ล้มเหลวบางส่วนด้วยตัวเอง (max_retries ค่าเริ่มต้น 2)
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
timeout=120, # seconds; long answers take time
)
received = ""
with client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Write a long story about a lighthouse"}],
stream=True,
) as stream:
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
received += chunk.choices[0].delta.content
if len(received) > 300: # stop early: enough text received
break
print(received)ข้อผิดพลาด#
ข้อผิดพลาดที่เกิดก่อนชังก์แรก — คีย์ผิด ยอดเงินว่าง โมเดลไม่รู้จัก — จะถูกโยนเป็น exception เมื่อคุณสร้างสตรีม:
import os
import openai
from openai import OpenAI
client = OpenAI(
base_url="https://api.cheaptokens.dev/v1",
api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
try:
stream = client.chat.completions.create(
model="deepseek-ai/DeepSeek-V4-Flash-0731",
messages=[{"role": "user", "content": "Hello"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
except openai.AuthenticationError: # 401: wrong or rotated key
print("Check the API key")
except openai.BadRequestError as e: # 400: e.g. unknown model ID
print("Bad request:", e.message)
except openai.APIStatusError as e: # other statuses, e.g. 402 when the balance is used up
print(e.status_code, e.message)รายการรหัสสถานะและวิธีแก้แบบเต็มอยู่ใน Common connection errors and how to fix them
สิ่งที่ส่งบนไวร์#
สำหรับดีบัก ให้ดูสตรีมดิบด้วย curl (-N ปิดการบัฟเฟอร์):
curl -N https://api.cheaptokens.dev/v1/chat/completions \
-H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-ai/DeepSeek-V4-Flash-0731", "stream": true,
"messages": [{"role": "user", "content": "Hi"}]}'แต่ละอีเวนต์เป็นบรรทัด data: {…} ที่มีชังก์ JSON; สตรีมจบด้วย data: [DONE] บรรทัดที่ขึ้นต้นด้วยเครื่องหมายทวิภาคคือคอมเมนต์ keep-alive ที่ส่งระหว่างการหยุดนาน — ไคลเอนต์จะไม่สนใจ



