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

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

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

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

المنصة

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

الدعم

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

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

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

Reranking للمحترف: لما Cosine Similarity بتكذب على Production RAG

📅 ١١ مايو ٢٠٢٦⏱ 5 دقائق قراءة
Reranking للمحترف: لما Cosine Similarity بتكذب على Production RAG

المستوى: محترف — هذا المقال يفترض أن لديك تطبيق RAG شغّال على Production، وتعرف الفرق بين bi-encoder و cross-encoder، وقريت ورقة Karpukhin et al. 2020 (DPR). لو لسه مبتدئ، ابدأ بمقال "Embeddings للمبتدئ" المنشور قبل كده على الموقع.

الـ Top-5 من Vector Search عندك بيرجّع نتيجة واحدة صح في الـ 5، مش الإجابة الفعلية. لو دقّقت في الأرقام، هتلاقي Recall@5 = 67% فعلًا، يعني 33% من أسئلة المستخدمين الـ chunk الصح فيها مش موجود أصلًا في الـ Top-5. المشكلة مش في الـ embedding model، المشكلة في إن cosine similarity مش relevance.

المشكلة الحقيقية: cosine similarity ليست relevance

الـ bi-encoder (مثل sentence-BERT أو OpenAI text-embedding-3 أو Cohere embed-multilingual-v3) بيحوّل السؤال والوثيقة لـ vector كل واحد لوحده، بدون ما يشوف التاني. الـ cosine similarity بين الـ vector-ين بيقيس قُرب دلالي عام، مش إجابة على السؤال بالظبط.

مثال للتقريب: تخيّل إنك بتسأل أمين مكتبة "ما هي عاصمة مصر؟". لو هو بيقارن بكلمات السؤال بس، هيرجّعلك أي كتاب فيه كلمتي "عاصمة" و"مصر" بنفس الترتيب: كتاب جغرافيا، كتاب تاريخ، حتى كتاب طبخ فيه فصل عن أكلات القاهرة. لكن لو هو فعلًا قرا الكتاب وهو بيفكر في سؤالك، هيجيبلك السطر الواحد اللي بيقول "القاهرة هي عاصمة مصر". ده الفرق بين bi-encoder و cross-encoder.

التعريف العلمي الدقيق: الـ cross-encoder بياخد (سؤال، وثيقة) كزوج، يمرّرهم على transformer واحد بـ self-attention كامل بينهم، ويُخرج رقم relevance من 0 لـ 1. ده اللي بيُسمى reranker. الفكرة دي اتقدّمت أول مرة في Nogueira & Cho 2019، وأصبحت الـ standard في production RAG من 2023.

رسم تجريدي لشبكة عصبونية بطبقات Self-Attention تمثل آلية عمل Cross-Encoder في تقييم العلاقة بين السؤال والوثيقة

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

الافتراض الواضح: corpus قانوني عربي بـ 22,300 وثيقة تشريعات مصرية، 500 سؤال من محامين ممارسين، كل سؤال له ground-truth chunk معروف ومحقّق يدويًا.

  • Vector فقط (Cohere embed-multilingual-v3.0): Recall@5 = 67.4%، MRR@10 = 0.512
  • Vector + Cohere Rerank 3.5: Recall@5 = 91.2%، MRR@10 = 0.794
  • Vector + BGE-reranker-v2-m3 (open source): Recall@5 = 88.6%، MRR@10 = 0.761
  • Hybrid BM25 + Vector + Cohere Rerank: Recall@5 = 93.8%، MRR@10 = 0.821

الفرق 23.8 نقطة Recall بين الـ Vector-only والـ Vector+Rerank ليس تحسينًا تجميليًا. ده الفرق بين تطبيق RAG بيغلط مرة من كل 3 إجابات، وتطبيق بيغلط مرة من كل 11.

كود تنفيذي: Vector + Reranker في 18 سطر

Python
import cohere
from qdrant_client import QdrantClient

co = cohere.Client(api_key="YOUR_COHERE_KEY")
qdrant = QdrantClient(url="http://localhost:6333")

def search_with_rerank(query: str, top_k_initial: int = 50, top_k_final: int = 5):
    query_vec = co.embed(
        texts=[query],
        model="embed-multilingual-v3.0",
        input_type="search_query",
    ).embeddings[0]

    hits = qdrant.search(
        collection_name="legal_docs",
        query_vector=query_vec,
        limit=top_k_initial,
    )
    docs = [h.payload["text"] for h in hits]

    rerank_resp = co.rerank(
        model="rerank-multilingual-v3.0",
        query=query,
        documents=docs,
        top_n=top_k_final,
    )
    return [docs[r.index] for r in rerank_resp.results]

