กลับไปที่บล็อก

API และ SDKคู่มือ

timeout และ retries ของ OpenAI Python SDK: ตั้งค่าสำหรับ CheapTokens

ตั้ง timeout, max_retries และ max_tokens ใน OpenAI Python SDK จับข้อผิดพลาดที่ถูกต้อง และป้องกันไม่ให้คำขอที่ค้างทำงานนาน 10 นาที

โดย CheapTokens Teamเผยแพร่เมื่อ ใช้เวลาอ่าน 5 นาที

โค้ด Python ที่มี timeout=30.0 และ max_retries=2 บนพื้นหลังสีเข้ม
ในหน้านี้
  1. SDK ทำอะไรเมื่อคุณไม่ตั้งค่าอะไรเลย
  2. ตั้ง timeout และ max_retries บนไคลเอนต์
  3. แทนที่ค่าสำหรับคำขอเดียว
  4. จับข้อผิดพลาดที่สำคัญ
  5. จำกัด max_tokens เพื่อไม่ให้คำตอบยาวหนี
  6. retries ส่งผลต่อบิลอย่างไร
  7. ก่อนที่คุณจะ ship

สคริปต์ของคุณเรียกโมเดล ไม่มีอะไรตอบกลับมา และสิบนาทีต่อมาก็ยังรออยู่ นั่นคือค่าเริ่มต้นของ OpenAI Python SDK: timeout 10 นาที และ retry 2 ครั้ง หากต้องการเปลี่ยน ให้ส่ง timeout=30.0 และ max_retries=2 ไปที่ OpenAI(...) แทนที่ค่าดังกล่าวต่อการเรียกด้วย client.with_options(...) และจำกัดคำตอบด้วย max_tokens

README ของ SDK (ตรวจสอบเมื่อ 27 ตุลาคม 2026) เอกสารทั้งหมดนี้ ด้านล่างนี้นำไปใช้กับ endpoint ของ CheapTokens คือ https://api.cheaptokens.dev/v1 ซึ่งใช้รูปแบบ OpenAI Chat Completions รายละเอียดของการตั้งค่านั้นอยู่ใน คำขอ API แรกของคุณกับ CheapTokens และ เอกสาร

SDK ทำอะไรเมื่อคุณไม่ตั้งค่าอะไรเลย#

ค่าเริ่มต้นสองอย่างที่สำคัญ timeout คือ 10 นาที retry คือ 2 ครั้ง พร้อม exponential backoff สั้น ๆ สำหรับข้อผิดพลาดการเชื่อมต่อและสำหรับการตอบกลับ 408, 409, 429 และ 5xx และเฉพาะเมื่อ body ของคำขอสามารถส่งซ้ำได้อย่างปลอดภัย คำขอที่ timeout ก็ถูก retry เช่นกัน

ดังนั้นแต่ละความพยายามมี timeout ของตัวเอง และกรณีแย่ที่สุดคือประมาณ timeout คูณด้วยจำนวนความพยายาม บวกกับช่วงหยุดระหว่างนั้น:

  • ค่าเริ่มต้น: 600 × 3 = 1800 วินาที ครึ่งชั่วโมง
  • timeout=30.0, max_retries=2: 30 × 3 = 90 วินาที

สมมติว่า endpoint เว็บต้องตอบภายใน 30 วินาที ด้วยค่าเริ่มต้น มันอาจค้างได้ครึ่งชั่วโมงก่อนที่โค้ดของคุณจะเห็นข้อผิดพลาด ลองตั้งค่าอื่นก่อนอ่านต่อ

ทายตัวเลข

ไคลเอนต์มี timeout=45.0 และ max_retries=3 เวลารอแย่ที่สุดในหน่วยวินาทีก่อนเกิด exception คือเท่าไร ไม่นับช่วงหยุดระหว่างความพยายาม?

แสดงคำตอบ

คำตอบ: 180

