نموذجي اللغوي كان يهذي: كيف أنقذني التوليد المعزز بالاسترجاع (RAG) من جحيم الهلوسة؟

يا جماعة الخير، السلام عليكم ورحمة الله وبركاته، معكم أخوكم أبو عمر.

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

الأيام الأولى كانت وردية. النموذج كان فاهم عليّ، ويجاوب على الأسئلة العامة بشكل مبهر. لكن الكارثة بدأت لما دخلنا في التفاصيل الدقيقة. سألته عن مادة معينة في قانون العمل لسنة 2017، والنموذج بكل ثقة “أفتى” لي بمادة قانونية كاملة، برقمها وتفاصيلها… المشكلة؟ هالمادة ما إلها أي وجود في الواقع! كانت من نسج خيال النموذج. قعدت صافن في الشاشة وأنا بحكي لحالي: “شو هالحكي؟ من وين جاب هالكلام؟”.

هون بلش الكابوس. النموذج كان “يهلوس” (Hallucinating) بشكل مستمر. يخلط معلومات صحيحة بمعلومات مخترعة، ويقدمها بثقة عمياء تخلي الواحد يشك في حاله. قضيت ليالي وأنا أحاول أعمل Fine-tuning وأغير في الـ Prompts، لكن الهلوسة كانت زي العفريت، كل ما أسد باب تطلعلي من شباك. حسيت المشروع كله رح ينهار، وسمعتي كمطور صارت على المحك. لحد ما في ليلة من الليالي، وأنا ببحث بيأس، وقعت عيني على مصطلح غيّر كل شي: Retrieval-Augmented Generation (RAG).

ما هي “هلوسة” النماذج اللغوية؟ ولماذا تحدث؟

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

تخيل النموذج كطالب ذكي جداً لكنه متوتر في امتحان. هو تدرب على مليارات النصوص من الإنترنت، وصار عنده قدرة رهيبة على التنبؤ بالكلمة التالية في أي جملة. لما تسأله سؤال ما بيعرف إجابته الدقيقة من ذاكرته (بيانات تدريبه)، بدل ما يحكي “لا أعرف”، بيحاول “يألف” إجابة تبدو الأكثر احتمالاً من الناحية اللغوية. هو لا يكذب عن قصد، بل هو مجرد آلة احتمالات بتحاول تكمل الفراغ بأفضل شكل ممكن بناءً على ما تعلمته. وهذه هي المصيبة في التطبيقات اللي بتحتاج دقة 100% زي التطبيقات القانونية أو الطبية.

طوق النجاة: التوليد المعزز بالاسترجاع (RAG)

الـ RAG هو مش نموذج جديد، بل هو “هندسة” أو “طريقة” ذكية جداً للجمع بين قوة النماذج اللغوية الكبيرة في الفهم والتوليد، وقوة محركات البحث التقليدية في استرجاع المعلومات الدقيقة.

شو قصة الـ RAG؟ كيف بيشتغل؟

الفكرة عبقرية في بساطتها. بدل ما نعتمد على “ذاكرة” النموذج المحدودة والمُدرّبة مسبقاً، بنعطيه “كتاب مفتوح” (Open Book) وقت الإجابة. هالكتاب هو قاعدة بياناتك الخاصة (وثائقك، ملفاتك، موقعك الإلكتروني، أي شي بدك ياه).

العملية بتمر بمراحل واضحة:

  1. الاسترجاع (Retrieval): لما المستخدم يسأل سؤال، النظام ما بروح للنموذج اللغوي مباشرة. أولاً، بياخذ السؤال وببحث في قاعدة بياناتك الخاصة (الكتاب المفتوح) عن أكثر أجزاء النص صلة بالسؤال. هذه العملية تشبه لما تبحث في جوجل عن معلومة.
  2. التعزيز (Augmentation): بعد ما يلاقي الأجزاء ذات الصلة (مثلاً، فقرتين من وثيقة PDF)، بيقوم “بتعزيز” السؤال الأصلي. يعني بيجهز prompt جديد للنموذج اللغوي، شكله كالتالي:

    “يا نموذج يا محترم، بالاعتماد على السياق التالي فقط، أجب عن سؤال المستخدم.

    السياق: [هنا نضع الفقرات اللي تم استرجاعها]

    سؤال المستخدم: [هنا نضع السؤال الأصلي]”

  3. التوليد (Generation): الآن، النموذج اللغوي يستقبل هذا الـ prompt المعزز. مهمته صارت أسهل بكثير وأكثر أماناً. بدل ما يجاوب من ذاكرته الواسعة اللي ممكن تكون خاطئة، هو الآن مجبر يجاوب بالاعتماد على السياق الدقيق والمحدّث اللي أعطيناه إياه. هيك، بنكون قضينا على الهلوسة من جذورها لأنه صار مربوط بمصدر موثوق.

