· 15 min read

How to Run Evals on a RAG Pipeline: Test Set, Metrics and CI

To run evals on a RAG pipeline, you need three things: a test set of real questions with expected answers and source passages, metrics that score retrieval and generation separately, and an automated run that repeats on every change. Without them, every tweak to a prompt or a chunk size is a guess, and you learn about regressions from users. This guide walks through the procedure, the standard metrics in plain terms, and what to do when the numbers are bad.
A stack of documents feeding a magnifying glass and a chat answer, each with its own gauge and checkmark, illustrating RAG pipeline evaluation
Not sure how good your RAG answers are?Tell us what your pipeline answers and where it goes wrong. We’ll suggest a test set, the metrics worth tracking and a release gate.
Evaluate my RAG system

The short answer

RAG evaluation is a loop, not a one-time audit. You collect real questions, write down what a good answer looks like and which passages contain it, run the pipeline, and score two things: did retrieval find the right passages, and did the model answer correctly from them. Then you automate the run so it repeats whenever anything changes.

The split matters most. A RAG system has two components that fail in different ways. If you only score the final answer, a bad result tells you something is wrong but not where. Scored separately, the numbers point at the fix: low retrieval recall means you work on chunking, search or reranking; good retrieval with bad answers means you work on the prompt, the context or the model. If you need a refresher on the components themselves, see our RAG architecture guide.

How to run RAG evals, step by step

  1. Write down what a good answer isBefore any metric, agree on the rules: must answers cite sources, what should the system say when the documents don't cover the question, which errors are unacceptable (a wrong price, a wrong dosage, another customer's data). These rules become your scoring criteria.
  2. Collect 50 to 100 real questionsTake them from search logs, support tickets, sales calls and pilot users. Keep the original wording, typos and vague phrasing included.
  3. Label expected answers and source passagesFor each question a domain expert records the correct answer and the document passages that contain it. The passages are what make retrieval measurable.
  4. Log every stage of a runFor each question store the retrieved chunks with their ranks and scores, the final prompt, the answer, latency and token cost. You can't score retrieval separately if you only keep the answer.
  5. Score retrievalCompare the retrieved chunks with the labeled passages: recall@k, precision@k and a rank metric. No language model is needed for this part, so it is fast, cheap and repeatable.
  6. Score answersCheck faithfulness to the retrieved context, relevance to the question and correctness against the expected answer, using an LLM judge that you have calibrated against human labels.
  7. Read the failures, not just the averagesSort the failed questions into categories: missing document, wrong chunk, ignored context, outdated source. The biggest category is your next piece of work.
  8. Automate it and set a gateRun the set in CI, compare with the last accepted baseline and block releases that score lower.
  9. Feed production back inAfter launch, sample real conversations every week and add each new failure to the test set.

Build the test set from real questions

The test set decides what your scores mean. A set of tidy questions written by the engineers who built the pipeline will give high scores and tell you little.

Size

Start with 50 to 100 questions. That finds the large failures and is small enough to label carefully. Plan to reach 200 to 500 before you treat score changes as release decisions, because small sets are statistically noisy. At 100 questions and an 80% pass rate, the 95% margin of error is about 8 percentage points in each direction. A change from 80% to 84% is inside the noise. At 400 questions the margin shrinks to about 4 points.

Sources and mix

Real user wording beats invented wording. Cover the mix your product will actually face:

  • Simple lookups answered by one passage.
  • Multi-part questions that need two or more passages, often from different documents.
  • Questions with exact terms: product codes, error numbers, names. Vector search alone often misses these.
  • Unanswerable questions where your documents have no answer. The expected behavior is to say so. Without these, you never measure the failure that hurts trust most: a confident invented answer.
  • Permission cases, if access differs by user: the same question asked by two roles should retrieve different documents.

A model can draft questions from your documents to get you started. According to the Ragas documentation, its test set generator builds a knowledge graph from your documents and produces single-hop and multi-hop queries from it. Treat generated questions as drafts for an expert to review. They tend to reuse the wording of the source text, which makes retrieval look better than it will be on real traffic.

Who writes the expected answers

Someone who would be trusted to answer the question without the system: a support lead, a compliance officer, a senior engineer. Engineers can prepare the candidates (pull the passages, draft an answer), but the expert approves. For each item, store the question, the expected answer, the IDs of the passages that support it, and a note on anything the answer must or must not include. Version the set in the repository next to the code, and re-check labels when the underlying documents change.

Evaluate retrieval and generation separately

