هندسة الذكاء الاصطناعيJune 13, 2026·6 دقيقة قراءة·Miracle KaluMiracle Kalu

فن الـ One-Shot Prompt: كيف أحصل على مسودات مفيدة من المحاولة الأولى

A developer typing a structured prompt into an AI coding assistant on a clean desk.

أسطورة السطر السحري

تُظهر معظم لقطات شاشة أدوات البرمجة بالذكاء الاصطناعي مستخدمًا يكتب "build me a payment system" ويحصل على تكامل Stripe يعمل. هذه العروض التوضيحية هي إعلانات أجهزة التمارين الرياضية لهندسة البرمجيات: مثيرة للإعجاب، ومنتشرة، وغير مرتبطة إلى حد كبير بواقع الإنتاج.

قضيت الثمانية عشر شهرًا الماضية في دمج النماذج اللغوية الكبيرة في سير عملي. كانت المفاجأة الأكبر ليست في مدى قدرتها، بل في مدى اعتماد المخرجات على شكل الموجه الأول. الموجه الجيد ذو المحاولة الواحدة يمكن أن يوفر ساعات. والموجه السيئ ينشئ ديونًا تقنية أسرع من أي مطور مبتدئ. يتحدث هذا المقال عن كيفية كتابة النوع الأول — مع الحفاظ على توقعات واقعية.

لماذا تفشل موجهات العروض التوضيحية في الإنتاج

تعمل موجهات العروض التوضيحية لأن العرض التوضيحي هو المنتج. أما في الكود الحقيقي، فالمنتج هو الحالة الحافة. لا يمكن لموجه من خمس كلمات أن يُضمن فلسفة معالجة الأخطاء، أو الاصطلاحات الحالية، أو حقيقة أن نوع Order يحتوي بالفعل على couponId قابل للقيمة الفارغة. يبدو الناتج صحيحًا حتى يصطدم بقاعدة البيانات.

ما الذي أستخدم موجهات المحاولة الواحدة من أجله فعليًا

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

ما هو الموجه ذو المحاولة الواحدة فعليًا

الموجه ذو المحاولة الواحدة ليس جملة واحدة. إنه حزمة سياق كاملة تُسلَّم في رسالة واحدة. يحتوي على المهمة، والقيود، وتنسيق المخرجات المتوقع، ومعلومات كافية حول السياق ليتمكن النموذج من استخلاص التنازلات الصحيحة. الهدف هو تجنب ذهاب وإياب طويل يربطه معظم الناس بما يُسمى "Vibe Coding".

المحاولة الواحدة مقابل عدم تقديم أمثلة

الموجه بدون أمثلة (zero-shot) يصف ما تريده. أما الموجه ذو المحاولة الواحدة فيُظهر ما يبدو عليه الحل الجيد. في هندسة البرمجيات، يعني ذلك عادةً مثالًا صغيرًا لتنسيق المدخلات والمخرجات المتوقع، بالإضافة إلى القواعد التي يوضحها المثال. المثال هو الفرق بين "اكتب كودًا نظيفًا" و"اكتب كودًا يبدو هكذا".

السياق الأدنى القابل للتطبيق

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

بنية الموجه ذي المحاولة الواحدة الجاهز للإنتاج

أستخدم نفس البنية لكل مهمة تقريبًا. تبدو هكذا:

## الدور
أنت مهندس TypeScript أول تراجع دالة للتحقق من صحتها وأسلوبها.

## المهمة
أعد كتابة الدالة أدناه لتستخدم الإرجاع المبكر، وتزيل الشروط المتداخلة، مع الحفاظ على السلوك.

## المدخلات
    function processOrder(order: Order | null): Result {
      if (order !== null) {
        if (order.items.length > 0) {
          if (order.status === "confirmed") {
            return { ok: true, total: order.items.reduce((a, b) => a + b.price, 0) };
          } else {
            return { ok: false, error: "Order not confirmed" };
          }
        } else {
          return { ok: false, error: "No items" };
        }
      } else {
        return { ok: false, error: "Missing order" };
      }
    }

## القواعد
- لا تغير توقيع الدالة.
- لا تضف تبعيات خارجية.
- أعد فقط الكود المُعاد كتابته، داخل كتلة TypeScript.

## مثال على الأسلوب المتوقع
    function validateUser(user: User | null): Validation {
      if (!user) return { ok: false, error: "Missing user" };
      if (!user.emailVerified) return { ok: false, error: "Email not verified" };
      return { ok: true, user };
    }

الدور والمهمة

يحدد الدور مستوى الخبرة. لا أطلب من النموذج أن يكون "مفيدًا". بل أطلب منه أن يكون مهندس TypeScript أول، أو مراجع كود صارم، أو كاتب تقني. المهمة هي فعل واحد. إذا احتجت إلى فعلين، أكتب موجهين. دمج المهام هو الطريق للحصول على نتيجة صحيحة جزئيًا في مكانين.

المدخلات والقواعد

المدخلات هي الكود أو المخطط أو البيانات الدقيقة التي يعمل عليها النموذج. القواعد تزيل درجات الحرية. أكون صريحًا بشأن التواقيع والتبعيات وتنسيق المخرجات، لأن النموذج سيتخمّن بخلاف ذلك. والتخمين سريع وخاطئ.

المثال الذي يعلّم الأسلوب

يُظهر المثال الشكل المطلوب دون تقديم الإجابة. يجب أن يوضح النمط لا الحل. إذا كان المثال قريبًا جدًا من المدخلات، فسيُردّد النموذج التفاصيل السطحية. وإذا كان مجردًا جدًا، فسيتجاهله.

مثال: من طلب غامض إلى موجد قابل للتنفيذ

