انتقل للمحتوى
علي هيثم·TECH·يردّ خلال أقل من ساعة
  • الرئيسيةابدأ من هنا
  • الأعمالدراسات حالة، مشاريع
  • الخدماتما الذي سأبنيه لك
  • المدونةمقالات، سلاسل
  • التدريبدورات، مختبرات، دورات
  • عنّيالمهندس وراء هذا الموقع
تسجيل الدخولابدأ مشروع
علي هيثم · TECH
  • الرئيسية↗
  • الأعمال↗
  • الخدمات↗
  • المدونة↗
  • التدريب↗
  • عنّي↗
تسجيل الدخولابدأ مشروع
متاح
علي هيثم·TECH

استوديو هندسي. دمشق، GMT+3.

aliyosef.online

الاستوديو

  • الأعمال
  • المدونة
  • التدريب
  • عنّي
  • تواصل معي

البوابة

  • تسجيل الدخول
  • فتح تذكرة دعم
  • متابعة مشروع
  • حسابي

مصادر

  • الوثائق
  • حالة الأنظمة
  • سجلّ التغييرات
  • حزمة العلامة
  • الخصوصية
  • الشروط

النشرة

ملاحظات تقنية وأخبار، أسبوعياً. بدون حشو.

مجاني. إلغاء الاشتراك متى ما حبيت.

تابعني على
© 2026 علي هيثم يوسف. جميع الحقوق محفوظة.مبنيّ يدويًا بـ React 19.آخر نشر · 2026-05-08كل الأنظمة تعمل
  1. الرئيسية/
  2. المدوّنة/
  3. هندسة AI
هندسة AI

تطوير مدفوع بالمواصفات مع LLMs

spec النموذج فيه يشتغل بدون rework. البنية، الـ anti-patterns، والـ diff الفعلي.

٢٦ كانون الثاني ٢٠٢٦·9 دقائق·بقلم علي يوسف

جاري تحميل المقال…

شاركXLinkedInRSS
استلم المقال التالي في بريدك.مقال جديد كل أحد. هندسة بلغة واضحة. مجاني، يمكنك إلغاء الاشتراك في أي وقت.اشترك→
AY
علي هيثم يوسف

مهندس وكاتب. أبني منصات متعدّدة المستأجرين، محرّكات مزامنة، وأنظمة موثوقة بهدوء. أكثر من ٦٠٠ مشروع مُسلَّم منذ ٢٠١٥.

اشتركابدأ مشروعاً→

اقرأ بعدها

  • AP
    Series
    ٢ شباط ٢٠٢٦·هندسة AI

    الهندسة المقترنة بـ AI، الجزء الأول: آليّة العمل

    افتتاح السلسلة. وين بساعد النموذج، وين بكذب، وكيف بنينا إيقاع يومي حول الاثنين.

    11 دقيقة
  • ES
    ١٨ كانون الثاني ٢٠٢٦·هندسة AI

    Eval suites للأدوات غير الحتمية

    كيف تختبر شي بيعطي جواب مختلف مرّتين. الـ harness، الـ tolerances، والـ budget.

    8 دقائق
  • CG
    ١٠ كانون الثاني ٢٠٢٦·هندسة AI

    حواجز تكلفة لـ آليّات الـ AI

    مكتبة محاسبة صغيرة بترجع تكلفتها بثلاث أسابيع. Tokens، retries، وإنذار الـ budget.

    6 دقائق
←العودة إلى كل المقالات

حين ينتج النموذج كوداً سيّئاً، المشكلة شبه دائماً أعلى من النموذج. الـ prompt «أعطني دالّة تفعل X» يلمح إلى spec يجب على النموذج تخمينه. spec سيّئ ينتج كوداً سيّئاً. spec جيّد ينتج كوداً يحتاج تحريراً لا إعادة كتابة. هذه بنية spec شحنّا منه، والأنماط المضادّة التي أزلناها للوصول إلى هناك.

