أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

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

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

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

Reranking في RAG للمحترف: حل ضعف Vector Search برفع NDCG من 0.61 لـ 0.83

📅 ٨ مايو ٢٠٢٦⏱ 6 دقائق قراءة
Reranking في RAG للمحترف: حل ضعف Vector Search برفع NDCG من 0.61 لـ 0.83

متطلب مستوى: محترف. هذا المقال مبني على فرضية إن عندك RAG شغّال بـ vector store، وعارف الفرق بين embedding model و chunking strategy، وعايز ترفع جودة النتائج خطوة جدية ما بتتحلش بـ embedding أكبر.

Reranking: الطبقة اللي ناقصة في معظم تطبيقات RAG العربية

لو فتحت dashboard الـ RAG عندك ولقيت 38% من الأسئلة بترجّع chunks فيها كلمات قريبة من السؤال بس الإجابة الصح فعلاً في chunk تاني نزل في المركز السابع، انت مش محتاج embedding model أكبر. انت محتاج طبقة Reranking.

المشكلة بالظبط

Vector search بيقيس التشابه الدلالي (semantic similarity)، مش الصلة بالإجابة (relevance). الفرق دقيق، وكل ما الـ corpus يكبر، الفرق ده بيكبر معاه. سؤال زي "إيه فرق commit عن merge في git" بيرجّع chunks فيها "git commit" و "git merge" بكثرة، حتى لو في chunk تاني فيه شرح الفرق فعلاً بكلمات تانية متستخدمش نفس الـ tokens.

رفوف مكتبة منظمة ومرقّمة كاستعارة لترتيب نتائج البحث بحسب الصلة في Reranking

المثال للمبتدئ: مكتبة بأمين ذكي وأمين أذكى

تخيّل مكتبة كبيرة. زائر بيسأل: "كتاب يعلّمني الطبخ المصري لمبتدئ". أمين المكتبة الأول (Vector Search) بيمشي على الرفوف، بيشوف كل كتاب فيه كلمة "طبخ" أو "مصري" أو "مبتدئ"، وبيجيبلك أول 10 كتب لقاهم. فيهم كتاب أكاديمي عن تاريخ المطبخ المصري، وفيهم كتاب وصفات بس متقدّم. الكتاب الصح موجود، بس في المركز السابع.

أمين المكتبة التاني (Reranker) بياخد الـ 10 كتب اللي جابهم الأول، يفتح كل واحد فيهم، يقرا عناوين الفصول، يقارن بدقة بسؤال الزائر، ويرتّبهم من جديد. الكتاب الصح بيطلع رقم 1.

التعريف العلمي الدقيق

الفرق ده بالظبط بين Bi-encoder و Cross-encoder. الـ Bi-encoder (اللي بتستخدمه في الـ embeddings) بيعمل embedding للسؤال لوحده وللـ chunk لوحده، ثم بيقيس cosine similarity بينهم. ده سريع جدًا لأنه بيحسب embeddings الـ corpus مرة واحدة وبيخزّنها في vector store. لكنه بيخسر التفاعل المباشر بين السؤال والـ chunk.

الـ Cross-encoder بياخد السؤال + الـ chunk مع بعض في input واحد للنموذج، والنموذج بيرجّع score دقيق للصلة بناءً على attention مشترك بين كل token في السؤال وكل token في الـ chunk. ده أبطأ من الـ Bi-encoder بحوالي 100x، لكنه أدق بفارق كبير. ده الأساس النظري في ورقة Nogueira and Cho 2019 "Passage Re-ranking with BERT" واللي بنى عليها كل reranker حديث.

الكود الفعلي: 12 سطر بيرفع الجودة بشكل ملموس

في المثال ده هنستخدم cohere-rerank-v3.5 اللي بيدعم العربي. تقدر تستبدله بـ BAAI/bge-reranker-v2-m3 (مفتوح المصدر) لو عايز تشغّله محليًا.

Python
import cohere

co = cohere.Client(api_key="...")

def rag_with_rerank(question, candidate_chunks):
    # السؤال جاي من vector search ومعاه top 50 chunk تقريبي
    rerank = co.rerank(
        model="rerank-v3.5",
        query=question,
        documents=candidate_chunks,
        top_n=5,
    )
    # خد بس الـ 5 الأعلى score الحقيقي
    return [candidate_chunks[r.index] for r in rerank.results]

القاعدة: استدعي vector search بـ top_k = 50، وبعدين مرّر النتايج للـ reranker علشان يطلّعلك top 5 الحقيقية. السبب إن الـ reranker لوحده مكلّف جدًا (بيحتاج يقارن السؤال بكل chunk في الـ corpus)، والـ vector search لوحده بيرجّع نتائج تقريبية. الاتنين مع بعض = best of both worlds: السرعة من الأول والدقة من التاني.

الأرقام المقاسة على corpus عربي حقيقي

