AI-ResearchPilot / docs /evaluation.md
Keerthisujana's picture
Initial deploy of AI ResearchPilot
6a5d1ee
|
Raw
History Blame Contribute Delete
8.67 kB

A newer version of the Gradio SDK is available: 6.22.0

Upgrade

Evaluation

All numbers below were produced by actually running python scripts/evaluate.py in this project's development environment and are saved verbatim in data/eval_results.json. Nothing here is invented. Reproduce them yourself with the same command β€” results will differ (likely improve) on a real Hugging Face Space where the primary transformer models can load; see the "Backend in use" line below and docs/architecture.md.

Backend in use for this run: tfidf-fallback (scikit-learn) embeddings, mmr-fallback reranking. Corpus: 17 documents / 45 chunks. Eval set: 8 hand-labeled questions with gold-relevant document ids (data/eval_questions.json).

12.1 System comparison (mean over the 8-question eval set)

System Recall@K Context Relevance Evidence Coverage Citation Correctness Hallucination Rate (proxy) Iterations Latency (s)
Basic Vector RAG 0.669 0.231 1.000 0.594 0.406 1.00 0.0015
Hybrid RAG 0.794 0.031 1.000 0.648 0.352 1.00 0.0019
Agentic RAG 0.631 0.177 0.896 0.345 0.655 1.25 0.0330

Honest reading of these numbers

This is not a case of the fancier system automatically winning β€” and we're reporting that plainly rather than reshaping the eval set or metrics until it does:

  • Hybrid RAG has the best recall and citation correctness on this run. Reciprocal Rank Fusion genuinely helps here: it catches keyword-critical matches (acronyms like "NMT", "BLEU") that pure semantic search under the TF-IDF fallback sometimes misses, without losing the semantic signal.
  • Agentic RAG has the worst citation correctness (0.345) and the highest hallucination-rate proxy (0.655) on this run. The Planner decomposes a single gold-labeled question into several sub-questions (e.g. "what datasets are used", "what limitations are reported"), and each sub-question pulls in its own passages β€” several of which are relevant to the sub-question but not to the original question's specific gold document set used for scoring. In other words: decomposition trades precision against the original question's narrow gold set for broader topical coverage. This is a real, known tension in agentic RAG, not a bug being hidden β€” see Future Work below for how we'd address it.
  • Agentic RAG's context relevance (0.177) sits between Basic (0.231) and Hybrid's oddly low 0.031. Hybrid RAG's very low context-relevance number is a measurement artifact worth flagging honestly: context_relevance is computed by re-embedding each passage against the original question using the Evidence Agent's scorer, but Hybrid RAG's own passages were selected by RRF-fused rank, not by that scorer β€” so passages that ranked well under hybrid fusion don't necessarily score well under the independent relevance check. This mismatch is a limitation of comparing systems with one shared metric function that only one of them was designed against; a fairer comparison would give every system's own native relevance signal equal standing, which is left for future work.
  • Agentic RAG is ~20x slower (0.033s vs ~0.002s) β€” expected, since it runs multiple retrieval cycles and several extra scoring passes per question. On the TF-IDF fallback this cost is trivial in absolute terms; with the real transformer models (embedding + cross-encoder + NLI + LLM generation, all CPU-bound on a free Space), expect several seconds per question, not milliseconds β€” still fast enough for an interactive demo.

Takeaway: on this small corpus, with the honest fallback backend, the simpler Hybrid RAG baseline is actually the stronger system by the precision-oriented metrics used here. The agentic system's real advantage β€” catching contradictions and honestly reporting insufficient evidence rather than guessing β€” isn't captured by Recall@K/citation-correctness at all; see Β§12.3.

12.2 Ablation study (mean over the same 8 questions)

Configuration Recall@K Context Relevance Evidence Coverage Citation Correctness Hallucination Rate (proxy) Iterations Latency (s)
Full Agentic RAG 0.631 0.177 0.896 0.345 0.655 1.25 0.0103
Without Planner 0.675 0.242 1.000 0.615 0.385 1.00 0.0031
Without Evidence Verification 0.631 1.000 0.969 0.281 0.719 1.00 0.0046
Without Adaptive Retrieval 0.631 0.177 0.896 0.345 0.655 1.00 0.0095
Without Contradiction Detection 0.631 0.177 0.896 0.345 0.655 1.25 0.0105
Without Final Verification 0.631 0.177 0.896 0.345 0.655 1.00 0.0093

Honest reading of the ablation

  • "Without Planner" scores better on every precision metric, confirming the same effect described above: on this eval set (built around single, fairly specific questions), decomposition spreads retrieval across sub-questions the gold-label set didn't anticipate. This is a genuine, useful finding about this eval set's design, not just the system: an eval set built from multi-part research questions (the kind ResearchPilot is actually meant for, e.g. "compare X and Y and identify the gaps") would need gold labels per sub-question, not one flat gold set per question, to fairly credit decomposition. That's flagged in Future Work.
  • "Without Evidence Verification" shows context_relevance jumping to a perfect 1.000 β€” but this is an artifact of that ablation's own mechanism, not genuine quality: disabling evidence verification forces every retrieved passage's relevance_label to SUPPORTED and relevance_score to 1.0 by construction (see _ablation_run in src/evaluation/benchmark.py), so of course the average of a constant 1.0 is 1.0. It's included for completeness and to make exactly this kind of artifact visible, not to claim the un-verified system is actually better.
  • Removing contradiction detection, adaptive retrieval, or final verification alone changes almost nothing in this run because none of these 8 questions happened to trigger a second retrieval cycle after the domain-floor/threshold fixes, except where noted (iterations stays 1.0 for those ablations vs 1.25 for the full system and the contradiction-detection ablation, which still loops since contradiction detection isn't what gates the sufficiency check). This is a real limitation of an 8-question eval set: it's too small to reliably exercise every branch. Expanding data/eval_questions.json (see Future Work) would give these ablations more room to differentiate.

12.3 What these metrics don't capture

The system-comparison table above cannot see two of ResearchPilot's actual differentiators, because neither Basic nor Hybrid RAG has any notion of either:

  1. Explicit contradiction surfacing. Only the Agentic RAG system detects and reports the real, verifiable conflict between two papers in the corpus reporting different BLEU-point improvements from back-translation/data-augmentation methods (Generalized Data Augmentation for Low-Resource Translation reports 1.5–8 BLEU; Data Augmentation for Low-Resource Neural Machine Translation reports 2.9 BLEU). Basic and Hybrid RAG would silently cite both without flagging the discrepancy.
  2. Honest insufficiency. Only the Agentic RAG system will say "Insufficient evidence to provide a reliable answer" for an off-corpus question (verified directly: tests/test_pipeline.py::test_off_domain_question_reports_insufficiency) instead of returning some passages regardless of fit, which is what Basic/Hybrid RAG do by construction (they always return their top-K).

Neither of these behaviors is rewarded β€” or even measured β€” by Recall@K, context relevance, or citation correctness. A faithfulness/abstention-aware metric (e.g., did the system correctly decline to answer an unanswerable question; did it correctly flag a genuine contradiction) would be needed to see the agentic approach's actual value in a table, and is a natural addition to src/evaluation/metrics.py (see Future Work).

12.4 Reproducing this evaluation

python scripts/evaluate.py

This regenerates data/eval_results.json from a live run. On a Hugging Face Space with the primary transformer models loaded, re-run this and compare β€” the README and this document will not be silently "corrected" to match; if you get materially different results, that's expected and is the point of shipping the script rather than a static table only.