ML Engineer

وكيل AutoML لا يرى أبدًا مجموعة اختباره المحجوبة (holdout)

مشروع ML Engineer وكيل مستقل يحلل خصائص مجموعة البيانات، ويخطط للتجارب، ويكتب شيفرة scikit-learn ويشغلها في بيئة معزولة (sandbox)، وكل ذلك داخل منظومة اختبار بنيت للتحقق من أنه يعمل بأمانة. الوكيل لا يرى المجموعة المحجوبة أبدًا: لا بحكم العرف، بل بحكم البناء. ورقمه الأبرز ليس أفضل درجة حققها، بل الفجوة بين درجة التحقق المتقاطع التي سعى إلى تحسينها ودرجة المجموعة المحجوبة التي لم يرها قط.

النوع
مشروع شخصي، 2026، من تصميمي وتنفيذي بالكامل
الوكيل
حلقة مخصصة بأربعة أدوار يؤديها نموذج لغوي كبير (LLM): المخطط، والمبرمج، والناقد، ومسؤول التسليم
البيئة المعزولة
حاوية Docker مقطوعة عن الشبكة، 2 غيغابايت، معالجان، جذر للقراءة فقط، و10 دقائق حدًّا لكل تدريب
المهام
ست مهام على بيانات جدولية: خمس منها فيها فخ مزروع، وواحدة ضابطة نظيفة
الاختبارات
188 حالة اختبار (pytest)، منها 16 داخل Docker

نسخة أولية تعمل. مسار المعالجة كله يعمل من أوله إلى آخره مع بديل مبرمج مسبقًا يقوم مقام النموذج؛ ولم ينشر بعد أي اختبار معياري على نموذج حقيقي.

المجموعة المحجوبة لا تلتقي بالوكيل أبدًا

يجري تقسيم البيانات قبل أن يوجد الوكيل، والدالة التي تشغل الوكيل ليس فيها أي معامل يمكن أن يحمل المجموعة المحجوبة. والتقييم يجري في حاوية أخرى، بعد أن ينهي الوكيل عمله.

مهمة واحدة عبر منظومة الاختبار
مجموعة البيانات مهمة مولدة أو ملف CSV تقسيم holdout زمن أو مجموعة أو فئة تشغيل الوكيل يرى بيانات التدريب فقط المجموعة المحجوبة كما تبدو وقت التنبؤ تقييم المحجوبة حاوية منفصلة التقرير فجوة، فخاخ، خط أساس مجموعة البيانات مهمة مولدة أو ملف CSV تقسيم holdout زمن أو مجموعة أو فئة تشغيل الوكيل يرى بيانات التدريب فقط المجموعة المحجوبة كما تبدو وقت التنبؤ تقييم المحجوبة حاوية منفصلة التقرير فجوة، فخاخ، خط أساس
  • إدخال أو إخراج
  • استدعاء LLM
  • شيفرة
  • مخزن بيانات
  • فحص أو بوابة
  1. مجموعة البيانات مهمة توقع انسحاب العملاء (churn) مولدة من بذرة، وفيها فخ مزروع واحد: عمود يملأ بعد وقوع النتيجة. أو ملف CSV خاص بك، حتى 64 ميغابايت.
  2. تقسيم holdout المهام الزمنية تحجب آخر 20% من البيانات، والمهام ذات المجموعات تحجب 25% من المجموعات، والبقية تحجب 20% بتقسيم طبقي. والأعمدة التي لا تعرف إلا بعد النتيجة تفرغ في المجموعة المحجوبة، كما ستكون وقت التنبؤ.
  3. تشغيل الوكيل المخطط والمبرمج والناقد ومسؤول التسليم يعملون على train.parquet وحده، في حدود 4 تجارب. والمجموعة المحجوبة ليست مخفية عنهم؛ بل لم تمرر إليهم أصلًا.
  4. تقييم المحجوبة بعد أن ينهي الوكيل عمله، تحمل حاوية أخرى كل نموذج مدرب مع المجموعة المحجوبة. ويجري تقييم كل التجارب، لا التجربة المسلمة وحدها.
  5. التقرير الفجوة بين درجة CV ودرجة المجموعة المحجوبة لكل تجربة (ما فوق 0.05 يعد خداعًا للذات)، والفخاخ المكتشفة والفائتة والإنذارات الكاذبة، وخط أساس بسيط مدرب على كل الأعمدة في البيئة المعزولة نفسها.