خلونا نوسّخ إيدينا: مثال عملي بسيط باستخدام Python

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

الأدوات اللي رح نحتاجها

  • مكتبة langchain للربط بين المكونات.
  • مكتبة للتعامل مع نماذج اللغة مثل langchain-openai.
  • مكتبة لإنشاء قاعدة بيانات فيكتور (Vector Store) مثل faiss-cpu.
  • مكتبة لقراءة الملفات مثل pypdf.

الكود خطوة بخطوة

لنفترض أن لدينا ملف PDF اسمه "my_document.pdf" ونريد أن نجعل النموذج يجيب على أسئلة منه.


# أولاً، نقوم بتثبيت المكتبات اللازمة
# pip install langchain langchain-openai faiss-cpu pypdf

import os
from langchain_community.document_loaders import PyPDFLoader
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA

# ضع مفتاح OpenAI الخاص بك هنا
os.environ["OPENAI_API_KEY"] = "sk-..."

# --- الخطوة 1: تحميل وتقسيم الوثائق ---
# سنقوم بتحميل ملف الـ PDF
loader = PyPDFLoader("my_document.pdf")
documents = loader.load()

# النماذج اللغوية لها حد معين من الكلمات (context window)
# لذلك يجب تقسيم النص الطويل إلى أجزاء صغيرة (chunks)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
texts = text_splitter.split_documents(documents)

print(f"تم تقسيم الوثيقة إلى {len(texts)} جزء.")

# --- الخطوة 2: إنشاء Embeddings وتخزينها في Vector Store ---
# الـ Embeddings هي تحويل النصوص إلى أرقام (فيكتور) ليفهمها الكمبيوتر
# الـ Vector Store هي قاعدة بيانات متخصصة في البحث عن هذه الفيكتورات المتشابهة
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(texts, embeddings)

print("تم إنشاء قاعدة البيانات الفيكتورية بنجاح.")

# --- الخطوة 3: إعداد سلسلة RAG ---
# هنا نربط كل شيء معًا
# llm: النموذج اللغوي الذي سيقوم بتوليد الإجابة النهائية
# chain_type="stuff": الطريقة التي سنجمع بها النصوص مع السؤال (مناسبة للنصوص الصغيرة)
# retriever: هو المسؤول عن البحث في قاعدة البيانات الفيكتورية
qa_chain = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0),
    chain_type="stuff",
    retriever=vectorstore.as_retriever()
)

# --- الخطوة 4: طرح الأسئلة ---
query = "ما هي أهم النقاط المذكورة في الفصل الثالث من الوثيقة؟"
result = qa_chain.invoke({"query": query})

print("n--- السؤال ---")
print(query)
print("n--- الإجابة ---")
print(result['result'])

بهذه البساطة، يا جماعة! الكود أعلاه يبني نظام RAG كامل. الآن، بدل ما النموذج “يهلوس”، هو مجبر يبحث في my_document.pdf ويستخرج الإجابة منه مباشرة. صار مساعد ذكي موثوق بدلاً من كونه “مُفتي” لا يعتمد عليه.

نصائح من أخوكم أبو عمر (من أرض المعركة)

