إزاي تكتب prompt لمهمة كود حقيقية
معظم الشكاوى من إن «الـ AI بيكتب كود وحش» مش شكوى من النموذج، دي شكوى من السؤال. الحاجة دي أسهل ما تتشرح بمثال واحد كامل، فخلينا ناخد مهمة حقيقية من مشروع حقيقي ونشوف الفرق بإيدينا.
المهمة: عندنا مشروع لارافيل فيه عملاء وأوردرات. عايزين endpoint واحد يرجّع أوردرات عميل معيّن، مع فلترة اختيارية بتاريخين، ومقسّم على صفحات.
المحاولة الأولى: الـ prompt الوحش
اكتبلي كود لارافيل يجيب أوردرات العميل
الرد بييجي بسرعة وشكله محترم:
public function index($id)
{
$orders = Order::where('customer_id', $id)->get();
return response()->json($orders);
}
الكود ده مش «غلط» بالمعنى الحرفي. هو بس مش صالح للاستخدام، ولأسباب مالهاش علاقة بالنموذج:
- مفيش تحقق من الصلاحية. أي واحد معاه رقم عميل يقدر يقرا أوردرات أي حد. دي مش تفصيلة، دي تسريب بيانات.
- مفيش pagination. أول عميل عنده عشرة آلاف أوردر هيقفّل الطلب.
- مفيش فلترة بالتاريخ — وهي أصلًا نص المطلوب.
$idخام مش Route Model Binding، فمفيش 404 لو العميل مش موجود.- بيرجّع كل أعمدة الجدول زي ما هي، بما فيها حاجات مش المفروض تخرج.
النموذج ماكانش عارف أي حاجة من دي. إنت ماقلتهاش.
المحاولة التانية: الـ prompt الكويس
السياق: مشروع Laravel 11 + MySQL. عندي موديل Order و Customer،
والعلاقة: Customer hasMany Order. عمود التاريخ اسمه placed_at وبيتخزن UTC.
عندي Policy على Customer فيها ميثود اسمها viewOrders.
المطلوب: endpoint واحد
GET /api/customers/{customer}/orders
- يرجّع أوردرات العميل ده هو بس
- from و to اختياريين (تاريخ)، الفلترة على placed_at
- ترتيب من الأحدث للأقدم
- 20 نتيجة في الصفحة
القيود:
- الفاليديشن في FormRequest منفصل، مش جوه الكنترولر
- استخدم Route Model Binding
- الصلاحية تتشيك بـ authorize قبل أي استعلام
- من غير N+1: الأوردر بيتعرض معاه items
- متكتبش شرح، اكتب الكود بس
المطلوب تسليمه: كلاس الـ FormRequest، ميثود الكنترولر، وسطر الراوت.
شوف الفرق: مفيش كلمة زيادة، بس فيه سياق، ومتطلب قابل للقياس، وقيود، وشكل مخرج محدد. النتيجة بقت حاجة زي دي:
final class OrderIndexRequest extends FormRequest
{
public function rules(): array
{
return [
'from' => ['nullable', 'date'],
'to' => ['nullable', 'date', 'after_or_equal:from'],
];
}
}
public function index(OrderIndexRequest $request, Customer $customer)
{
$this->authorize('viewOrders', $customer);
return $customer->orders()
->with('items')
->when($request->date('from'), fn ($q, $from) => $q->where('placed_at', '>=', $from))
->when($request->date('to'), fn ($q, $to) => $q->where('placed_at', '<=', $to))
->latest('placed_at')
->paginate(20);
}
Route::get('customers/{customer}/orders', [OrderController::class, 'index']);
ده كود تقدر تشتغل بيه فعلًا. الصلاحية بتتشيك قبل أي حاجة، الفلترة اختيارية بجد، مفيش N+1، والفاليديشن في مكانه.
لسه فيه غلطة — وهنا بيت القصيد
الكود اللي فوق فيه حاجة هتوجعك بعد أسبوعين في الإنتاج.
$request->date('to') بترجّع التاريخ عند بداية اليوم، يعني 2026-08-30 معناها 2026-08-30 00:00:00. فأي أوردر اتعمل في نفس اليوم الساعة عشرة الصبح هيقع بره الفلتر. المستخدم هيقولك «أنا مختار لحد ٣٠، والأوردر بتاع ٣٠ مش ظاهر» — وهو معاه حق.
الإصلاح سطر:
->when($request->date('to'), fn ($q, $to) => $q->where('placed_at', '<=', $to->endOfDay()))
وفي مشروع بيخدم مستخدمين في مصر والسيرفر UTC، فيه طبقة تانية: «آخر اليوم» بتاعت المستخدم مش «آخر اليوم» بتاعت السيرفر. لو التطبيق بيعرض بتوقيت القاهرة، الفلتر لازم يتحوّل قبل المقارنة، مش بعدها.
النقطة المهمة: الـ prompt الكويس رفع مستوى الكود من «مرفوض» لـ «شبه جاهز»، لكن هو ما شالش خطوة المراجعة. الغلطة دي مكانتش هتتصاد إلا بواحد فاهم أن التاريخ من غير وقت بيتحوّل لمنتصف الليل. ولو عايز قائمة الفحص كاملة، كتبتها في [مراجعة الكود اللي الذكاء الاصطناعي كتبه](/blog/ai-code-review-checklist).
ست قواعد اطلع بيها من المثال ده
- السياق قبل الطلب. الإصدار، قاعدة البيانات، أسماء الموديلات والأعمدة، والقواعد اللي عندك. سطرين سياق بيوفروا عليك مراجعة كاملة.
- المتطلب بصيغة قابلة للاختبار. «مقسّم على صفحات» كلام؛ «٢٠ في الصفحة» متطلب.
- اكتب القيود صراحة — وخصوصًا اللي متعملهوش. «من غير N+1»، «متغيّرش الميجريشن»، «متضيفش باكدج جديدة».
- حدد شكل المخرج. «الكلاس والميثود والراوت بس، من غير شرح» بيوفر عليك صفحتين قراية.
- قطعة واحدة في المرة. طلب فيه خمس ميزات بيرجّع خمس أنصاف حلول.
- اطلب الاختبار مع الكود. «اكتبلي feature test بيتأكد إن مستخدم تاني بياخد 403» بتكشف نص الأخطاء قبل ما تشوفها.
جرّبها النهاردة
خد آخر تاسك اشتغلت فيها، واكتب الـ prompt بتاعها مرتين: مرة زي ما إنت بتكتب عادة، ومرة بالقواعد الستة دي. حط الردين جنب بعض. الفرق هتشوفه بنفسك من غير ما حد يقولك.
وفي أكاديمية أنوبت بندرّب على ده جوه المسار نفسه — الطالب في [الباك إند المتقدم](/courses/back-end-2) بيكتب المتطلب بصيغة قابلة للاختبار الأول، وبعدين يشتغل. القدرة إنك تحوّل كلام مبهم لمتطلب واضح هي نفسها مهارة الهندسة، سواء إنت بتكلم نموذج أو بتكلم زميل.