Batch API للـ AI: شغّل المهام بالليل بنصف التكلفة
لو عندك 100 ألف مهمة AI غير عاجلة، Batch API يخليك تشغّلها بهدوء خلال الليل وتدفع أقل بدل ما تحرق الميزانية على طلبات متزامنة.
مستوى القارئ: متوسط
المشكلة باختصار
الطريقة الشائعة إنك تبعت كل صف في CSV كطلب API عادي. ده مفهوم لو المستخدم مستني الرد الآن. لكنه بيبقى اختيار غالي لو المهمة أصلًا مش مستعجلة: تصنيف تذاكر دعم، تلخيص مراجعات منتجات، تنظيف أوصاف كتالوج، أو استخراج حقول من مستندات داخلية.
اللي بيحصل فعلاً إن السيرفر عندك يبدأ يعمل queue داخلية، retry logic، rate limit handling، ومراقبة فشل. بعد شوية تلاقي نفسك بنيت نصف Batch API بنفسك. الطريقة دي بتفشل لما العدد يكبر لأنك بتنافس traffic المستخدمين على نفس الـ rate limits، وبتدفع سعر المعالجة المتزامنة رغم إنك موافق تستنى.
الافتراض هنا إن عندك مهام كثيرة، النتيجة مطلوبة خلال ساعات، وليس خلال ثواني. مثال واقعي: متجر عنده 80 ألف مراجعة منتج جديدة في نهاية الأسبوع، وعايز يصنفها إلى شكاوى جودة، شحن، سعر، أو تجربة استخدام قبل اجتماع الاثنين.
الفكرة بمثال بسيط
ركز في التشبيه العملي: بدل ما تقف على الشباك تطلب 10 آلاف ورقة واحدة واحدة، تسيب ملف مرتب فيه كل الطلبات، وترجع بعد ما الموظف يخلصهم. أنت خسرت السرعة اللحظية، لكن كسبت سعر أقل وتنظيم أوضح.
في OpenAI، Batch API مبني على ملف JSONL ترفعه بغرض batch، وبعدها تنشئ batch بنافذة معالجة. وثائق OpenAI تذكر إن المعالجة غير المتزامنة تتم خلال 24 ساعة وبخصم 50% مقارنة بالطلبات المتزامنة. في Anthropic، Message Batches تعمل بفكرة مشابهة، وتدعم مجموعات كبيرة من الطلبات مع نافذة قد تصل إلى 24 ساعة، وتعرض docs التسعير كخصم 50% على input وoutput tokens.
المهم هنا: Batch API مش موديل جديد. هو طريقة تشغيل مختلفة لنفس نوع المهام. بتكسب تكلفة وسعة تشغيل، وبتخسر زمن الاستجابة الفوري.
مثال تنفيذي: ابنِ ملف JSONL
المثال التالي يحوّل ملف مراجعات إلى JSONL مناسب لفكرة batch. استخدمه كنقطة بداية، وعدّل الـ endpoint والـ model حسب مزودك وحسب التوثيق الحالي.
import csv
import json
input_csv = "reviews.csv"
output_jsonl = "batch_reviews.jsonl"
with open(input_csv, newline="", encoding="utf-8") as src, \
open(output_jsonl, "w", encoding="utf-8") as out:
reader = csv.DictReader(src)
for row in reader:
review_id = row["review_id"]
review_text = row["review_text"][:4000]
task = {
"custom_id": f"review-{review_id}",
"method": "POST",
"url": "/v1/responses",
"body": {
"model": "gpt-5.4-mini",
"input": [
{
"role": "system",
"content": "صنف المراجعة إلى: جودة، شحن، سعر، تجربة استخدام. أعد JSON فقط."
},
{
"role": "user",
"content": review_text
}
]
}
}
out.write(json.dumps(task, ensure_ascii=False) + "\n")
print(f"wrote {output_jsonl}")