مسارات أخرى في المخطط

  • لا بيئة معزولة متاحة: يتوقف الاختبار المعياري بدل تشغيل الشيفرة على الجهاز المضيف. والتنفيذ على المضيف يحتاج إلى خيار صريح، وكل نتيجة تذكر ذلك.
  • فشل إحدى المهام: يسجل الفشل وتواصل المهام الأخرى.

داخل حلقة الوكيل

أربعة أدوار يؤديها النموذج اللغوي، تستدعيها شيفرة Python عادية بالتناوب. لا أحد منها يستطيع استدعاء غيره، ولا أحد منها يستطيع نقض الحسابات التي تجري بينها.

تجربتان، إحداهما ضبط فيها تسرّب
الإحاطة خصائص + تدقيق الأعمدة المخطط فرضيات مرتبة المبرمج يكتب candidate.py تدريب معزول بلا شبكة، بيانات تدريب فحوص التسرّب 7 فحوص، حسابية فقط الناقد نموذج أصغر مسؤول التسليم يختار بدرجات CV وحدها الإحاطة خصائص + تدقيق الأعمدة المخطط فرضيات مرتبة المبرمج يكتب candidate.py تدريب معزول بلا شبكة، بيانات تدريب فحوص التسرّب 7 فحوص، حسابية فقط الناقد نموذج أصغر مسؤول التسليم يختار بدرجات CV وحدها
  • إدخال أو إخراج
  • استدعاء LLM
  • شيفرة
  • فحص أو بوابة
  1. الإحاطة شيفرة عادية، لا نموذج، تحلل خصائص بيانات التدريب وتدقق الأعمدة وتقترح مخططًا للتحقق المتقاطع (CV) موسومًا بعبارة «نصيحة، لا قاعدة»: فالتزام الوكيل به من عدمه جزء مما يقاس.
  2. المخطط يعيد فرضيات مرتبة بصيغة JSON يجري التحقق منها وفق مخطط بيانات (schema).
  3. المبرمج يكتب candidate.py للفرضية الأولى. ويرى درجات CV وآخر 4 دروس وآخر 3 إخفاقات؛ أما درجة المجموعة المحجوبة فلا وجود لها بعد.
  4. تدريب معزول حاوية Docker مقطوعة عن الشبكة، بذاكرة 2 غيغابايت ومعالجين ونظام ملفات للقراءة فقط، وفيها train.parquet وحده. المخرجات: درجة CV واستراتيجيته، والسمات المستخدمة، والنموذج المدرب.
  5. فحوص التسرّب لنفترض أن النموذج أبقى على العمود اللاحق للنتيجة: سمة واحدة تفصل بين الفئات بقيمة AUC تبلغ 0.97 أو أكثر تعد ملاحظة حرجة، فتوضع التجربة في الحجر.
  6. الناقد نموذج أصغر، للحد جزئيًّا من انحياز النموذج إلى عمله، يقرأ الملاحظات ويغير الاتجاه: إسقاط العمود. ويسمح بتغيير واحد للاتجاه في كل تشغيل.
  7. المبرمج الفرضية التالية، ومعها الدرس المستفاد.
  8. تدريب معزول تجربة ثانية في حاوية جديدة.
  9. فحوص التسرّب لا ملاحظة حرجة هذه المرة.
  10. الناقد يقرر التوقف.
  11. مسؤول التسليم يختار تجربة واحدة استنادًا إلى درجات CV والملاحظات وحدها. وإذا سمى تجربة غير موجودة، رجعت المنظومة إلى أفضل درجة CV لم توضع تجربتها في الحجر.

مسارات أخرى في المخطط

  • فشل المبرمج: تسجل المحاولة على أنها إخفاق من المبرمج وتواصل الحلقة، دون تشغيل البيئة المعزولة ولا الناقد.
  • فشل المخطط: ينتهي التشغيل بخطأ.
  • فشل الناقد: تقبل التجربة وتستمر الحلقة.
  • 4 تجارب على الأكثر؛ وقائمة انتظار فارغة تقود أيضًا إلى مسؤول التسليم.

فحوص لا يستطيع النموذج مجادلتها