كيف يبدو spec قابل للاستخدام#

أربعة أقسام، بهذا الترتيب، كلّ مرّة:

## الهدف
جملة واحدة. «ماذا» بالإضافة إلى، حيث مفيد، «لماذا».

## المدخلات
- النوع، الاسم، ما يمثّله كلّ
- القيود (المدى، قابليّة الـ null، الصيغة)
- الحالات الحدّيّة التي تهمّ (فارغ، كبير، unicode، …)

## المخرجات
- النوع، كيف يبدو النجاح
- ماذا يعيد / يرمي الفشل
- آثار جانبيّة، إن وجدت

## أمثلة
ثلاثة على الأقلّ:
١. مسار سعيد: مدخل نموذجيّ، مخرج متوقّع
٢. حالة حدّيّة: قيد عند حدّه
٣. فشل: مدخل يجب أن ينتج خطأ

## خارج النطاق
ماذا هذا ليس له. سطران أو ثلاثة.

قسم «خارج النطاق» هو السلاح السرّيّ. النموذج متفائل؛ سيُضيف بمساعدة ميزات لم تطلبها. قسم يقول صراحة «لا تتعامل مع pagination، ذلك يعيش في مكان آخر» يمنع حوالي نصف زحف النطاق غير المرغوب.

spec حقيقيّ، قبل وبعد#

هذا spec أنتج كوداً مروّعاً، وإعادة الكتابة التي أنتجت شيئاً شحنّاه.

قبل (مبهم، فقرة واحدة)#

اكتب دالّة تستورد CSV لجهات الاتّصال. يجب أن تتحقّق من البريد وتتخطّى المكرّرات. تأكّد أنّها تتّسع.

أنتج هذا كوداً:

  • قام بكشف المكرّرات الخاصّ به في الذاكرة (فلم يستطع «الاتّساع»).
  • تحقّق من البريد بـ regex رفض aliases الـ +.
  • أعاد void فلم يكن لدى المنادي فكرة عن عدد المستوردين.
  • سجّل الأخطاء إلى stdout.

كلّ من هذه كان تخميناً اضطرّ النموذج لاتّخاذه. كلّ تخمين كان خاطئاً.

بعد (مهيكل)#

## الهدف
استورد جهات الاتّصال من CSV stream إلى قاعدة بيانات Drift المحلّيّة، بشكل idempotent.

## المدخلات
- `Stream<List<int>> csv` — محتويات الملفّ، مُرمَّز UTF-8
- `String tenantId` — المستأجر النشط
- `int? batchSize` — حجم chunk للإدراجات، افتراضيّاً ٥٠٠

## المخرجات
- `ImportResult { imported: int, skipped: int, errors: List<RowError> }`
- يرمي `ImportFailed` فقط على خطأ قاتل (header تالف).

## أمثلة
١. ١٠٠٠ صفّ صحيح، بدون مكرّرات → imported=١٠٠٠، skipped=٠، errors=[]
٢. ١٠٠٠ صفّ، ٥٠ موجودون أصلاً بالبريد → imported=٩٥٠، skipped=٥٠، errors=[]
٣. ١٠٠٠ صفّ، ١٠ ببريد مشوّه → imported=٩٩٠، skipped=٠، errors=[١٠ RowErrors مع رقم الصفّ + السبب]

## خارج النطاق
- لا إرسال إشعارات. المنادي يفعل ذلك.
- لا تقارير تقدّم. المنادي يُغلّف بإشارة تقدّمه الخاصّة.
- لا حذف لجهات اتّصال «قديمة». الاستيراد يُدرج فقط.
- لا اكتشاف صيغة CSV تلقائيّ. UTF-8 مع فاصلة، سلاسل بين علامتَي اقتباس.

التمريرة الأولى ضدّ هذا الـ spec كانت ٩٠٪ صحيحة. حرّرنا الـ ١٠٪ المتبقّية (في الغالب شكل RowError، الذي اخترعه النموذج بشكل معقول لكن ليس بالضبط لنمطنا الموجود)، كتبنا اختبارات ضدّ الأمثلة الثلاثة، شحنّا.

