النسخة الأولى من الموجّه (البرومبت) مسودة. كثيرًا ما تعطيك شيئًا قريبًا مما تريد، والفجوة بين القريب والصحيح تُسدّ بالتكرار: تغيير الموجّه عن قصد، وتشغيله مجددًا على المُدخل نفسه، والتحقق من أن التغيير ساعد. إذا جرى ذلك بإهمال، يتحول التكرار إلى إعادة صياغة عشوائية حتى تبدو مخرجات محظوظة واحدة جيدة. وإذا جرى كتجربة صغيرة، يعطيك موجّهًا ينجح على المُدخلات المئة التالية، لا على المُدخل الذي اختبرته فقط.
للطريقة خمس خطوات: حدّد شكل الجيد، واحتفظ بمُدخلات اختبار ثابتة، وغيّر شيئًا واحدًا في كل مرة، وقارن المخرجات، واعرف متى تتوقف.
حدّد شكل الإجابة الجيدة
قبل أن تعدّل أي شيء، اكتب ما يجب أن تفعله المخرجات، على شكل فحوص تجيب عنها بنعم أو لا. عبارة "رسالة commit جيدة" لا يمكن فحصها. أما هذه فيمكن:
- سطر الموضوع أقل من 50 حرفًا.
- تتبع صيغة Conventional Commits (
fix:وfeat:وغيرهما). - نص الرسالة يقول لماذا كان التغيير ضروريًا، لا ما يُظهره الفرق (diff) أصلًا.
- تذكر رقم الـ issue حين يوجد.
للمعايير وظيفتان. تخبرك بما تضيفه إلى الموجّه، لأن كلًا منها كثيرًا ما يكون تعليمة ناقصة. وتمنعك من الحكم على المخرجات بمدى لطف وقعها، وهي أسهل طريقة لقبول إجابة واثقة لكنها خاطئة.
احتفظ بمجموعة صغيرة من مُدخلات الاختبار
اختر من ثلاثة إلى عشرة مُدخلات وأبقِها ثابتة أثناء العمل. ضمّنها حالات معتادة، وحالتين صعبتين (حقل فارغ، أو مُدخل طويل جدًا، أو لغة لم يتوقعها الموجّه)، وكل مُدخل فشل من قبل. الموجّه المضبوط على مثال واحد يميل إلى ملاءمة ذلك المثال والفشل في التالي.
اكتب الموجّه قالبًا فيه خانة للمُدخل، حتى تعمل كل نسخة على المادة نفسها بالضبط.
غيّر شيئًا واحدًا في كل مرة
إذا غيّرت الدور والصيغة والأمثلة معًا وتحسّنت المخرجات، فلن تعرف أي تغيير فعل ذلك، وقد تحتفظ بتعديلين بلا فائدة. غيّر شيئًا واحدًا، وشغّل، وقارن. التبويبات التالية ثلاث نسخ من موجّه واحد، كل منها تغيير واحد عن السابقة.
- if len(password) > 8:
+ if len(password) >= 8:
return TrueUpdate password length validation
This commit updates the password validation logic by changing the comparison operator from > to >=. As a result, passwords that are exactly 8 characters long will now be considered valid. This change improves the accuracy of the validation and provides a better experience for users creating accounts.
النسخة 1 تفشل في المعيارين 2 و3: الموضوع بلا بادئة نوع، ونص الرسالة يعيد سرد الفرق بكلمات أكثر. النسخة 2 تضيف متطلبات الصيغة وتنجح في المعيارين 1 و2، لكن نصها ما زال يصف الفرق. التعديل التالي البديهي تعليمة أخرى ("اشرح السبب")، لكن النموذج لا يستطيع شرح سبب لم يُعطَ له قط. النسخة 3 تضيف السياق الناقص بدلًا من ذلك، فيأتي النص والإشارة إلى الـ issue دون أن يُطلبا. هذا أشيع درس في التكرار: حين لا تصلح التعليمة المخرجات، يكون الموجّه في الغالب ناقص المعلومات، لا ناقص التشديد.
قارن المخرجات جنبًا إلى جنب
شغّل كل نسخة على كل مُدخل اختبار، وشغّل كلًا منها أكثر من مرة، لأن نماذج المحادثة تختار كلماتها بالسحب العشوائي ويختلف تشغيلان للموجّه نفسه. ضع المخرجات بجوار بعضها وافحصها وفق معاييرك، لا وفق ما تتذكره من التشغيل السابق.
وللمعايير الدقيقة، يمكن أن يؤدي استدعاء نموذج ثانٍ المرور الأول من التقييم. الصق المخرجات في موجّه تقييم مع المعايير مكتوبة بوضوح:
| المعيار | المخرج A | المخرج B |
|---|---|---|
| 1. الموضوع أقل من 50 حرفًا | نجاح: الموضوع 45 حرفًا | نجاح: الموضوع نفسه، 45 حرفًا |
| 2. Conventional Commits | نجاح: يبدأ بـ "fix:" | نجاح: يبدأ بـ "fix:" |
| 3. النص يشرح السبب | فشل: "Change the length check from > to >=" يعيد سرد الفرق | نجاح: "users who followed the instructions could not sign up" |
| 4. يذكر الـ issue | فشل: لا رقم issue | نجاح: "Fixes #412" |
تعامل مع المقيّم من النماذج على أنه مساعد، لا حَكَم. وثّق Zheng وزملاؤه عام 2023، في بحث "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena"، تحيّزات لدى النماذج المقيِّمة، منها تفضيل الإجابات الأطول والإجابة في موضع معين. اجعل المعايير قابلة للفحص، واطلب دليلًا مقتبسًا، وبدّل ترتيب A وB حين تقارن بين اثنين، واقرأ عينة من المخرجات بنفسك. والفحوص مثل عدّ الأحرف أكثر موثوقية كسطر كود منها كحكم نموذج.
أصلح الموجّه، لا المحادثة
في المحادثة يغريك أن تصحح الإجابة برسائل متابعة: "أقصر"، "لا، اذكر الـ issue"، "استخدم الصيغة الأخرى". هذا يعطيك مخرجًا جيدًا واحدًا ويترك الموجّه سيئًا كما كان. حين ينجح تصحيح ما، انقله إلى الموجّه وشغّل الموجّه من جديد. وفي المرة القادمة التي تحتاج فيها إلى النتيجة، تلصق رسالة واحدة بدلًا من تكرار خمس.
احتفظ بالنسخ القديمة مع ملاحظة من سطر واحد عما تغيّر وما أصلحه. ملف نصي عادي يكفي. وحين يجعل تعديل لاحق الأمور أسوأ، تستطيع العودة بدلًا من محاولة تذكّر ما كان الموجّه يقوله.
إجراء المقارنة في الكود
ما إن يعمل الموجّه عبر واجهة API، يستطيع سكربت قصير إنتاج العرض المتجاور لكل نسخة وكل مُدخل اختبار. يستخدم هذا السكربت مكتبة Python من OpenAI ويكتب ملف markdown تقرؤه من أوله إلى آخره.
from openai import OpenAI
client = OpenAI()
MODEL = "your-model-id" # e.g. from your provider's model list
# each prompt file contains {input} where the test diff goes
PROMPTS = {
"v2": open("prompts/commit_v2.txt").read(),
"v3": open("prompts/commit_v3.txt").read(),
}
TESTS = [open(f"tests/diff_{i}.txt").read() for i in range(1, 6)]
with open("results.md", "w") as out:
for i, test in enumerate(TESTS, 1):
out.write(f"## Test {i}\n\n")
for name, template in PROMPTS.items():
for run in (1, 2):
response = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": template.replace("{input}", test)}],
)
out.write(f"### {name}, run {run}\n\n{response.choices[0].message.content}\n\n")
متى تتوقف
توقف حين ينجح كل معيار على كل مُدخل اختبار عبر تشغيلين أو ثلاثة. الإضافة بعد ذلك تضيف طولًا في الغالب، وكل تعليمة إضافية شيء آخر قد يتعارض مع البقية.
وتوقف أيضًا حين تبدأ التغييرات في تبادل الإخفاقات: تعديل يصلح الاختبار 2 ويكسر الاختبار 4، والتالي يعكس ذلك. هذا النمط يعني أن الموجّه يُطلب منه شيء لا تستطيع تعليمة واحدة تثبيته. المخارج المعتادة أن تعرض الصيغة بمثالين (الموجّه بالأمثلة)، أو تقسم العمل إلى خطوات بـسلسلة الموجّهات، أو تنقل الأجزاء الحتمية، مثل عدّ الأحرف أو فحص الصيغة، إلى كود يفحص المخرجات. وإذا نفدت أفكارك، يمكن أن يساعد الموجّه الفوقي: أعطِ نموذجًا الموجّه والمُدخل والمخرج السيئ، واسأله أي جزء من الموجّه سبّب ذلك على الأرجح.
الأسئلة الشائعة
كيف أحسّن موجّهًا يعطي إجابات سيئة؟
انظر إلى الإجابة السيئة وسمِّ ما فيها من خطأ: صيغة خاطئة، أو حقيقة ناقصة، أو جمهور خاطئ، أو طول زائد. ثم ابحث عما لم يقله الموجّه وكان سيمنع ذلك، وأضف ذلك الشيء الواحد، وشغّل النسخة الجديدة على المُدخل نفسه. الإجابات السيئة تأتي في الغالب من سياق ناقص أو تعليمة صيغة ناقصة أكثر مما تأتي من الصياغة.
كم مُدخل اختبار أحتاج لاختبار موجّه؟
للموجّه الذي ستعيد استخدامه، تكفي عادةً من ثلاثة إلى عشرة: بضع حالات معتادة، وحالة أو حالتان حدّيتان (قصير جدًا، أو طويل جدًا، أو غير مألوف)، ومُدخل واحد فشل سابقًا. أبقِها ثابتة أثناء التحسين، حتى يأتي أي تغيير في المخرجات من الموجّه لا من مُدخل مختلف.
لماذا أحصل على إجابة مختلفة حين أشغّل الموجّه نفسه مرة أخرى؟
نماذج المحادثة تختار كل كلمة بالسحب من توزيع احتمالات، فتتنوع المخرجات بين التشغيلات. عندما تقارن نسختين من موجّه، شغّل كلًا منهما أكثر من مرة على المُدخلات نفسها. الفرق الذي يظهر في كل تشغيل حقيقي على الأرجح، والذي يظهر في تشغيل واحد قد يكون مصادفة. وعبر واجهة API يمكنك أيضًا خفض درجة الحرارة لتقليل التنوع.
هل أستخدم الذكاء الاصطناعي لتقييم مخرجات موجّهي؟
نعم، للمعايير التي تستطيع صياغتها بدقة، مثل "نص الرسالة يقول لماذا كان التغيير ضروريًا" أو "يذكر رقم الـ issue". أعطِ المقيّم معاييرك بالضبط واطلب نجاحًا أو فشلًا لكل معيار مع اقتباس دليلًا. للمقيّمين من النماذج تحيّزات معروفة، منها تفضيل الإجابات الأطول وتفضيل موضع على آخر، فاقرأ بعض المخرجات بنفسك وبدّل الترتيب حين تقارن بين اثنين.
متى أتوقف عن تحسين الموجّه؟
توقف حين ينجح كل معيار على كل مُدخل اختبار عبر تشغيلين أو ثلاثة، أو حين يصلح كل تغيير جديد حالة ويكسر أخرى. عند تلك النقطة لا يكون الموجّه هو المشكلة عادةً: قد تحتاج المهمة إلى أمثلة، أو إلى تقسيمها إلى خطوات، أو إلى فحص في الكود.