الخطوة النهائية: دمج المعلومات المسترجعة مع الـ LLM لتوليد إجابة دقيقة وبدون هلوسة

دقائق القراءة: 5

لماذا تُعد هذه الخطوة هي الأهم في بنية RAG؟

بعد أن أنشأت خط الاسترجاع، وخزّنت المقاطع النصية في قاعدة متجهية، ثم فعّلت Retriever لإحضار الأجزاء الأقرب لسؤال المستخدم، تصل الآن إلى أخطر مرحلة هندسياً: كيف تدمج هذه المعلومات مع النموذج اللغوي بحيث يُنتج إجابة دقيقة، قابلة للتتبع، ومنخفضة الهلوسة؟ هنا يتحول النظام من مجرد بحث دلالي إلى تطبيق معرفي عملي.

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

المعمارية الكاملة لتدفق البيانات من السؤال إلى الإجابة

في المرحلة السابقة، تعلّمت استرجاع المعلومات المطابقة لسؤال المستخدم. الآن يجب أن يتحول الخرج المسترجع إلى context payload منظم يُرسل مع السؤال إلى النموذج.

تسلسل المعالجة النموذجي

  • استقبال سؤال المستخدم الخام.
  • إجراء تنظيف بسيط أو إعادة صياغة اختيارية للسؤال.
  • إرسال السؤال إلى Retriever.
  • استرجاع أفضل المقاطع وفق التشابه الدلالي المبني على Embeddings.
  • ترتيب النتائج، وتصفية التكرار، وربما قصّ المقاطع الزائدة.
  • بناء Prompt صريح يفرض على النموذج الإجابة من السياق فقط.
  • تمرير السؤال والسياق إلى LLM.
  • إرجاع إجابة نهائية مع إمكانية إرفاق المصادر أو أرقام المقاطع.

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

المبدأ الذهني الصحيح: لا ترسل “بيانات كثيرة”، بل “سياقاً قابلاً للاستهلاك”

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

  • ارتفاع استهلاك الرموز Tokens.
  • تشويش انتباه النموذج عند وجود تفاصيل غير مرتبطة جزئياً بالسؤال.
  • زيادة احتمال المزج بين المقاطع وصناعة استنتاجات غير مدعومة.

لذلك يجب أن تبني طبقة وسطى بين الاسترجاع والتوليد تقوم بالآتي:

  • اختيار أفضل k مقاطع فقط.
  • إزالة المقاطع المتشابهة جداً.
  • ترقيم المقاطع لتسهيل الاستشهاد بها.
  • قصّ البيانات الوصفية غير المهمة للمستخدم النهائي.
  • تحديد تعليمات واضحة تمنع الإجابة خارج المحتوى المرفق.

تصميم Prompt مقاوم للهلوسة

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

أجب عن سؤال المستخدم بالاعتماد الحصري على المقاطع المرجعية المرفقة أدناه. إذا لم تحتوِ المقاطع على المعلومة المطلوبة بشكل صريح، فقل: “لا أملك معلومات كافية في السياق المسترجع للإجابة بدقة”. لا تخمّن، ولا تضف معرفة خارجية، واذكر أرقام المقاطع التي استندت إليها عند الإمكان.

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

مثال عملي باستخدام LangChain

إذا كنت قد أنهيت مقدمة LangChain وإنشاء أول Chain، فستلاحظ أن الدمج هنا هو بناء سلسلة تربط retriever مع prompt template ثم مع النموذج.

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0.1
)

prompt = ChatPromptTemplate.from_template("""
You are a retrieval-grounded assistant.
Answer the user's question using only the provided context.
If the answer is not explicitly present in the context, say:
"لا أملك معلومات كافية في السياق المسترجع للإجابة بدقة"

Question:
{question}

Context:
{context}
""")

parser = StrOutputParser()

def format_docs(docs):
    chunks = []
    for i, doc in enumerate(docs, start=1):
        chunks.append(f"[Chunk {i}]\\n{doc.page_content}")
    return "\\n\\n".join(chunks)

def answer_with_rag(question, retriever):
    docs = retriever.invoke(question)
    context = format_docs(docs)
    chain = prompt | llm | parser
    return chain.invoke({
        "question": question,
        "context": context
    })

هذا المثال يوضح الفكرة الأساسية: المستندات المسترجعة لا تُرسل كما هي، بل تُنسّق عبر دالة مثل format_docs حتى يحصل النموذج على سياق مرتب ومفهرس.

التحكم في الدقة عبر المعاملات والحدود التشغيلية

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

  • temperature=0.0 - 0.3 لتقليل التنويع غير الضروري.
  • تحديد عدد المقاطع المسترجعة مثل k=3 أو k=5.
  • استخدام حد أقصى للسياق لتجنب الإغراق النصي.
  • إرجاع المصادر مع الإجابة لرفع القابلية للتدقيق.

متى تستعمل Stuff ومتى تحتاج استراتيجية أكثر تقدماً؟

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

أما إذا كانت المقاطع كثيرة أو متداخلة، فقد تحتاج إلى:

  • Map-Reduce لتلخيص كل مقطع أولاً ثم دمج النتائج.
  • Refine لبناء الإجابة تدريجياً مع كل مقطع جديد.
  • Reranking لإعادة ترتيب المقاطع قبل الإرسال للنموذج.

وهذه القرارات المعمارية ترتبط مباشرة بحجم البيانات، تكلفة التشغيل، وزمن الاستجابة.

مثال على إخراج منظم يقلل الالتباس

السؤال: كيف يمنع نظام RAG الهلوسة؟

الإجابة المتوقعة: يمنع نظام RAG الهلوسة عبر تزويد النموذج اللغوي بسياق مسترجع من مصادر خارجية مرتبطة بالسؤال، بدلاً من الاعتماد الكامل على المعرفة الداخلية للنموذج. وتزداد الدقة عندما يُطلب من النموذج الإجابة من المقاطع فقط مع رفض التخمين. المصادر المستخدمة: [Chunk 1], [Chunk 2].

أخطاء هندسية شائعة يجب تجنبها

  • تمرير المقاطع بلا تعليمات تقييدية للنموذج.
  • عدم التمييز بين نص المصدر وطلب المستخدم داخل prompt.
  • استرجاع مقاطع كثيرة جداً من قاعدة البيانات المتجهة ثم توقع دقة أعلى.
  • رفع temperature في تطبيق هدفه factual answering.
  • عدم اختبار الحالات التي تكون فيها الإجابة غير موجودة في السياق.

الخلاصة العملية للمهندس

الخطوة النهائية في RAG ليست مجرد “إرسال المستندات إلى النموذج”، بل تصميم قناة انضباط معرفي بين الاسترجاع والتوليد. كلما كان السياق منسقاً، مختصراً، ومصحوباً بتعليمات صارمة، اقتربت من إجابة دقيقة وقابلة للتفسير. وكلما تركت النموذج بلا حواجز، عاد إلى سلوكه الاحتمالي الطبيعي وارتفعت الهلوسة.

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

15 comments

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *