ملاحظات من دورة الإصدار — الجزء الخامس
أكثر صفحة تمّ الاستشهاد بها ولم تُنشر في الربع الماضي كانت تلك التي أطلقها مراقبنا من تلقاء نفسه عند الساعة 2:14 صباحًا. كان الإصدار المرشّح قد اجتاز البوابة، ومكث عند 5% للدقائق الأربع المطلوبة، وتقدّم إلى 25%، ثم توقّف هناك. رصد مُراقب الجودة لكل دقيقة ثلاث قراءات متتالية دون العتبة على الشريحة الخاصة بالمجال القانوني، فأوقف الطرح، وأعاد توجيه التوجيه إلى الإصدار السابق. وبحلول وقت إطلاق إشعار مهندس المناوبة — للإيصال، لا لعطل — كانت حركة الإنتاج قد عادت إلى الإصدار المعروف بسلامته منذ تسع دقائق.
لم يكن على أحد أن يفعل شيئًا. تصف البنية المعمارية الواردة في المقال الأول من هذه السلسلة ماهية المراحل الأربع. هذا المقال يدور حول ما يعمل بين الموافقات البشرية — طبقة الأتمتة تحت البنية، الحدّ الذي عنده إمّا أن يفعل خط الأنابيب الصواب من تلقاء نفسه أو لا يفعل.
الادّعاء الرئيسي: ينبغي أن تكون معظم قرارات خط الأنابيب آلية، ولكن ليس كلّها. الحدّ مهم. خط الأنابيب الذي يُؤتمت كلّ شيء سيُرقّي في النهاية إصدارًا كان ينبغي لإنسان أن يلتقطه؛ وخط الأنابيب الذي لا يُؤتمت شيئًا لا غرض له. رسم هذا الحدّ بشكل صحيح هو ما يدور حوله هذا المقال.
طيف الأتمتة
يقع كل قرار في خط الأنابيب في مكان ما على طيف يمتدّ من “يُطلق من تلقاء نفسه دون أيّ إشعار بشري” إلى “يرفض المضيّ قُدُمًا دون موافقة موقّعة صراحةً.” أدناه موضع كل إجراء حامل للوزن في خط الأنابيب الذي شحنّاه على ذلك الطيف.
اثنان من العلامات أعلاه باللون الأحمر بدلًا من تلوينها وفق منطقتها. هذان هما القراران غير المتماثلين — الموضعان اللذان يتّخذ فيهما خط الأنابيب موقفًا حازمًا حول مَن يحقّ له تحديد ماذا. مُحفّز التراجع التلقائي يُطلَق دون أن يستأذن؛ ولا يمكنك تعطيله، لأن غاية وجوده هي أنه يعمل عند الساعة 2:14 صباحًا. تجاوز فشل البوابة يرفض التقدّم دون مبرّر مكتوب؛ ولا يمكنك تعطيله أيضًا، لأن غاية وجوده هي أن نفسك في المستقبل بحاجة إلى قراءة السبب. أمّا معظم بقية خط الأنابيب فقابل للتهيئة؛ هذان الاثنان ليسا كذلك.
كيف يُطلَق التراجع التلقائي فعليًا
السؤال الأكثر طرحًا عن التراجع التلقائي هو “ما الذي يمنعه من الانطلاق لسبب خاطئ؟” الإجابة الصادقة هي: لا شيء بمفرده. تأتي الحماية من طريقة توصيل المُحفّز.
تُشغّل مرحلة المراقبة حلقة تسجيل نقاط لكل دقيقة. كلّ دقيقة، فهي:
- تأخذ عيّنة من مجموعة صغيرة من آثار الإنتاج الحديثة من الإصدار النشط.
- تُعيد تشغيل كلّ أثر عبر النموذج النشط (لا المرشّح — نحن نُسجّل ما يخدم فعليًا).
- تُسجّل كل إعادة تشغيل باستخدام نفس الحَكَم المُعاير ذي المرجع البشري الذي قاد البوابة-2[1].
- تحسب درجة جودة مخرجات واحدة على العيّنة. تكتبها إلى
CanaryHealthSample.
يُطلَق التراجع عندما تنخفض ثلاث عيّنات متتالية لكل دقيقة دون عتبة التراجع (افتراضيًا: 0.85 من عتبة البوابة — أي 0.55 إذا كانت البوابة 0.65). ليس دقيقة سيّئة واحدة؛ بل ثلاث. الإغلاق ذو الثلاث دقائق هو مرشّح الضوضاء — قراءة شاذّة واحدة لا تُحفّز أيّ شيء، أمّا تراجع مستمرّ فيُحفّزه.
عندما ينقطع الإغلاق، يُنفّذ عامل التراجع:
# عمليًا — يُشغّل خط الأنابيب هذا من تلقاء نفسه. دون إقرار بشري.
POST /api/v1/releases/<previous_release_sha>/activate
# استجابة في أقل من ثانية؛ تصريف الطلبات الجارية في نحو 12 ثانية على خدمة بنحو 100 نسخةيُطلَق إيصال. يرى مهندس المناوبة إشعار Slack للإيصال، لا لعطل. يفتح الإيصال؛ فيرى القراءات الثلاث دون العتبة، والزمن المنقضي، وقيم تجزئة vindex_sha256_before/after[2]. اثنتا عشرة ثانية هي زمن تصريف الطلبات الجارية؛ أمّا التبديل نفسه فدون الثانية. بحلول الوقت الذي يكون فيه المهندس مستيقظًا بما يكفي ليسأل “هل عليّ أن أفعل شيئًا؟” تكون الإجابة “لا، ولكن عليك مع ذلك أن تنظر في سبب سماح البوابة بمرور هذا.”
إيصال التراجع التلقائي الفعلي
هكذا يبدو الإيصال في الإنتاج. بنفس التنسيق المتسلسل بالتجزئة الموثّق في صفحة الامتثال، مع الحقول الإضافية الخاصة بحدث تراجع تلقائي:
{
"kind": "auto_rollback",
"release_id": "rel_a01c66",
"previous_release_id": "rel_8f72b1",
"trigger_at": "2026-05-29T02:14:23Z",
"completed_at": "2026-05-29T02:14:35Z",
"elapsed_seconds": 12,
"trigger_reason": "observer_quality_threshold_breach",
"observer_readings": [
{ "minute_at": "2026-05-29T02:11:00Z", "quality_score": 0.523, "below_threshold": true, "slice": "legal-IP-licensing" },
{ "minute_at": "2026-05-29T02:12:00Z", "quality_score": 0.508, "below_threshold": true, "slice": "legal-IP-licensing" },
{ "minute_at": "2026-05-29T02:13:00Z", "quality_score": 0.491, "below_threshold": true, "slice": "legal-IP-licensing" }
],
"rollback_threshold": 0.55,
"active_manifest_sha256_before": "9abaeaf6c91f8b...",
"active_manifest_sha256_after": "8f72b1de4a93c5...",
"audit_chain_signature": "sha256(...)",
"notified_users": ["oncall@customer.example"],
"notification_sent_at": "2026-05-29T02:14:36Z"
}الإيصال نفسه هو أول نقطة تواصل لمهندس المناوبة. قراءته تُجيب على الأسئلة التي قد يطرحها مهندس نصف مستيقظ فعليًا: ما الذي حفّزه، وأيّ شريحة فشلت، وبأيّ قدر، وكم استغرق التبديل، وما الذي يعمل الآن. والإجراء التالي من هناك عادةً ما يكون “اذهب وانظر في سبب اجتياز البوابة لهذا في المقام الأول” — وهو ما يحتوي عليه إيصال الإصدار الفاشل أصلًا عبر جدول Spearman لكل شريحة.
ما الذي لا يفعله خط الأنابيب من تلقاء نفسه
النتيجة الطبيعية لقاعدة “التراجع التلقائي يُطلَق دون استئذان” هي أن بعض الأمور الأخرى لا تستطيع ذلك فعليًا. ثلاثة رفضات صريحة.
لا يُرقّي إصدارًا فشل في البوابة دون تجاوز موقّع. يضع فشل البوابة على الإصدار وسم gate_fail؛ وترفض نقطة النهاية /activate قبول تجزئة البيان؛ ولا تعمل أي صيغة من سطر الأوامر للالتفاف على هذا. الطريق الوحيد للأمام هو تجاوز قسري بـ forceGateOverride: true وoverrideReason: "<نص حر>". حقل السبب مطلوب، نصّ حرّ، ويُوضع في سجلّ التدقيق إلى جانب مُعرّف المستخدم. صمّمنا هذا حتى تستطيع نفسك في المستقبل قراءة سبب قبول نفسك الحالية تراجع شريحة. ثلاثة أشخاص استخدموا مسار التجاوز في الواقع. ما زالت مبرّراتهم في سجلّ التدقيق.
لا يتقدّم من الكناري إلى 100% إذا كانت أيّ مراقبة في تدهور. إذا كان تأخّر p95، أو معدّل 5xx، أو درجة جودة المخرجات خارج نطاقه عند نهاية مكوث نقطة التفتيش، يتوقّف خط الأنابيب عند تلك النقطة ويستدعي. لا يتقدّم ثم يعتذر لاحقًا.
لا يبدأ كناري تلقائيًا لإصدار بارد الانطلاق. الإصدار الذي لا يحمل تاريخًا من حركة الإنتاج — كصقل دقيق طازج على مجموعة بيانات جديدة كليًا، مثلًا — ليس لديه ما يُقارن جودة مخرجاته به. يرفض خط الأنابيب بدء كناري على إصدار بارد الانطلاق. نحن نشترط نشر ظلّ لمدة 24 ساعة أولًا، يُراقب المرشّح مقابل آثار إنتاج حقيقية ولكنه لا يُقدّم أيًّا من استجاباته. بعد 24 ساعة يكون لدينا خط أساس للجودة؛ ثم يمكن أن يمضي الكناري. أبطأ؛ صادق؛ غير قابل للتهيئة.
ما مدى سرعة التعافي، من البداية إلى النهاية؟
رقم زمن التعافي الذي ننشره هو 12 ثانية. ذلك هو تصريف الطلبات الجارية على خدمة بنحو 100 نسخة. أمّا تبديل البيان نفسه فدون الثانية. ولكي يكون مفيدًا للقارئ، تحتاج الاثنتا عشرة ثانية إلى تفكيك:
- من 0 إلى 60 ثانية قبل التراجع: تصل القراءات الثلاث المتتالية دون العتبة. تبدأ أوّل قراءة دون العتبة مؤقّت الإغلاق. تُمدّد كلّ دقيقة لاحقة الإغلاق إذا ظلّت الجودة دون العتبة.
- t = 0: تكتب القراءة الثالثة دون العتبة إلى
CanaryHealthSample. يرصد عامل التراجع الضربة الثالثة ويُرسل/activate previous_release. - t < ثانية واحدة: يقلّب مؤشّر الإصدار النشط في طبقة التوجيه (في Redis). تبدأ الطلبات الجديدة في الوصول إلى الإصدار السابق.
- t = 1 إلى ~12 ثانية: يستمرّ الإصدار المرشّح في خدمة أيّ طلبات كانت جارية عند حدوث التبديل. تصريف الطلبات الجارية. بعض الاستجابات المتدفّقة تستغرق 8 إلى 10 ثوانٍ لتكتمل طبيعيًا، فيكون ذيل التنظيف نحو 12 ثانية على خدمة نمطية.
- t ≈ 13 ثانية: يُكتب إيصال سجلّ التدقيق ويُوقّع. يُطلَق الإشعار.
بالمقارنة مع تشريحات ما بعد الحادثة العلنية التي نُواصل الاستشهاد بها كمراسي: استغرق عطل Cloudflare في يونيو 2022[3] 44 دقيقة من “نحن نعرف ما ينبغي التراجع عنه” إلى “اكتمل التراجع” — وكان ذلك على مستوى البنية التحتية. استغرق عطل Atlassian في أبريل 2022[4] 12 ساعة لكل موقع لأن الحالة كانت موزّعة على عدّة أنظمة. عتبة “صاحب الأداء النخبوي” لزمن التعافي من النشر الفاشل وفق DORA[5] موثّقة بأنها دون الساعة. اثنتا عشرة ثانية ليست أفضل من العتبة النخبوية بمرتبة من الحجم — بل أفضل بثلاث مراتب من الحجم. القرار المعماري الذي يجعل ذلك ممكنًا هو بيان الإصدار المُجمَّع من المرحلة 1. دون البيان، ليس لديك كائن واحد يمكنك إعادة توجيه التوجيه إليه.
تمارين التراجع — الممارسة غير البرّاقة التي لا يُجريها أحد
ها هو الجزء الذي تتخطّاه معظم الفرق: الإشارة الموثوقة الوحيدة على أن مسار تراجعك يعمل هي أنك أجريت تمرينًا متعمّدًا ومجدولًا وأكّدت ذلك. نُجري واحدًا كل ربع سنة. يسير التمرين كالتالي:
- اختر وقتًا في ساعات العمل خلال أيام الأسبوع، مُجدولًا عشوائيًا. أخبر الفريق أنه قادم، لكن دون الساعة المحدّدة.
- احقن تراجعًا اصطناعيًا في الجودة على شريحة الكناري. (لدينا علم وضع اختبار يجعل النموذج المرشّح يستجيب لرأس سحري بـ “أرفض الإجابة” — مضمون إفشاله للحَكَم المُعاير.)
- ادفع إصدار الاختبار عبر البوابة (يجتازها — نحن نختبر التراجع، لا البوابة). ابدأ كناريًا.
- يلاحظ المراقب ثلاث قراءات دون العتبة. يُطلَق التراجع التلقائي.
- انتظر تفاعل مهندس المناوبة. سجّل الوقت الذي يستغرقه. لاحظ ما إذا كان يثق بالإيصال بما يكفي لعدم الاتصال هاتفيًا منزعجًا.
- تحقّق من أن سجلّ التدقيق يُظهر علم وضع الاختبار في إيصال التراجع، حتى تستطيع عمليات التدقيق المستقبلية تمييز التمرين عن الحادثة الفعلية.
استغرق أوّل تمرين أجريناه 19 ثانية من البداية إلى النهاية (12 ثانية تبديل + 7 ثوانٍ من تأخير الاستقرار اضطررنا لإصلاحها). أمّا أحدث تمرين — الربع الأوّل من 2026 — فقد استغرق 12 ثانية. لا يحقّ تخطّي التمرين أبدًا. كل ربع سنة؛ لكل مجموعة عملاء.
معظم الفرق لم تُجرِ قطّ تمرين تراجع متعمّدًا. أوّل مرة يعمل فيها مسار تراجعها تكون أثناء حادثة حقيقية، تحت الضغط، مع عدّة أشخاص في المكالمة. التمرين هو ما يجعل رقم الاثنتي عشرة ثانية رقمًا حقيقيًا لا تطلّعيًا.
ما الذي لا يحلّه هذا
ثلاث قيود صادقة:
يمكن للتراجع التلقائي أن يتأرجح ذهابًا وإيابًا. إذا كان كلا الإصدارين المرشّح والسابق سيّئَين — فلنقل إن الإصدار السابق كان لديه أيضًا تراجع بطيء النموّ في شريحة لم يلتقطه أحد — يمكن لخط الأنابيب أن يتراجع، ثم يفشل الإصدار السابق أيضًا في مراقبه ما بعد التراجع، ولا يوجد إصدار ثالث للتراجع إليه. يوقف خط الأنابيب حركة المرور إلى صفحة صيانة بدلًا من التذبذب. الحلّ هو الإبقاء على أكثر من إصدار سابق سليم مفهرسًا في سلسلة البيان حتى يكون هدف التراجع قابلًا للتهيئة.
يُضيف المراقب تكلفة استدلال. إعادة تشغيل آثار الإنتاج عبر النموذج النشط على عيّنة 5% تُضيف تقريبًا 5% إلى إنفاق الاستدلال. نظنّ أنّ هذه هي المقايضة الصحيحة. يرى بعض العملاء أنّ ذلك مكلف للغاية على أعباء عمل ذات هامش منخفض ويرغبون في خفض معدّل العيّنة. القرص موجود.
حَكَم سيّئ أسوأ من غياب الحَكَم. إذا كان الحَكَم المُعاير الذي يُسيّر المراقب نفسه غير معاير — انحرف عن المرجع البشري، أو دُرّب على مدوّنة قديمة — يمكن للمراقب أن يُطلق تراجعًا تلقائيًا لسبب خاطئ. وتيرة إعادة المعايرة مهمة. توثّق قطعة معايرة-الحَكَم[6] الإجراء؛ والمطلب التشغيلي هو أن تُجريه فعليًا.
الأسئلة الشائعة
لماذا مُحفّز التراجع هو ثلاث دقائق متتالية بدلًا من واحدة؟
لأنّ درجات جودة LLM لها أرضية ضوضاء — يمكن لقراءة دقيقة شاذّة واحدة أن تأتي من خصوصية في العيّنة (حدث أن وقعت عيّنة آثار 5% على شريحة صعبة)، لا من تراجع حقيقي. إغلاق الثلاث دقائق هو أرخص مرشّح ضوضاء يُبقي مع ذلك زمن التفاعل الإجمالي دون دقيقة ونصف. ضبطنا في كلا الاتجاهين؛ ثلاث هي البقعة الحلوة لشكل حركة عملائنا النمطية. المكوث قابل للتهيئة لكل إصدار إذا كان شكل حركتك مختلفًا.
هل يجب أن يكون التراجع التلقائي قابلًا للضبط على “إيقاف”؟
في خط الأنابيب الذي نشحنه، لا. النقطة من امتلاك آلية أمان آلية هي أنها تعمل عند الساعة 2:14 صباحًا حين لا يُراقب أحد. تراجع تلقائي قابل لإيقافه هو ورقة لاصقة تقول “كان لدينا شبكة أمان”. الحجّة لجعله قابلًا للتهيئة هي أن بعض أعباء العمل ذات مخاطر منخفضة جدًا لا تُبرّر أيّ تراجعات إيجابية كاذبة. نظنّ أنّ هذه الحجّة تقود إلى المكان الخطأ — إذا كان عبء عملك ذا مخاطر منخفضة جدًا للتراجع التلقائي، فأنت لست بحاجة إلى خط أنابيب إصدار أصلًا.
كيف تتعاملون مع الحالة التي يكون فيها الإصدار السابق سيّئًا أيضًا؟
هدف التراجع هو previous_release افتراضيًا، ولكنّ سلسلة البيان تُخزّن تاريخًا أكثر من مجرد N-1. يستطيع المشغّلون إعادة توجيه التراجع إلى أيّ تجزئة بيان سليمة تاريخيًا — /api/v1/releases/<historically_good_sha>/activate — وهو مسار التدخّل اليدوي حين يُصادف تراجع N-1 التلقائي إصدارًا سابقًا سيّئًا. صمّام النجاة موجود. وهو نادر.
ما المقياس الصحيح للأمثلة — MTTR أم MTBF؟
MTTR — متوسّط زمن التعافي — بفارق كبير، على الأقل لأنظمة LLM. يفترض MTBF (متوسّط الزمن بين الأعطال) مفهومًا حتميًا لـ“الفشل“ لا تمتلكه أعباء عمل LLM. تنحرف جودة المخرجات باستمرار؛ و“الفشل“ هو نداء عتبة. يكون التحسين من أجل التعافي السريع متينًا بغضّ النظر عن موضع رسم العتبة؛ أمّا التحسين من أجل عدم الفشل أبدًا فهشّ وزائف. عتبة DORA النخبوية[5] مُؤطّرة هي نفسها بمصطلحات MTTR، وهو الإطار الصحيح.
هل تُجرون فعلًا تمارين تراجع؟
نعم — كل ربع سنة، مُجدولة، مع علم وضع اختبار في الإيصال حتى يمكن تمييز التمرين عن الحادثة الفعلية في سجلّ التدقيق. كشف أوّل تمرين أجريناه عن تأخير استقرار مدّته 7 ثوانٍ لم نكن ندرك وجوده. التمرين هو الطريقة الوحيدة لمعرفة أن المسار يعمل فعليًا؛ قراءة كتيّب التشغيل لا تكفي. معظم الفرق لم تُجرِ واحدًا، ولهذا فإن أرقام MTTR لمعظم الفرق تطلّعية لا مُقاسة.
المراجع
- معايرة LLM-as-judge. Zheng وآخرون، Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (NeurIPS 2023). المرجع لسبب ضرورة وجود حَكَم مُعاير ولماذا يهمّ التوافق لكل شريحة أكثر من التوافق الإجمالي. تعتمد حلقة التسجيل لكل دقيقة لدى المراقب على هذا.
- شهادة أوزان vindex. موثّقة في صفحة امتثال Divinci وتُستعرض في مقال المجالات الخاضعة للتنظيم. حقول `vindex_sha256_before/after` في إيصال التراجع التلقائي هي المرساة التشفيرية التي يستطيع المدقّق التحقّق منها دون الثقة بسجلّاتنا.
- عطل Cloudflare في يونيو 2022. Cloudflare outage on June 21, 2022. "06:58: تمّ العثور على السبب الجذري وفهمه. يبدأ العمل على التراجع عن التغيير الإشكالي… 07:42: اكتمل آخر التراجعات." أربع وأربعون دقيقة للتراجع على مستوى البنية التحتية، جزئيًا لأن المهندسين داسوا على تراجعات بعضهم البعض. مرساة ادّعاء "التبديل المُسيَّر بالبيان لا يمكنه امتلاك ذلك النمط من الفشل".
- عطل Atlassian في أبريل 2022. Post-Incident Review: April 2022 Outage. 12 ساعة لكل موقع للاستعادة، و14 يومًا إجماليًا لـ 883 موقعًا، لأن الحالة كانت موزّعة على أنظمة مُصدَرة بصورة مستقلة. مرساة ادّعاء "بيان الإصدار المُجمَّع هو الشيء الذي يجعل ثوانٍ-لا-ساعات ممكنًا".
- عتبة DORA للتعافي من النشر الفاشل. DORA — Software delivery performance metrics. موثّقة عتبة "صاحب الأداء النخبوي" لـ"زمن التعافي من النشر الفاشل" بأنها دون الساعة. رقم الاثنتي عشرة ثانية لخط الأنابيب هو ثلاث مراتب من الحجم تحت العتبة النخبوية، وهي الطريقة الصحيحة لقراءة المقارنة.
- Calibrating the AI judge. مقالنا الرفيق Calibrating the AI Judge. الإجراء للحفاظ على معايرة الحَكَم ذي المرجع البشري عبر الزمن. الادّعاء التشغيلي في هذا المقال — بأنّ التراجع التلقائي لا يعمل إلا بقدر جودة الحَكَم الذي يُسيّره — لا يصمد إلا إذا كانت إعادة معايرة الحَكَم تجري دوريًا فعلًا.
- داخلي — مرجع خط أنابيب Divinci. البنية التي تقع تحتها طبقة الأتمتة هذه: مقال خط الأنابيب ذي المراحل الأربع. سطح API الكامل موثّق في مرجع API؛ قسم إدارة الإصدار هو الذي يدور حوله هذا المقال.
التالي في هذه السلسلة: اختبار CI لنماذج اللغة المخصّصة في 2026. هذا المقال يدور حول الطبقة التشغيلية بين الموافقات البشرية. أمّا التالي فهو الطبقة التي تسبق بدء خط الأنابيب — CI ما قبل الدمج: ما الذي تُقيّمه عند وقت طلب السحب، وأيّ أنواع التراجعات تلتقطها فعليًا قبل أن تراها البوابة، وأيّها لا تلتقطها.
هل أنت مستعد لبناء حل الذكاء الاصطناعي المخصص؟
اكتشف كيف يمكن لـ Divinci AI مساعدتك في تطبيق أنظمة RAG وأتمتة ضمان الجودة وتبسيط عملية تطوير الذكاء الاصطناعي.
ابدأ اليوم