Where each metric measures the pipeline Question Retriever search, rerank Ranked chunks top k Language model prompt + chunks Answer Retrieval metrics chunks vs. labeled source passages recall@k, precision@k, MRR, nDCG no model call needed Generation metrics answer vs. chunks: faithfulness answer vs. question: relevance answer vs. expected answer: correctness Two scorecards. A low number on the left is a search problem; a low number on the right with a good left side is a model or prompt problem.
Retrieval is scored against labeled passages, generation against the retrieved chunks, the question and the expected answer.

Retrieval sets the ceiling. If the passage with the answer never reaches the prompt, no model or prompt can produce a grounded correct answer. So measure retrieval first, on its own, and fix it before you spend time on prompts.

Retrieval metrics

MetricWhat it asksHow to read it
Recall@kOf the passages that should have been found, what share is in the top k results?The most important retrieval number. Low recall means the answer was not available to the model.
Precision@kOf the k results returned, what share is relevant?Low precision means noise in the prompt: higher cost, and more chances for the model to pick up the wrong fact.
MRRHow high does the first relevant result rank? (Average of 1 divided by its rank.)Rank 1 scores 1.0, rank 2 scores 0.5, rank 5 scores 0.2. Good for tuning a reranker.
nDCG@kAre the most relevant results at the top of the list, compared with an ideal ordering?Use it when relevance is graded (highly, partly, not relevant) rather than yes or no.

Set k to the number of chunks you actually pass to the model. Recall@20 is of little comfort if only the top 5 go into the prompt. It also helps to measure recall at two points, before and after reranking, so you can tell whether the first-stage search or the reranker lost the passage.

Answer metrics

MetricWhat it asksNeeds an expected answer?
Faithfulness (groundedness)Is every claim in the answer supported by the retrieved passages? Usually computed by splitting the answer into claims and checking each one against the context.No
Answer relevanceDoes the answer address the question that was asked, without drifting or padding?No
CorrectnessDoes the answer agree with the expected answer on the facts that matter?Yes
Refusal accuracyFor unanswerable questions, did the system decline instead of inventing an answer? For answerable ones, did it avoid declining?Yes (a label that the question is unanswerable)

Faithfulness and correctness are not the same thing, and the gap between them is diagnostic. A faithful but wrong answer means the retrieved document was wrong or outdated: a data problem. A correct but unfaithful answer means the model used its training data instead of your sources: it happened to be right this time, and it will not be when your facts differ from the public ones. Our guide to RAG hallucinations covers how to reduce both kinds.

LLM-as-judge and its limits

Answer metrics need something that reads text and makes a judgment. People do this best and slowest. An LLM judge is a second model prompted to grade the output: given the question, the retrieved passages and the answer, is each claim supported? It makes it practical to score hundreds of answers on every change.

The limits are real, and you should plan around them:

  • A judge is a model, with model errors. It can pass a fluent, well-structured answer that is subtly wrong, and it lacks your domain knowledge unless you give it the expected answer.
  • Scores drift. The same answer can get different grades across runs, and a new judge model version can shift every score at once. Old and new numbers stop being comparable.
  • Wide scales are unreliable. "Rate accuracy from 1 to 10" produces numbers nobody can interpret. A narrow question with a pass or fail answer ("Is the refund period stated in the answer the same as in the expected answer?") is far more repeatable.
  • It costs money and time. Each judged answer is one or more extra model calls. Claim-by-claim faithfulness checks multiply that.
Calibrate the judge before you trust it

Have domain experts label 50 to 100 answers as pass or fail. Run the judge on the same answers and count the disagreements. Read each one and adjust the judge prompt until agreement is high enough for the decision you are making. Pin the judge model version, set its temperature to zero where the provider allows it, and repeat the comparison whenever the judge prompt or model changes.

Keep a human review sample

Calibration is not a one-time event. Each week, pull a sample of scored answers, for example 20 to 50, and have an expert grade them without seeing the judge's verdict. Weight the sample toward what matters: answers the judge failed, answers users rated down, high-risk topics, and a random slice of passes to catch what the judge lets through. Track judge-versus-human agreement as a metric of its own. When it drops, fix the judge before you believe any other number.

Regression checks in CI

A RAG pipeline changes in more ways than ordinary code: prompts, chunk size, embedding model, reranker, the answering model, and the documents themselves. Any of these can fix ten questions and break five others. A regression run makes that visible before release.

  • Two tiers. Retrieval metrics need no model calls beyond embedding the questions, so run them on every pull request. Run the full suite with judged answer metrics before each release and on a nightly schedule.
  • Compare with a baseline, not an absolute target. Store the scores of the last accepted version. Fail the build when a metric drops by more than the noise you measured for your set size.
  • Diff per question. An unchanged average can hide five new failures and five new passes. List the questions that flipped and read them.
  • Hard-fail a critical subset. Mark the questions where a wrong answer is unacceptable (pricing, legal, safety, permissions). Any failure there blocks the release regardless of the average.
  • Pin what you can. Model versions, judge prompt, test set version and index snapshot. Otherwise you can't tell whether your change or someone else's moved the score.
  • Track cost and latency in the same run. A change that adds two points of recall and doubles response time is a trade-off someone should approve.

Evaluation libraries

Retrieval metrics take a few dozen lines to write yourself. For answer metrics, open-source libraries give you judge prompts to start from; check them against your human labels like any other judge. Three common ones, as their own documentation describes them:

LibraryWhat its documentation offers for RAG
RagasRAG metrics including Context Precision, Context Recall, Faithfulness, Response Relevancy and Noise Sensitivity. Faithfulness is the share of claims in the response supported by the retrieved context, scored 0 to 1. Context Recall has an LLM-based variant that uses a reference answer and non-LLM variants that compare against reference contexts or their IDs. Includes a test set generator.
DeepEvalRetriever metrics (Contextual Relevancy, Contextual Precision, Contextual Recall) and generator metrics (Answer Relevancy, Faithfulness), plus G-Eval for custom criteria. Metrics return a score from 0 to 1 with a reason and pass against a threshold. It plugs into Pytest, and evals run with the deepeval test run command.
TruLensOpen-source, OpenTelemetry-native evals and tracing. Its documentation frames RAG quality as the "RAG triad": context relevance, groundedness and answer relevance. Includes leaderboard and compare views for app versions.

Online signals after launch

An offline test set measures the questions you thought of. Production shows you the ones you didn't. Log every request with its retrieved chunks and answer, and watch:

  • Explicit feedback: thumbs up and down with an optional comment. Few users leave it, so treat it as a source of examples, not a rate you can trust.
  • Rephrased questions: a user asking the same thing again in different words usually means the first answer failed.
  • Escalations: handoffs to a human agent or a support ticket opened right after an answer.
  • No-answer rate: how often the system declines. A sudden rise points to a broken index or ingestion job; a rate near zero on a narrow knowledge base suggests it is answering things it shouldn't.
  • Reference-free judge scores: faithfulness and answer relevance on a sample of live traffic, tracked as a trend.
  • Latency and cost per answer, split into retrieval and generation.

Every confirmed production failure goes into the test set with an expected answer and source passages. That is how a set of 80 questions becomes 400 that reflect real use.

Built by Gilzor

Results we’ve shipped

70+products launched
98%delivered on time
85%clients come back
5.0on Clutch
Art Scherbakov, Co-FounderAndrew Laminsky, CTOYuri Rudenya, Head of Mobile Development at GilzorAlena Timofeeva, Product Marketing Lead

Talk to the people who build it. Tell us about your project and get a free estimate of scope, timeline and cost.

See how we’d approach yours

Symptom, likely cause, fix

When scores are bad, the pattern across the two scorecards usually names the cause:

SymptomLikely causeFix to try first
"I don't know" although the document exists; low recall@kThe passage is not retrieved: chunks split the answer, or the query wording differs from the document'sCheck the document is indexed; adjust chunking; add keyword search next to vector search (hybrid); rewrite queries
Recall is good at k=20, answers are still wrongThe right passage ranks low and is cut off or buried in noiseAdd or tune a reranker; pass fewer, better chunks; track MRR or nDCG
Right passage in the prompt, wrong answer; low faithfulnessThe model ignores or misreads context, or the prompt allows outside knowledgeTighten the prompt to answer only from sources; reduce context noise; try a stronger model
Confident answer to a question the documents don't coverNo refusal path; weakly related chunks are treated as evidenceInstruct the model to decline without support; add a relevance threshold; add unanswerable questions to the test set
Faithful to the source but factually outdatedStale or duplicate document versions in the indexFix ingestion freshness; remove superseded versions; filter by date or version
Multi-part questions are half answeredOne search can't cover two topicsSplit the question into sub-queries and merge results
Numbers from tables or PDFs come out wrongParsing flattened the table or lost the layoutUse a parser that keeps table structure; chunk tables whole
Offline scores are high, users complainThe test set doesn't match real questions, or the judge is too lenientRebuild the set from production logs; recalibrate the judge against human labels
Scores dropped and nobody changed the codeNew documents in the index, or the provider updated a modelPin model versions; run evals nightly; evaluate after each large ingestion

