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

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

خلوني أحكيلكم قصة صارت معي قبل فترة، قصة علّمتني درس ما بنساه. كنا شغالين على مشروع كبير لشركة محاماة محترمة، والمطلوب كان بناء مساعد ذكي (Chatbot) يساعد المحامين الجدد في البحث ضمن أرشيف ضخم من القضايا والقوانين الداخلية للشركة. الأرشيف كان عبارة عن آلاف ملفات الـ PDF والـ Word، عالم ثاني.

بعد أسابيع من الشغل والتعب، أطلقنا النسخة التجريبية. النموذج اللغوي الكبير (LLM) اللي استخدمناه كان ذكي وبيفهم السياق بشكل ممتاز. في اجتماع العرض التقديمي، كان المدير التنفيذي للشركة موجود، ومتحمس يشوف “التحفة التكنولوجية” اللي عملناها. سأل سؤال بسيط عن قضية معينة من الأرشيف: “ما هي تفاصيل الحكم في قضية العميل ‘س’ ضد الشركة ‘ص’ لعام 2019؟”

وهون كانت الصدمة… المساعد الذكي جاوب بثقة مطلقة، وبلش يسرد تفاصيل وحيثيات حكم… من وحي الخيال! اختلق أرقام قضايا، وأسماء قضاة، وتواريخ، وكلها غلط بغلط. شعرت وقتها كأن الأرض انشقت وبلعتني. المدير نظر إليّ نظرة لن أنساها، وقال بلهجة حادة: “شو هاد يا أبو عمر؟ هاد مش مساعد، هاد مؤلف قصص خيالية!”.

هذا الموقف المحرج كان بداية رحلتي الحقيقية مع مشكلة “الهلوسة” (Hallucination) في نماذج الذكاء الاصطناعي، والبحث عن حل جذري أنقذنا من هذا الجحيم، وهو ما يعرف اليوم بالبحث المعزز بالتوليد أو “RAG”.

ما هي “الهلوسة” في عالم الذكاء الاصطناعي؟ وليش بتصير؟

قبل ما ندخل في الحل، خلينا نفهم المشكلة. “الهلوسة” هي لما النموذج اللغوي الكبير (LLM) يخترع معلومات ويقدمها على أنها حقيقة مؤكدة. هو لا يكذب عن قصد، لأنه أصلاً ما عنده “قصد” أو “وعي”.

السبب بسيط: النماذج اللغوية هي عبارة عن آلات إحصائية عملاقة للتنبؤ بالكلمة التالية. تم تدريبها على كميات هائلة من نصوص الإنترنت، ومهمتها هي توليد نص “يبدو” منطقياً ومقنعاً بناءً على الأنماط اللي تعلمتها. هي مثل الطالب اللي قرأ كل كتب المكتبة، بس وقت الامتحان ما معه ولا كتاب، فبيعتمد على ذاكرته. أحياناً ذاكرته بتخلطه، فبيبدأ “يألّف” إجابات تبدو صحيحة لكنها في الحقيقة غير دقيقة.

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

الحل السحري: البحث المعزز بالتوليد (RAG) – كيف بيشتغل؟

هنا يأتي دور البطل: Retrieval-Augmented Generation (RAG). فكرته عبقرية في بساطتها: بدلاً من أن نطلب من النموذج الإجابة من “ذاكرته” الواسعة وغير الموثوقة، سنعطيه “كتاباً مفتوحاً” (Open Book) يحتوي على المعلومات الدقيقة التي نحتاجها، ونطلب منه أن يقرأ هذا الكتاب ويجيب على سؤالنا من خلاله فقط.

هذا “الكتاب المفتوح” هو بياناتك الخاصة (ملفات PDF، قواعد بيانات، مقالات موقعك، …إلخ). العملية تتم على ثلاث مراحل رئيسية:

المرحلة الأولى: التجهيز والفهرسة (Indexing)