بعد ما اشتغلت على أكثر من مشروع باستخدام RAG، جمعتلكم شوية نصائح عملية ممكن توفر عليكم وقت وجهد كبير:

  • اهتم بتقسيم النصوص (Chunking): طريقة تقسيمك للوثائق لأجزاء صغيرة تؤثر بشكل مباشر على جودة البحث. لا تقسم الكلمات في منتصف الجملة. استخدم RecursiveCharacterTextSplitter لأنه ذكي ويحاول الحفاظ على بنية الفقرات.
  • جودة الـ Retriever هي كل شيء: إذا كانت نتائج البحث الأولية (الاسترجاع) سيئة، فالإجابة النهائية ستكون سيئة حتماً. جرب تغيير عدد النتائج المسترجعة (parameter اسمه k) وشوف كيف تتأثر الجودة.
  • الـ Prompt هو الملك: الـ prompt اللي بتعطيه للنموذج في مرحلة التوليد مهم جداً. كن واضحاً في تعليماتك. جملة مثل “أجب بالاعتماد على السياق فقط. إذا كانت الإجابة غير موجودة في السياق، قل بوضوح ‘لا أملك معلومات كافية للإجابة’.” يمكن أن تصنع فرقاً هائلاً.
  • لا تهمل الـ Metadata: عند تقسيم الوثائق، يمكنك إضافة بيانات وصفية (metadata) لكل جزء، مثل رقم الصفحة أو اسم الملف. هذا يساعدك لاحقاً على ذكر المصدر في الإجابة، مما يزيد من ثقة المستخدم.
  • فكر في Hybrid Search: أحياناً البحث عن طريق الكلمات المفتاحية (keyword search) التقليدي يكون أفضل من البحث الدلالي (vector search) للأسماء والمصطلحات الدقيقة. الجمع بين الاثنين (Hybrid Search) يعطي نتائج خارقة في كثير من الأحيان.

الخلاصة: من الهلوسة إلى الثقة 😌

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

بالنسبة لي، كانت RAG هي المنقذ الذي حول مشروع على حافة الفشل إلى قصة نجاح، وحول علاقتي بالنماذج اللغوية من علاقة شك وحذر إلى علاقة ثقة وتعاون. إذا كنت تعمل مع نماذج لغوية وتحتاج إلى إجابات دقيقة وموثوقة من مصادر بياناتك الخاصة، فصدقني، الـ RAG هو صديقك الذي تبحث عنه.

لا تخافوا من التجربة، وسّخوا إيديكم بالكود، واكتشفوا القوة بأنفسكم. بالتوفيق يا أبطال! 👨‍💻

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

​معمارية البرمجيات

تحديث المونوليث كجراحة قلب مفتوح: كيف أنقذنا نمط الخانق (Strangler Fig) من جحيم “إياك أن تلمس هذا الكود”؟

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

25 مايو، 2026 قراءة المزيد
تسويق رقمي

ما وراء الكلمات المفتاحية: كيف حولنا بيانات Schema.org إلى أسلحة سرية في حرب نتائج البحث؟

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

25 مايو، 2026 قراءة المزيد
صورة المقال
تجربة المستخدم والابداع البصري

كانت شاشاتنا الفارغة مقبرة للتفاعل: كيف أنقذتنا ‘الحالات الفارغة الذكية’ من جحيم ‘وماذا الآن؟’

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

25 مايو، 2026 قراءة المزيد
برمجة وقواعد بيانات

كانت استعلاماتنا تزحف: كيف أنقذتنا فهارس قواعد البيانات من جحيم البحث البطيء؟

قصة من الميدان عن كيفية تحويل استعلامات SQL البطيئة التي تشبه السلحفاة إلى عمليات فائقة السرعة باستخدام أداة بسيطة وقوية: فهارس قواعد البيانات. مقالة عملية...

25 مايو، 2026 قراءة المزيد
الشبكات والـ APIs

من جحيم الـ Polling إلى نعيم الـ Webhooks: كيف أنقذت “خطافات الويب” تطبيقاتنا من السؤال المستمر “هل من جديد؟”

أروي لكم قصة من واقع تجربتي كمبرمج، كيف انتقلنا من طريقة الاستطلاع المستمر (Polling) المرهقة للخوادم، إلى الاعتماد على "خطافات الويب" (Webhooks) الذكية. مقالة عملية...

25 مايو، 2026 قراءة المزيد
التوظيف وبناء الهوية التقنية

ملفي الشخصي كان مقبرة للمشاريع: كيف أنقذتني ‘سردية المشاريع’ من جحيم ‘وماذا بعد؟’

هل ملفك الشخصي مجرد قائمة بمشاريع غير مكتملة أو تطبيقات تعليمية؟ اكتشف كيف حوّلتُ 'مقبرة المشاريع' الخاصة بي إلى قصة نجاح متماسكة باستخدام تقنية 'سردية...

24 مايو، 2026 قراءة المزيد
البودكاست