إليك إعادة كتابة حقيقية قمت بتفويضها مؤخرًا. كان الطلب الأولي من زميل "اجعل هذه التحققات أنظف". هذا ليس موجهًا؛ إنه مزاج. حوّلته إلى موجه ذي محاولة واحدة وحصلت على مسودة أولى احتاجت إلى مراجعة واحدة بدلًا من خمس.

الأصل الفوضوي

كانت الدالة تتولى التحقق من القسائم في عملية دفع متجر إلكتروني. تحققت من الوجود وتاريخ الانتهاء وسقف الاستخدام وأهلية المنتج في كتلة متداخلة واحدة. كانت التعقيد الدوري مرتفعًا، ورسائل الخطأ غير متسقة، وإضافة قاعدة تحقق جديدة تعني إضافة مستوى تداخل جديد.

الموجه الذي كتبته

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

المسودة الأولى التي تلقيتها

type CouponError = "EXPIRED" | "USAGE_LIMIT" | "NOT_APPLICABLE" | "INVALID";

function applyCoupon(coupon: Coupon, cart: Cart): Result<Coupon, CouponError> {
  if (!coupon.active) return err("INVALID");
  if (coupon.expiresAt < Date.now()) return err("EXPIRED");
  if (coupon.usedCount >= coupon.maxUses) return err("USAGE_LIMIT");
  if (!cart.items.some((item) => coupon.productIds.includes(item.productId))) {
    return err("NOT_APPLICABLE");
  }
  return ok(coupon);
}

لم يكن الناتج مثاليًا. استخدم نوع Result مخصصًا اضطررت إلى مواءمته مع اصطلاح الأخطاء الحالي لدينا، وشددت بعض أسماء المتغيرات. لكن البنية كانت صحيحة، والمنطق سليم، واستغرقت المراجعة خمس دقائق بدلًا من ثلاثين.

تحويل النمط إلى دالة قابلة لإعادة الاستخدام

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

interface PromptParts<T> {
  role: string;
  task: string;
  input: string;
  rules: string[];
  example: string;
}

function buildOneShotPrompt<T>(parts: PromptParts<T>): string {
  if (!parts.task.trim()) throw new Error("Task is required");
  if (!parts.input.trim()) throw new Error("Input is required");

  return [
    `## Role\n${parts.role}`,
    `## Task\n${parts.task}`,
    `## Input\n${parts.input}`,
    `## Rules\n${parts.rules.map((r) => `- ${r}`).join("\n")}`,
    `## Example of expected style\n${parts.example}`,
  ].join("\n\n");
}

const prompt = buildOneShotPrompt({
  role: "You are a senior TypeScript engineer.",
  task: "Refactor the function to use early returns and preserve behavior.",
  input: processOrderFunction.toString(),
  rules: [
    "Do not change the function signature.",
    "Do not add external dependencies.",
    "Return only the refactored code.",
  ],
  example: validateUserFunction.toString(),
});

فرض العقد

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

اصطياد المدخلات الناقصة

تصطاد الدالة المساعدة أيضًا الخطأ الأكثر شيوعًا: نسيان تضمين المدخلات الفعلية. لقد كتبت موجهات تصف دالة بشكل جميل دون تضمينها أبدًا. يسعد النموذج أن يُخيّل دالة بنفس الاسم. تجعل الدالة المساعدة ذلك مستحيلًا.

لماذا تكافئ نوافذ السياق الاختصار والبنية

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

الانضباط في ميزانية الرموز

أحافظ على موجهات المحاولة الواحدة تحت 1,500 رمز من التعليمات والأمثلة. هذا الحد يجبرني على تحديد ما يهم فعلًا. إذا لم أتمكن من شرح المهمة في هذه الميزانية، فأنا لا أفهمها بما يكفي لتفويضها.

متى تجزئة المهمة

إذا كانت المهمة تحتاج إلى سياق أكثر مما تسمح به الميزانية، فلا أكتب موجهًا أكبر. بل أقسم المهمة. يعمل موجه المحاولة الواحدة بشكل أفضل مع التحويلات المحدودة. ويفشل في "تصميم هذا النظام" لأن تصميم الأنظمة تكراري بطبيعته.

أنماط الفشل التي ستواجهها

المبالغة في ملاءمة المثال

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

افتراض سياق مشترك

لا يعرف النموذج قواعد lint الخاصة بك، أو فلسفتك في الاختبار، أو قيود النشر ما لم تخبره بها. أضيف الآن قسم قيود في كل موجه، حتى عندما يبدو زائدًا عن الحاجة. التكرار أرخص من التنظيف.

طلب عدد كبير من المخرجات

الموجه الذي يطلب كودًا واختبارات وتوثيقًا وسكربت ترحيل في آن واحد ينتج نسخًا سطحية من الأربعة. أفضل موجهًا واحدًا لكل مخرج، ثم تمريرة تركيبية إذا لزم الأمر.

متى لا يجب استخدام المحاولة الواحدة

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

القوة الحقيقية لموجهات المحاولة الواحدة لا تكمن في استبدال التفكير أو المراجعة. بل تكمن في ضغط أجزاء التنفيذ الواضحة حتى أتمكن من توجيه انتباهي إلى الأجزاء التي تهم.

النتائج المستخلصة

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

مشاركة:

XLinkedIn
Miracle Kalu

كتبه

Miracle Kalu

Senior Full Stack Engineer

أعجبك ما قرأته؟

أنا متاح لأدوار الهندسة الأولى والاستشارات التقنية. لنتحدث.

تواصل →

نُشر 13 يونيو 2026 · 6 دقيقة قراءة

مواصلة القراءة