0Pricing
AI Engineering Academy · درس

لماذا يهم التقييم في RAG

تعرّفوا إلى نمطي الفشل المستقلين في أنظمة RAG: فشل الاسترجاع وفشل التوليد، واكتشفوا سبب الحاجة إلى مقاييس منفصلة لتشخيص كل منهما.

لماذا يهم التقييم في RAG درس مجاني في AI Engineering Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في AI Engineering Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.

لا يمكنك تحسين ما لا تقيسه

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

نمطا فشل مستقلان

يتضمن RAG مرحلتين متميزتين يمكن أن تفشلا بصورة مستقلة: الاسترجاع والتوليد. يفشل الاسترجاع عندما لا تُرتّب الأجزاء ذات الصلة ضمن أفضل K من النتائج — إذ لا يستطيع LLM إنشاء إجابة جيدة إذا لم تُسترجع المعلومات الصحيحة أصلًا. ويفشل التوليد عندما تُسترجع الأجزاء الصحيحة، لكن LLM يتجاهلها أو يسيء قراءتها أو يضيف معلومات هلوسية. تحتاج إلى مقاييس منفصلة لكل مرحلة لتحديد المكوّن الذي يسبب المشكلة.

خطر الاكتفاء بالتقييم من البداية إلى النهاية

يؤدي قياس جودة الإجابة النهائية فقط إلى إخفاء مصدر حالات الفشل. لنفترض أن نظامك يقدم إجابات خاطئة في 30% من الحالات. فهل يرجع ذلك إلى أن الاسترجاع لا يعثر على الأجزاء الصحيحة، أم إلى أن LLM يتجاهل الأجزاء الجيدة؟ إذا كنت تعرف معدل الخطأ النهائي فقط، فلن تعرف أي مكوّن ينبغي إصلاحه. راقب المرحلتين بصورة منفصلة: قِس جودة الاسترجاع باستخدام مجموعات البيانات المرجعية، وجودة التوليد باستخدام درجات الأمانة.

# Diagnosis example: which stage is failing?

# Test 1: Is retrieval finding the right chunks?
retrieval_hit_rate = evaluate_retrieval(questions, ground_truth_chunks)
print(f'Retrieval hit rate@5: {retrieval_hit_rate:.1%}')
# If this is low (< 80%), fix chunking and embedding first

# Test 2: Given perfect context, does LLM generate correct answers?
generation_faithfulness = evaluate_generation(questions, perfect_context)
print(f'Generation faithfulness: {generation_faithfulness:.1%}')
# If retrieval is fine but this is low, fix your prompts

إنشاء مجموعة بيانات مرجعية

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

# Golden dataset format
golden_dataset = [
    {
        'question': 'How many vacation days do employees receive in their first year?',
        'answer': '15 days',
        'relevant_chunks': ['employee_handbook_p24', 'benefits_summary_p3'],
        'source_doc': 'employee_handbook_2025.pdf'
    },
    {
        'question': 'What is the parental leave duration for primary caregivers?',
        'answer': '16 weeks fully paid',
        'relevant_chunks': ['parental_leave_policy_p1'],
        'source_doc': 'parental_leave_policy.pdf'
    }
]

إنشاء مجموعات بيانات ذهبية باستخدام LLMs

إنشاء 100 سؤال يدويًا أمر ممل. يمكنكم تسريع ذلك باستخدام نموذج LLM لتوليد البيانات: مرّروا كل جزء من المستند إلى GPT-4o واطلبوا منه إنشاء 3 إلى 5 أسئلة متنوعة يمكن العثور على إجاباتها في ذلك الجزء، بالإضافة إلى نص الإجابة المتوقعة. راجعوا عينة يدويًا لاكتشاف مشكلات الجودة. يتوسع هذا الأسلوب بسرعة ليشمل آلاف الأسئلة، لكنه قد يفوّت الحالات الحدّية التي قد يطرحها المستخدمون الحقيقيون فقط.