توقّفنا عن قول «النموذج يكتب كوداً سيّئاً» حالما اعترفنا بأنّ الشكوى الحقيقيّة كانت «النموذج يكتب الكود الذي لم ندرك أنّنا حدّدناه بشكل سيّئ».

مراجعة هندسيّة، الأسبوع الرابع عشر

أنماط مضادّة أزلناها#

خمسة أشياء كنّا نضعها في specs أضرّت بالإخراج:

١. «أفضل الممارسات» كقيد#

«استخدم أفضل الممارسات في معالجة الأخطاء». هذا لا يعني شيئاً. النموذج يأخذ متوسّط آلاف الاتّفاقيّات وينتج شيئاً عامّاً. استبدل بـ: «على خطأ parse، ارمِ ParseError مع رقم الصفّ والسبب. استمرّ في معالجة الصفوف المتبقّية.»

٢. «أداء عالٍ» أو «يتّسع جيّداً»#

هذه الكلمات تطلق إفراط هندسة. النموذج يضيف caching، معالجة batch، تزامن async، كلّها قد تكون خاطئة لسياقك. استبدل بالقيد الفعليّ: «يجب أن يتعامل مع ١٠٠ ألف صفّ في أقلّ من ٣٠ ثانية على جهاز الاختبار.»

٣. ذيل «وأيضاً»#

«اكتب دالّة تفعل X. وأيضاً تعامل مع الحالة حين Y. وأيضاً دعها Z». سلسلة «وأيضاً» تُقرأ من النموذج كسلسلة تبعيّة؛ النموذج يخترع تشابكاً بنيويّاً لم يكن مطلوباً. استبدل بمتطلّبات منفصلة، مسمّاة.

٤. تلميحات تنفيذ#

«استخدم hash map». «استخدم streams». تلميحات من مهندس متعب لم ينتهِ من التفكير. النموذج سيتبعها. إن لم تؤمن بالتلميح كاملاً، لا تُضمّنه. دع النموذج يقترح؛ أنت تحرّر.

٥. «اجعله عامّاً»#

هذه ميزة تنتج أكثر التمريرات الأولى إيلاماً. النموذج يخترع معاملات نوع وتجريدات لا تحتاجها. إن احتجت العمومية فعلاً، حدّد حالة الاستخدام الثانية. وإلّا قل «لجهات الاتّصال فقط، لا حاجة للتعميم.»

أين تنقذنا صيغة الـ spec#

ثلاثة أماكن، بترتيب الأثر:

  1. جودة التمريرة الأولى. الدقّة المتوسّطة على spec مهيكل ~٩٠٪. على prompt غير مهيكل، ~٥٠٪. الفرق بين «هذا قابل للشحن بعد التحرير» و «هذا أسرع للرمي بعيداً.»
  2. القابليّة للمراجعة. زميل يقرأ الـ spec، لا الـ prompt. الـ spec يبقى في وصف الـ PR كي يستطيع المراجع رؤية ما طُلب.
  3. إعادة الاستخدام. نفس الـ spec، مطبّقاً بعد ستّة أشهر حين تغيّر الشركة القاعدة، ينتج diff مُصحَّح بتحرير سطرَين.

أين لا تساعد صيغة الـ spec#

التصميم المفتوح («كيف يجب أن نُهيكل هذه الوحدة»)، التصحيح («ما الخطأ هنا»)، وإعادة الهيكلة («نظّف هذا») كلّها تحتاج أشكالاً مختلفة. الـ specs لـ «ابنِ هذا الشيء»، لا «حسّن هذا الشيء». prompts مختلفة.

الجزء التالي من هذه السلسلة عن حزم الـ eval لأدوات غير حتميّة، وهي أقرب شيء لاختبار وحدة للنموذج نفسه. صفحة السلسلة تتابع البقيّة.