45 × (3 retries + 1 ความพยายามแรก) = 180 วินาที; ช่วงหยุดระหว่างความพยายามเพิ่มขึ้นเล็กน้อย

ตั้ง timeout และ max_retries บนไคลเอนต์#

วิธีแก้ที่ง่ายที่สุดคือตั้งทั้งสองครั้งเดียวตอนสร้างไคลเอนต์:

python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
    timeout=30.0,      # seconds per attempt
    max_retries=2,     # 0 turns retries off
)

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Summarize this ticket in two sentences: ..."}],
    max_tokens=800,
)
print(resp.choices[0].message.content)
print(resp.usage.prompt_tokens, resp.usage.completion_tokens)

max_retries ต้องเป็นจำนวนเต็มที่ไม่ติดลบ timeout รับ float หรือออบเจ็กต์ httpx Timeout หากคุณต้องการขีดจำกัดแยกสำหรับการเชื่อมต่อและการอ่าน README ของ main branch ปัจจุบัน import httpx2 สำหรับสิ่งนั้น เวอร์ชันเก่าใช้ httpx ดังนั้นรัน pip show openai และตรวจสอบว่าการติดตั้งของคุณใช้ตัวไหน float ธรรมดาไม่ต้อง import และใช้ได้ทั้งสองแบบ

เส้นทางการร้องขอด้วย timeout=30 และสอง retries
หนึ่งคำขอ: ความพยายาม, timeout, สูงสุดสอง retries, แล้ว exception

ใช้ model id แบบเต็มจาก เอกสาร CheapTokens คือ deepseek-ai/DeepSeek-V4-Flash-0731 ที่นี่: id แตกต่างกันระหว่างผู้ให้บริการ โมเดลนี้รับ output tokens สูงสุด 32,768 ต่อคำตอบและมี context 380K ซึ่งเป็นเหตุผลว่าทำไมบรรทัด max_tokens ด้านบนจึงอยู่ที่นั่นโดยเจตนา เพิ่มเติมด้านล่าง และเกี่ยวกับโมเดลใน cheap DeepSeek

แทนที่ค่าสำหรับคำขอเดียว#

ไคลเอนต์เดียว งานต่างกัน คำตอบแชทควรยอมแพ้เร็ว สรุปตอนกลางคืนรอได้ แทนที่จะสร้างไคลเอนต์ที่สอง ให้สร้างหนึ่งสำหรับการเรียก:

python
quick = client.with_options(timeout=5.0, max_retries=0)
resp = quick.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": "Reply with one word: ok"}],
    max_tokens=5,
)

with_options ส่งคืนสำเนาพร้อมค่าใหม่และปล่อย client ไว้เหมือนเดิม การตั้ง max_retries=0 เป็นสิ่งที่ถูกต้องเมื่อโค้ดของคุณเอง retry อยู่แล้ว เช่น คิวงานที่นำงานกลับเข้าคิว มิฉะนั้นสองชั้นจะคูณกัน: 3 ความพยายามของ SDK ภายใน 3 ความพยายามของคิวคือ 9 คำขอสำหรับงานเดียว

จับข้อผิดพลาดที่สำคัญ#

หลังจาก retries หมด SDK จะ raise exception คลาสข้อผิดพลาดทุกตัวสืบทอดจาก openai.APIError และคำขอที่ล้มเหลวมี request_id ซึ่งเป็นสิ่งที่คุณบันทึก:

python
import openai

def ask(prompt: str) -> str | None:
    try:
        r = client.chat.completions.create(
            model="deepseek-ai/DeepSeek-V4-Flash-0731",
            messages=[{"role": "user", "content": prompt}],
            max_tokens=800,
        )
        return r.choices[0].message.content
    except openai.APITimeoutError:
        print("timed out after retries")
    except openai.RateLimitError as e:
        print("429, slow down:", e.request_id)
    except openai.APIConnectionError:
        print("cannot reach the API")
    except openai.APIStatusError as e:
        print("HTTP", e.status_code, e.request_id)
    return None

