تحسين RAG: استخدام خوارزمية (MMR) لضمان تنوع ودقة المعلومات المسترجعة

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

لماذا نحتاج إلى MMR داخل أنظمة RAG؟

في البنية التقليدية لأنظمة Retrieval-Augmented Generation، يقوم Retriever بإرجاع أعلى المقاطع تشابهاً مع سؤال المستخدم وفق مسافة متجهية مثل cosine similarity. المشكلة الهندسية هنا أن أعلى النتائج غالباً تكون متقاربة جداً في المعنى، بل أحياناً مكررة جزئياً لأنها خرجت من نفس الفقرة أو من صفحات تصف الفكرة نفسها بصياغات متشابهة. النتيجة أن النموذج يستقبل سياقاً ضيقاً ومكرراً، فيفقد تنوع الأدلة ويزداد احتمال إغفال معلومة مهمة موجودة في مقطع أقل تشابهاً لكنه أكثر فائدة.

هنا تظهر قيمة خوارزمية Maximal Marginal Relevance أو MMR. هذه الخوارزمية لا تبحث فقط عن المقاطع الأكثر صلة بالسؤال، بل توازن بين عاملين معاً: الارتباط بالاستعلام، وعدم التشابه الزائد بين النتائج المختارة نفسها. عملياً، هذا يعني أنك لا تريد فقط أفضل 5 مقاطع مرتبطة بالسؤال، بل أفضل 5 مقاطع مرتبطة ومتنوعة بما يكفي لتغطية أبعاد الإجابة.

المشكلة المعمارية في الاسترجاع التقليدي

إذا كنت قد طبقت سابقاً سلسلة دمج السياق المسترجع مع LLM، فستلاحظ أن جودة الإجابة تعتمد بشدة على جودة المقاطع الداخلة إلى النافذة السياقية. عند استخدام Top-K Similarity Search فقط، يحدث عادة أحد السيناريوهين:

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

في الأنظمة الإنتاجية، هذه المشكلة تؤثر على:

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

كيف تعمل خوارزمية MMR برمجياً؟

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

صياغة منطق MMR يمكن فهمها كالتالي:

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

عادة يوجد معامل مثل lambda_mult للتحكم في هذا التوازن:

  • قيمة مرتفعة تعني تفضيل الصلة المباشرة بالسؤال.
  • قيمة منخفضة تعني تفضيل التنوع أكثر.

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

تدفق البيانات داخل خط RAG عند استخدام MMR

1) تجهيز المستندات

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

2) إنشاء التضمينات Embeddings

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

3) التخزين داخل قواعد البيانات المتجهة Vector DBs

سواء استخدمت ChromaDB أو قاعدة سحابية مثل Pinecone، ستقوم القاعدة بإرجاع مجموعة مرشحة أولية من المقاطع الأقرب للاستعلام.

4) إعادة الترتيب باستخدام MMR

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

5) تمرير السياق إلى النموذج

بعد اختيار المقاطع النهائية، يتم بناؤها في قالب Prompt واضح يطلب من النموذج الإجابة اعتماداً على السياق فقط.

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

تطبيق MMR باستخدام LangChain

إطار LangChain يوفر هذه الآلية بسهولة على مستوى Retriever. المثال التالي يوضح الإعداد الأساسي:

from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma
from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")

vectorstore = Chroma(
    persist_directory="./chroma_db",
    embedding_function=embedding_model
)

retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={
        "k": 4,
        "fetch_k": 12,
        "lambda_mult": 0.6
    }
)

query = "كيف تحسن MMR جودة الاسترجاع في أنظمة RAG؟"
docs = retriever.invoke(query)

for i, doc in enumerate(docs, 1):
    print(f"Document #{i}")
    print(doc.page_content[:300])
    print("-" * 50)

في هذا المثال:

  • fetch_k يحدد عدد المرشحين الأوّليين قبل إعادة الترتيب.
  • k هو عدد المقاطع النهائية بعد تطبيق MMR.
  • lambda_mult يوازن بين الصلة والتنوع.

دمج الاسترجاع المتنوع مع التوليد

بعد الحصول على المقاطع المتنوعة، نمررها إلى النموذج ضمن سلسلة بسيطة:

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

prompt = ChatPromptTemplate.from_template("""
أنت مساعد تقني متخصص في RAG.
اعتمد فقط على السياق التالي للإجابة:

{context}

السؤال:
{question}
""")

context = "\n\n".join([doc.page_content for doc in docs])

chain = prompt | llm | StrOutputParser()

response = chain.invoke({
    "context": context,
    "question": query
})

print(response)

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

متى يكون MMR مفيداً جداً؟

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

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

أفضل الممارسات الهندسية عند الضبط

اختيار قيم مناسبة

  • ابدأ بـ k=4 أو k=6.
  • اجعل fetch_k أكبر من k بمرتين أو ثلاث على الأقل.
  • جرّب lambda_mult بين 0.4 و0.7.

انتبه لجودة التقسيم

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

اختبره بمقاييس حقيقية

لا تعتمد على الانطباع فقط. قارن بين:

  • نسبة تكرار المقاطع.
  • مدى تغطية الإجابة لمحاور السؤال.
  • عدد الرموز المرسلة للنموذج.
  • رضا المستخدم النهائي عن اكتمال الإجابة.

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

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

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

7 comments

اترك تعليقاً

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