تحسين جودة الردود باستخدام تقنيات (Few-Shot Prompting) داخل LangChain
تحسين جودة الردود باستخدام تقنيات Few-Shot Prompting داخل LangChain
عند بناء تطبيقات تعتمد على نماذج اللغة الكبيرة، يكتشف المهندس بسرعة أن المشكلة ليست في تشغيل النموذج فقط، بل في جعل الإجابات منضبطة، متسقة، وقريبة من النمط المطلوب. كثير من النماذج تستطيع الفهم العام، لكنها تتذبذب عندما تطلب منها تنسيقاً محدداً، أسلوباً تحريرياً ثابتاً، أو منطقاً تنفيذياً متكرراً. هنا تظهر قيمة تقنية Few-Shot Prompting باعتبارها وسيلة عملية لتعليم النموذج من خلال أمثلة صغيرة داخل الطلب نفسه دون الحاجة إلى Fine-Tuning.
الفكرة الأساسية بسيطة هندسياً: بدلاً من إرسال تعليمات مجردة فقط، نقوم بحقن عدة أمثلة إدخال/إخراج داخل Prompt لكي يستنتج النموذج النمط المطلوب. في البيئات الإنتاجية، هذه التقنية فعالة جداً عندما نريد توحيد أسلوب الرد، تقليل الغموض، أو إجبار النظام على إنتاج مخرجات أقرب إلى القالب المتوقع، خاصة عند دمجها مع هندسة الأوامر داخل الكود وStructured Output Parsers.
متى نستخدم Few-Shot Prompting بدلاً من الحلول الأخرى؟
هذه التقنية مناسبة عندما تكون المشكلة سلوكية أو تنسيقية أكثر من كونها معرفية. إذا كان النموذج يعرف المجال لكن يفشل في اتباع الأسلوب، فإضافة أمثلة غالباً أفضل وأسرع من إعادة تدريب نموذج. أما إذا كانت المشكلة نقص معرفة خارجية حديثة أو وثائق خاصة بالشركة، فهنا يكون RAG هو المسار الصحيح. وإذا كان المطلوب تغيير عميق ودائم في سلوك النموذج على نطاق واسع، فقد يصبح Fine-Tuning أكثر جدوى.
- استخدم
Few-Shotلتحسين النبرة، البنية، والتنسيق. - استخدم RAG عندما تحتاج إلى حقائق موثقة من مصادر خارجية.
- استخدم
Fine-Tuningعندما تريد سلوكاً دائماً ومتكرراً عبر حالات كثيرة.
المعمارية البرمجية داخل LangChain
داخل سلاسل LangChain، يعمل Few-Shot Prompting كطبقة تشكيل للسياق قبل وصول الطلب إلى LLM. تدفق البيانات يمر غالباً بالمراحل التالية:
- استقبال مدخل المستخدم.
- اختيار أمثلة مناسبة ثابتة أو ديناميكية.
- حقن الأمثلة داخل
Prompt Template. - إرسال النص المركب إلى النموذج.
- استقبال الرد الخام.
- تمرير الرد إلى
Parserأو طبقة تحقق إن لزم.
هذه البنية مهمة لأنها تفصل بين منطق الأعمال وطبقة التوجيه النصي. أي أنك تستطيع تحديث الأمثلة دون تغيير منطق التطبيق نفسه، وهو أسلوب ممتاز في الأنظمة التي تحتاج تحسينات مستمرة أو تجارب A/B Testing.
بناء قالب Few-Shot عملي
قبل البدء، من الأفضل أن تكون قد أعددت البيئة البرمجية كما في مقال تثبيت مكتبات Python الأساسية، وأنهيت الاتصال الأول مع API. المثال التالي يبني مصنفاً بسيطاً يحول شكاوى العملاء إلى ردود دعم مختصرة ومهنية:
from langchain_core.prompts import PromptTemplate, FewShotPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.output_parsers import StrOutputParser
examples = [
{
"customer_message": "وصل الطلب متأخراً يومين وأحتاج تفسيراً واضحاً.",
"support_reply": "نعتذر عن التأخير. تم تسجيل ملاحظتك، ويجري التحقق من سبب التأخر مع شركة الشحن وسنوافيك بالتحديث خلال 24 ساعة."
},
{
"customer_message": "استلمت منتجاً مختلفاً عن الذي طلبته.",
"support_reply": "نعتذر عن الخطأ في الطلب. يرجى إرسال رقم الطلب وصورة المنتج المستلم لنبدأ فوراً بإجراءات الاستبدال."
}
]
example_prompt = PromptTemplate(
input_variables=["customer_message", "support_reply"],
template="رسالة العميل: {customer_message}\nالرد الاحترافي: {support_reply}"
)
few_shot_prompt = FewShotPromptTemplate(
examples=examples,
example_prompt=example_prompt,
prefix="أنت موظف دعم فني محترف. اكتب رداً عربياً واضحاً ومهذباً ومختصراً.",
suffix="رسالة العميل: {input}\nالرد الاحترافي:",
input_variables=["input"]
)
model = ChatOpenAI(model="gpt-4o-mini", temperature=0.2)
parser = StrOutputParser()
chain = few_shot_prompt | model | parser
response = chain.invoke({
"input": "تم خصم المبلغ مرتين من بطاقتي وأريد استرجاع الدفعة الزائدة."
})
print(response)
في هذا المثال، الأمثلة لا تعطي معلومات معرفية جديدة فقط، بل تحدد للنموذج شكل الجواب، درجته الرسمية، وطوله التقريبي. هذا يقلل التذبذب أكثر بكثير من مجرد كتابة تعليمات عامة مثل “كن مهذباً”. ويمكنك تعميق هذا المسار عبر ضبط Temperature لتقليل العشوائية.
كيف يقرأ النموذج هذه الأمثلة؟
النموذج لا “يحفظ” الأمثلة بالطريقة البشرية، لكنه يلتقط النمط الإحصائي داخل السياق الحالي. إذا كانت جميع الأمثلة تبدأ باعتذار وتنتهي بخطوة تنفيذية، فغالباً سيكرر السلوك نفسه. لذلك يجب أن تكون الأمثلة:
- قصيرة ولكن معبرة.
- متجانسة في النبرة.
- قريبة من سيناريوهات الاستخدام الحقيقي.
- غير متناقضة في البنية أو التعليمات.
استخدام أمثلة ديناميكية بدلاً من أمثلة ثابتة
في التطبيقات المتقدمة، لا نستخدم دائماً أمثلة ثابتة. يمكن انتقاء الأمثلة الأقرب إلى سؤال المستخدم آلياً عبر تشابه دلالي باستخدام Embeddings وVector Databases. هذه البنية تسمى أحياناً Example Retrieval، وهي مفيدة عندما يصبح عدد الأمثلة كبيراً أو متنوعاً.
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
examples = [
{"input": "أريد استرجاع المال", "output": "نعتذر لك. يرجى تزويدنا برقم الطلب لبدء معالجة الاسترجاع."},
{"input": "تم إرسال المقاس الخطأ", "output": "نعتذر عن الخطأ. سنساعدك في الاستبدال فور تزويدنا بتفاصيل الطلب."},
{"input": "الشحنة متأخرة", "output": "نعتذر عن التأخير. نتحقق حالياً من حالة الشحن وسنحدثك قريباً."}
]
selector = SemanticSimilarityExampleSelector.from_examples(
examples,
OpenAIEmbeddings(),
Chroma,
k=2
)
هنا يتم اختيار أفضل مثالين فقط لكل طلب. هذا يحسن الجودة ويخفض استهلاك الرموز Tokens لأنك لا ترسل جميع الأمثلة في كل مرة.
تصميم البرومبت الاحترافي
حتى مع الأمثلة القوية، يجب أن تكون التعليمات الأساسية واضحة. البرومبت الجيد يحدد الدور، الهدف، القيود، وشكل المخرجات. مثال مناسب:
أنت مساعد دعم فني عربي. استخرج نية العميل أولاً بشكل ضمني، ثم اكتب رداً لا يزيد عن 60 كلمة، يبدأ بتعاطف مهني وينتهي بخطوة عملية واحدة فقط. التزم بأسلوب الأمثلة السابقة ولا تضف معلومات غير مؤكدة.
بهذا الشكل، أنت لا تعتمد على الأمثلة وحدها، بل تبني “عقداً سلوكياً” يوجه النموذج ويقلل الانحرافات. وعند الحاجة إلى نواتج منظمة، يمكنك دمج ذلك مع مبدأ JSON Output كما في المقال الخاص بـ Output Parsers.
أفضل الممارسات الهندسية
1) لا تكثر الأمثلة بلا داعٍ
إضافة أمثلة كثيرة قد تربك النموذج أو ترفع التكلفة. الأفضل عادة بين مثالين إلى خمسة أمثلة عالية الجودة، إلا إذا كان السيناريو شديد التعقيد.
2) راقب الانحياز في الأمثلة
إذا كانت كل الأمثلة متشابهة جداً، فقد يبالغ النموذج في التعميم. التنوع المنضبط مهم: اختلاف في الصياغة، مع ثبات في المعيار.
3) اختبر الأداء بشكل آلي
لا يكفي الانطباع البشري. قارن بين Zero-Shot وFew-Shot عبر مجموعة اختبار، ثم راقب الجودة بواسطة Evaluation أو LangSmith.
4) اجمعها مع الذاكرة أو الاسترجاع عند الحاجة
إذا كان التطبيق محادثياً، يمكن دمج Few-Shot مع Buffer Memory أو Summary Memory. وإذا كان يعتمد على معرفة خارجية، فدمجه مع RAG يكون أكثر احترافية.
أخطاء شائعة يجب تجنبها
- كتابة أمثلة ممتازة لكن إعطاء تعليمات نهائية متناقضة معها.
- وضع أمثلة طويلة جداً فتستهلك السياق وتقلل مساحة سؤال المستخدم.
- الاعتماد على أمثلة من بيئة مختلفة عن التطبيق الفعلي.
- نسيان اختبار حالات الحافة
Edge Cases.
الخلاصة العملية
تقنية Few-Shot Prompting داخل LangChain ليست مجرد تحسين تجميلي، بل أداة هندسية حقيقية لضبط السلوك وتقليل التذبذب في الإجابات. قيمتها الكبرى أنها سريعة التنفيذ، منخفضة المخاطر مقارنة بـ Fine-Tuning، ويمكن دمجها بسهولة مع سلاسل المعالجة، الذاكرة، المحللات، وحتى أنظمة RAG. عندما تصمم أمثلتك بعناية وتفهم مسار البيانات من الإدخال حتى المخرج، تتحول البرومبتات من نصوص عشوائية إلى طبقة تحكم هندسية قابلة للقياس والتحسين المستمر.
1 comment