ลำดับจากแคบไปกว้าง APIStatusError ครอบคลุมการตอบกลับ 4xx หรือ 5xx ใด ๆ ดังนั้นหากมันมาก่อน มันจะกลืน RateLimitError แนวคิดเดียวกันสำหรับ timeout: มันอยู่เหนือข้อผิดพลาดการเชื่อมต่อทั่วไป ในสคริปต์แบบ batch return None คือประเด็นทั้งหมด: บันทึก prompt ไปยังรายการถัดไป และรัน failures ซ้ำในตอนท้าย

เมื่อ timeout ทำงานและ retries หมด นี่คือสิ่งที่ exception ดูเหมือน:

ข้อความ APITimeoutError หลังจาก retries หมด
สิ่งที่ timeout ที่จับได้ดูเหมือนใน log

สำหรับกรณี 429 โดยละเอียด รวมถึงการรอระหว่างความพยายาม ดู 429 Too Many Requests จาก AI API

จำกัด max_tokens เพื่อไม่ให้คำตอบยาวหนี#

timeout หยุดการรอ มันไม่ได้ทำให้โมเดลเขียนน้อยลง หากไม่มี max_tokens โมเดลที่มีขีดจำกัดคำตอบ 32,768 tokens สามารถเขียนคำตอบยาวมากได้ และคำตอบยาวก็ช้า ตั้งขีดจำกัดที่เหมาะกับงาน: 800 สำหรับสรุปตั๋ว, 5 สำหรับใช่/ไม่

ค่าใช้จ่ายคือคำตอบอาจถูกตัด ตรวจสอบ resp.choices[0].finish_reason: length หมายถึงขีดจำกัดถูกชนก่อนที่โมเดลจะเสร็จ ทำไมคำตอบ AI จึงหยุดกลางประโยค? ครอบคลุมเรื่องนี้ หากคุณ stream คำตอบแทน คำแรกจะมาถึงเร็วและรู้สึกว่ารอสั้นลง ดู Streaming responses ใน Python

retries ส่งผลต่อบิลอย่างไร#

retry คือคำขอใหม่ หากความพยายามถูกประมวลผลแล้ว มันเป็นคำขอแยกที่มี tokens ของตัวเอง สมมติว่าสรุปตั๋วคือ 1,500 tokens เข้าและ 400 ออก: หนึ่งคำขอมีค่าใช้จ่าย $0.000063 ตามราคาวันนี้ และ ตารางราคา ฉบับเต็มมีโมเดลอื่น ๆ ราคาคงที่ต่อโมเดล ไม่มีช่วง peak ดังนั้น retry ตอนตี 3 มีค่าใช้จ่ายเท่ากับตอนเที่ยง

เลื่อนสไลเดอร์ไปยัง batch ของคุณเอง:

เครื่องคำนวณค่าใช้จ่าย

batch ของสรุปตั๋ว 1,000 รายการ

โทเค็นอินพุตต่อคำขอ: 1,500 · โทเค็นเอาต์พุตต่อคำขอ: 400 · คำขอต่อวัน: 1,000

โมเดลต่อวันต่อเดือน
GLM-5.3-Flash$0.046$1.38
DeepSeek-V4-Flash$0.0625$1.88
MiniMax-M2.7$0.135$4.05

ตารางแสดงหนึ่งรอบ หากหนึ่งในสิบของ batch ต้องใช้ความพยายามครั้งที่สอง ให้เพิ่มหนึ่งในสิบ retries เป็นประกันราคาถูกเมื่อ failures หายาก และเป็นนิสัยแพงเมื่อคุณตั้ง max_retries=10 กับ endpoint ที่ล้มเหลวซ้ำ ๆ

ก่อนที่คุณจะ ship#

เช็กลิสต์

Timeouts และ retries พร้อมสำหรับ production