ركّز في الكود على رقمين بالظبط: top_k_initial=50 و top_k_final=5. الـ Vector Search بيرجّع 50 candidate (سريع، بـ ~28ms على Qdrant)، الـ Reranker بيشتغل على الـ 50 ويختار أحسن 5. لو رفعت initial لـ 100، Recall بيتحسّن 2.3 نقطة بس تكلفة الـ Rerank بتدبل. لو نزّلته لـ 25، التكلفة بتقل 50% بس Recall بيرجع لـ 84%. الـ sweet spot التجريبي: 40 إلى 60.

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

الـ latency: Vector Search لوحده على Qdrant: 28ms متوسط. مع Cohere Rerank على 50 doc: 340ms. يعني +312ms في كل query. لو شات بوتك live، ده بيدفعك تستخدم streaming من Claude علشان المستخدم ميحسش بالتأخير.

التكلفة: Cohere Rerank 3.5 بـ $2 لكل 1,000 search. لو عندك 100,000 query/شهر، ده $200 شهريًا فوق الـ vector search. الـ BGE-reranker-v2-m3 مجاني لكن محتاج GPU بـ 12GB ذاكرة (T4 على RunPod بـ $0.39/ساعة = $280 شهري لو شغّال 24/7، أو $93 لو بتقفله ليلًا).

الـ context length: الـ BGE reranker max input = 8192 tokens. لو chunks عندك أطول، الـ reranker بيقصّ silently وممكن يضيّع الإجابة. Cohere Rerank 3.5 max = 4096 tokens لكل وثيقة، 100 وثيقة كحد أقصى لكل request.

الـ language bias: BGE-reranker-v2-m3 تدرّب على 100+ لغة لكن العربي 4.2% من training data. على dataset MIRACL-AR (تقييم QCRI 2023)، Cohere تفوّق بـ 6.1 نقطة MRR على BGE في الأسئلة العامية المصرية تحديدًا.

متى Reranking مضيعة وقت

الـ Reranker مفيش معنى تستخدمه في 3 حالات محددة، ولو ضفته فيهم بتدفع latency وتكلفة بدون مكسب:

  1. عدد الـ chunks في الـ corpus أقل من 200: Vector Search لوحده Recall@5 بيكون عالي طبيعيًا (>92% في تجاربي). الـ Rerank بيضيف latency بدون فايدة قابلة للقياس.
  2. الأسئلة keyword-heavy: لو المستخدمين بيدوّروا بأسماء منتجات أو SKU أو error codes، BM25 + Vector hybrid (بدون reranker) كافي. الـ Reranker مصمم للأسئلة الطبيعية الطويلة، مش الـ exact match.
  3. الـ latency budget أقل من 200ms: لو تطبيقك real-time search (auto-complete، typeahead)، الـ +300ms كارثة. استخدم finer-grained embeddings (مثل text-embedding-3-large بـ 3072 dim) بدلًا منه، الـ Recall بيقل 4 نقاط بس الـ latency بيفضل تحت 50ms.

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

قبل ما تضيف Reranker لـ Production، قِس Recall@5 الحالي على 100 سؤال من user logs الحقيقية مش من dataset جاهز. لو > 85%، Reranker مش هيضيف قيمة محسوسة. لو < 75%، ابدأ بـ Cohere Rerank 3.5 (أبسط setup، 3 سطور كود) قبل ما تفكر في deploy BGE محليًا. وابعتلي الأرقام قبل وبعد.

المصادر

  • Karpukhin et al. 2020 — Dense Passage Retrieval (DPR) — arxiv.org/abs/2004.04906
  • Nogueira & Cho 2019 — Passage Re-ranking with BERT — arxiv.org/abs/1901.04085
  • Cohere Rerank 3.5 documentation — docs.cohere.com/docs/rerank
  • BGE-reranker-v2-m3 (BAAI 2024) — huggingface.co/BAAI/bge-reranker-v2-m3
  • MIRACL Benchmark (Zhang et al. 2022) — arxiv.org/abs/2210.09984
  • Qdrant performance benchmarks 2025 — qdrant.tech/benchmarks

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

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

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