يا جماعة الخير، السلام عليكم ورحمة الله. اسمحوا لي أحكي لكم قصة صارت معي ومع فريقي قبل فترة، قصة فيها إحباط وسهر ليالي، وفيها كمان لحظة “وجدتها!” اللي غيرت كل شي.
كنا شغالين على مشروع كبير لأحد العملاء، عبارة عن مساعد ذكي (Chatbot) لشركة محاماة ضخمة. الهدف كان بسيط: المساعد لازم يجاوب على أسئلة المحامين المتدربين حول آلاف الوثائق والقوانين الداخلية للشركة. جبنا أحدث نموذج لغوي كبير (LLM)، ودفعنا عليه “اللي فوقنا واللي تحتنا”، وكنا متحمسين جداً. في البداية، كانت النتائج مبهرة، النموذج كان بيفهم الأسئلة المعقدة ويرد بلغة سليمة ومقنعة.
لكن الكارثة بدأت تظهر شوي شوي. مرة سألنا المساعد عن “الإجراء المتبع في حال تعارض المصالح في القضية رقم 542″، فماذا كانت الإجابة؟ أعطانا إجراءً مفصلاً ومنطقياً جداً… لكنه مختلق بالكامل! لا هو موجود في وثائق الشركة ولا في أي قانون نعرفه. المساعد “ألّف” الإجابة من رأسه بثقة تامة. والموقف اللي عنجد “فرّطنا من الضحك” (والقهر)، لما سألناه عن مادة قانونية معينة، فجاوبنا بمشهد من مسلسل مصري مشهور! وقتها عرفنا إنه إحنا في ورطة حقيقية. النموذج كان “يهلوس” (Hallucinating) بشكل خطير، والعميل كان على وشك يفقد صبره. دخلنا في دوامة من الإحباط، أو زي ما بحب أسميها: “جحيم الإجابات الخاطئة”.
ما هي هلوسة النماذج اللغوية الكبيرة (LLM Hallucination)؟
قبل ما نكمل، خلونا نفهم شو يعني “هلوسة”. هلوسة الذكاء الاصطناعي مش زي هلوسة البشر، هي مصطلح لوصف ميل النماذج اللغوية الكبيرة لاختراع معلومات تبدو صحيحة ومنطقية، لكنها في الواقع خاطئة أو لا أساس لها من الصحة.
طيب ليش بصير هيك؟
ببساطة، النموذج اللغوي الكبير هو آلة احتمالات فائقة التعقيد، وليس قاعدة بيانات للمعرفة. هو لا “يعرف” الحقيقة، بل يتنبأ بالكلمة التالية الأكثر احتمالاً بناءً على مليارات النصوص التي تدرب عليها. إذا كان السؤال يتعلق بموضوع غير موجود في بيانات تدريبه، أو إذا كان السياق غير واضح، فإنه “يملأ الفراغات” بأكثر النصوص إقناعاً، حتى لو كانت خاطئة.
تخيل أنك تسأل طالباً ذكياً جداً قرأ كل كتب المكتبة لكنه لم يحفظها عن ظهر قلب. إذا سألته سؤالاً دقيقاً، قد لا يتذكر الإجابة بالضبط، لكنه سيستخدم ذكاءه وقدرته اللغوية لتأليف إجابة تبدو مقنعة جداً. هذا بالضبط ما يفعله الـ LLM.
محاولاتنا الأولى الفاشلة: “الترقيع” لا يجدي نفعاً
في البداية، حاولنا حل المشكلة بالطرق التقليدية، لكن للأسف كانت مثل اللي بحاول يصلح “بنشر” في عجلة سيارة بشريط لاصق.
1. هندسة الأوامر (Prompt Engineering)
أول شي عملناه هو تحسين الأوامر (Prompts). صرنا نكتب أوامر طويلة ومعقدة، ونقول للنموذج “يا عمي، كن دقيقاً!”، “لا تخترع معلومات”، “اعتمد فقط على الحقائق”. هذا الأسلوب حسّن النتائج بنسبة 10-20%، لكنه لم يحل المشكلة من جذورها. كان الأمر أشبه بترويض أسد جائع بإعطائه التعليمات شفهياً. غير عملي وغير مضمون.
2. إعادة التدريب (Fine-Tuning)
الفكرة الثانية كانت: “لماذا لا نعيد تدريب النموذج على بياناتنا الخاصة؟”. هذا ما يعرف بالـ Fine-Tuning. نظرياً، الفكرة ممتازة. عملياً، اكتشفنا أنها كابوس لوجستي. إعادة التدريب تتطلب:
- كمية هائلة من البيانات المنظمة: آلاف الأمثلة على شكل سؤال وجواب صحيح.
- قوة حاسوبية جبارة: تكلفة استئجار معالجات الرسوميات (GPUs) لساعات وأيام كانت فلكية.
- وقت وخبرة: العملية معقدة وتستغرق وقتاً طويلاً.
والأهم من كل هذا، حتى بعد إعادة التدريب، النموذج سيظل قادراً على الهلوسة عند سؤاله عن أي شيء خارج نطاق البيانات التي تدرب عليها حديثاً. كانت حلاً مكلفاً وغير شامل.
المنقذ وصل: تقنية التوليد المعزز بالاسترجاع (RAG)
بينما كنا على وشك إعلان فشل المشروع، اقترح أحد أعضاء الفريق الصغار سناً (الله يجزيه الخير) أن نجرّب تقنية اسمها “RAG”. في البداية، كنت متشككاً، لكن بعد قراءة بسيطة، أدركت أن هذا قد يكون هو الحل الذي نبحث عنه.
ما هو الـ RAG ببساطة؟
فكرة RAG عبقرية في بساطتها. بدلاً من أن تطلب من النموذج اللغوي (الطالب الذكي) أن يجيب من ذاكرته الواسعة والمشوشة، أنت تفعل الآتي:
- تذهب إلى المكتبة (قاعدة بياناتك الخاصة) وتجد الكتاب والصفحة المحددة التي تحتوي على الإجابة (هذه هي مرحلة **الاسترجاع – Retrieval**).
- تعطي الكتاب مفتوحاً على الصفحة الصحيحة للطالب وتقول له: “اقرأ هذه الفقرة وأجب على السؤال بناءً عليها فقط” (هذه هي مرحلة **التوليد – Generation**).
بهذه الطريقة، أنت تجبر النموذج على الاعتماد على مصدر حقيقي وموثوق للمعلومات (بياناتك أنت)، بدلاً من الاعتماد على “ذاكرته” العامة. أنت تحول النموذج من “مخترع” إلى “باحث وملخص” فائق الذكاء.
كيف طبقنا RAG خطوة بخطوة؟ (الجزء العملي)
هنا يبدأ الجزء الممتع. تطبيق RAG ليس معقداً كما يبدو، خصوصاً مع وجود مكتبات برمجية مثل LangChain و LlamaIndex التي تبسط العملية بشكل كبير. سأشرح لكم الخطوات الأساسية مع أمثلة كود بايثون بسيطة باستخدام مكتبة LangChain كمثال.
الخطوة الأولى: تجهيز “الكُتُب المفتوحة” (بناء قاعدة المعرفة)
قبل أي شيء، نحتاج إلى تحويل وثائقنا (PDFs, Word, Txt) إلى مكتبة قابلة للبحث السريع من قبل الكمبيوتر.
- تحميل وتقسيم المستندات: نقوم بتحميل المستندات وتقسيمها إلى أجزاء صغيرة (Chunks). هذا مهم لأننا لا نستطيع إرسال مستند من 100 صفحة إلى النموذج مرة واحدة.
- إنشاء المتجهات (Embeddings): هذه هي الخطوة السحرية. نقوم بتحويل كل جزء نصي إلى تمثيل رقمي (Vector) باستخدام نموذج خاص. هذا التمثيل الرقمي يلتقط “المعنى” الدلالي للنص. ببساطة، هو “تحويل النص إلى أرقام تفهمها الآلة”.
- تخزين المتجهات: نقوم بتخزين هذه المتجهات النصية في قاعدة بيانات متخصصة تسمى (Vector Database) مثل Chroma, FAISS, أو Pinecone. هذه القاعدة تسمح لنا بالبحث عن “المعنى” وليس فقط الكلمات المفتاحية.
هذا مثال بسيط لكيفية القيام بذلك برمجياً:
# ملاحظة: هذا الكود هو مثال توضيحي ويتطلب تثبيت المكتبات اللازمة
# pip install langchain openai chromadb pypdf sentence-transformers
from langchain.document_loaders import PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings # or HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
# 1. تحميل وتقسيم المستندات
loader = PyPDFLoader("قوانين_الشركة_الداخلية.pdf")
documents = loader.load()
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=150)
texts = text_splitter.split_documents(documents)
# 2. إنشاء المتجهات وتخزينها
# يتطلب وجود مفتاح API من OpenAI
embeddings = OpenAIEmbeddings()
vector_db = Chroma.from_documents(
documents=texts,
embedding=embeddings,
persist_directory="./chroma_db" # لحفظ قاعدة البيانات محلياً
)
print("تم بناء قاعدة المعرفة بنجاح!")
الخطوة الثانية: بناء نظام الاسترجاع والتوليد
الآن بعد أن أصبحت مكتبتنا جاهزة، نحتاج إلى ربطها بالنموذج اللغوي الكبير.
سير العمل يصبح كالتالي:
- المستخدم يطرح سؤالاً.
- نظامنا يحول السؤال إلى متجه (Embedding).
- نستخدم هذا المتجه للبحث في قاعدة بيانات المتجهات (Chroma) عن أكثر الأجزاء النصية تشابهاً وذات صلة بالسؤال.
- نأخذ هذه الأجزاء المسترجعة (السياق) ونرسلها إلى النموذج اللغوي الكبير مع السؤال الأصلي.
- النموذج اللغوي الكبير يقرأ السياق ويولد إجابة دقيقة بناءً عليه.
وهذا هو الكود الذي يكمل العملية:
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
# 3. إعداد النموذج وسلسلة الأسئلة والأجوبة
llm = ChatOpenAI(temperature=0.0, model_name="gpt-4") # temperature=0 لتقليل الإبداع والهلوسة
# إنشاء "السلسلة" التي تربط كل شيء ببعضه
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # هذا أبسط أنواع السلاسل
retriever=vector_db.as_retriever(search_kwargs={"k": 3}) # استرجاع أفضل 3 نتائج
)
# 4. طرح سؤال والحصول على إجابة مدعومة بالحقائق!
question = "ما هو الإجراء المتبع في حال تعارض المصالح؟"
answer = qa_chain.run(question)
print("--- السؤال ---")
print(question)
print("n--- الإجابة ---")
print(answer)
عندما طبقنا هذا النظام، كانت النتائج مذهلة. الإجابات أصبحت دقيقة، وعندما لا يجد النموذج المعلومة في الوثائق، كان يجيب بـ “لا أجد معلومات حول هذا الموضوع في المصادر المتاحة لي”، بدلاً من اختراع إجابة. لقد أنقذنا المشروع! 🎉
نصائح من “كيس” أبو عمر: دروس تعلمناها بالطريقة الصعبة
خلال رحلتنا مع RAG، تعلمنا بعض الدروس القيمة التي أود مشاركتها معكم:
- نظافة البيانات أهم من حجمها: “Garbage in, garbage out”. قاعدة بيانات معرفية صغيرة ومنظمة ونظيفة أفضل ألف مرة من قاعدة بيانات ضخمة ومليئة بالمعلومات غير ذات الصلة أو المكررة.
- التقطيع الذكي (Smart Chunking): طريقة تقسيمك للمستندات (chunking strategy) تؤثر بشكل كبير على جودة النتائج. لا تقطع النصوص في منتصف الجملة. حاول التقطيع عند نهاية الفقرات أو العناوين.
- لا تكن بخيلاً في السياق (Context): جرب استرجاع عدد مختلف من الأجزاء (Chunks). أحياناً 3 أجزاء كافية، وأحياناً تحتاج إلى 5. لكن احذر، فإعطاء سياق أكثر من اللازم قد يربك النموذج أيضاً.
- الـ Prompt لا يزال هو الملك: حتى مع RAG، يمكنك تحسين النتائج بشكل كبير من خلال توجيه النموذج في الـ prompt النهائي. على سبيل المثال، أضف هذه الجملة إلى الـ prompt: “أجب على السؤال التالي بالاعتماد *فقط* على السياق المرفق. إذا لم تكن الإجابة في السياق، قل بوضوح ‘لا أعرف’.”
- التقييم المستمر: قم ببناء مجموعة من الأسئلة والأجوبة النموذجية (Golden Set) واستخدمها لاختبار نظامك بشكل دوري للتأكد من أن أي تغييرات تقوم بها تحسن الجودة ولا تضر بها.
الخلاصة: RAG ليس عصا سحرية، ولكنه أفضل “عدة إسعافات أولية” لدينا
في النهاية، تقنية RAG لم تكن حلاً سحرياً قضى على الهلوسة بنسبة 100%، لكنها كانت الأداة التي حولت نموذجنا اللغوي من مصدر قلق وإحراج إلى أصل قيّم وموثوق. لقد منحتنا القدرة على “تأريض” النموذج في واقع بياناتنا الخاصة، وجعل إجاباته قابلة للتحقق والتتبع.
إذا كنت تعمل مع النماذج اللغوية الكبيرة وتواجه مشكلة الهلوسة، فأنصحك بشدة أن تنظر إلى RAG. إنه يحول الـ LLM من “طالب ذكي ولكنه كاذب أحياناً” إلى “مساعد باحث مجتهد لا يتحدث إلا من مصدر”.
لا تخافوا من هلوسات النموذج، بل تعلموا كيف تروضونها. الـ RAG هو لجامكم الأول. يلا، شدوا حيلكم! 💪