كشف تسرّب البيانات حساب بحت، ولا وجود لأي نموذج لغوي في هذه الوحدة: فالكاشف الذي يستطيع النموذج أن يقنع نفسه بتجاوزه لن يعلن إلا ما كان النموذج يتمناه.

خمسة من فحوص التسرّب السبعة، مع عتباتها في الشيفرة
الفحصينبه عند
سمة واحدة تفصل بين الفئاتAUC ≥ 0.90 (حرجة ابتداء من 0.97)
القيم المفقودة تفصل بين الفئاتالفصل ≥ 0.85
تحقق متقاطع أفضل من أن يصدقCV ≥ 0.985
صفوف شبه مكررةنسبتها ≥ 0.15
عدم توازن الفئاتنسبة الفئة الموجبة < 0.05

ما الذي يقاس

  • الفجوة

    درجة CV مطروحًا منها درجة المجموعة المحجوبة، لكل تجربة. والفجوة التي تتجاوز 0.05 توسم بأنها خداع للذات.

  • الفخاخ

    خمس مهام تحمل كل منها فخًّا مزروعًا واحدًا (تسرّب الهدف، الترتيب الزمني، المجموعات، التكرارات، عدم توازن الفئات) وواحدة ضابطة نظيفة. وتحصى الفخاخ المكتشفة والفائتة والإنذارات الكاذبة كل على حدة.

  • خط أساس بسيط

    نموذج gradient boosting على كل الأعمدة، مدرب في البيئة المعزولة نفسها. والمقصود أن يقع في الفخاخ، فيظهر ما تجنبه الوكيل.

  • التكلفة

    الرموز (tokens) والتكلفة والزمن الفعلي لكل تشغيل، من السجلات نفسها.

خيارات هندسية

  • عزل بحكم توقيع الدالة

    نقطة دخول الوكيل ليس فيها أي معامل يمكن أن يحمل المجموعة المحجوبة. والاختبارات تتحقق من هذا التوقيع، ومن أن الحلقة لا تستورد وحدة التقييم أبدًا، وتفتش كل موجِّه (prompt) مسجل بحثًا عن أي درجة من درجات المجموعة المحجوبة بدقة من 2 إلى 8 خانات عشرية.

  • محجوبة كما في وقت التنبؤ

    الأعمدة اللاحقة للنتيجة تفرغ في المجموعة المحجوبة؛ وإلا لبدا التسرّب المزروع مجرد سمة جيدة.

  • نصيحة لا إلزام

    حارس التقسيم يوصي بمخطط للتحقق المتقاطع ولا يفرضه. فلو فرضه لتعذر الوقوع في الفخاخ أصلًا.

  • الإغلاق عند الفشل

    لا بيئة معزولة، لا تشغيل. والتشغيل على الجهاز المضيف يحتاج إلى خيار صريح ويوسم به كل ناتج.

  • السمات مكانها مسار المعالجة

    تحضير البيانات لا يسمح له إلا بحذف صفوف، فكل تحويل يقع داخل مسار المعالجة (pipeline) الذي يعمل أيضًا وقت التنبؤ.

  • الإخفاقات بيانات

    التدريب الذي ينهار يخرج خروجًا نظيفًا مع ذكر المرحلة التي فشلت، ويصير تجربة مسجلة لا انهيارًا.

التقنيات

الوكيل
حلقة Python مخصصة، SDK متوافق مع OpenAI، JSON يجري التحقق منه وفق مخطط، بالوضع الصارم مع بديل احتياطي
تعلم الآلة
scikit-learn، pandas، NumPy، SciPy، PyArrow، joblib
البيئة المعزولة
Docker: بلا شبكة، بحدود للمعالج والذاكرة والعمليات، وجذر للقراءة فقط
الواجهة الخلفية
Python 3.12، FastAPI، WebSocket، SQLModel، SQLite، أشرطة تسجيل وإعادة تشغيل
الواجهة الأمامية
React 18، Vite، Tailwind CSS 4، رسوم بيانية SVG مرسومة يدويًّا
الجودة
pytest، ruff، GitHub Actions

هل تبني شيئًا مشابهًا؟

يسعدني أن أشرح التصميم والمفاضلات، أو ما سأغيّره في الخطوة التالية.