ASDRP · Agentic RAG Track · Module 06
Instrument your RAG pipeline with the Metrics-Driven Development loop and build your first evaluation dataset.
What we'll cover
Evaluation mindset
Three ingredients of rigorous evaluation:
golden_questions.json (8 Qs, diverse, single- & multi-hop)Metrics-Driven Development
Metrics-Driven Development
The two halves
The two halves
Retriever metrics: context precision, context recall, context entities recall, noise sensitivity
Generator metrics: faithfulness, response relevancy, factual correctness
Always ask first: is this a retrieval problem or a generation problem? The fix is completely different.
RAGAS harness setup
nest_asyncioimport sys, types
# RAGAS 0.4.3 tries to import a langchain_community
# module that has been removed. Stub it before importing ragas.
_vx = types.ModuleType(
"langchain_community.chat_models.vertexai")
class ChatVertexAI: # placeholder — intentionally non-functional
pass
_vx.ChatVertexAI = ChatVertexAI
sys.modules[
"langchain_community.chat_models.vertexai"] = _vx
# Notebooks already run an event loop; RAGAS uses asyncio.
import nest_asyncio
nest_asyncio.apply()
# Now it is safe to import ragas.
from ragas.dataset_schema import (
SingleTurnSample, EvaluationDataset)
asyncio. Without this patch, nested await calls crash.
RAGAS harness setup
import os, litellm
from ragas.llms import llm_factory
from ragas.embeddings.base import embedding_factory
LLM_MODEL = "ollama_chat/nemotron-3-super:cloud" # writes answers
JUDGE_MODEL = "ollama_chat/gemma4:31b-cloud" # grades answers
EMBEDDING_MODEL = "ollama/qwen3-embedding:0.6b"
generator_llm = llm_factory(LLM_MODEL, provider="litellm",
client=litellm.completion, temperature=0.3)
judge_llm = llm_factory(JUDGE_MODEL, provider="litellm",
client=litellm.completion, temperature=0.0)
ragas_embeddings = embedding_factory(
"litellm", model=EMBEDDING_MODEL,
api_base=os.environ["OLLAMA_API_BASE"])
generator_llm and judge_llm separate.
RAGAS harness setup
SingleTurnSample & EvaluationDatasetimport json
from ragas.dataset_schema import (
SingleTurnSample, EvaluationDataset)
golden = json.loads(open("golden_questions.json").read())
samples = []
for g in golden:
out = rag_answer(g["question"])
samples.append(SingleTurnSample(
user_input = g["question"],
retrieved_contexts = out["retrieved_contexts"],
response = out["response"],
reference = g["reference"],
))
eval_dataset = EvaluationDataset(samples=samples)
print(f"Dataset: {len(eval_dataset.samples)} rows")
Each SingleTurnSample holds:
user_input — the questionretrieved_contexts — passages returned by the retrieverresponse — the generator's answerreference — the ground-truth answerEvaluationDataset ready for Module 07 scoring.
RAGAS harness setup
import os, json
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv()) # resolves to tutorials/.env
HAVE_KEYS = bool(os.environ.get("OLLAMA_API_KEY"))
if HAVE_KEYS:
# ... build the real RAG and call rag_answer() ...
eval_dataset = EvaluationDataset(samples=live_samples)
else:
raw = json.load(open("frozen/sample_dataset.json"))
eval_dataset = EvaluationDataset(samples=[
SingleTurnSample(**s) for s in raw["samples"]
])
print("(using illustrative frozen data — set OLLAMA_API_KEY "
"in tutorials/.env to run live)")
frozen/sample_dataset.json ships 2 illustrative rows so you can follow every downstream cell without spending any API credits.
Module 06 · Summary
Run the notebook: 06_why_evaluate.ipynb · Next: Module 07 scores the first retriever metrics on this dataset.