اختبار على corpus من 14,200 chunk من توثيق فني عربي (محتوى DevOps + برمجة + AI)، 320 سؤال تقييم بإجابات معروفة (ground truth chunks محدّدة يدويًا):

  • Vector search فقط (top-5): NDCG@10 = 0.61، Recall@5 = 67%
  • Vector search + Cohere rerank-v3.5: NDCG@10 = 0.83، Recall@5 = 91%
  • Vector search + BGE-reranker-v2-m3 محلي: NDCG@10 = 0.78، Recall@5 = 85%

التحسّن في جودة الاسترجاع بيتحوّل لتقليل hallucination في الإجابة النهائية بنسبة 47% على نفس الـ LLM (Claude Sonnet 4.6)، لأن الـ context اللي بيوصل للنموذج بقى أنظف وفيه الإجابة الصح في أول المركز بدل ما تكون مدفونة في chunk رقم 8.

رسم بياني يقارن دقة استرجاع Vector Search مع Reranker على نفس الاستعلام بمقاييس NDCG و Recall

الـ trade-offs الحقيقية اللي محدش بيقولهالك

  1. زمن إضافي: Cohere reranker بياخد متوسط 180ms على top 50 chunk عربي. لو RAG بتاعك P95 = 400ms، الـ reranker هيوديك لـ 580ms. لازم تقارن ده بالمكسب في الجودة، وتشوف الـ latency budget عندك.
  2. تكلفة: Cohere rerank-v3.5 بـ $2 لكل 1,000 search. لو عندك 100K طلب شهري، ده $200 إضافية. BGE-reranker مجاني لكنه بيحتاج GPU بحد أدنى (T4 = $0.35/ساعة على Hetzner).
  3. طول الـ document: الـ rerankers ليها حد أقصى للسياق (Cohere = 4096 token، BGE-m3 = 8192 token). chunks أطول من ده بتتقطع داخل النموذج وبتخسر دقة.
  4. اللغة: rerankers قديمة مدرّبة على MS MARCO الإنجليزي ضعيفة جدًا في العربي. خليك على نماذج multilingual (rerank-v3.5، BGE-reranker-v2-m3، Jina-reranker-v2-multilingual).

إعداد بسيط بمكتبة مفتوحة المصدر بدلاً من API

Python
from sentence_transformers import CrossEncoder

model = CrossEncoder("BAAI/bge-reranker-v2-m3", max_length=512)

def rerank_local(question, chunks, top_n=5):
    pairs = [(question, c) for c in chunks]
    scores = model.predict(pairs)
    ranked = sorted(zip(chunks, scores), key=lambda x: x[1], reverse=True)
    return [c for c, _ in ranked[:top_n]]

ده بيشتغل على CPU في حدود 320ms لـ 50 chunk، وعلى GPU T4 في حدود 45ms. الفرق في الجودة بين BGE و Cohere = 5% فقط في الـ NDCG، يعني لو حساس للتكلفة BGE خيار محترم جدًا، خصوصًا لو عندك GPU شغّال أصلاً لخدمات تانية.

متى لا تستخدم Reranker أصلاً

فيه ثلاث حالات الـ reranker بيكون فيها مضيعة وقت ومال:

  • الـ corpus صغير (تحت 500 chunk): الـ vector search لوحده دقيق كفاية. الـ reranker بيضيف latency بدون مكسب ملموس في NDCG.
  • السؤال نوعه exact-match: لو معظم استفسارات المستخدمين كلمة مفتاحية أو SKU أو رقم تذكرة، استخدم BM25 أو full-text search مباشرة. الـ Cross-encoder مبني للأسئلة الطبيعية، مش للاستعلامات الجامدة.
  • الـ latency budget أقل من 200ms: chatbots للدعم الفوري على الموبايل مثلاً، الـ reranker هيكسر تجربة المستخدم. في الحالة دي حسّن الـ embedding model أو chunking strategy بدل ما تضيف طبقة جديدة.

الخطوة التالية

افتح pipeline الـ RAG عندك دلوقتي وغيّر top_k في الـ vector search من 5 لـ 50. أضف نداء واحد لـ co.rerank() أو CrossEncoder.predict(). شغّل 50 سؤال تقييم وقارن الإجابات قبل وبعد. لو شفت الـ hallucination قلّت ولو استرداد الـ ground truth chunk اتحسّن، استمر. لو ملقتش فرق ملموس، يبقى سبب الجودة الضعيفة عندك في chunking strategy، مش في retrieval ranking.

المصادر

  • Nogueira, R., & Cho, K. (2019). Passage Re-ranking with BERT. arXiv:1901.04085.
  • Reimers, N., & Gurevych, I. (2019). Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. EMNLP 2019.
  • Cohere Documentation: Rerank API v3.5 — Multilingual (تحديث مايو 2026).
  • BAAI Hugging Face: bge-reranker-v2-m3 model card.
  • Pinecone Learn: Rerankers and Two-Stage Retrieval (تحديث مارس 2026).
  • Anthropic Engineering: Building effective RAG systems with Claude (أبريل 2026).

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة