قياس أثر إعادة الترتيب
أجروا مقارنة معيارية قبلية وبعدية بين الاسترجاع أحادي المرحلة والاسترجاع على مرحلتين مع إعادة الترتيب، وقيسوا NDCG وMRR وجودة الإجابة من البداية إلى النهاية.
قياس أثر إعادة الترتيب درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
لماذا نقيس تأثير إعادة الترتيب؟
تضيف إعادة الترتيب زمناً وتكلفة إلى مسار المعالجة لديكم. ومن دون القياس، لا يمكنكم تحديد ما إذا كان التعقيد الإضافي يستحق ذلك. تحدد المقارنة المعيارية مقدار التحسن في جودة الاسترجاع وجودة الإجابة الشاملة، مما يتيح لكم اتخاذ قرار مستنير. كما تكشف أنواع الاستعلامات التي تستفيد أكثر، وبذلك يمكنكم تطبيق إعادة الترتيب بشكل انتقائي بدلاً من تطبيقها على كل طلب.
إنشاء مجموعة اختبارات مرجعية
تتطلب المقارنة المعيارية الموثوقة مجموعة اختبارات مرجعية، وهي مجموعة من الاستعلامات المقترنة بمعرّفات المستندات المعروفة بصلتها بها. أنشئوها بأخذ عينات من استعلامات المستخدمين الفعلية من سجلات تطبيقكم، وتحديد المستندات ذات الصلة يدوياً أو باستخدام التعليقات التوضيحية من الخبراء، ثم تنظيمها في تنسيق منظّم. وتكفي مجموعة اختبارات تضم 50 إلى 200 استعلام لمعظم أغراض تقييم RAG.
golden_test_set = [
{
'query': 'How does pgvector HNSW indexing improve search speed?',
'relevant_doc_ids': ['doc_042', 'doc_107'],
},
{
'query': 'What is the difference between BM25 and dense retrieval?',
'relevant_doc_ids': ['doc_015'],
},
{
'query': 'How to implement reciprocal rank fusion in Python?',
'relevant_doc_ids': ['doc_093', 'doc_094'],
},
# ... 47 more entries
]
print(f'Test set size: {len(golden_test_set)} queries')
print(f'Avg relevant docs per query: {sum(len(e["relevant_doc_ids"]) for e in golden_test_set) / len(golden_test_set):.1f}')مقاييس الاسترجاع: NDCG وMRR ومعدل الإصابة
استخدموا ثلاثة مقاييس متكاملة لتقييم جودة الاسترجاع. يقيس معدل الإصابة عند K ما إذا كان مستند واحد ذو صلة على الأقل يظهر ضمن أول K نتائج. يقيس MRR (متوسط الرتبة التبادلية) متوسط مقلوب رتبة أول مستند ذي صلة. ويقيس NDCG عند K (الكسب التراكمي المخصوم والمطبّع) جودة الترتيب، مع إعطاء المراتب الأعلى وزناً أكبر من المراتب الأدنى.
def compute_retrieval_metrics(results: list[str], relevant_ids: set, k: int = 5):
results_at_k = results[:k]
relevant_found = [r for r in results_at_k if r in relevant_ids]
# Hit rate
hit = 1 if relevant_found else 0
# MRR
rr = 0
for i, doc_id in enumerate(results_at_k, start=1):
if doc_id in relevant_ids:
rr = 1.0 / i
break
# NDCG (binary relevance)
import math
dcg = sum(
1.0 / math.log2(i + 1)
for i, doc_id in enumerate(results_at_k, start=1)
if doc_id in relevant_ids
)
ideal = sum(1.0 / math.log2(i + 1) for i in range(1, min(len(relevant_ids), k) + 1))
ndcg = dcg / ideal if ideal > 0 else 0
return {'hit': hit, 'rr': rr, 'ndcg': ndcg}خط الأساس: الاسترجاع الكثيف أحادي المرحلة
قبل قياس تأثير إعادة الترتيب، أنشئوا خط أساس باستخدام الاسترجاع الكثيف أحادي المرحلة. شغّلوا كل استعلام في مجموعة الاختبارات عبر أداة الاسترجاع ذات المشفّرين، واجمعوا معرّفات المستندات المرتبة، ثم احسبوا متوسط NDCG وMRR ومعدل الإصابة. يوضح لكم خط الأساس مقدار التحسن الممكن انطلاقاً من الوضع الحالي — فإذا كان خط الأساس لديكم يبلغ بالفعل 0.95 في NDCG@5، فلن يتبقى مجال كبير لتحسينه بإعادة الترتيب.
def evaluate_pipeline(retriever_fn, test_set: list[dict], k: int = 5) -> dict:
all_metrics = []
for entry in test_set:
query = entry['query']
relevant = set(entry['relevant_doc_ids'])
results = retriever_fn(query, top_k=k)
result_ids = [r['id'] for r in results]
metrics = compute_retrieval_metrics(result_ids, relevant, k)
all_metrics.append(metrics)
n = len(all_metrics)
return {
f'hit_rate@{k}': sum(m['hit'] for m in all_metrics) / n,
f'mrr@{k}': sum(m['rr'] for m in all_metrics) / n,
f'ndcg@{k}': sum(m['ndcg'] for m in all_metrics) / n,
}تشغيل المقارنة المعيارية قبل التغيير وبعده
شغّلوا دالة التقييم نفسها على كل من أداة الاسترجاع أحادية المرحلة وأداة الاسترجاع ثنائية المرحلة مع إعادة الترتيب. اطبعوا النتائج جنباً إلى جنب لجعل التحسن (أو عدمه) واضحاً فوراً. وتابعوا زمن الاستجابة لكل استعلام إلى جانب مقاييس الجودة — فقد لا تكون زيادة جودة الاسترجاع بنسبة 5 بالمئة جديرة بزيادة زمن الاستجابة بمقدار 400ms، وذلك بحسب متطلبات SLA الخاصة بتطبيقكم.
import time
def evaluate_with_latency(retriever_fn, test_set, k=5):
metrics_list = []
latencies = []
for entry in test_set:
t0 = time.perf_counter()
results = retriever_fn(entry['query'], top_k=k)
latencies.append((time.perf_counter() - t0) * 1000)
result_ids = [r['id'] for r in results]
metrics_list.append(compute_retrieval_metrics(
result_ids, set(entry['relevant_doc_ids']), k
))
n = len(metrics_list)
return {
f'hit_rate@{k}': sum(m['hit'] for m in metrics_list) / n,
f'ndcg@{k}': sum(m['ndcg'] for m in metrics_list) / n,
'p50_latency_ms': sorted(latencies)[n // 2],
'p99_latency_ms': sorted(latencies)[int(n * 0.99)],
}
baseline = evaluate_with_latency(dense_retrieval_fn, golden_test_set)
two_stage = evaluate_with_latency(two_stage_fn, golden_test_set)
print('Baseline:', baseline)
print('Two-stage:', two_stage)تفسير تحسينات NDCG
تتراوح التحسينات المعتادة الناتجة عن إضافة إعادة الترتيب باستخدام cross-encoder إلى الاسترجاع الكثيف بين 0.05 و0.15 كقيمة مطلقة لـ NDCG@5، وهو ما يعادل تقريباً 5 إلى 15 نقطة مئوية. ويكون التحسن أكبر عندما: (1) تكون استعلاماتكم متنوعة وتضم العديد من إعادة الصياغة، أو (2) تضم مجموعة المستندات العديد من المقاطع القريبة من الصلة، أو (3) تكون أداة الاسترجاع في المرحلة الأولى ضعيفة. وإذا رأيتم تحسناً في NDCG يقل عن 0.02، فقد لا تبرر الفائدة التعقيد الإضافي.
# Interpreting benchmark results
example_results = {
'baseline': {'hit_rate@5': 0.78, 'ndcg@5': 0.64, 'p99_latency_ms': 35},
'two_stage': {'hit_rate@5': 0.89, 'ndcg@5': 0.77, 'p99_latency_ms': 287},
}
delta_ndcg = example_results['two_stage']['ndcg@5'] - example_results['baseline']['ndcg@5']
delta_latency = example_results['two_stage']['p99_latency_ms'] - example_results['baseline']['p99_latency_ms']
print(f'NDCG improvement: +{delta_ndcg:.2f} (+{delta_ndcg/example_results["baseline"]["ndcg@5"]*100:.0f}%)')
print(f'Latency increase: +{delta_latency}ms')
# NDCG improvement: +0.13 (+20%) — clearly worth the 252ms latency costقياس جودة الإجابة الشاملة
تقيس مقاييس الاسترجاع ما إذا كانت المستندات الصحيحة قد استُرجعت، لكن المقياس النهائي هو جودة الإجابة الشاملة. استخدموا مُقيِّماً قائماً على LLM لتقييم ما إذا كانت الإجابات المُولّدة من السياق المُعاد ترتيبه أكثر صحة وأمانة من الإجابات المُولّدة من سياق المرحلة الواحدة. قيّموا الإجابات على مقياس من 1 إلى 5 من حيث الصحة والأمانة والصلة، ثم احسبوا المتوسط عبر مجموعة الاختبارات.
from openai import OpenAI
client = OpenAI()
JUDGE_PROMPT = '''
Rate the following answer on a scale of 1-5 for correctness and faithfulness to the context.
Question: {question}
Context: {context}
Answer: {answer}
Ground truth: {ground_truth}
Return a JSON with fields: {"correctness": int, "faithfulness": int, "explanation": str}
'''
def judge_answer(question, context, answer, ground_truth):
prompt = JUDGE_PROMPT.format(
question=question, context=context,
answer=answer, ground_truth=ground_truth,
)
response = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}],
response_format={'type': 'json_object'},
)
import json
return json.loads(response.choices[0].message.content)التحليل الطبقي حسب نوع الاستعلام
تخفي المقاييس المتوسطة اختلافات مهمة بين أنواع الاستعلامات. قسّموا مجموعة الاختبارات إلى فئات — عمليات البحث عن حقائق (من، ماذا، متى)، والاستعلامات الإجرائية (كيفية تنفيذ شيء ما)، والاستعلامات المفاهيمية (لماذا، اشرح)، والاستعلامات التقنية (رموز الأخطاء، وأسماء API) — ثم احسبوا المقاييس لكل مجموعة على حدة. وغالباً ما تحقق إعادة الترتيب أكبر فائدة في الاستعلامات المفاهيمية والإجرائية، حيث يكون الفهم الدلالي أهم من مطابقة الكلمات المفتاحية.
def stratified_eval(retriever_fn, test_set, k=5):
groups = {'factual': [], 'procedural': [], 'conceptual': [], 'technical': []}
for entry in test_set:
q = entry['query'].lower()
if any(w in q for w in ['how to', 'how do', 'steps to']):
groups['procedural'].append(entry)
elif any(w in q for w in ['why', 'explain', 'what is the reason']):
groups['conceptual'].append(entry)
elif any(c.isupper() for c in q.split()) or 'error' in q:
groups['technical'].append(entry)
else:
groups['factual'].append(entry)
for group_name, group_entries in groups.items():
if group_entries:
metrics = evaluate_pipeline(retriever_fn, group_entries, k)
print(f'{group_name} ({len(group_entries)} queries): ndcg@{k}={metrics[f"ndcg@{k}"]:.3f}')اختبار الانحدار مع التكامل مع CI
شغّلوا المقارنة المعيارية للاسترجاع باعتبارها اختبار انحدار في CI. حدّدوا الحدود الدنيا المقبولة لـ NDCG@5 وMRR ومعدل الإصابة. وأي تغيير في مسار المعالجة يتسبب في انخفاض المقاييس إلى ما دون الحد يفشل عملية البناء في CI، مما يمنع وصول تراجعات جودة الاسترجاع إلى الإنتاج. ويكتسب ذلك أهمية خاصة بعد تغيير أحجام المقاطع أو نماذج التضمين أو نماذج إعادة الترتيب.
# pytest integration for retrieval quality gates
import pytest
MIN_NDCG_5 = 0.70
MIN_HIT_RATE_5 = 0.85
def test_retrieval_quality_meets_threshold():
metrics = evaluate_pipeline(production_retriever_fn, golden_test_set, k=5)
assert metrics['ndcg@5'] >= MIN_NDCG_5, (
f'NDCG@5 {metrics["ndcg@5"]:.3f} below threshold {MIN_NDCG_5}'
)
assert metrics['hit_rate@5'] >= MIN_HIT_RATE_5, (
f'Hit rate {metrics["hit_rate@5"]:.3f} below threshold {MIN_HIT_RATE_5}'
)
# Run with: pytest tests/test_retrieval.py -vتصوير مقاييس الاسترجاع
يصعب تفسير الأرقام الخام عند مقارنة تجارب متعددة. أنشئوا جدول مقارنة بسيطاً أو مخططاً شريطياً يعرض NDCG وMRR ومعدل الإصابة وزمن الاستجابة جنباً إلى جنب لمسارات المعالجة التالية: خط الأساس، والاسترجاع الهجين فقط، والاسترجاع الهجين مع إعادة الترتيب. ويساعد تتبع هذه المقاييس بمرور الوقت أثناء إجراء التحسينات في إنشاء سجل لتحسين الاسترجاع، يوجّه قرارات التحسين المستقبلية.
def print_comparison_table(results: dict[str, dict]):
headers = ['Pipeline', 'NDCG@5', 'MRR@5', 'Hit@5', 'P99 ms']
print('|'.join(f'{h:20}' for h in headers))
print('-' * (len(headers) * 21))
for pipeline_name, metrics in results.items():
row = [
pipeline_name,
f'{metrics.get("ndcg@5", 0):.3f}',
f'{metrics.get("mrr@5", 0):.3f}',
f'{metrics.get("hit_rate@5", 0):.3f}',
f'{metrics.get("p99_latency_ms", 0):.0f}',
]
print('|'.join(f'{v:20}' for v in row))
results = {
'Dense only': {'ndcg@5': 0.64, 'mrr@5': 0.68, 'hit_rate@5': 0.78, 'p99_latency_ms': 35},
'Hybrid RRF': {'ndcg@5': 0.71, 'mrr@5': 0.74, 'hit_rate@5': 0.84, 'p99_latency_ms': 55},
'Hybrid + Rerank': {'ndcg@5': 0.77, 'mrr@5': 0.81, 'hit_rate@5': 0.89, 'p99_latency_ms': 287},
}
print_comparison_table(results)اتخاذ الإجراءات بناءً على نتائج المقارنة المعيارية
بعد تشغيل المقارنات المعيارية، استخدموا النتائج لاتخاذ قرارات عملية. إذا حسّنت إعادة الترتيب NDCG بأقل من 0.03، فتجاوزوها وركّزوا على تحسين المرحلة الأولى. وإذا كان معدل الإصابة منخفضاً، فهذا يعني أن المرحلة الأولى لا تسترجع المستندات ذات الصلة — فزيدوا حجم مجموعة المرشحين أو انتقلوا إلى الاسترجاع الهجين. وإذا تحسنت جودة الإجابة الشاملة بشكل ملحوظ رغم محدودية مكاسب الاسترجاع، فقد تكون أداة إعادة الترتيب تُظهر جملاً شديدة الصلة يستفيد منها LLM بفعالية، حتى مع بقاء موضع الترتيب دون تغيير.
تحقق سريع
اختبروا فهمكم لقياس تأثير الاسترجاع وإعادة الترتيب من هذا الدرس.
مراجعة الدرس
في هذا الدرس تعلّمتم أن إنشاء مجموعة اختبارات مرجعية تتضمن مستندات معروفة الصلة أمر أساسي قبل قياس جودة الاسترجاع، وأن NDCG وMRR ومعدل الإصابة هي مقاييس الاسترجاع الأساسية الثلاثة التي تقيس معاً جودة الترتيب بشكل شامل، وأن جودة الإجابة الشاملة باستخدام مُقيِّم قائم على LLM توفر المقياس النهائي لتحسن مسار المعالجة. شغّلوا دائماً المقارنات المعيارية للاسترجاع كاختبارات انحدار في CI. بعد ذلك سنستكشف بث LLM لعرض الرموز أثناء توليدها.
تعلم Python مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 30
- الدروس
- 120
الأسئلة الشائعة
هل درس «قياس أثر إعادة الترتيب» مجاني؟
نعم — نص درس «قياس أثر إعادة الترتيب» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.
ماذا ستتعلم في «قياس أثر إعادة الترتيب»؟
أجروا مقارنة معيارية قبلية وبعدية بين الاسترجاع أحادي المرحلة والاسترجاع على مرحلتين مع إعادة الترتيب، وقيسوا NDCG وMRR وجودة الإجابة من البداية إلى النهاية. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟
لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «قياس أثر إعادة الترتيب»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟
نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- لماذا ينجح الاسترجاع على مرحلتين
- إعادة الترتيب باستخدام Cross-Encoder مع Cohere وBGE
- الضغط السياقي وتصفية الصلة
- قياس أثر إعادة الترتيب