الأدلة الإرشادية
تقييم RAG
تغيّرت النسخة الإنجليزية من هذه الصفحة منذ ترجمتها. الصفحة الإنجليزية هي النسخة الحالية. اقرأها بالإنجليزية
قد تكون الإجابة المعزَّزة بالاسترجاع خاطئة لأربعة أسباب مختلفة: لم يُسترجَع المقطع الصحيح قط، أو استُرجع ورُتِّب في مرتبة متدنية جدًا، أو رُتِّب في مرتبة عالية بما يكفي ثم أُسقط من السياق، أو وصل إلى النموذج وأخطأ فيه النموذج مع ذلك. ولا يستطيع رقم دقة واحد أن يميّز بينها. يشغِّل Oloproof نظام RAG على أنه مرحلتان يستطيع رؤيتهما، ويقيس كلًّا منهما، ويعيد تنفيذ الحالات المُخفِقة في ظل تغييرات مضبوطة ليكتشف أيّ الأسباب ينطبق.
examples/support_rag/ هو المشروع الذي تشغِّله هذه الصفحة. ولا يحتاج إلى بيانات اعتماد أي مزوِّد.
نظام على مراحل
النظام صنف (class) له مرحلة استرجاع ومرحلة توليد، ومزيَّن بـ @rag_system:
from oloproof import Passage, Retrieval, rag_system
@rag_system(
name="support-rag",
version="slice-b-example",
depth=6,
top_k=2,
token_budget=40,
index_version="kb-2026-09-16",
)
class SupportRag:
def retrieve(self, input, depth):
...
return Retrieval(query=input["question"], depth=depth, candidates=tuple(passages))
def generate(self, input, context):
...
return {"answer": answer, "citations": [best.doc_id]}
def count_tokens(self, passage):
return len((passage.text or "").split())تُعيد retrieve(input, depth) ما يصل إلى depth من المرشَّحات، بصيغة Passage(doc_id=..., score=..., text=...)، بالترتيب الذي أنتجها به المسترجِع لديك. يسجِّل Oloproof المواضع ولا يعيد ترتيبها أبدًا. ثم يُبقي أول top_k، ويُسقط المقاطع التي تتجاوز token_budget، ويمرِّر ما تبقّى إلى generate(input, context). لا تلزم count_tokens(passage) إلا مع token_budget؛ فـ Oloproof لا يقدِّر عدد الرموز (tokens) أبدًا.
يشير oloproof.yaml إلى الصنف ويمكنه أن يتجاوز أيًّا من إعداداته:
system:
name: support-rag
version: slice-b-example
rag:
object: app:SupportRag
depth: 6
top_k: 2
token_budget: 40
index_version: kb-2026-09-16index_version جزء من هوية الاسترجاع. غيِّره حين يتغيّر الفهرس، وإلا فستُعاد استخدام عمليات استرجاع مخزَّنة في ذاكرة التخزين المؤقت مقابل فهرس لم يعد يُعيدها.
ما تُعلنه الحالة
تحمل حالة RAG حقلين تحت expected لا يحتاجهما أي نوع آخر من الحالات:
{"id":"refund_annual","input":{"question":"How long do refunds take for annual plans?"},"expected":{"answer":"14 days","relevant":[{"doc_id":"kb-01"}],"gold_context":[{"doc_id":"kb-01","text":"Refunds for annual plans are issued within 14 days of an approved request. Support reviews each request on the same business day."}]},"metadata":{"topic":"billing"}}- يسرد expected.relevant المستندات التي تجيب عن السؤال. تقرؤه مقاييس الاسترجاع، والحالة التي
تخلو منه تُستبعَد منها مع no_relevance_labels.
- expected.gold_context هو نص المقطع نفسه. يستبدله التشخيص بالسياق المسترجَع، والحالة المُخفِقة
التي تخلو منه لا يمكن تشخيصها.
المُقيِّمات
evaluators:
- {type: contains, criterion: answer_correct, field: answer, expected_field: answer}
- {type: hit_rate, k: 2}
- {type: recall, k: 2}
- {type: ndcg, k: 6}
- {type: citation_validity}
slices: [metadata.topic, relevant_position, context_truncated]
min_slice_support: 4تأخذ hit_rate وrecall وmrr وndcg المعامل k وتسمّي معيارها الخاص انطلاقًا منه: hit_rate_at_2. ويمكن لأي مدخل في expected.relevant أن يحمل أيضًا chunk_id وgrade، وقيمته الافتراضية 1؛ وعندئذ يعدّ relevance_unit: chunk كل جزء (chunk) وحدةً قائمة بذاتها بدلًا من المستندات الكاملة. يتحقق citation_validity من أن كل معرِّف تستشهد به الإجابة يسمّي مقطعًا في السياق الذي أُعطيته، ومع require_citations: true تُخفق الإجابة التي لا تستشهد بشيء. أما groundedness_judge وcitation_support_judge فهما حَكَمان من نوع LLM يقرآن السياق المُجمَّع، ويأخذان provider وmodel مثل أي حَكَم آخر.
oloproof runثلاثة صفوف من جدول المقاييس:
│ answer_correct │ 69.2% │ [38.5%, 91.0%] │ 9 / 13 observed · 0 missing · 0 excluded │
│ ndcg_at_6 │ 0.866 │ [0.506, 0.990] │ mean of 13 observed · 0 missing · 0 excluded │
│ citations_valid │ 100.0% │ [75.2%, 100.0%] │ 13 / 13 observed · 0 missing · 0 excluded │وبينها، يقرأ كلٌّ من hit_rate_at_2 وrecall_at_2 القيمة 92.3%، أي 12 من 13 مرصودة، بحدٍّ أدنى قدره 63.9%: فالمقطع ذو الصلة لسؤال واحد لم يُسترجَع قط.
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 0 hit/13 miss; generate 0 hit/13 missالسطر Stages هو ذاكرة التخزين المؤقت الخاصة بالنظام ذي المراحل. يُخزَّن الاسترجاع والتوليد كلٌّ على حدة، فلا يؤدي تغيير في التوليد أبدًا إلى إعادة تشغيل الاسترجاع.
اكتشاف السبب
أخفقت أربعة أسئلة. يعيد diagnose تنفيذها مع وضع المقطع الذهبي مكان السياق المسترجَع، إلى جانب مجموعة ضابطة تعيد تنفيذها دون تغيير:
oloproof diagnose RUN_ID --intervention gold-context --criterion answer_correctSelected: 4 failed cases with gold context (observed; no population claim)
Control: 0 of 4 passed when re-executed without the intervention
Recovered under gold context: 3 of 4
RETRIEVAL_MISS: 1 of 4, recovered; no relevant evidence was retrieved
CONTEXT_ASSEMBLY_LOSS: 2 of 4, recovered; relevant evidence within top-k was left out of the context
GENERATION_FAILURE: 1 of 4, still failed with the gold context
Implicated: context budget, in 2 of the 3 recovered failures.
Candidate experiment: a larger token budget. This is a hypothesis to test, not an established cause.
Candidate experiment: smaller chunks. This is a hypothesis to test, not an established cause.
Diagnosis sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69
Child runs: gold context run_01M3C3REAAZDF9FD8N2C8BG17P, control run_01M3C3REAFVXK2VM4MYAQYH6KE
Cases: oloproof inspect sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69الحالة التي تنجح مع المقطع الذهبي وتُخفق من دونه أخفقت في مرحلة سابقة للنموذج. أما الحالة التي تُخفق والمقطع الذهبي بين يديها فهي من مسؤولية النموذج. والمجموعة الضابطة هي ما يجعل هذه القراءة آمنة: فالحالة التي تتعافى عند إعادة تشغيل عادية كانت متقلِّبة، لا مُشخَّصة.
يسرد معرِّف التشخيص الحالةَ الكامنة وراء كل عدد:
oloproof inspect DIAGNOSIS_IDmoney_back: RETRIEVAL_MISS, relevant_not_retrieved, strength intervention_recovery, best relevant position none
refund_review: CONTEXT_ASSEMBLY_LOSS, relevant_dropped_from_context, strength intervention_recovery, best relevant position 2
seat_count: GENERATION_FAILURE, fails_with_gold_context, strength intervention_non_recovery, best relevant position 1
security_review: CONTEXT_ASSEMBLY_LOSS, relevant_dropped_from_context, strength intervention_recovery, best relevant position 2إنه يسمّي عاملًا، ولا يسمّي سببًا أبدًا. فعبارتا "Implicated" و"candidate experiment" هما أقوى ما يستخدمه من كلمات، لأن تعافي أربع حالات في ظل تدخُّل واحد لا يثبت سبب إخفاقها.
اختبار الإصلاح قبل إجرائه
يعيد تدخُّلان آخران تشغيل الاسترجاع المسجَّل بإعداد مختلف، فلا يُجرى أي استدعاء للمسترجِع. يوسِّع top-k حدَّ القطع:
oloproof diagnose RUN_ID --intervention top-k --top-k 4 --criterion answer_correctSelected: 4 failed cases with gold context (observed; no population claim)
Control: 0 of 4 passed when re-executed without the intervention
Recovered under top-k 4: 0 of 4
Confirmed under top-k 4: 0 of 0 RANKED_OUT cases also recovered
Labels from gold context (diagnosis sha256:b2846cbe04099225bda4bf21beb1738f54d6cc0e9a7ce210bb3eb467619cbd69): 3 of 4 recovered
RETRIEVAL_MISS: 1 of 4, recovered; no relevant evidence was retrieved
CONTEXT_ASSEMBLY_LOSS: 2 of 4, recovered; relevant evidence within top-k was left out of the context
GENERATION_FAILURE: 1 of 4, still failed with the gold context
Diagnosis sha256:668084c3e99df84f7b63f138792aa96f48e5cb8251fee3acae8e1cc0500ba085
Child runs: gold context run_01M3C3REAAZDF9FD8N2C8BG17P, control run_01M3C3REAFVXK2VM4MYAQYH6KE, top-k 4 run_01M3C3RKHTGGV37079V11JJ78M, replay control run_01M3C3RKJ076K7MSVQ94J4ZE2P
Cases: oloproof inspect sha256:668084c3e99df84f7b63f138792aa96f48e5cb8251fee3acae8e1cc0500ba085لم يتعافَ شيء، وهذا ما تنبّأت به الوسوم: لم يكن أي إخفاق هنا مقطعًا رُتِّب دون حدِّ القطع بقليل. تحمل إعادة التشغيل وسوم السياق الذهبي معها، فيُقرأ التشخيصان معًا. ويأخذ reranker الخيار --reranker مع module:function ويعيد تشغيل الاسترجاع عبر أداة إعادة الترتيب الخاصة بك بدلًا من ذلك.
إجراء التجربة
سمّى التشخيص ميزانية رموز أكبر. ارفع token_budget إلى 120 وشغِّل من جديد:
Cache: execution 0 hit/13 miss; judgment 0 hit/65 miss
Stages: retrieve 13 hit/0 miss; generate 7 hit/6 missأُعيد استخدام كل عملية استرجاع، لأن top_k وميزانية الرموز خارج هوية الاسترجاع؛ ولم يُعَد التوليد إلا للحالات الست التي تغيّر سياقها. ثم قارِن، باستخدام سياسة المقارنة الخاصة بالمثال:
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yamlComparison sha256:d801ed897f1fa1b196ca1e3f73a1ef4ffe6845d6ee8bddaea8a44da94d27a75b of run_01M3C3RYJZ4PAJ8P4P9NT71360 against run_01M3C3R5Y9D18WGSZQFA7N4XRT · 13 paired cases
answer_correct: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
hit_rate_at_2: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
recall_at_2: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
ndcg_at_6: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excluded
citations_valid: +0.0 points [-33.6, +33.6] · 13 paired · 0 missing · 0 excludedيلي ذلك سطر استكشافي واحد لكل شريحة ومقياس، ثم القرارات:
Decisions
answers-not-worse answer_correct non-inferiority, margin 5.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
citations-not-worse citations_valid non-inferiority, margin 2.0 points INSUFFICIENT_EVIDENCE interval_overlaps_margin
Gate: BLOCK (exit 3)لم تُفِد التجربة: فلم تغيِّر ولا حالة واحدة من الحالات الثلاث عشرة حكمها. كما أن ثلاث عشرة حالة مقترنة ما كانت لتستطيع إثبات تغيير بأي حجم يهمّ الإصدار، وهذا هو الأمر الآخر الذي تقوله الفترة.
إلى أين بعد ذلك
- تتناول الشرائح relevant_position وcontext_truncated.
- تتناول قواعد المقارنة القواعد التي حُسمت بها الخطوة الأخيرة.
- تتناول الحُكّام ما يجب أن يجتازه حَكَم الاستناد (groundedness) قبل أن يُسمح له بتطبيق البوابة.