هذه المرحلة تتم مرة واحدة في البداية (أو كلما تحدثت بياناتك). الهدف منها هو تحويل مستنداتك إلى صيغة يفهمها الكمبيوتر ويستطيع البحث فيها بسرعة.

  • التقطيع (Chunking): نقوم بتقسيم مستنداتك الكبيرة إلى أجزاء أو “مَقاطع” صغيرة. ليش؟ لأن التعامل مع مقاطع صغيرة ومركزة أسهل وأكثر دقة عند البحث عن معلومة محددة.
  • التضمين (Embeddings): هذه هي الخطوة السحرية. نستخدم نموذجاً متخصصاً لتحويل كل “مقطع” نصي إلى متجه رياضي (Vector)، وهو عبارة عن قائمة طويلة من الأرقام. هذه المتجهات تمثل “معنى” النص في فضاء رياضي. النصوص ذات المعاني المتقاربة تكون متجهاتها “قريبة” من بعضها في هذا الفضاء.
  • التخزين (Storing): نقوم بتخزين هذه المتجهات مع النصوص الأصلية المقابلة لها في قاعدة بيانات متخصصة تسمى “قاعدة بيانات المتجهات” (Vector Database). من أشهر الأمثلة عليها: Pinecone, ChromaDB, FAISS.

باختصار، مرحلة الفهرسة تحول وثائقك من مجرد نصوص إلى مكتبة منظمة حسب المعنى، جاهزة للبحث الفوري.

المرحلة الثانية: البحث والاسترجاع (Retrieval)

هذه المرحلة تحدث في كل مرة يسأل فيها المستخدم سؤالاً.

  1. استعلام المستخدم (User Query): يأتي المستخدم ويسأل سؤالاً، مثلاً: “ما هي شروط الإجازة السنوية للموظفين؟”.
  2. تضمين الاستعلام: نقوم بتحويل سؤال المستخدم أيضاً إلى متجه (Embedding) باستخدام نفس النموذج الذي استخدمناه في المرحلة الأولى.
  3. البحث عن التشابه: نأخذ متجه السؤال ونبحث في قاعدة بيانات المتجهات عن المقاطع النصية التي تمتلك المتجهات الأكثر شبهاً وقرباً منه. هذه هي المقاطع الأكثر صلة بسؤال المستخدم.

النتيجة؟ نحصل على أفضل 3 أو 5 مقاطع من مستنداتنا الأصلية التي يُحتمل أنها تحتوي على إجابة السؤال.

المرحلة الثالثة: التعزيز والتوليد (Augmentation & Generation)

هنا نجمع كل شيء معاً.

  1. بناء السياق (Context Building): نأخذ المقاطع النصية التي استرجعناها في المرحلة السابقة.
  2. صياغة الطلب المعزز (Augmented Prompt): نقوم بإنشاء طلب (Prompt) جديد للنموذج اللغوي الكبير (LLM) بالصيغة التالية:

    “بناءً على السياق التالي فقط: [هنا نضع المقاطع النصية المسترجعة]. أجب على السؤال التالي: [هنا نضع سؤال المستخدم الأصلي]. إذا كانت الإجابة غير موجودة في السياق، قل ‘لا أعرف الإجابة’.”
  3. التوليد (Generation): نرسل هذا الطلب المعزز إلى الـ LLM، والذي سيقوم بدوره بتوليد إجابة دقيقة ومبنية حصراً على المعلومات التي زودناه بها، مما يمنع الهلوسة بشكل شبه كامل.

خلونا نشوف مثال عملي: بناء نظام RAG بسيط

الكلام النظري جميل، لكن “الإيد اللي في المي مش زي الإيد اللي في النار”. خلينا نطبق عملياً باستخدام لغة Python ومكتبة LangChain الشهيرة لتبسيط الأمور.

الخطوة 1: تجهيز البيئة والمكتبات

أولاً، تأكد من تثبيت المكتبات اللازمة. سأستخدم OpenAI كنوذج لغوي، و FAISS كقاعدة بيانات متجهات تعمل في الذاكرة (سهلة للمبتدئين).


pip install langchain openai faiss-cpu tiktoken

لا تنسَ وضع مفتاح API الخاص بـ OpenAI في متغيرات البيئة (Environment Variable) تحت اسم OPENAI_API_KEY.

الخطوة 2: تحميل وتجهيز البيانات

لنفترض أن لدينا مستنداً بسيطاً عن سياسة الشركة الداخلية. سنضعه كنص عادي في الكود مباشرة.


from langchain.text_splitter import RecursiveCharacterTextSplitter

# هذا هو مستندنا الذي نريد البحث فيه
company_policy_text = """
مرحباً بكم في سياسة شركتنا.
الإجازة السنوية للموظفين هي 21 يوماً مدفوعة الأجر بعد إتمام السنة الأولى.
يمكن تقديم طلبات الإجازة عبر بوابة الموظفين الإلكترونية.
يجب تقديم الطلب قبل 15 يوماً على الأقل من تاريخ بدء الإجازة.
ساعات العمل الرسمية من 9 صباحاً حتى 5 مساءً، من الأحد إلى الخميس.
العمل عن بعد متاح يومين في الأسبوع بالتنسيق مع المدير المباشر.
"""

# 1. التقطيع (Chunking)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,  # حجم كل مقطع
    chunk_overlap=20   # تداخل بين المقاطع لضمان عدم فقدان السياق
)
docs = text_splitter.create_documents([company_policy_text])

print(f"تم تقطيع النص إلى {len(docs)} مقطع.")

الخطوة 3: إنشاء قاعدة بيانات المتجهات (Vector Store)

الآن سنحول هذه المقاطع إلى متجهات ونخزنها في FAISS.


from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS

# 2. التضمين والتخزين (Embedding & Storing)
embeddings = OpenAIEmbeddings()
vector_store = FAISS.from_documents(docs, embeddings)

print("تم إنشاء قاعدة بيانات المتجهات بنجاح!")

الخطوة 4: بناء سلسلة RAG والاستعلام

هذه هي المرحلة النهائية حيث نربط كل شيء معاً ونسأل سؤالنا.


from langchain.chains import RetrievalQA
from langchain.llms import OpenAI

# 3. بناء السلسلة (Chain)
llm = OpenAI(temperature=0) # temperature=0 لجعل الإجابات دقيقة وغير إبداعية
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff", # "stuff" تعني وضع كل المقاطع المسترجعة في السياق
    retriever=vector_store.as_retriever()
)

# طرح سؤال
question = "كم عدد أيام الإجازة السنوية؟"
response = qa_chain.run(question)

print(f"السؤال: {question}")
print(f"الإجابة: {response}")

# طرح سؤال آخر
question_2 = "هل يمكنني العمل من المنزل؟"
response_2 = qa_chain.run(question_2)

print(f"nالسؤال: {question_2}")
print(f"الإجابة: {response_2}")

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

نصائح من خبرة أبو عمر

  • فن التقطيع (Chunking): حجم المقطع (chunk_size) والتداخل (chunk_overlap) يؤثران بشكل كبير على دقة النتائج. لا يوجد رقم سحري، عليك التجربة بناءً على طبيعة مستنداتك. ابدأ بقيم متوسطة (مثلاً 1000 للحجم و 100 للتداخل) ثم قم بالتعديل.
  • جودة بياناتك هي كل شيء: تذكر مبدأ “Garbage in, garbage out”. إذا كانت مستنداتك الأصلية مليئة بالأخطاء أو المعلومات القديمة، فإن RAG سيعطيك إجابات خاطئة ولكن بثقة! نظّف وحَدّث مصادرك أولاً.
  • اختر نموذج التضمين (Embedding Model) المناسب: هناك العديد من نماذج التضمين، بعضها أفضل للغات معينة أو لمجالات متخصصة (طبية، قانونية). استثمر بعض الوقت في البحث عن أفضل نموذج لحالتك.
  • لا يقتصر RAG على الأسئلة والأجوبة: يمكنك استخدام نفس التقنية لتلخيص المستندات الطويلة بناءً على نقاط معينة، أو لكتابة محتوى جديد مستوحى من قاعدة بيانات معرفية محددة.