FAQ

How do I run AI evals on my RAG pipeline?
Collect 50 to 100 real user questions, and for each one record the expected answer and the passages that contain it. Run the pipeline on every question and score two stages separately: retrieval (recall@k, precision@k, MRR or nDCG against the labeled passages) and generation (faithfulness to the retrieved context, relevance to the question, correctness against the expected answer). Use an LLM judge for the answer metrics, check the judge against human labels, then rerun the whole set automatically whenever a prompt, model, chunking rule or document set changes.
How many questions does a RAG test set need?
Start with 50 to 100. That is enough to find the big failures and small enough for an expert to label in a few days. Grow it to 200 to 500 before you rely on it for release decisions, because small sets are noisy: at 100 questions and an 80% pass rate, the 95% margin of error is about 8 points either way, so a move from 80% to 84% proves nothing. At 400 questions the margin is about 4 points.
What is the difference between faithfulness and correctness?
Faithfulness (also called groundedness) asks whether every claim in the answer is supported by the retrieved passages. Correctness asks whether the answer matches the expected answer. They diverge in both directions. An answer can be faithful and wrong when retrieval returned an outdated document, and it can be correct and unfaithful when the model answered from its training data instead of your sources. You need both numbers.
Can I use an LLM to grade RAG answers?
Yes, and at any real volume you have to. But treat the judge as a measuring tool that needs calibration. Have people label 50 to 100 answers, run the judge on the same answers and compare. Use narrow pass or fail questions instead of 1 to 10 scores, pin the judge model version and prompt, and rerun the comparison whenever either changes. Keep a human review sample running, because a judge can miss the same domain errors the answering model makes.
Which RAG evaluation metrics matter most?
If you track only three, track recall@k for retrieval, faithfulness for generation and correctness against expected answers end to end. Recall@k tells you whether the answer was even available to the model. Faithfulness tells you whether the model stuck to the sources. Correctness tells you whether the user got the right answer. Add precision and a rank metric such as MRR or nDCG when you tune reranking, and a refusal check for questions your documents can't answer.
Can I generate the test set synthetically?
You can use a model to draft questions from your documents, and libraries such as Ragas include a test set generator for this. Treat the output as a draft. Synthetic questions tend to be cleaner and closer to the document wording than what real users type, so retrieval looks better on them than it is. Have a domain expert review every generated item and mix in real questions from search logs, support tickets and pilot users as soon as you have them.
How often should RAG evals run?
Run the cheap retrieval metrics on every pull request that touches prompts, chunking, embeddings, retrieval or the model. Run the full suite with LLM-judged answer metrics before each release, and on a schedule, for example nightly, to catch changes you did not make yourself: new documents in the index or a provider updating a model. Review a sample of production conversations by hand every week.

Where Gilzor fits

If you have a RAG pipeline and no reliable way to say how good it is, that is the work we offer under RAG evaluation services: a test set built from your real questions with your experts, separate retrieval and answer scorecards, a calibrated judge, and a regression run in your CI. We build custom RAG systems and add RAG to existing products as well, so the findings can go straight into fixes. A 2-week fixed-price Discovery Sprint is the usual way to start. Tell us what your system answers, where it goes wrong and what a wrong answer costs you.

No sales pitch

Get a straight answer for your project

Tell us what you’re building. We’ll reply with options, a rough cost and timeline. If we’re not the right fit, we’ll say so.

Next, a few optional questions so the first call is useful. We use your details only to reply to your request. Privacy Policy

Andrew Laminsky
Written byAndrew Laminsky

CTO of Gilzor. Responsible for architecture and the engineering standards our teams work by.

LinkedIn →

Gilzor · AI/ML Solutions partner

Need a team for your AI product?

95%referred by business partners
70+successful launches
85%repeat business
98%delivered on time

The team behind them

Art Scherbakov
Art ScherbakovCo-Founder
Andrew Laminsky
Andrew LaminskyCTOLinkedIn
Yuri Rudenya
Yuri RudenyaHead of Mobile Development at GilzorLinkedIn
Alena Timofeeva
Alena TimofeevaProduct Marketing LeadLinkedIn
Tell us what you’re buildingOptions, a rough cost and timeline for your project. No commitment.

More insights