الدرس 4 من 23

تعمق في بنية RAG

أنماط الفشل الشائعة

2 دقيقة للقراءة

فهم لماذا تفشل أنظمة RAG أمر حاسم لبناء حلول قوية. معظم حالات الفشل تحدث في الاسترجاع، وليس التوليد.

فئات الفشل

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

فشل الاسترجاع

1. عدم تطابق الاستعلام-المستند

استعلامات المستخدم لا تطابق لغة المستند:

# المستخدم يسأل: "كيف ألغي اشتراكي؟"
# المستند يحتوي: "إجراء إنهاء الاشتراك..."

# الحل: توسيع الاستعلام
def expand_query(query: str, llm) -> str:
    prompt = f"""أعد كتابة سؤال المستخدم هذا ليطابق أسلوب التوثيق الرسمي:
    سؤال المستخدم: {query}
    استعلام بأسلوب التوثيق:"""
    return llm.invoke(prompt)

2. استرجاع غير كافٍ

لم يتم استرجاع مستندات كافية ذات صلة:

# المشكلة: أعلى 4 يفتقد معلومات حرجة
results = vectorstore.similarity_search(query, k=4)  # قليل جداً

# الحل: استرجع أكثر، ثم أعد الترتيب
results = vectorstore.similarity_search(query, k=20)
top_results = reranker.rerank(query, results, top_k=4)

3. مشاكل التقطيع

سياق مهم منقسم عبر القطع:

القطعة 1: "سياسة الإرجاع تسمح للعملاء بـ..."
القطعة 2: "...إرجاع العناصر خلال 30 يوماً من الشراء."

الحل: استخدم قطع متداخلة أو استرجاع الأب-الابن.

تسمم السياق

محتوى غير ذي صلة لكنه متشابه دلالياً:

# الاستعلام: "دوال قوائم Python"
# المسترجع: مقال عن قوائم غذاء ثعبان Python

# الحل: تصفية البيانات الوصفية
results = vectorstore.similarity_search(
    query,
    k=10,
    filter={"category": "programming"}
)

الضياع في الوسط

نماذج اللغة الكبيرة تولي اهتماماً أقل لسياق الوسط:

الموقع      | الانتباه
------------|----------
البداية     | عالي
الوسط       | منخفض  ← المعلومات الحرجة غالباً تضيع هنا
النهاية     | عالي

الحلول:

# 1. قصر السياق على القطع الأكثر صلة
context_docs = reranked_docs[:3]  # لا تفرط في التحميل

# 2. أعد الترتيب حسب الأهمية
def reorder_for_attention(docs):
    """ضع الأهم في البداية والنهاية."""
    if len(docs) <= 2:
        return docs
    # الأكثر صلة أولاً، الثاني في النهاية
    return [docs[0]] + docs[2:] + [docs[1]]

# 3. لخص السياقات الطويلة
if total_tokens(docs) > 2000:
    docs = [summarize(doc) for doc in docs]

مصادر الهلوسة

تجاوز المعرفة البارامترية

معرفة تدريب النموذج تتجاوز السياق المسترجع:

# السياق: "شركتنا تأسست في 2019"
# مخرج النموذج: "تأسست في 2015" (من بيانات التدريب)

# الحل: تعليمات تأسيس صريحة
prompt = """أجب فقط باستخدام السياق المقدم.
إذا لم يحتوي السياق على الإجابة، قل "ليس لدي هذه المعلومات."

السياق: {context}

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

فجوات السياق

المعلومات المفقودة تؤدي للتلفيق:

# اكتشف وتعامل مع الفجوات
def generate_with_confidence(query: str, context: str, llm):
    response = llm.invoke(f"""
    بناءً على السياق، أجب على السؤال.
    قيّم ثقتك (عالية/متوسطة/منخفضة) بناءً على تغطية السياق.

    السياق: {context}
    السؤال: {query}

    التنسيق:
    الإجابة: [إجابتك]
    الثقة: [عالية/متوسطة/منخفضة]
    """)

    if "الثقة: منخفضة" in response:
        return "ليس لدي معلومات كافية للإجابة على هذا بدقة."
    return response

قائمة فحص التصحيح

عندما تكون جودة RAG ضعيفة:

1. جودة الاسترجاع
   □ هل يتم استرجاع المستندات ذات الصلة؟
   □ هل نموذج التضمين مناسب لمجالك؟
   □ هل القطع بالحجم الصحيح؟

2. جودة السياق
   □ هل المحتوى غير ذي الصلة يلوث السياق؟
   □ هل مرشحات البيانات الوصفية مطبقة بشكل صحيح؟
   □ هل السياق طويل جداً (الضياع في الوسط)؟

3. جودة التوليد
   □ هل الموجه يؤسس النموذج على السياق؟
   □ هل عتبات الثقة مناسبة؟
   □ هل النموذج يعترف بعدم اليقين؟

التشخيص السريع

def diagnose_rag(query: str, pipeline):
    """تشخيص مشاكل خط أنابيب RAG."""
    # فحص الاسترجاع
    docs = pipeline.retrieve(query, k=10)
    print(f"تم استرجاع {len(docs)} مستندات")

    # فحص درجات الصلة
    for i, doc in enumerate(docs[:5]):
        print(f"{i+1}. الدرجة: {doc.metadata.get('score', 'N/A')}")
        print(f"   المحتوى: {doc.page_content[:100]}...")

    # فحص التكرارات
    contents = [d.page_content for d in docs]
    duplicates = len(contents) - len(set(contents))
    print(f"القطع المكررة: {duplicates}")

    # فحص طول السياق
    total_chars = sum(len(d.page_content) for d in docs[:4])
    print(f"إجمالي طول السياق: {total_chars} حرف")

مبدأ التصحيح: عندما يفشل RAG، افحص الاسترجاع أولاً. 80% من مشاكل الجودة تنشأ في الاسترجاع، وليس التوليد.

في الوحدة التالية، سنتعمق في نماذج التضمين وقواعد البيانات المتجهة—أساس الاسترجاع الفعال. :::

اختبار

الوحدة 1: تعمق في بنية RAG

خذ الاختبار