عندما ينجح الطلب تقنيًا لكنه يفشل فعليًا
تخيّل أنك تتحدث مع الشخصية نفسها منذ أسابيع. صوتها مألوف، ولغتها متسقة، وردودها ذكية ومفعمة بالحياة.
ثم، من دون تغيير الشخصية أو النموذج، يبدأ شيء ما بالشعور على نحو خاطئ.
يستغرق الرد التالي عشر ثوانٍ حتى يبدأ. تتوقف فجأة ميزة تعتمد على المخرجات المنظّمة. تبدأ الشخصية بالهذيان، أو تُدخل مقاطع من لغة أخرى، أو ترد بأسلوب يبدو صادرًا عن نموذج أضعف بكثير.
من وجهة نظر الخادم، لم يفشل شيء. أعادت الواجهة 200 OK، ووصلت الـ tokens، واحتُسبت تكلفة الطلب.
أما من وجهة نظر المستخدم، فقد أصبح النموذج أسوأ فجأة.
هذه الفجوة هي ما دفعنا إلى بناء نظام مسبار كناري وعزل لمسارات المزوّدين في Reverie.
اسم نموذج واحد، وبيئات استدلال متعددة
OpenRouter هو بوابتنا الأساسية للنماذج. ومن نقاط قوته أن النموذج الواحد يمكن أن تقدّمه جهات استدلال مستقلة عديدة. فإذا تعذر أحد المزوّدين، يستطيع آخر معالجة الطلب. يمنحنا ذلك سعة أكبر وأسعارًا تنافسية وقدرة أعلى على الصمود مقارنة بالاعتماد على endpoint واحد.
لكنه يضيف أيضًا متغيرًا خفيًا.
قد يبقى اسم النموذج كما هو، بينما تتغير البنية التحتية التي تشغّله من طلب إلى آخر. فقد يستخدم كل مزوّد محرك استدلال أو عتادًا أو مستوى quantization أو parser أو قالب محادثة أو طابورًا أو طبقة سياسات إضافية مختلفة.
توضح وثائق توجيه المزوّدين في OpenRouter أن التوجيه الافتراضي يراعي التوفر الحديث والسعر، مع الاحتفاظ بمزوّدين آخرين كخيارات fallback. هذه إشارات مهمة، لكن قد يكون endpoint متاحًا ورخيصًا، ومع ذلك ينتج نتيجة غير مقبولة لمنتج بعينه.
وقد تحدث OpenRouter علنًا أيضًا عن فروق قابلة للقياس بين المزوّدين الذين يشغّلون النموذج نفسه. نظريًا، ينبغي للأوزان المتطابقة بالدقة نفسها أن تتصرف بصورة متشابهة. لكن تشغيل نموذج كبير في بيئة إنتاج عملية معقدة، ولذلك تظهر الفروق.
ماذا نعني بـ «تدهور النموذج»؟
«تدهور النموذج» ليس تشخيصًا معياريًا واحدًا، ولا يعني تلقائيًا أن المزوّد استبدل النموذج عمدًا بآخر أصغر.
نستخدم المصطلح بمعنى تشغيلي: يكون endpoint الاستدلال متدهورًا عندما يعجز عن الحفاظ على السلوك أو القدرات أو الأداء التفاعلي المتوقع من النموذج المطلوب مع prompts تمثيلية، حتى لو نجح الطلب من الناحية التقنية.
أوضح الأشكال بالنسبة إلى Reverie هي:
- تدهور زمن الاستجابة: ينجح الاتصال، لكن زمن وصول أول token يطول بما يكسر إحساس المحادثة الحية.
- تدهور القدرات: يعيد endpoint المفترض أن يدعم المخرجات المنظّمة نصًا تالفًا أو يتوقف عن مطابقة الـ schema.
- تدهور السلوك: تصبح الردود تالفة أو غير مترابطة أو مكررة بصورة غير متوقعة، أو تنحرف بوضوح إلى لغة أخرى.
- عدم توافق السياسات: يضيف المضيف طبقة فلترة خاصة به، فتحوّل مشهدًا تدعمه Reverie إلى رفض أو رد فارغ أو نص مبتور.
هناك أسباب محتملة كثيرة. قد تؤثر quantization منخفضة الدقة في prompts الصعبة، كما تشير وثائق OpenRouter والأبحاث المنشورة عن quantization. لكنها ليست تفسيرًا شاملًا: أخطاء محرك الاستدلال أو tool parser، ومشكلات tokenizer أو قالب المحادثة، والطوابير المثقلة، وmiddleware الخاص بالمزوّد قد تكون مهمة بالقدر نفسه. وقد لاحظ OpenRouter أن parsers في استدعاءات الأدوات تتسبب غالبًا بفروق أكبر من الدقة وحدها.
السؤال المهم ليس «أي سبب يبدو أكثر إثارة للشك؟»، بل «هل نستطيع عزل الـ endpoint وإعادة إنتاج الخلل؟».
حالتان جعلتا المشكلة ملموسة
لم يكن هذا قلقًا نظريًا بالنسبة إلينا.
في مقارنة ثبّتت كل طلب على مزوّد محدد، أفسد أحد المزوّدين بداية 19 ردًا من أصل 20 بإضافة علامة ترقيم أو جزء من token غير ذي صلة. وعبر أربعة عشر مضيفًا آخر يشغّلون النموذج نفسه، ظهر الخلل 0 مرة في 49 ردًا. وفي تقمص الأدوار يكون الحرف الأول غالبًا علامة تنسيق Markdown، ولذلك كان byte زائد واحد قادرًا على إفساد تنسيق الرد كله.
وفي اختبار آخر، أنتج endpoint واحد مزيجًا شديدًا بين البرتغالية والإسبانية في 3 من 3 عمليات توليد. ظل prompt نفسه باللغة البرتغالية لدى المضيف الرسمي للنموذج ولدى المضيفين الآخرين المختبرين من فئة الدقة نفسها. لم يعد القول إن «النموذج غير متسق بطبيعته» تفسيرًا مقنعًا؛ فالخلل كان يتبع الـ endpoint.
هذه الأعطال خفية لأنها لا تطلق exception بالضرورة. يرى رصد التوفر التقليدي واجهة سليمة، بينما يرى المستخدم شخصية فقدت فجأة القدرة على الكلام بصورة صحيحة.
إجابتنا: اختبار كل مسار، لا النموذج فقط
كل ثلاثين دقيقة، يكتشف نظام الكناري المزوّدين النشطين الذين يشغّلون نموذج المحادثة الافتراضي في Reverie. ثم يرسل إلى كل واحد مجموعة صغيرة من الطلبات الاصطناعية، مثبتة على ذلك المزوّد وحده مع تعطيل fallbacks.
التثبيت مهم. فإذا سُمح للمسبار بالانتقال إلى fallback، قد يخفي مزوّد ثانٍ سليم عطل الأول. نحتاج إلى معرفة بيئة الاستدلال التي أنتجت النتيجة بدقة.
يختبر النظام أربعة عقود محددة يمكن للحاسوب الحكم عليها.
1. زمن الوصول إلى أول token
في محادثة streaming، يمثل throughput نصف التجربة فقط. أول token هو ما يحدد مدة بقاء المستخدم أمام مؤشر التحميل.
نقيسه مباشرة من الـ stream. يفشل المزوّد في اختبار التأخير إذا لم ينتج نصًا خلال عشر ثوانٍ. الحد متساهل عن قصد، ولا تكفي جولة بطيئة واحدة لإزالة المضيف، فقد يحدث ضغط مؤقت على الطوابير.
2. الفلترة والرفض الصامت
نرسل تكملة ثابتة لتقمص الأدوار تمثل حركة الاستخدام التي تدعمها Reverie. يفحص المسبار سبب الانتهاء وأنماط الرفض عالية الثقة والمخرجات الفارغة.
ونشغّله أيضًا على مضيفين معروفين بالفلترة بوصفهم عينات ضبط إيجابية. إذا نجحت عينة منها بصورة غير متوقعة، فلا نعلن بقية المزوّدين سليمين؛ بل نضع علامة على أن المسبار نفسه أصبح ضعيفًا. الاختبار الذي لم يعد يكشف خلله المعروف ليس دليلًا على السلامة.
3. المخرجات المنظّمة
نطلب كائنًا صغيرًا وفق schema ثابتة ونتحقق من النتيجة. نتعامل مع خطأ النقل والمخرج التالف على نحو مختلف: انقطاع الاتصال يعني تعذر الوصول إلى المزوّد، أما اكتمال التوليد مع العجز عن مطابقة الـ schema فهو دليل على تراجع في القدرات.
«الـ endpoint يعلن دعم المعامل» و«الـ endpoint يلتزم به بصورة موثوقة» ليسا الوعد نفسه.
4. سلامة اللغة
تدعم Reverie سبع عشرة لغة للواجهة، ولذلك فإن smoke test باللغة الإنجليزية وحدها سيفوّت بعض الأعطال التي يواجهها مستخدمونا فعلًا.
يتناوب الكناري بين اللغات المدعومة باستخدام prompts اصطناعية لتقمص الأدوار. يبحث كاشف محلي وحتمي عن انتقال واضح للرد كاملًا إلى لغة أخرى، وعن مزج لغوي مستمر، وعن تلف واضح في الترميز. لا يستخدم محادثات حقيقية ولا يطلب من نموذج آخر إصدار حكم ذاتي.
يُعد المخرج الغامض أو القصير جدًا غير حاسم، لا فاشلًا. وعند اكتشاف خلل لغوي، ينفذ الكناري محاولتي تأكيد فوريتين ويتطلب أغلبية. ويكرر اللغة نفسها في الجولة التالية، فلا يستطيع المزوّد الإفلات من قاعدة الجولات المتتالية لمجرد أن الدور انتقل إلى لغة أخرى.
صممنا النظام كي يشك في استنتاجاته
إزالة سعة الاستدلال تلقائيًا مفيدة، لكن الإيجابية الكاذبة قد تصنع انقطاعًا أكبر من العطل الأصلي. لذلك يتضمن الكناري عدة مكابح:
- أخطاء النقل لا تُحسب كإخفاقات جودة. حالات timeout وrate limit واستجابات 5xx تجمّد النتيجة بدل دفع سلسلة الإخفاق نحو التعليق.
- جولة سيئة واحدة لا تكفي. يجب أن يفشل المزوّد في جولتين متتاليتين تُنفذان كل نصف ساعة.
- المراقبة والتنفيذ منفصلان. يمكننا تشغيل النظام في وضع المراقبة، وتسجيل المضيفين الذين كان سيجري تعليقهم، وإخطار المسؤولين وقياس الإيجابيات الكاذبة قبل تفعيل الإجراء الآلي.
- للسعة حد أدنى. لا يعلق الكناري مزوّدًا إذا كان ذلك سيترك أقل من مضيفين اثنين في الإنتاج، بل ينبه المسؤول.
- يُختبر التعافي أيضًا. يستمر اختبار المزوّدين المعلقين، وتعيد جولتان سليمتان متتاليتان المضيف مبكرًا.
- تتصاعد مدة الإخفاقات المتكررة تدريجيًا. يستمر التعليق يومًا في المرة الأولى، وثلاثة أيام في التالية، وسبعة أيام بعد ذلك. وبعد أربعة عشر يومًا من دون تعليق جديد، يتلاشى السجل ويبدأ السلم من جديد.
الهدف ليس معاقبة المزوّدين، بل إبعاد حركة المستخدمين عن مسار غير سليم يمكن إعادة إنتاج خلله، مع إبقاء طريق واضح للعودة عند إصلاح المشكلة.
ثلاث طبقات من الحماية
يجمع قرار التوجيه النهائي ثلاثة أنواع من الاستبعادات:
- استبعادات مدمجة خضعت للمراجعة لعيوب أو اختلافات سياسات قسناها ولا نريد إعادتها بالخطأ.
- استبعادات تشغيلية للحوادث يستطيع المسؤول إضافتها فورًا من دون انتظار deployment جديد.
- تعليقات مؤقتة يفرضها الكناري على المزوّدين الذين يتجاوزون حد الإخفاق الآلي.
تُدمج هذه القوائم في إعداد OpenRouter المسمى provider.ignore عند إنشاء Reverie للطلب. لا يحتاج المستخدم إلى تكرار المحاولة حتى يختار الحظ مزوّدًا أفضل؛ فالمسار غير السليم يخرج من قائمة المرشحين.
يُسجّل كل قرار آلي، ويتلقى المسؤولون إشعارًا عند التحولات المهمة، ويمكن رفع التعليق يدويًا عند الحاجة.
ما الذي يضمنه هذا النظام وما الذي لا يضمنه؟
نطاق الكناري ضيق عن قصد. يستطيع الكود تقييم التأخير وصحة الـ schema والفلترة عالية الثقة وسلامة اللغة والترميز. لكنه لا يدّعي القدرة على تقييم ما إذا كانت الشخصية طريفة بما يكفي، أو مدركة للمشاعر بما يكفي، أو وفية لشخصية معقدة.
لا تزال هذه الأسئلة الأوسع تحتاج إلى تقييمات مبنية على prompts تمثيلية، ومراجعة بشرية، وtelemetry الإنتاج، والأهم من ذلك كله بلاغات المستخدمين.
ولا يعني النظام أن كل رد غريب يثبت تدهور النموذج. فالنماذج التوليدية احتمالية، وقد تتراكم في المحادثة الطويلة سياقات متعارضة، وقد يحتوي تعريف الشخصية تعليمات متنافسة. أحيانًا يكون الرد الغريب مجرد رد غريب.
ما تغير هو أن عبارة «إنه النموذج نفسه» لم تعد نهاية التحقيق. أصبح بإمكاننا عزل المسار وإعادة إنتاج الإخفاقات الموضوعية وإبقاء الحركة اللاحقة بعيدًا عنه.
الموثوقية تعني الحفاظ على التجربة
يظل التوجيه عبر مزوّدين متعددين ذا قيمة كبيرة. فهو يمنح Reverie السعة والمرونة اللازمتين لإبقاء المحادثات متاحة عندما تتعطل endpoints منفردة.
لكن المرونة ليست مجرد تلقي استجابة HTTP. فالرد الذي يبدأ متأخرًا جدًا، أو يفقد بنيته المطلوبة، أو يرفض محتوى مدعومًا، أو يبدل اللغة فجأة، لا يصبح سليمًا لمجرد أن الفاتورة تقول إن الطلب نجح.
في منتج لشخصيات الذكاء الاصطناعي، تعني الموثوقية شيئًا أكثر إنسانية: يجب أن تظل الشخصية هي الشخصية نفسها، أيًا كانت الآلة التي تتحدث نيابة عنها.
هذا هو المعيار الذي صُممت وسائل حماية التوجيه الجديدة لدينا للحفاظ عليه.
إذا لاحظت تغيرًا مفاجئًا في جودة الرد أو لغته، فأرسل إلينا بلاغًا يتضمن اسم النموذج والوقت التقريبي. تساعدنا هذه المعلومات في ربط التجربة التي رأيتها بالمسار المحدد الذي قدّمها.

