الخلاصة
- بدأت OpenAI التحقيق عند 00:55:27 بالتوقيت العالمي في ارتفاع أخطاء واجهات البرمجة التي تحمل رمز
invalid_prompt. - قالت الشركة عند 01:39:33 إنها طبقت معالجة وتراقب التعافي، ثم أعلنت عند 02:20:19 استعادة كل الخدمات المتأثرة؛ واستغرق السجل العلني 1 ساعة و24 دقيقة و52 ثانية.
- لا ينشر سجل الحادثة حالة HTTP؛ وبشكل منفصل تربط حزمة Python الرسمية الحالة 400 الفعلية بفئة
BadRequestErrorولا تضعها ضمن الإعادة المعتادة. - لا يجوز للعميل أن يهمل كل مهمة تحمل الاسم، ولا أن يعيدها كلها بلا حد؛ المطلوب حالة انتظار تحفظ الدليل وتفحص سلامة التكرار.
- لم تكشف OpenAI السبب الجذري أو نسبة الفشل أو المناطق أو النماذج أو نقاط النهاية أو عدد الطلبات والعملاء، لذلك لا يمكن نسبة كل خطأ مماثل خلال الفترة إلى الحادثة.
تعتمد الواجهات على عقد ضمني يتجاوز صيغة JSON. فاسم الخطأ يخبر العميل بما ينبغي أن يفعله ومن يملك الخطوة التالية. عندما يقول الرد إن المدخل غير صالح، يفترض النظام أن الإصلاح عند المطور. وعندما يقول الخادم إنه يعاني خطأ داخليا، ينتظر العميل أو يعيد المحاولة.
في هذه الحادثة لم يتطابق الاسم مع مكان المعالجة المعلن. رفعت OpenAI حالة خدمة، حققت في المشكلة وطبقت تخفيفا، مع أن الرمز الظاهر يوجه اللوم نحو الطلب. هنا لا تختفي المسؤولية، لكنها تنقسم بطريقة لا يستطيع برنامج بسيط قراءتها من رقم الحالة وحده.
على المزود أن يحدد الحادثة من دون ملء الفراغ بالتخمين
يقدم سجل OpenAI ثلاث نقاط زمنية دقيقة: التحقيق، ثم المعالجة والمراقبة، ثم التعافي. ويحدد APIs مكونا متأثرا ويصنف الأثر بأنه minor. هذه المعلومات تمنح العملاء نافذة للمراجعة وإشارة رسمية إلى أن الظاهرة لم تكن مجرد خطأ محلي منفرد.
لكن السجل لا يشرح لماذا ظهر الخلل باسم invalid_prompt. ولا يذكر جذرا تقنيا أو نطاقا جغرافيا أو قائمة بالنماذج ونقاط النهاية. كما لا يقدم مقاما لقياس نسبة الأخطاء أو عددا للعملاء.
لذلك لا يحق للعميل أن يكتب سببا نيابة عن المزود. تزامن خطأ مع النافذة الرسمية يقوي الاشتباه، لكنه لا يثبت أن كل طلب صحيح أو أن كل استجابة 400 جاءت من العطل نفسه. قد توجد مدخلات خاطئة حقيقية في الوقت ذاته.
على العميل أن يحفظ المهمة قبل توزيع اللوم
المسؤولية الأولى لدى العميل هي ألا يحول تشخيصا أوليا إلى فقد دائم. يمكن نقل العمليات غير المعتادة إلى قائمة انتظار تحفظ وقت UTC ونقطة النهاية والنموذج وإصدار الحزمة ورمز الخطأ وعدد المحاولات.
توضح وثائق حزمة Python أن معرّف الطلب متاح في استثناءات APIStatusError الفاشلة. هذا المعرف يساعد المزود والعميل على الحديث عن معاملة واحدة بدلا من رسالة عامة ظهرت آلاف المرات.
ويمكن للعميل حفظ بصمة غير قابلة للعكس لبنية الطلب كي يثبت أن الشكل نفسه كان يعمل سابقا. لا ينبغي نسخ نص المطالبة أو المفاتيح أو البيانات الشخصية إلى سجل الحادثة. الاستجابة لمشكلة توافر لا تبرر توسيع خطر الخصوصية.
عدم الإعادة التلقائية لا يعني عدم المراقبة
تحول الحزمة الرسمية HTTP 400 إلى BadRequestError. وتعيد افتراضيا بعض أخطاء الاتصال و408 و409 و429 والحالات من 500 فما فوق، مع مراعاة توجيه صريح مثل x-should-retry. أما 400 العادية فلا تدخل المسار المعتاد. هذه قاعدة شرطية عند تلقي 400 فعلا، وليست دليلا على حالة استجابات الحادثة.
هذه قاعدة سليمة في التشغيل اليومي. إرسال مدخل سيئ مرات أخرى لا يصححه، وقد يهدر السعة ويخفي عيبا في التطبيق. ولا تبرر حادثة واحدة إضافة كل أخطاء 400 إلى حلقة إعادة آلية.
المشكلة تظهر عندما يعامل النظام «لا تعيد» على أنها «لا تراقب». يجب أن يملك حتى الخطأ الدائم خط أساس وإنذارا عند الارتفاع المفاجئ. إذا تزامن الارتفاع مع سجل رسمي وكان شكل الطلب معروفا بالنجاح، تتغير الحالة إلى انتظار محكوم، لا إلى نجاح مفترض.
الاستعادة مسؤولية مشتركة ولكن قرار التكرار محلي
يعلن المزود متى يعتقد أن الخدمة عادت، لكنه لا يعرف كل أثر في عمليات العميل. ربما ألغي تقرير، أو أرسل مستخدم الطلب إلى خدمة بديلة، أو نفذت خطوة لاحقة رغم ضياع الاستجابة.
قبل التكرار، يفحص العميل هل العملية آمنة إذا حدثت مرتين. ويبدأ باختبارات قليلة ثم يفتح الطابور تدريجيا مع حد للسرعة والعدد. وإذا كان هناك أثر خارجي مثل نشر أو إخطار أو تحديث سجل، يبحث أولا عن نتيجة المحاولة الأصلية.
لا يمكن لصفحة الحالة أن تتخذ هذا القرار بدلا عنه. كما لا يمكن للعميل أن يطلب من المزود ضمان عدم التكرار إذا لم يمنح العملية مفتاحا ثابتا وسجلا يربط المحاولات بالنتيجة التجارية.
إعلان التعافي يغلق سجل المزود لا سجل العميل
عند 02:20:19 قالت OpenAI إن الخدمات المتأثرة تعافت بالكامل. يعني ذلك إغلاق الحالة العامة. ولا يعني أن الطلبات التي صنفها العميل نهائية عادت، أو أن قائمة الأعمال الفاشلة أعيدت، أو أن كل حساب رأى التعافي في اللحظة نفسها.
تحذر صفحة الحالة أيضا من أن المقاييس مجمعة عبر الشرائح والنماذج وأنواع الأخطاء، وقد تختلف تجربة العميل بحسب الطبقة والميزة. ومن ثم فإن 1 ساعة و24 دقيقة و52 ثانية هي مدة السجل العلني، لا مدة انقطاع موحدة لكل مستخدم.
يحتاج العميل إلى إغلاق مستقل: فصل المدخلات الخاطئة فعلا، وحصر الطلبات المحتمل تأثرها، وإعادة الآمن منها مرة محدودة، ثم التحقق من النتيجة ومن غياب آثار مكررة. إذا بقيت مهمة في حالة مجهولة، فالتعافي التشغيلي لم يكتمل حتى لو اختفت اللافتة.
المسؤولية المشتركة تحتاج لغة لا تخدع الآلة
الدرس الأوسع يخص تصميم عقد الخطأ. إذا أمكن لخلل عند المزود أن يظهر باسم يحمل معنى محددا عن العميل، فعلى المزود أن يشرح لاحقا سبب العبور وما إذا كان سيغير التصنيف أو الإشارة. لم تنشر OpenAI هذا التفسير بعد.
وفي المقابل، على العملاء ألا يبنوا قرارا غير قابل للمراجعة على الاسم وحده. الحالة الصحيحة بين الرفض الدائم والتكرار الأعمى هي شك موثق: دليل محفوظ، إشارة رسمية، اختبار محدود، ثم مصالحة.
لا يثبت السجل من أخطأ في كل طلب، ولا يثبت أن الاستجابات كانت 400. لكنه يثبت أن حدود المسؤولية التي يفهمها الإنسان قد لا تطابق الحدود التي برمجت عليها الأتمتة. إصلاح هذا الفرق مسؤولية يتقاسمها الطرفان، حتى عندما يظل السبب التقني غير معلن.