الخلاصة: RAG ليس عصا سحرية، ولكنه أقرب ما يكون! 🪄

تقنية البحث المعزز بالتوليد (RAG) غيرت قواعد اللعبة. لقد حولت النماذج اللغوية الكبيرة من مجرد “ببغاوات” ذكية تردد ما تعلمته، إلى “باحثين” خبراء يمكنهم استخدام وثائق محددة لتقديم إجابات دقيقة وموثوقة. هي الجسر الذي يربط بين القوة التوليدية الهائلة للـ LLMs وبين أرض الواقع المتمثلة في بياناتك الخاصة.

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

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

يلا، ورجونا همتكم! 💪

أبو عمر

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

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

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

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

آخر المدونات

نصائح برمجية

كانت بياناتنا تتغير بغدر: كيف أنقذتنا ‘الكائنات غير القابلة للتغيير’ (Immutability) من جحيم الآثار الجانبية؟

أشارككم قصة حقيقية عن خطأ برمجي غامض كاد أن يصيب فريقنا بالجنون، وكيف كان الحل في مفهوم بسيط وقوي يسمى "اللامتغيرية" (Immutability). اكتشف كيف يمكن...

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

كنا ضائعين بين المونوليث والخدمات المصغرة: كيف أنقذنا ‘المونوليث النمطي’ (Modulith) من جحيم التعقيد؟

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

18 مايو، 2026 قراءة المزيد
خوارزميات

كانت شخصياتنا في اللعبة تسير في حوائط: كيف أنقذتنا خوارزمية A* من جحيم المسارات الغبية؟

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

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

كانت واجهاتنا جزرًا معزولة: كيف أنقذنا ‘نظام التصميم’ من جحيم الفوضى البصرية؟

أشارككم قصة حقيقية من قلب المعركة البرمجية، كيف انتقلنا من فوضى الواجهات والتصاميم المتضاربة إلى نظام متناغم وموحّد. هذه رحلتنا في بناء "نظام تصميم" (Design...

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

كانت تحديثات قاعدة البيانات كابوساً: كيف أنقذتنا أدوات الترحيل (Migrations) من جحيم التعديلات اليدوية؟

هل عانيت يوماً من تحديث مخطط قاعدة البيانات يدوياً بين فريقك؟ أبو عمر يشارككم قصة حقيقية حول كيف غيّرت أدوات الترحيل (Migrations) طريقة عمل فريقه،...

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

كانت خوادمنا تستجدي التحديثات: كيف أنقذتنا ‘خطاطيف الويب’ (Webhooks) من جحيم الاستقصاء المستمر (Polling)؟

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

17 مايو، 2026 قراءة المزيد
الحوسبة السحابية

كانت بنيتنا التحتية قصراً من رمال: كيف أنقذتنا “البنية التحتية ككود” (IaC) من جحيم البيئات المتضاربة؟

أشارككم قصة حقيقية عن ليلة كادت أن تنهار فيها شركتنا بسبب الفوضى في البنية التحتية، وكيف كانت "البنية التحتية ككود" (IaC) طوق النجاة الذي انتشلنا...

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

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

هل تشعر أن ملفك الشخصي على GitHub لا يعكس قدراتك الحقيقية؟ في هذه المقالة، أشاركك يا صديقي تجربتي الشخصية، أنا أبو عمر، وكيف انتقلت من...

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