def generate_qa_pairs_for_chunk(chunk_text, llm_client):
    prompt = (
        'Given the following document excerpt, generate 3 diverse questions '
        'that can be answered using ONLY this text. '
        'For each question, provide the exact answer from the text.\n\n'
        f'Text:\n{chunk_text}\n\n'
        'Format each as JSON: {"question": ..., "answer": ...}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

تقييم الاسترجاع: معدل الإصابة

معدل الإصابة@K هو نسبة الأسئلة التي يظهر فيها جزء واحد ذو صلة على الأقل ضمن نتائج الاسترجاع K الأولى. وهو أبسط مقاييس الاسترجاع وأكثرها وضوحًا. ويعني معدل إصابة@5 البالغ 85% أن الجزء ذي الصلة كان ضمن أول 5 نتائج في 85 سؤالًا من أصل 100. تتبّعوا معدل الإصابة بشكل منفصل حسب أنواع المستندات، وأطوال الاستعلامات، وفئات الموضوعات لمعرفة المواضع التي يواجه فيها نظام الاسترجاع أكبر الصعوبات.

def compute_hit_rate(golden_dataset, retriever, top_k=5):
    hits = 0
    for item in golden_dataset:
        results = retriever.retrieve(item['question'], top_k=top_k)
        retrieved_ids = {r['id'] for r in results}
        relevant_ids = set(item['relevant_chunks'])
        if retrieved_ids & relevant_ids:  # intersection not empty
            hits += 1
    hit_rate = hits / len(golden_dataset)
    print(f'Hit rate@{top_k}: {hit_rate:.1%} ({hits}/{len(golden_dataset)})')
    return hit_rate

تقييم التوليد: الأمانة

تقيس الأمانة ما إذا كانت الإجابة المُولَّدة تحتوي فقط على معلومات يمكن التحقق منها في السياق المسترجَع. تضيف الإجابة غير الأمينة حقائق لا يدعمها السياق، وهذا ما يُسمى بالهلوسة. قيّموا الأمانة بأن تطلبوا من نموذج LLM مُقيِّم (أو مقيّم بشري) فحص كل جملة في الإجابة مقابل السياق، والإبلاغ عن أي ادعاءات لا تدعمها الأجزاء المسترجعة. وتُعد درجة أمانة تبلغ 95% أو أكثر هدفًا مناسبًا للأنظمة المستخدمة في الإنتاج.

def evaluate_faithfulness(answer, context, llm_client):
    prompt = (
        'Given this context and answer, evaluate faithfulness.\n\n'
        f'Context: {context}\n\n'
        f'Answer: {answer}\n\n'
        'For each sentence in the answer, determine if it is '
        'supported by the context (FAITHFUL) or not (HALLUCINATED). '
        'Return a JSON: {"score": 0.0-1.0, "issues": ["sentence..."]}.'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

تقييم التوليد: صلة الإجابة

تقيس صلة الإجابة ما إذا كانت الإجابة المُولَّدة تتناول سؤال المستخدم فعلًا. فقد تكون الإجابة أمينة جدًا، لكنها مع ذلك لا تصيب الهدف لأنها تجيب عن سؤال مختلف لكنه مرتبط به. قيسوا الصلة بشكل منفصل عن الأمانة. استخدموا نموذج LLM مُقيِّمًا لتقدير مدى تناول الإجابة للسؤال المطروح مباشرة، باستخدام مقياس من 1 إلى 5. وغالبًا ما تشير صلة الإجابة المنخفضة إلى مشكلة في بنية prompt أو إلى أن السياق المسترجَع لا يحتوي الإجابة فعلًا.

def evaluate_answer_relevance(question, answer, llm_client):
    prompt = (
        f'Question: {question}\n\n'
        f'Answer: {answer}\n\n'
        'Rate how well this answer addresses the question on a 1-5 scale:\n'
        '5 = fully answers the question\n'
        '3 = partially answers but misses key aspects\n'
        '1 = does not address the question at all\n\n'
        'Return JSON: {"score": 1-5, "reason": "brief explanation"}'
    )
    response = llm_client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': prompt}]
    )
    return response.choices[0].message.content

تتبّع المقاييس بمرور الوقت

يصبح التقييم أكثر فائدة عندما تتتبّعون المقاييس بمرور الوقت أثناء إجراء التغييرات. خزّنوا نتائج التقييم في قاعدة بيانات أو جدول بيانات مع الطوابع الزمنية وتسميات الإصدارات (مثل: chunk_size=500, embed=3-small, k=5). عند تجربة استراتيجية جديدة لتقسيم الأجزاء أو نموذج تضمين جديد، أجروا التقييم نفسه وقارنوا النتائج. يمنع ذلك التراجع في الأداء؛ فقد تحسّنون الأمانة لكنكم تخفّضون معدل الإصابة دون قصد. أجروا دائمًا التقييم الكامل قبل دمج التغييرات في بيئة الإنتاج.

import json
from datetime import datetime

def save_evaluation_results(metrics, config, output_file='eval_history.jsonl'):
    record = {
        'timestamp': datetime.utcnow().isoformat(),
        'config': config,
        'metrics': metrics
    }
    with open(output_file, 'a') as f:
        f.write(json.dumps(record) + '\n')
    print(f'Saved eval result: hit_rate={metrics["hit_rate"]:.1%}, '
          f'faithfulness={metrics["faithfulness"]:.1%}')

منهجية التقييم

إلى جانب المقاييس المحددة، يتطلب التقييم تغييرًا في المنهجية: تعاملوا مع RAG كنظام تعلّم آلي ذي أداء قابل للقياس، وليس كروبوت محادثة تقيّمونه بصورة ذاتية من خلال التحدث إليه. حدّدوا معايير النجاح مسبقًا (مثل: hit rate@5 > 85%، وfaithfulness > 95%). أنشئوا مجموعة اختبار تظل ثابتة ولا تُستخدم مطلقًا لاتخاذ قرارات التطوير. خصّصوا مجموعة تطوير منفصلة للتكرار والتحسين. تميّز هذه الممارسة المنضبطة بين الفرق التي تطلق أنظمة RAG موثوقة والفرق التي تطلق عروضًا تجريبية مبهرة تفشل في بيئة الإنتاج.

مجموعة الاختبار مقابل مجموعة التطوير

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

import json
from sklearn.model_selection import train_test_split

def split_golden_dataset(all_questions, test_ratio=0.3, seed=42):
    dev_set, test_set = train_test_split(
        all_questions,
        test_size=test_ratio,
        random_state=seed
    )
    print(f'Dev set: {len(dev_set)} questions')
    print(f'Test set: {len(test_set)} questions (FROZEN)')
    with open('eval/dev_set.json', 'w') as f:
        json.dump(dev_set, f, indent=2)
    with open('eval/test_set.json', 'w') as f:
        json.dump(test_set, f, indent=2)
    return dev_set, test_set

تحقق سريع

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

مراجعة الدرس

تعلّمتم في هذا الدرس: نمطَي الفشل المستقلين في الاسترجاع والتوليد، اللذين يتطلبان مقاييس منفصلة، وكيفية بناء مجموعة بيانات ذهبية تتكون من ثلاثيات السؤال والإجابة والجزء لإجراء تقييم موضوعي، ومعدل الإصابة بوصفه المقياس الأساسي للاسترجاع، والأمانة وصلة الإجابة بوصفهما المقياسين الأساسيين للتوليد، وأهمية تتبّع المقاييس بمرور الوقت لمنع التراجعات. سننتقل بعد ذلك إلى تنفيذ مقاييس استرجاع محددة، بما في ذلك MRR وNDCG.

الأسئلة الشائعة

هل درس «لماذا يهم التقييم في RAG» مجاني؟

نعم — نص درس «لماذا يهم التقييم في RAG» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة AI Engineering Academy، انتقل إلى CoddyKit PRO. تتضمن دورة AI Engineering Academy 4 دروس في المجموع.

ماذا ستتعلم في «لماذا يهم التقييم في RAG»؟

تعرّفوا إلى نمطي الفشل المستقلين في أنظمة RAG: فشل الاسترجاع وفشل التوليد، واكتشفوا سبب الحاجة إلى مقاييس منفصلة لتشخيص كل منهما. تتمرن على AI Engineering Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ AI Engineering Academy؟

لا تُشترط خبرة سابقة. AI Engineering Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «لماذا يهم التقييم في RAG»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس AI Engineering Academy هذا؟

نعم. كل درس في AI Engineering Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا يهم التقييم في RAG
  2. مقاييس الاسترجاع: معدل الإصابة وMRR وNDCG
  3. مقاييس التوليد: الأمانة وملاءمة الإجابة
  4. بناء أداة تقييم آلية
← العودة إلى AI Engineering Academy