تطلب من الـ agent أن يبني ميزة. فيُنتج شيئًا. إنه شبه صحيح، فتعيد صياغة الـ prompt. وما زال غير مضبوط تمامًا، فتعيد الصياغة مجددًا. كل سحبة للرافعة تبدو كأنها تقدّم، وكلٌّ منها تبدو أقلّ قليلًا كأنها هندسة. وفي مكان ما بين ذلك، توقّفت عن بناء نظام وبدأت تلعب على آلة قِمار.
هذا الانعكاس — أعِد الرمي حتى يبدو صحيحًا — هو أوضح عرَض لمشكلة لا علاقة لها بجودة النموذج اللغوي. الـ AI لم يغيّر شكل هندسة البرمجيات الجيدة. بل جعل تخطّيها أسهل بكثير.
أولًا، ما معنى «الحتمية» فعلًا
تعريفان بسيطان، لأن الحُجّة كلها تقوم عليهما.
الحتمية (determinism) تعني أن المُدخل نفسه يُنتج دائمًا المُخرج نفسه. تخيّل function نقية: تعطيها 2 فتُعيد 4، في كل مرة، إلى الأبد. (وقد تظلّ بطيئة أو غير متزامنة — فالحتمية تتعلق بِـ القابلية للتنبّؤ لا بالسرعة.)
اللاحتمية (non-determinism) تعني أن المُدخل نفسه قد يُنتج مُخرجات مختلفة. وهذا لا يعني العشوائية. بل يعني أن المُخرج مسحوب من نطاق من الاحتمالات. اطلب من النموذج صياغة الرسالة نفسها مرتين فتحصل على مسودّتين مختلفتين — كلتاهما معقولة، ولا واحدة مطابقة للأخرى.
هذا التمييز أقدم من الـ AI. رسمَته علوم الحاسوب منذ عقود، والدرس المستفاد من تلك النظرية القديمة يستحقّ الحفظ: يمكنك دائمًا تحويل آلة غير قابلة للتنبّؤ إلى أخرى قابلة للتنبّؤ، لكن النسخة القابلة للتنبّؤ أكثر تعقيدًا. أنت لا تزيل اللاحتمية مجانًا — بل تدفع ثمنها بنيةً. هذه المقايضة لم تختفِ قط. النماذج اللغوية الكبيرة جعلت الجميع يشعرون بها من جديد فحسب.
الـ slop كودٌ بلا نموذج
التعريف السهل لِـ «slop» هو أن يكتب الـ AI كودًا سيّئًا. وهذا خطأ، والتصحيح هو بيت القصيد:
الـ slop كودٌ بلا نموذج موثوق خلفه.
الـ slop بلا حدود واضحة. قواعده ضمنية لا معلَنة. لا يمكنك فحص حالاته. سلوكه مبعثر عبر الملفات، ولا سبيل آمن لتغييره. وهنا الجزء الذي يفاجئ الناس — قد يعمل تمامًا. الـ slop ليس مرادفًا لِـ «معطوب»، ولا حتى «سيّئ». يمكن للكود أن يعمل، ويجتاز اختباراته، ويُطلَق إلى production، ويظلّ slop، لأن الـ slop يتعلق بِـ غياب النموذج، لا بوجود الأخطاء.
هذا ما يجعل انعكاس إعادة الصياغة خطيرًا للغاية. حين لا يكون المُخرج مضبوطًا تمامًا، يكون إصلاح البنية الكامنة صعبًا، وسحب الرافعة مجددًا سهلًا. فتسحبها. تبدو كأنها زخم. لا شيء منها يضيف نموذجًا. هذا هو الفخّ نفسه الذي يُفسِد الـ vibe coding: يمكنك توليد جبل من الكود العامل بينما فهمك له لا يلحق به أبدًا.
لماذا ينجرف الـ AI نحو الـ slop
سببان، كلاهما بنيوي — ولا واحد منهما «النموذج ليس ذكيًا بما يكفي».
تعلّم من كودنا كلّه، لا من الكود الجيّد. حين يُترك الـ agent بلا قيود، فهو لا يميل نحو أفضل الممارسات. بل يعيد إنتاج وتضخيم الأنماط التي تسود بالفعل في الـ codebase الذي يعمل فيه — الجيّدة والسيّئة على حدّ سواء. وجِّهه إلى نظام مرتّب فيوسّع الترتيب؛ وجِّهه إلى فوضى فيوسّع الفوضى بثقة وطلاقة.
الـ agents مطيعة، لكنها لا تملك كثيرًا من المبادرة. هذا هو الجزء المخالف للحدس. اطلب من الـ agent أن يبني شيئًا فيذهب مباشرةً إلى الكود. لن يتوقف ليقترح نموذجًا أولًا، ولن يسأل عن الحالات، ولن يعترض بأن المتطلبات ناقصة — إلّا إذا أمرته بذلك صراحةً. القلق المعتاد بشأن الـ agents أنها مفرطة في الاستقلالية. أما الفشل الحقيقي فهو العكس: لم يُسلّمها أحد نموذجًا لتعمل انطلاقًا منه، فتملأ الفجوات بافتراضات، ويُضخَّم الافتراض الخاطئ عبر كل ما يُبنى فوقه.
الطرق الأربع التي يُستبعَد بها النموذج
يميل العمل الذي يقوده الـ AI إلى استبعاد النموذج تمامًا، وعادةً ما يحدث ذلك عبر واحدة من أربع حركات:
- الـ one-shotting. الانتقال من الـ prompt إلى النتيجة مباشرةً، متخطّيًا التكرار والحكم البشري اللذَين كانا سيُظهران المتطلبات الحقيقية.
- التحكّم بالتدفّق عبر النثر (prose control flow). محاولة ترميز «افعل X دائمًا، ولا تفعل Y أبدًا، ثم الخطوة 1 و2 و3» كتعليمات بلغة طبيعية في ملف skills أو
CLAUDE.md— على أمل أن يتبعها الـ agent. قد يفعل. وقد لا يفعل. التعليمات في النثر ليست كالبنية في النظام. - الـ agents بوصفها النظام كلّه. رمي المزيد من الـ agents على المشكلة بلا شيء يقيّدها. المزيد من الـ agents بلا مزيد من البنية ليس إلّا مزيدًا من الفوضى، وبوتيرة أسرع.
- تشابك الاهتمامات. يعلن الـ agent أن الهدف «تمّ» لحظةَ يعمل شيءٌ ما، بلا فصلٍ بين الأجزاء. إنها نسخة عصر الـ AI من كود المطوّر المبتدئ: يعمل، لكنه متشابك ويخيف تغييره.
وثمّة مخرج خامس مغرٍ — أضِف سياقًا أكثر فقط. وهو لا يفيد. سياقٌ أكثر لا يعني بنيةً أكثر. الـ context window الأكبر لا يُغني عن نموذج صريح، وبعد حدٍّ معيّن، حشو المزيد من التعليمات لا يضيف إلّا ضوضاء. (وهذا هو الدرس الحقيقي من هندسة السياق: ما يراه النموذج يهمّ هائلًا، لكن كومة من التعليمات ليست نموذجًا.)
الحل: نواة حتمية، وقشرة وكيلة
هذا هو التصحيح، وهو شكلٌ معماري أكثر منه تقنية.
النمط الشائع اليوم هو AI يستدعي برامج — يجلس الـ agent في المركز بوصفه الموجّه، ومنظّم الحركة، يقرّر كل شيء ويمدّ يده إلى الأدوات وهو يمضي. وهذا محفوف بالمخاطر وكسول في آنٍ، لأنه يسلّم كل قرار إلى المكوّن الوحيد اللاحتمي بطبيعته.
اِعكِسه. اكتب برنامجًا يستدعي الـ AI.
- ادفع اللاحتمية إلى الأطراف — أحكام التقدير الغامضة بحق. صياغة نص. سدّ فجوة. تقرير ما إذا كان وصفٌ مكتملًا. هذه أمورٌ لا إجابة واحدة صحيحة لها، وهي بالضبط ما يبرع فيه الـ AI.
- أبقِ الحتمية في النواة — الانتقالات الفعلية، يفرضها البرنامج المحيط لا الـ AI. هذا الفعل مستحيل حتى يتحقّق ذلك الشرط المسبق. تلك قواعد صارمة لا يملك الـ AI أن يتجاوزها بفقرة واثقة.
البرنامج المحيط هو الجزء الذي يضمن السلوك. أما الـ AI فمختصٌّ تستدعيه للمهام الفرعية الغامضة، لا المدير الذي يقرّر ما المسموح بحدوثه.
كيف يبدو ذلك عمليًا
تخيّل مساعد بريد إلكتروني، مُنمذَجًا كمجموعة صغيرة من الحالات الصريحة:
جمع المتطلبات ← الصياغة ← التكرار معك ← الإرسال
البنية — لا النموذج — تقرّر ما يمكن أن يحدث تاليًا. لا يمكنك الإرسال دون مسودّة معتمَدة. لا يمكنك الصياغة دون متطلبات مكتملة. تلك يفرضها البرنامج. وداخل كل حالة، يؤدّي الـ AI الجزء الملائم له فعلًا: هل ينقص هذه المتطلبات شيء؟ وماذا ينبغي أن تقول هذه المسودّة؟ القضبان تصمد؛ والنموذج يملأ المحتوى الغامض بينها.
لاحظ كم أن هذا أكثر أمانًا من agent يحمل التدفّق كلّه في رأسه. لا يوجد prompt بارع بما يكفي لجعل النظام يرسل بريدًا غير معتمَد، لأن «الإرسال» ببساطة غير قابل للوصول من حالةٍ بلا مسودّة معتمَدة. لم تطلب من النموذج أن يكون حذرًا — بل جعلت الحركة غير الآمنة مستحيلة بنيويًا.
هذه هي النواة الموثوقة الكامنة تحت الأنماط الأكثر تقدّمًا في مواضع أخرى من هذا الموقع: الـ workflow الديناميكي الذي يُطلق وينسّق عدّة agents لا يكون جديرًا بالثقة إلّا لأن سكربتًا حتميًا — لا مزاج نموذج — هو من يقرّر الترتيب، والبوابات، وما الذي يُحتسَب إنجازًا.
النمذجة بلا طقوس
لا يعني شيء من هذا صَوغَ كل شيء صياغةً رسمية. والخيط الهادي:
النمذجة ليست طقسًا حين تحلّ محلّ الحيرة.
اِنمذِج الأجزاء المربِكة من النظام فقط، وحيث يستحقّ النموذج مكانه بإزالته حيرةً حقيقية. ولست بحاجة إلى الـ state machines تحديدًا. إنها طريقة نظيفة لجعل الانتقالات المسموح بها صريحة، لكن المطلوب الحقيقي هو مجرّد بنية — مخطّط انسيابي، مخطّط عمليات، نموذج مجال بسيط، أي شيء يجعل منطق النواة صريحًا ويبقيه مفصولًا عن الواجهة.
النقطة ليست في الترميز. النقطة أن يكون في نظامك، في مكان ما، جوابٌ صادق عن سؤال «أيّ الحالات موجودة، وأيّ الانتقالات مسموح بها» — وأن يعيش ذلك الجواب في البرنامج، لا في رأس النموذج وحده.
من أين تبدأ
لست بحاجة إلى إعادة هيكلة أي شيء. اختر سير عمل واحدًا مربِكًا موجودًا — ذاك الذي تشقّ طريقك عبره بإعادة الصياغة أصلًا — وانمذِجه صراحةً. ثم اطرح ثلاثة أسئلة:
- ما الذي ينبغي أن يكون حتميًا هنا؟ أيّ الانتقالات يجب ضمانها، في كل مرة، بلا استثناء؟
- أين يكون التكرار مفيدًا فعلًا؟ أين ينتمي الإنسان حقًا إلى الحلقة، بدل أن يُطلَب منه مجرّد ختمٍ بالموافقة؟
- أين يمكن فصل المنطق عن الواجهة؟ ما السلوك الأساسي، وما مجرّد عرضٍ ملفوف حوله؟
هذه هي الممارسة كلّها. لا هجرة إطار عمل، ولا إعادة كتابة — سير عمل واحد، جُعِل مقروءًا.
الصورة الأكبر
الغريزة حين يكون مُخرج الـ AI غير موثوق أن تمدّ يدك إلى prompt أفضل أو context window أكبر. وكلاهما يعالج مشكلة بنيوية كأنها مشكلة صياغة. الجواب الذي يصمد فعلًا هو نموذج: بيانٌ صريح لكيفية تصرّف النظام، يجلس في النواة الحتمية، بينما يُدفَع العمل الغامض بأمان إلى الأطراف.
اضبط هذا الشكل ويكفّ الـ agent عن أن يكون آلة قِمار تُطعمها بلا انقطاع. يصبح ما يبرع فيه حقًا — مختصًّا سريعًا لا يكلّ تستدعيه للأجزاء التي كانت أحكامَ تقدير على أي حال، داخل نظامٍ ما زال يعرف تمامًا ما المسموح له أن يفعله.