Aditya
Deploy RAG benchmark dashboard
af383cf
Raw
History Blame Contribute Delete
7.07 kB
"""End-to-end RAG evaluation demo.
This script shows the full workflow:
1. Build a real RAG system on a knowledge base document
2. Run it against a curated dataset of questions
3. Evaluate every answer with 8 quality metrics
4. Save results to the database
5. Print a summary table
Run with:
python examples/rag_eval.py
Optional flags:
python examples/rag_eval.py --doc data/knowledge_base.txt
python examples/rag_eval.py --doc my_report.pdf --name my-rag-v2
"""
import asyncio
import argparse
import json
import sys
from pathlib import Path
# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from eval_framework.config import get_settings, configure_logging
from eval_framework.rag.pipeline import RAGPipeline
from eval_framework.judges.pipeline import EvaluationPipeline
from eval_framework.storage.database import EvalDatabase
from eval_framework.types import QAPair
from eval_framework.utils.llm_client import get_llm_client
from eval_framework.evaluators import (
FaithfulnessEvaluator,
RelevanceEvaluator,
CompletenessEvaluator,
HallucinationRateEvaluator,
LatencyEvaluator,
CostEvaluator,
)
from eval_framework.evaluators.conciseness import ConcisenessEvaluator
from eval_framework.evaluators.coherence import CoherenceEvaluator
configure_logging()
console = Console()
def build_evaluators(model_name: str):
"""Build the set of evaluators to run."""
client = get_llm_client("groq")
return [
FaithfulnessEvaluator(client, model_name),
RelevanceEvaluator(client, model_name),
CompletenessEvaluator(client, model_name),
HallucinationRateEvaluator(client, model_name),
ConcisenessEvaluator(client, model_name),
CoherenceEvaluator(client, model_name),
LatencyEvaluator(model_name=model_name),
CostEvaluator(model_name=model_name),
]
async def main(doc_path: str, dataset_path: str, system_name: str, concurrency: int):
settings = get_settings()
if not settings.groq_api_key:
console.print("[red]GROQ_API_KEY not set in .env[/red]")
return
# ── Step 1: Build the RAG system ──────────────────────────────────────────
console.print(Panel(
f"Document: [cyan]{doc_path}[/cyan]\n"
f"Dataset: [cyan]{dataset_path}[/cyan]\n"
f"System: [cyan]{system_name}[/cyan]",
title="RAG Evaluation",
expand=False,
))
with console.status("[bold green]Building RAG index..."):
rag = RAGPipeline(
doc_path=doc_path,
chunk_size=500,
chunk_overlap=75,
top_k=3,
model_name=settings.groq_model,
).build()
console.print("[green]RAG pipeline ready[/green]")
# ── Step 2: Load dataset ───────────────────────────────────────────────────
with open(dataset_path) as f:
raw_data = json.load(f)
dataset = [
QAPair(
question=item["question"],
answer=item["answer"],
context=item.get("context"), # May be None β€” RAG will fill this in
)
for item in raw_data
]
console.print(f"[green]Loaded {len(dataset)} questions[/green]")
# ── Step 3: Build evaluators ───────────────────────────────────────────────
evaluators = build_evaluators(settings.groq_model)
console.print(f"[green]{len(evaluators)} evaluators ready[/green]")
# ── Step 4: Run evaluation ─────────────────────────────────────────────────
pipeline = EvaluationPipeline(evaluators=evaluators, concurrency=concurrency)
console.print(
f"\n[yellow]Running {len(dataset)} questions Γ— {len(evaluators)} metrics "
f"(concurrency={concurrency})...[/yellow]"
)
console.print("[dim]This takes ~2-4 minutes on Groq free tier[/dim]\n")
with console.status("[bold green]Evaluating..."):
report = await pipeline.run(
system=rag.query,
dataset=dataset,
system_name=system_name,
)
# ── Step 5: Save to database ───────────────────────────────────────────────
db_path = Path(__file__).parent.parent / "data" / "results.db"
db = EvalDatabase(str(db_path))
db.save_report(report)
console.print(f"\n[green]Saved report {report.id[:8]}... to {db_path}[/green]")
# ── Step 6: Print summary ──────────────────────────────────────────────────
table = Table(
title=f"Results: {system_name}",
show_header=True,
header_style="bold magenta",
)
table.add_column("Metric", style="cyan", min_width=22)
table.add_column("Score", min_width=8)
table.add_column("Rating", min_width=12)
for metric, score in report.summary_scores.items():
metric_name = metric.value if hasattr(metric, "value") else str(metric)
if score >= 0.8:
rating = "[green]EXCELLENT[/green]"
elif score >= 0.6:
rating = "[yellow]GOOD[/yellow]"
elif score >= 0.4:
rating = "[orange1]FAIR[/orange1]"
else:
rating = "[red]POOR[/red]"
table.add_row(metric_name, f"{score:.3f}", rating)
console.print(table)
console.print(
f"\n[dim]Total cost: ${report.total_cost:.4f} | "
f"Examples: {report.total_examples_evaluated} | "
f"Run ID: {report.id[:8]}[/dim]"
)
console.print("\n[bold]Open the dashboard to explore results:[/bold]")
console.print(" streamlit run dashboard/app.py")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="RAG Evaluation Demo")
parser.add_argument(
"--doc",
default="data/knowledge_base.txt",
help="Path to knowledge base document (.txt or .pdf)",
)
parser.add_argument(
"--dataset",
default="data/rag_dataset.json",
help="Path to QA dataset JSON",
)
parser.add_argument(
"--name",
default="rag-langchain-groq",
help="System name for the evaluation report",
)
parser.add_argument(
"--concurrency",
type=int,
default=2,
help="Max concurrent Groq API calls (2 = safe for free tier)",
)
args = parser.parse_args()
asyncio.run(main(
doc_path=args.doc,
dataset_path=args.dataset,
system_name=args.name,
concurrency=args.concurrency,
))