API وSDKدليل
مهلة وإعادات محاولة OpenAI Python SDK: اضبطها لـ CheapTokens
اضبط timeout وmax_retries وmax_tokens في OpenAI Python SDK، والتقط الأخطاء الصحيحة، وامنع طلبًا عالقًا من العمل لمدة 10 دقائق.

في هذه الصفحة
استدعى سكربتك النموذج، ولم يعد شيء، وبعد عشر دقائق لا يزال ينتظر. هذا هو الوضع الافتراضي في OpenAI Python SDK: مهلة 10 دقائق وإعادة محاولتين. لتغيير ذلك، مرّر timeout=30.0 وmax_retries=2 إلى OpenAI(...)، وتجاوزها لكل استدعاء باستخدام client.، وحدّد الإجابة بـmax_tokens.
يوثّق README الخاص بـ SDK (تم التحقق في 27 أكتوبر 2026) كل هذا. أدناه يتم تطبيقه على نقطة نهاية CheapTokens، https:/، التي تتحدث بصيغة OpenAI Chat Completions. تفاصيل هذا الإعداد موجودة في طلبك الأول لواجهة API مع CheapTokens والوثائق.
ما يفعله SDK عندما لا تضبط شيئًا#
هناك وضعان افتراضيان مهمان. المهلة 10 دقائق. إعادة المحاولات 2، مع تراجع أسي قصير، لأخطاء الاتصال ولردود 408 و409 و429 و5xx، وفقط عندما يمكن إعادة إرسال جسم الطلب بأمان. الطلب الذي تنتهي مهلته يُعاد أيضًا.
لذا تحصل كل محاولة على مهلتها الخاصة، وأسوأ حالة هي تقريبًا المهلة مضروبة في عدد المحاولات، بالإضافة إلى فترات التوقف بينها:
- الافتراضي: 600 × 3 = 1800 ثانية، نصف ساعة
timeout=30.0،max_retries=2: 30 × 3 = 90 ثانية
لنفترض أن نقطة نهاية ويب يجب أن تجيب خلال 30 ثانية. مع الإعدادات الافتراضية يمكن أن تتعطل لمدة نصف ساعة قبل أن يرى كودك خطأً. جرّبها على إعداد آخر قبل متابعة القراءة.
خمّن الرقم
عميل لديه timeout=45.0 وmax_retries=3. ما أقصى انتظار بالثواني قبل الاستثناء، دون احتساب فترات التوقف بين المحاولات؟
تخمينك
0400
إظهار الإجابة
الإجابة: 180
45 × (3 إعادات + 1 محاولة أولى) = 180 ثانية؛ تضيف فترات التوقف بين المحاولات قليلًا فوق ذلك.
اضبط timeout وmax_retries على العميل#
أبسط إصلاح هو ضبط كليهما مرة واحدة، عند إنشاء العميل:
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 للفرع الرئيسي الحالي httpx2 لذلك، بينما استخدمت الإصدارات الأقدم httpx، لذا شغّل pip show openai وتحقق من أيّهما يستخدمه تثبيتك. لا يحتاج float العادي إلى import ويعمل في الحالتين.

استخدم معرّف النموذج الكامل من وثائق CheapTokens، deepseek- هنا: تختلف المعرّفات بين المزوّدين. يقبل هذا النموذج حتى 32,768 رمز إخراج لكل إجابة ولديه سياق 380K، ولهذا يوجد سطر max_tokens أعلاه عن قصد. المزيد عنه أدناه، وعن النموذج في cheap DeepSeek.
تجاوزه لطلب واحد#
عميل واحد، مهام مختلفة. رد الدردشة يجب أن يستسلم بسرعة، وملخص ليلي يمكنه الانتظار. بدلًا من إنشاء عميل ثانٍ، اشتق واحدًا للاستدعاء:
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 هو الخيار الصحيح عندما يعيد كودك المحاولة بالفعل، مثل طابور مهام يعيد إدراج المهمة. وإلا تتضاعف الطبقتان: 3 محاولات SDK داخل 3 محاولات طابور تعني 9 طلبات لمهمة واحدة.
التقط الأخطاء المهمة#
بعد نفاد إعادات المحاولة، يرفع SDK استثناءً. كل فئة خطأ ترث من openai.APIError، وتحمل الطلبات الفاشلة request_id، وهو ما تسجّله:
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. الأمر نفسه ينطبق على المهلة: فهي تقع فوق خطأ الاتصال العام. في سكربت دفعي، return None هو كل الهدف: سجّل الـ prompt، وانتقل إلى التالي، وأعد تشغيل الإخفاقات في النهاية.
عندما تنطلق المهلة وتنفد إعادات المحاولة، هكذا يبدو الاستثناء:

لحالة 429 بالتفصيل، بما في ذلك الانتظار بين المحاولات، راجع 429 Too Many Requests من واجهة AI API.
حدّد max_tokens حتى لا تفلت إجابة طويلة#
المهلة توقف الانتظار. لكنها لا تجعل النموذج يكتب أقل. بدون max_tokens، يكون النموذج ذو حد إجابة 32,768 رمزًا حرًا في كتابة رد طويل جدًا، والرد الطويل بطيء. اضبط حدًا يناسب المهمة: 800 لملخص تذكرة، و5 لسؤال نعم/لا.
الثمن هو أن الإجابة قد تُقطع. تحقق من resp.: length يعني أن الحد وصل قبل أن ينتهي النموذج. لماذا تتوقف إجابة AI في منتصف الجملة؟ يغطي ذلك. إذا بثثت الإجابة بدلًا من ذلك، تصل الكلمات الأولى مبكرًا ويبدو الانتظار أقصر، راجع بث الردود في Python.
ماذا تفعل إعادات المحاولة بالفاتورة#
إعادة المحاولة طلب جديد. إذا عولجت محاولة، فهي طلب منفصل برموزه الخاصة. لنفترض أن ملخص تذكرة يستهلك 1,500 رمز إدخال و400 إخراج: يكلف طلب واحد $0.000063 بأسعار اليوم، ولدى جدول الأسعار الكامل بقية النماذج. الأسعار ثابتة لكل نموذج، بلا ساعات ذروة، لذا تكلف إعادة المحاولة في الثالثة صباحًا مثل واحدة في الظهيرة.
حرّك المنزلقات إلى دفعتك الخاصة:
حاسبة التكلفة
دفعة من 1,000 ملخص تذكرة
رموز الإدخال لكل طلب: 1,500 · رموز الإخراج لكل طلب: 400 · الطلبات يوميًا: 1,000
| النموذج | يوميًا | شهريًا |
|---|---|---|
| GLM-5.3-Flash$0.02$0.04 | $0.046 | $1.38 |
| DeepSeek-V4-Flash$0.015$0.10 | $0.0625 | $1.88 |
| MiniMax-M2.7$0.05$0.15 | $0.135 | $4.05 |
يعرض الجدول تمريرة واحدة. إذا احتاج عُشر الدفعة إلى محاولة ثانية، أضف العُشر. إعادات المحاولة تأمين رخيص عندما تكون الإخفاقات نادرة، وعادة مكلفة عندما تضبط max_retries=10 مقابل نقطة نهاية تستمر في الفشل.
قبل أن تنشر#
قائمة التحقق
المهل وإعادات المحاولة، جاهزة للإنتاج



