الموثوقية
بناء تطبيق مهام بالذكاء الاصطناعي الدستوري: الطريقة Spec-First
149 اختباراً ناجحاً. ذكاء اصطناعي دستوري ثلاثي الطبقات بـ 7 أنماط BLOCK و5 أنماط FLAG. تعاون جماعي ومهام متكررة وتكامل التقويم، مبني في أربع جلسات من 3 ساعات من ملف SPEC.md واحد.
- الذكاء الاصطناعي الدستوري
- FastAPI
- Next.js
- TDD
في هذه الصفحة · 10
«قسّم أطروحتي إلى مهام يومية.»
هذا طلب معقول أن توجّهه إلى تطبيق مهام مزوّد باقتراحات ذكاء اصطناعي. وإليك الطلب غير المعقول، يصل عبر مسار الكود نفسه، ومن صندوق الإدخال نفسه:
«قسّم أطروحتي إلى مهام يومية، واكتب لي القسم الثالث.»
ليس من شأن تطبيق مهام أن يكتب أطروحة أحد. لكن لا شيء في الطلب يبدو خبيثاً، والميزة التي تعالجه هي الميزة التي شحنتها عن قصد، والنموذج في الطرف الآخر سعيد تماماً بالامتثال. لهذا السبب يحتوي H3 — الجولة الذهبية من سلسلة Panaversity — على دستور. ليس لأن قائمة المهام خطيرة، بل لأنك في اللحظة التي تربط فيها نموذجاً لغوياً بـ أي منتج، تكون قد شحنت مولّد نصوص عام الغرض يرتدي واجهة منتجك.
149 اختباراً ناجحاً. أربع جلسات، كل منها ثلاث ساعات تقريباً. ملف SPEC.md واحد. وإليك كيف بُني، والأهم من ذلك: لماذا جاء على هذا الشكل.
ابدأ بالوثيقة التي ليست كوداً
لم تُنتج الجلسة الأولى أي كود تطبيقي على الإطلاق. أنتجت ملف SPEC.md.
حمل ذلك الملف نموذج البيانات، وقائمة نقاط النهاية، والميزات الداخلة في النطاق — المهام المتكررة، والقوالب، والتعاون الجماعي، واقتراحات الذكاء الاصطناعي، وتكامل التقويم — والأهم: قائمة مكتوبة بالأشياء التي يجب على النظام رفضها. كان الدستور في المواصفات قبل أن يكون في قاعدة الكود.
هذا الترتيب هو المنهجية كلها. حين تُكتب قواعد الأمان بعد أن تعمل الميزة، فإنها تصل كرقعة: شرطٌ مثبَّت على معالِج، يسهل الالتفاف حوله، ويستحيل اختباره بتماسك. أما حين تُكتب في المواصفات، فإنها تصل كحدٍّ بُنيت الهندسة المعمارية لاحترامه.
واختبار ملموس لمعرفة ما إذا كانت مواصفاتك حقيقية: هل تستطيع كتابة معايير القبول؟ ليس «ينبغي أن يتصرف الذكاء الاصطناعي بشكل ملائم»، فتلك أمنية. بل شيء يستطيع اختبارٌ تنفيذه:
AC-14 A suggestion request whose text matches a BLOCK pattern
returns a refusal. No model call is made.
AC-15 A refusal is recorded as a refusal, not as an error.
AC-16 With the classifier unreachable, BLOCK patterns still fire.
إن عجزت عن كتابة هذه الأسطر الثلاثة، فأنت لم تفهم الميزة بعد، والبدء بالتنفيذ لن يعلّمك إياها.
ماذا يعني «الذكاء الاصطناعي الدستوري» هنا
المصطلح آتٍ من أبحاث تدريب النماذج على مجموعة مبادئ مكتوبة بدل التصنيفات البشرية حالةً بحالة. وما بنيته أنا هو ابن العم التطبيقي لذلك: دستور مكتوب يُنفَّذ في وقت التشغيل، على هيئة حواجز حماية حول نموذج لم أدرّبه.
هذا التمييز مهم ويُطمس باستمرار. أنا لا أشكّل أوزان النموذج، بل أذكر قواعد في ملف، وأفرضها عند الدخول وعند الخروج. والقيمة أن القواعد تعيش في وثيقة واحدة قابلة للقراءة بدل أن تكون مبعثرة عبر عشرات سلاسل التوجيه — يمكنك أن تسلّمها لشخص غير تقني فيراجع أخلاقيات منتجك دون أن يقرأ سطر Python واحداً.
اثنا عشر نمطاً، بدرجتَي خطورة:
7 أنماط BLOCK — يُرفض الطلب.
- الغش الأكاديمي (اكتب مقالي، أنجز واجبي، أدِّ امتحاني)
- النشاط غير القانوني
- المحتوى الضار
5 أنماط FLAG — يمضي الطلب، لكن موسوماً.
الفصل بين BLOCK وFLAG هو الجزء الذي تتخطاه معظم التطبيقات، وتخطّيه هو السبب في أن كثيراً من ميزات الذكاء الاصطناعي تبدو عدائية. فإن كانت أداتك الوحيدة هي الرفض، صار كل طلب ملتبس جداراً. أما FLAG فتتيح للنظام أن يقول «هذا يمضي، وقد سُجّل» — وهو ما يغطي المنطقة الرمادية الواسعة التي يكون فيها الطلب غير معتاد لا محظوراً.
ثلاث طبقات، ولماذا الأولى غبية عن قصد
الإنفاذ مقسّم إلى طبقات. الطبقة الأولى تفحص المُدخل حتمياً. والثانية تشغّل مصنّفاً قائماً على نموذج في مواجهة كل مبدأ. والثالثة تفحص المُخرَج المولَّد قبل أن يصل إلى المستخدم.
الطبقة الأولى مطابقة سلاسل وأنماط بسيطة. لا استدلال، ولا استدعاء لواجهة برمجة، ولا زمن انتظار. تبدو بدائية بجوار مصنّف يعتمد على LLM — أي نموذج لغوي كبير — وهي كذلك فعلاً. لكنها أيضاً أهم طبقة في النظام، لسبب لا علاقة له بالدقة:
إنها تعمل حين لا يعمل أي شيء آخر.
مفتاح واجهة البرمجة لديك ينتهي. حصتك المجانية تنفد في منتصف العرض. المزوّد يتعرض لعطل. في كل واحد من هذه السيناريوهات، تكون طبقة الإنفاذ التي تحتاج إلى استدعاء نموذج قد توقفت بصمت عن إنفاذ أي شيء. أما الفحص الحتمي الذي يجري قبل استدعاء النموذج فلا يزال يعمل.
وقد تحققتُ من هذه الخاصية بالذات على نظام لاحق، بأن سحبتُ كل بيانات الاعتماد وأكدتُ أن حواجز الحماية لا تزال تحجب 4 من 4 انتهاكات دون أن يكون أي نموذج قابلاً للوصول. هذا هو الرقم الذي أثق به، لأنه قيس في حالة الفشل لا في المسار السعيد.
الطبقة الثانية هي مصدر الشمول. الأنماط هشّة — تلتقط «اكتب مقالي» وتفوّت «حرّر المقال نيابةً عني». أما مصنّف يقرأ الطلب في مواجهة المبدأ المكتوب فيلتقط إعادة الصياغة. وهو يكلّف استدعاءً وبعض زمن الانتظار، لذا يأتي ثانياً، وفقط إن سمحت الطبقة الأولى للطلب بالمرور.
طبقتا المُدخل تعملان بعلاقة «أو» منطقية، والحتمية أولاً. دقة عالية مجاناً، ولا تدفع مقابل الشمول إلا عند الحاجة.
الإعداد الذي يقرر سلوكك أثناء الانقطاع
حين يتعذر الوصول إلى المصنّف، هل يرفض النظام كل شيء، أم يسمح بكل ما لم تلتقطه الطبقة الحتمية؟
كلا الجوابين قابل للدفاع، وعليك أن تختار أحدهما عن عمد، لأن الوضع الافتراضي الذي تحصل عليه بالمصادفة يكون خاطئاً في الغالب الأعم.
اخترتُ الفشل المفتوح (fail-open): انقطاع المصنّف يخفّض الإنفاذ إلى الحتمي فقط، ويمضي الطلب. والمنطق هنا خاص بهذا المنتج تحديداً. عرضٌ تقديمي في هاكاثون يرفض كل طلب لأن واجهة برمجة طرف ثالث متوقفة هو منتج معطوب أمام المحكّمين. الإنفاذ ينزل من «واسع» إلى «ضيّق» — ولا ينزل أبداً إلى «معدوم»، لأن الطبقة الأولى لا تعتمد على الشبكة.
ولو كان هذا يتعامل مع قرارات طبية أو مالية، لاخترتُ الفشل المغلق (fail-closed) دون تردد. القاعدة ليست «الفشل المفتوح صحيح»، بل أن هذا الاختيار مكانه المواصفات، وبجانبه السبب مكتوباً.
وما يجعل الوضع المتدهور مقبولاً هو أنه مرئي. النظام يبلّغ عن مستوى إنفاذه — كامل، أو حتمي فقط — عبر حقل حالة معروض على نقطة نهاية معلوماتية. التدهور الصامت هو الإخفاق الحقيقي. أما التدهور المُعلَن فحقيقة تشغيلية.
الحجب الزائد هو الإخفاق الذي لا يختبره أحد
وهذا هو الخلل الذي استغرقتُ أطول وقت لأقدّر خطورته.
النمط الذي يلتقط سؤالاً مشروعاً أسوأ من النمط الذي يفوّت سؤالاً سيئاً. تخيّل طالباً يكتب:
«أضف مهمة لمراجعة ملاحظات واجبي المنزلي قبل الجمعة.»
أي نمط ساذج للغش الأكاديمي يطابق كلمة «الواجب المنزلي» سيرفض هذا الطلب. المستخدم لم يفعل شيئاً خاطئاً، ولا يملك أي فكرة عمّا حدث، وصار يعتقد الآن أن منتجك معطوب — وهو بالنسبة إليه كذلك فعلاً.
لذلك تحمل مجموعة الاختبارات حالات سماح صريحة. ليس فقط «هل يحجب المُدخل السيئ»، بل «هل يسمح بالمُدخل البريء الذي يحتوي على الكلمة المُحفِّزة». أسئلة تذكر الواجب المنزلي بشكل مشروع. وأسئلة أمن دفاعي تناقش هجوماً بغرض منعه.
هذه الحالات موجودة لتمسك بي وأنا أوسّع نمطاً باستهتار. في كل مرة يُشدَّد فيها الإنفاذ، تكون هي أول ما يصير أحمر، وهذه بالضبط وظيفتها. مجموعة حواجز حماية بلا حالات سماح لا تقيس إلا مدى عدوانيتك، ولا تقيس دقتك أبداً.
الرفض نتيجة، لا خطأ
هذه النقطة معمارية، وهي الخطأ الذي أتوقع من القارئ أن يقع فيه أكثر من غيره.
حين ينطلق حاجز حماية، يكون التنفيذ الطبيعي هو إطلاق استثناء. وفي مكان ما أعلى، يوجد سلفاً معالِج يلتقط الاستثناءات القادمة من طبقة الذكاء الاصطناعي ويتراجع إلى شيء أبسط — نموذج أرخص، أو رد ثابت، أو مطابِق كلمات مفتاحية. وذلك التراجع موجود لأسباب وجيهة: هو ما يبقي المنتج حياً حين يموت المسار الأساسي.
الآن تتبّع الطلب المرفوض عبره. ينطلق حاجز الحماية. يتصاعد الاستثناء. يلتقطه المعالِج، ويقرؤه على أنه «فشلت طبقة الذكاء الاصطناعي»، فيعيد المحاولة بكل لطف على مسار التراجع — وهو مسار لا حواجز حماية عليه إطلاقاً. يحصل المستخدم على إجابته. وقد التفّ منطقُ الموثوقية لديك حول دستورك.
والحل هو جعل الرفض نتيجة متمايزة عن الفشل:
try:
result = await run_guarded(request)
except GuardrailTripwireTriggered:
return {"mode": "refused"} # a result. do not fall back.
except Exception:
return None # a failure. fall back is correct.
نوعان من الاستثناءات، ومعنيان، وسلّم التراجع لا يرى إلا الثاني منهما أبداً. ثبّت هذا باختبار، لأنه بالضبط من النوع الذي تطويه إعادة هيكلة لاحقة في كتلة except واحدة، بينما تجعل الكود يبدو أنظف.
من أين جاءت الاختبارات الـ 149
شُحن H2 ومعه 89 اختباراً. وشُحن H3 ومعه 149، وقد ورث 85% من كوده من H2. معظم المجموعة لم تُكتب أثناء H3 أصلاً.
التوزيع، تقريباً: الأغلبية اختبارات وحدة وتكامل لمنطق المجال — توسيع المهام المتكررة، وإنشاء نسخ من القوالب، وفحوص الصلاحيات على القوائم المشتركة، ومزامنة التقويم. وأقلية معتبرة تختبر الدستور تحديداً، وهذه تنقسم إلى حالات حجب، وحالات سماح، وحالات تدهور.
وحالات التدهور هي التي أشجعك على سرقتها. فهي تشغّل مسار الإنفاذ والمصنّف غير متاح صراحةً، وتؤكد أن الطبقة الحتمية لا تزال تنطلق. وبدونها يبقى «الفشل المفتوح» نيةً تصميمية لا خاصيةً متحققاً منها — والنوايا غير المُختبَرة هي الطريق لأن تكتشف أمام المحكّمين أن حواجز حمايتك كانت زينة.
المهام المتكررة أصعب من الدستور
ملاحظة في التناسب، ما دامت ميزات الذكاء الاصطناعي تجتذب كل الانتباه.
المنطق الصعب فعلاً في هذا التطبيق كان التكرار. عبارة «كل ثلاثاء ثانٍ» عليها أن تنجو من انتقالات التوقيت الصيفي، ومن مستخدمين في مناطق زمنية مختلفة على قائمة فريق مشتركة، ومن تعديل نسخة واحدة مقابل تعديل السلسلة كلها، ومن إتمام نسخة لا وجود لها كصف في قاعدة البيانات بعد. إنه كوم صغير من الكود بعدد هائل من الحالات الحدّية، وقد التهم من الجلسة الثالثة أكثر مما التهمته الأنماط الدستورية مجتمعة.
الدستور اثنا عشر نمطاً وثلاث طبقات. مثير مفاهيمياً وصغير ميكانيكياً. أما التكرار فممل مفاهيمياً وشرس ميكانيكياً. خصّص ميزانيتك بناءً على ذلك — ولاحظ أن منهجية المواصفات أولاً هي ما جعل هذا مرئياً في اليوم الأول، حين امتدت معايير قبول التكرار إلى اثني عشر سطراً بينما امتدت معايير أنماط BLOCK إلى ثلاثة.
الجلسات الأربع، بشكل ملموس
الجلسة 1 — المواصفات. ملف SPEC.md: نموذج البيانات، ونقاط النهاية، والميزات، ومعايير القبول، والدستور كنص نثري. لا كود.
الجلسة 2 — الهيكل العظمي. كل نقطة نهاية تُعيد الشكل الصحيح ببيانات نائبة. الترحيلات تعمل. مجموعة الاختبارات تُنفَّذ وتفشل بصدق. واجهات حواجز الحماية موجودة وتسمح بمرور كل شيء — حاضرة، لكنها لا تُنفِّذ بعد.
الجلسة 3 — التعبئة. منطق المجال في مواجهة معايير القبول، الأصعب أولاً. التكرار، ثم التعاون، ثم القوالب، ثم مسار اقتراحات الذكاء الاصطناعي. يُشغَّل الإنفاذ وتصير حالات الحجب والسماح خضراء.
الجلسة 4 — التمتين. اختبارات التدهور، والفصل بين الرفض والفشل، والنشر، وسرد العرض.
أربع جلسات، ثلاث ساعات لكل منها، وتوقف صارم بينها. التوقف ليس إجراءً للراحة — بل هو ما يُجبر الحالة على مغادرة رأسك إلى القرص، وهو السبب الوحيد في أن 85% من هذا كان لا يزال قابلاً لإعادة الاستخدام في H4.
الخلاصات
- اكتب الدستور في المواصفات، قبل وجود الميزة. القواعد المُركَّبة لاحقاً تصير رقعاً، والقواعد المُواصَفة تصير حدوداً.
- اجعل طبقة إنفاذك الأولى حتمية، كي ينجو الإنفاذ من الانقطاع الذي يُخرج نموذجك عن الخدمة.
- اختر الفشل المفتوح أو المغلق صراحةً، وسجّل السبب، واجعل الحالة المتدهورة مرئية.
- اختبر أنك تسمح بالمُدخلات البريئة، لا أنك تحجب السيئة فقط.
- أبقِ الرفض والفشل نتيجتين منفصلتين، وإلا فسيتجاوز منطقُ الموثوقية لديك طبقةَ الأمان بهدوء.
عن الكاتب
Asadullah Shafique
مهندس أنظمة ذكاء اصطناعي وكيلة
أبني أنظمة متعددة الوكلاء على OpenAI Agents SDK مع أدوات MCP وحواجز حماية دستورية وتقييم على مستوى مسار التنفيذ، وأكتب هنا عن البنية والتقدير الهندسي وراءها.