التحقق من صلاحية مخرجات LLM
التحقق من صلاحية مخرجات النموذج اللغوي (LLM Output Validation) هو الشيفرة التي تفحص استجابة النموذج قبل أن يستخدمها التطبيق، ومعها الاختبارات التي تثبت أن هذه الفحوص تعمل. فحين تغذّي المخرجاتُ برمجياتٍ أخرى لا قارئاً بشرياً فقط، تحتاج إلى عقد: غالباً JSON يجب أن يطابق مخططاً (JSON Schema)، إضافةً إلى قواعد العمل وفحوص السياسات. والاستجابة التي تخالف العقد تُرفض أو يُعاد طلبها أو تُستبدل ببديل آمن (Fallback) قبل أن تصل إلى قاعدة بيانات أو شاشة أو نظام آخر.
مثال: صندوق الدعم في متجر يطلب من نموذج فرز كل رسالة عميل وإرجاع intent وpriority وorder_id ومسودة رد في reply. يوجّه الخادم التذكرة بحسب intent ويعرض reply لموظف الدعم. ويفحص التحقق أن الاستجابة JSON، وأن intent إحدى أربع قيم مسموح بها، وأن رقم الطلب موجود فعلاً في الرسالة، وأن الرد يُعرض نصاً لا وسوماً (Markup) أبداً.
لماذا يهم
في درس اختبار الهلوسة سألتَ هل الإجابة مطابقة لمصادرها. أما هذا الدرس فيسأل: هل يستطيع التطبيق استخدامها بأمان؟ فحقل مفقود يُسقط المحلّل (Parser)، و"Refund" بدلاً من "refund" يرسل التذكرة إلى الطابور الخاطئ، ورقم طلب مختلَق يُطلق إجراءً على طلب عميل آخر، وشيفرة (Script) مخبّأة في الرد تعمل في متصفح الموظف. هذه عيوب عادية مصدرها غير عادي.
وبالنسبة إلى المختبِر، يحوّل العقدُ المخرجاتِ الغامضة إلى شيء يمكن التحقق منه. ففحص المخطط حتمي حتى حين لا تكون الصياغة كذلك، لذا يمكن تشغيله في كل بناء. ولأن النموذج سيُنتج أحياناً مخرجات سيئة مهما كان الموجّه جيداً، فالسؤال المفيد ليس «هل يلتزم النموذج دائماً؟» بل «ماذا يفعل التطبيق حين لا يلتزم؟»، وهذا سؤال يمكن اختباره.
المخرجات المهيكلة: امنح الاستجابة عقداً
المخرجات المهيكلة (Structured Output) تعني أن يجيب النموذج بصيغة تقرؤها الآلة، وهي JSON في الغالب، بأسماء حقول ثابتة وقيم مسموح بها. وعبارة في الموجّه مثل «أجب بصيغة JSON فقط» طلبٌ لا ضمان. وتوفر واجهات برمجية كثيرة للنماذج أيضاً وضع JSON أو خيار مخرجات مهيكلة أو استدعاء الأدوات (Tool Calling)، فتقيّد الاستجابة بدرجات متفاوتة بصيغة JSON صالحة أو بمخطط تزوّدها به. اقرأ ما يضمنه مزوّدك فعلاً: فقد يقتصر الضمان على صحة الصياغة أو على جزء من JSON Schema، وقد تنقطع الاستجابة عند حدّ رموز المخرجات (Output Tokens) أو تأتي رفضاً بدلاً من البيانات.
اكتب العقد على هيئة JSON Schema محفوظ في المستودع، يستخدمه مدقّق التطبيق والاختبارات معاً. في المخطط أدناه ترفض additionalProperties: false الحقول التي لم يطلبها أحد، وتحدد enum القيم المسموح بها (مع التمييز بين الأحرف الكبيرة والصغيرة)، ويقيّد pattern رقم الطلب. والحقل order_id مطلوب لكنه قد يكون null: فالرسالة التي لا تحوي رقم طلب تحصل على القيمة null صراحةً، لا على حقل مفقود ولا على رقم مختلَق. ويشرح دليل JSON كيف يذهب التحقق من المخطط أبعد من فحص أن النص JSON صالح. ولاحظ أن قيم format مثل date مجرد توصيفات (Annotations) افتراضياً في الإصدارات الحديثة من المواصفة، فكثير من المدققات يتجاهلها ما لم يُضبط لذلك؛ استخدم pattern أو فحصاً في الشيفرة حين تهمّ الصيغة.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["intent", "priority", "order_id", "reply"],
"additionalProperties": false,
"properties": {
"intent": { "enum": ["refund", "delivery", "account", "other"] },
"priority": { "enum": ["high", "normal", "low"] },
"order_id": { "type": ["string", "null"], "pattern": "^ORD-[0-9]{6}$" },
"reply": { "type": "string", "minLength": 1, "maxLength": 800 }
}
}تحقّق على طبقات: التحليل والمخطط والقواعد وضوابط الحماية
كل طبقة تلتقط ما لا تستطيع سابقتها التقاطه. والاستجابة التي تفشل في أي طبقة لا تصل إلى المستهلك كما هي أبداً: تُسجَّل مع إصداري الموجّه والنموذج، ثم يعيد التطبيق المحاولة ضمن حدّ صارم أو يلجأ إلى بديل آمن مثل طابور بشري. واختبر مسار الفشل بالعناية نفسها التي تختبر بها المسار السليم: ماذا يرى المستخدم، وهل يصمد حدّ إعادة المحاولة، وهل يكفي السجل لإعادة إنتاج الحالة.
- التحليل (Parsing): هل هي JSON أصلاً؟ نص قبل JSON، أو سياج شيفرة Markdown، أو كائن مبتور، كلها تفشل هنا. وإذا كان التطبيق يُصلح المخرجات، كأن يحذف السياج، فهذا الإصلاح سلوك منصوص عليه في المواصفات يجب اختباره.
- المخطط (Schema): الحقول المطلوبة، والأنواع، والقيم المسموح بها، والأطوال، وعدم وجود حقول زائدة. وفشل المخطط يجعل المخرجات غير قابلة للاستخدام مهما كانت صياغتها جيدة.
- قواعد العمل (Business Rules): هل للقيم معنى بالنسبة إلى هذا المدخل وهذه البيانات؟ يجب أن يظهر
order_idفي الرسالة وأن يخص ذلك العميل. وهذه الطبقة تلتقط القيم المختلَقة التي تطابق المخطط تماماً. - ضوابط الحماية (Guardrails): فحوص سياسات حول النموذج تحجب المخرجات أو تنقّحها أو تستبدلها، مثل بيانات شخصية في الرد، أو موضوع محظور، أو رابط خارج قائمة السماح. اختبرها في الاتجاهين: المخرجات السيئة تُوقَف، والمخرجات العادية لا تُحجب خطأً.
- 1استجابة النموذجنص خام من النموذج: مدخل غير موثوق
{"intent":"refund",…} - 2التحليلهل هي JSON أصلاً؟
فرع: نص أو سياج شيفرة أو JSON مبتور: رفضفشل
- 3فحص المخططالحقول المطلوبة والأنواع وقيم
enumوعدم وجود حقول زائدةفرع: حقل مفقود أو قيمة خارج
enum: رفضفشل - 4قواعد العملالقيم تناسب هذا المدخل: رقم الطلب موجود في الرسالة
فرع: قيمة مختلَقة أو مستحيلة: رفض وتسجيلفشل
- 5ضوابط الحمايةالسياسات: البيانات الشخصية والمواضيع المحظورة وقائمة سماح الروابط
فرع: تُحجب أو تُنقَّح أو تُستبدل، وتُسجَّلتنبيه
بوابة: اجتازت كل الطبقات
- 6قبول مع بقائها غير موثوقةكل مستهلك يرمّز بحسب سياقه: HTML ومعاملات SQL وقوائم السماحنجاح
- عند أي رفضسجّله مع إصداري الموجّه والنموذج؛ وأعد المحاولة ضمن حدّ صارم أو انتقل إلى طابور بشري
الاتساق بين التشغيلات
قد يعطي المدخل نفسه مخرجات مختلفة في استدعاءات مختلفة. وخفض درجة الحرارة (Temperature) يقلل التباين لكنه لا يضمن استجابات متطابقة، لذا فتشغيل ناجح واحد لا يثبت الكثير. شغّل كل حالة مهمة عدة مرات، مثلاً 10 مرات، بإصدار النموذج وإصدار الموجّه والمعاملات المستخدمة في بيئة الإنتاج، وسجّل N وكل نتيجة.
لا تقارن الاستجابات كاملةً كنصوص. حدّد الحقول التي يجب أن تثبت، مثل intent وpriority والمعرّفات والمبالغ المستخرجة، والحقول التي يجوز أن تتغير، مثل صياغة reply. والقرار الذي يتقلّب بين التشغيلات عيب حتى لو بدت كل إجابة معقولة، لأن الطلب نفسه يلقى معاملة مختلفة. وقد تكون المخرجات متسقة وخاطئة باتساق، لذا تكمّل فحوص الاتساق فحوص الصحة ولا تحلّ محلها أبداً.
- صلاحية المخطط: يجب أن ينجح كل تشغيل. فمع حجم الاستخدام في بيئة الإنتاج، يعني فشل واحد في كل 10 استدعاءات طلبات فاشلة كثيرة كل يوم.
- اتفاق القرارات: عُدّ القيم المختلفة التي أخذها كل حقل ثابت عبر التشغيلات.
- حين يتقلّب قرار، اسأل هل القاعدة معرّفة أصلاً. وكثيراً ما يكون الإصلاح بذكر القاعدة في الموجّه، أو بحساب ذلك الحقل بشيفرة عادية.
عامل مخرجات النموذج كمدخل غير موثوق
تُدرج قائمة OWASP لأهم عشرة مخاطر لتطبيقات النماذج اللغوية لعام 2025 المعالجةَ غير السليمة للمخرجات (LLM05) خطراً مستقلاً: مخرجات نموذج تُمرَّر إلى مكونات أخرى دون تحقق وتعقيم ومعالجة كافية. فمن كتب المدخل، أو كتب المستندات التي قرأها النموذج، يستطيع التأثير فيما يكتبه، لذا لا يجوز للشيفرة المستقبِلة أن تثق بالمخرجات لأنها «جاءت من نموذجنا».
صلاحية المخطط ليست أماناً: "reply": "<b>Sorry</b>" نص صالح. وكل مستهلك يعالج المخرجات بحسب سياقه: رمّزها أو استخدم معقِّماً صارماً قبل عرضها في HTML، ومرّرها إلى SQL معاملاً لا نصاً ملصوقاً، وتحقق من عناوين URL وأسماء الملفات والأوامر مقابل قائمة سماح، ولا تدع النموذج يُطلق إجراءً لا يحق للمستخدم تنفيذه. اختبر بوسوم وأحرف خاصة غير ضارة، وعلى أنظمة تملكها أو لديك إذن مكتوب باختبارها فقط. ويسرد دليل اختبار أمان النماذج اللغوية حالات اختبار غير ضارة لكل سياق.
جرّبها: مولّد مجموعات الأحرف الخاصة جرّبها: مرمّز كيانات HTML
مثال تطبيقي: حالة فرز واحدة وعشرة تشغيلات
المدخل: «مرحباً، الطلب ORD-204913 وصل مكسوراً، وأريد استرداد أموالي». شغّل المختبِر هذه الحالة 10 مرات مقابل المخطط أعلاه، وسجّل لكل استجابة مختلفة أول طبقة فشلت فيها، إن وُجدت، فظهرت خمسة أنماط (أدناه). والنمط R4 هو الأكثر فائدة: رقم الطلب فيه يطابق النمط، لكنّ فيه رقمين متبادلَي الموضع، فلا تلتقطه إلا قاعدة العمل.
في التشغيلات العشرة كلها كانت قيمة intent هي refund، لكن priority جاءت normal 7 مرات وhigh 3 مرات. ويذكر تقرير الخطأ المدخلَ، وN = 10، والتوزيع، وإصداري النموذج والموجّه، وسؤالاً واحداً لمالك المنتج: هل البضاعة التالفة أولوية عالية؟ وبعد الاتفاق على القاعدة، إما أن تُذكر في الموجّه مع أمثلة، وإما أن يستخرج النموذج الواقعة وحدها (هل وصل المنتج تالفاً؟) ثم تُحسب priority منها في شيفرة عادية يفحصها اختبار مطابقة تامة.
R1 {"intent":"refund","priority":"normal","order_id":"ORD-204913","reply":"..."}
parse ok, schema ok, rules ok -> accept
R2 Here is the JSON: {"intent":"refund", ...}
parse fails: text before the JSON -> reject, one retry
R3 {"intent":"refund","priority":"normal","reply":"..."}
schema fails: required field order_id is missing -> reject, one retry
R4 {..., "order_id":"ORD-204931", ...}
rules fail: order number is not in the message -> reject, human queue
R5 {..., "reply":"<b>Sorry</b>, the item arrived broken..."}
all layers pass -> accept, show as textأخطاء شائعة
- الثقة بعبارة «أجب بصيغة JSON فقط» في الموجّه، أو بوضع JSON لدى المزوّد، وإهمال التحقق في الشيفرة.
- اعتبار الاستجابة المطابقة للمخطط استجابةً صحيحة: المخطط يفحص الشكل، فرقم الطلب المختلَق الذي يطابق النمط ينجح رغم ذلك.
- تشغيل الحالة مرة واحدة، أو مقارنة الاستجابات كاملةً كنصوص، بدلاً من تكرار التشغيل وفحص الحقول التي يجب أن تثبت.
- اختبار أن ضابط الحماية يحجب المخرجات السيئة فقط، دون اختبار أن المخرجات العادية تمر، ودون اختبار ما يراه المستخدم بعد الرفض.
- عرض المخرجات أو تخزينها أو تنفيذها دون ترميز يناسب سياقها لأنها جاءت من نموذج الفريق نفسه.
من منظور ضمان الجودة
ابدأ في جلسات التنقيح (Refinement) أو مراجعة التصميم: اطلب عقد المخرجات، واسأل من يملكه، وأي الحقول يجب أن تثبت، وماذا يحدث عند كل نوع من الرفض. وإن لم يستطع أحد الإجابة، فهذه أولى ملاحظاتك. وراجع كل تغيير في المخطط كما تراجع تغيير عقد واجهة برمجية، لأن الموجّه والخادم والاختبارات كلها تعتمد عليه.
أتمِت الطبقات الحتمية في كل طلب دمج (Pull Request) بمجموعة اختبار ثابتة، وشغّل مجموعة اختبارات الاتساق متعددة التشغيلات ليلاً أو قبل الإصدار، بعتبات متفق عليها مسبقاً. وبعد الإصدار اطلب أعداد حالات الرفض لكل طبقة من سجلات بيئة الإنتاج: فارتفاع نسبة فشل المخطط بعد تغيير النموذج أو الموجّه إشارة انحدار. وأشرك فريق الأمن في مراجعة كل مستهلك للمخرجات، ومالك المنتج في كل قاعدة عمل يطبقها النموذج.
تمرين عملي
تحقّق من صلاحية مخرجات استخراج بيانات الإيصال
يرسل تطبيق مصروفات نص الإيصال إلى نموذج ويحفظ JSON الذي يعيده، ويُعرض merchant في قائمة مصروفات بصيغة HTML. العقد: merchant نص من 1 إلى 80 حرفاً، وdate بصيغة YYYY-MM-DD، وtotal رقم أكبر من 0، وcurrency إحدى القيم SAR أو USD أو EUR، وcategory إحدى القيم travel أو meals أو office أو other، ولا يُسمح بأي حقول أخرى. قاعدة العمل: total يساوي سطر TOTAL في الإيصال.
لكل استجابة من A إلى G أدناه، سمِّ أول طبقة تفشل فيها (التحليل أو المخطط أو قاعدة العمل) أو اكتب «مقبولة»، واذكر ما يجب أن يفعله التطبيق. ثم: شُغّل الإيصال نفسه 10 مرات فجاءت category بالقيمة meals 6 مرات وother 4 مرات. ماذا تُبلغ، وماذا تقترح؟
Receipt: AL NOOR CAFE, Riyadh. Date: 2026-09-14. 2 x Coffee @ 18.00. TOTAL: SAR 36.00
A {"merchant":"Al Noor Cafe","date":"2026-09-14","total":36.00,
"currency":"SAR","category":"meals"}
B Here is the data: {"merchant":"Al Noor Cafe", ...}
C as A, but "date":"14/09/2026"
D as A, but "total":"36.00"
E as A, but "total":18.00
F as A, but "merchant":"<i>Al Noor</i> Cafe"
G as A, plus "tip":0- اقرأ العقد وقاعدة العمل.
- افحص كل استجابة طبقةً طبقة وتوقف عند أول فشل.
- للاستجابات المقبولة، قرّر كيف يجب أن تعرض قائمة المصروفات القيم.
- اكتب ملاحظة الاتساق في تقرير خطأ قصير.
إظهار الإجابة النموذجية
A: مقبولة. B: يفشل التحليل لوجود نص قبل JSON؛ ارفضها وأعد المحاولة مرة واحدة، أو احذف المقدمة فقط إن كان هذا الإصلاح محدداً. C: يفشل المخطط، فالتاريخ لا يطابق YYYY-MM-DD. D: يفشل المخطط، فـtotal نص لا رقم. G: يفشل المخطط، فـtip حقل لا يسمح به العقد. وفي C وD وG ارفض الاستجابة وأعد المحاولة مرة واحدة ضمن الحد؛ فإن فشلت الإعادة أيضاً فأحِل الإيصال إلى الإدخال اليدوي.
E: تجتاز التحليل والمخطط لكنها تفشل في قاعدة العمل: 18.00 سعر قهوة واحدة لا إجمالي الإيصال TOTAL البالغ 36.00. ارفضها وسجّلها وأحِل الإيصال إلى مراجعة يدوية؛ فلا يلتقط قيمة معقولة مطابقة للمخطط كهذه إلا فحص القواعد.
F: مقبولة، لأن الوسوم داخل اسم التاجر تبقى نصاً صالحاً. ويجب أن تعرضها قائمة المصروفات نصاً، فتُظهر <i>Al Noor</i> Cafe حرفياً أو تحذف الوسوم بمعقِّم يعتمد قائمة سماح، ولا تعرضها أبداً على أنها HTML.
الاتساق: أبلِغ عن الإيصال، وN = 10، والتوزيع (meals 6 وother 4)، وإصدار النموذج وإصدار الموجّه والمعاملات. فالإيصال نفسه يُصنَّف في فئات مختلفة في تشغيلات مختلفة. اطلب من مالك المنتج تعريف قاعدة التصنيف (مثلاً: المقاهي والمطاعم ضمن meals)، وضعها في الموجّه مع أمثلة أو في الشيفرة، واتفقوا على عتبة اتساق لمجموعة الاختبار قبل الإصدار.
أسئلة شائعة
إذا كان مزوّدي يضمن مخرجات مطابقة للمخطط، فهل ما زلت بحاجة إلى التحقق؟
نعم. اقرأ الضمان بدقة: فقد يغطي جزءاً من JSON Schema فقط، وقد تنقطع الاستجابة أو تأتي رفضاً، والنماذج والمزوّدون يتغيرون. وقواعد العمل وضوابط الحماية مسؤوليتك في كل الأحوال. والتحقق في شيفرتك رخيص، واختباراته تبقى صالحة حين يتغير المزوّد.
ما الفرق بين التحقق وضابط الحماية؟
التحقق يفحص المخرجات مقابل عقدك وقواعد العمل ويجيب عن سؤال «هل يستطيع التطبيق استخدامها؟». أما ضابط الحماية فيفرض سياسة، مثل منع البيانات الشخصية أو النصائح الخارجة عن النطاق، وقد يحجب المخرجات أو ينقّحها أو يستبدلها. وكلاهما يعمل في الشيفرة حول النموذج، وكلاهما يحتاج إلى اختبارات تثبت أنه يوقف المخرجات السيئة ويمرّر العادية.
هل يجب أن يعيد التطبيق المحاولة تلقائياً عند فشل التحقق؟
إعادة المحاولة المحدودة تصميم شائع لحالات فشل التحليل والمخطط، وأحياناً تُرفق رسالة خطأ التحقق بالطلب الجديد. ويجب أن يكون لها حدّ صارم، لأن كل محاولة تكلّف وقتاً ومالاً. أما فشل قواعد العمل والسياسات فيذهب عادةً إلى بديل آمن، مثل طابور بشري أو رسالة آمنة، بدلاً من تكرار المحاولة حتى يمتثل النموذج.
المراجع
- OWASP Top 10 for LLM Applications 2025أخطر عشرة مخاطر أمنية في تطبيقات النماذج اللغوية الكبيرة (LLM01:2025–LLM10:2025)، بدءاً بحقن الموجّهات والإفصاح عن المعلومات الحساسة.
- JSON Schema Specificationالمفردات المستخدمة لوصف بنية مستندات JSON والتحقق منها (الأنواع والحقول المطلوبة والصيغ).
- OWASP Cheat Sheet Series: Cross Site Scripting Preventionمنع XSS: الترميز عند الإخراج بحسب كل سياق، وتعقيم HTML الذي يكتبه المستخدم، ومواضع الإدراج الآمنة في DOM وحمايات الأطر، مع اعتبار CSP طبقة دفاع إضافية فقط.
- Define success criteria and build evaluationsإرشادات مزوّد نماذج لكتابة معايير نجاح قابلة للقياس ومجموعات تقييم تُصحَّح بالكود أو بالمطابقة التامة أو بنموذج.
تدرّب بأدوات متقن
التحقق من مستند JSON مقابل مخطط JSON Schema (الكلمات المفتاحية الأساسية في draft-07 / 2019-09 / 2020-12).
التحقق من صحة صياغة JSON مع تحديد مواقع الأخطاء بدقة واقتراحات مفيدة للإصلاح.
مقارنة مستندي JSON دلالياً وإبراز القيم المضافة والمحذوفة والمتغيرة.
اختبر التعابير النمطية مباشرةً مع إبراز التطابقات ومجموعات الالتقاط ومعاينة الاستبدال.
ولّد مدخلات مليئة بالأحرف الخاصة: علامات الاقتباس، والأحرف الوصفية لـ SQL/HTML/JSON، وأحرف التحكم، والرموز التعبيرية، وحيل المسارات.
تهريب أحرف HTML الخاصة (< و> و& وعلامات الاقتباس) إلى كيانات لمنع هجمات XSS.
للتعمّق أكثر
- اختبار أمان النماذج اللغوية (LLM Security Testing)المعالجة غير السليمة للمخرجات: عامل مخرجات النموذج كمدخل غير موثوق
- اختبار النماذج اللغوية الكبيرة (LLM Testing)كيف تكتب تحققات على مخرجات غير حتمية
- تقييم النماذج اللغوية (LLM Evaluation)الخطوة 5: شغّل وكرّر وحدّد العتبات
- ما هو JSON؟كيفية التحقق من صحة JSON
تقدّمك في هذا الموضوع
سجّل الدخول لتتابع تقدّمك
علّم الموضوعات مكتملة، وتابع من حيث توقفت، وافتح امتحانات التخصص.