Post

Evaluating RAG Pipelines with Ragas: Moving Beyond Vibes

Evaluating RAG Pipelines with Ragas: Moving Beyond Vibes

Introduction

Retrieval-Augmented Generation (RAG) has become the de facto architecture for building AI applications that need to reason over proprietary data. Building a prototype RAG system takes an afternoon; making it production-ready takes months. The biggest hurdle? Evaluation.

Most developers start by “vibes-based testing”—typing a few queries into their chat interface, reading the output, and subjectively deciding if the response “looks right.” While this works for a prototype, it fails catastrophically at scale. How do you know if changing your chunking strategy or switching from OpenAI to Anthropic actually improved the system? You need quantitative, automated metrics. This is where Ragas (Retrieval Augmented Generation Assessment) comes in.

The Core Challenge of RAG Evaluation

A RAG pipeline consists of two distinct halves:

  1. The Retriever: Searches your vector database to find context relevant to the user’s question.
  2. The Generator (LLM): Synthesizes that context to formulate a coherent answer.

If the system gives a bad answer, you must diagnose why. Did the retriever fail to find the right document? Or did the LLM hallucinate despite having the correct document?

Enter Ragas: Automated Metrics for RAG

Ragas is a framework that uses LLMs as judges to evaluate your RAG pipelines without requiring human-annotated ground-truth datasets. It breaks down evaluation into highly specific metrics that target different components of your pipeline.

1. Faithfulness (Generation)

This metric checks for hallucinations. It asks: Is the generated answer entirely derived from the retrieved context? If the LLM brings in outside knowledge that isn’t present in the retrieved documents, the Faithfulness score drops.

2. Answer Relevance (Generation)

This metric measures how well the generated answer addresses the original user prompt. It penalizes incomplete answers and answers that go off on tangent, even if the information is factually correct.

3. Context Precision (Retrieval)

This evaluates whether the retriever ranked the most relevant documents at the very top of the results. High precision means the LLM doesn’t have to sift through irrelevant noise to find the answer.

4. Context Recall (Retrieval)

This evaluates whether the retriever managed to fetch all the necessary information required to answer the question. If a question requires details from two different documents and the retriever only found one, Context Recall will be low.

Code Example: Running a Ragas Evaluation

While you might be orchestrating your backend in Ruby on Rails, data science and evaluation frameworks like Ragas are built in Python. Here is how you can write a script to evaluate a batch of responses generated by your Rails app.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# evaluate_rag.py
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall,
)

# 1. Prepare your evaluation dataset
# In a real scenario, you would export this data from your database (e.g., via a Rails rake task)
data = {
    "question": [
        "What is the company's remote work policy?"
    ],
    "answer": [
        "The company allows remote work for up to 3 days a week, but requires core hours between 10 AM and 3 PM."
    ],
    "contexts": [
        ["Employees may work remotely 3 days per week. Core hours are 10:00 to 15:00 EST."]
    ],
    "ground_truth": [
        "Remote work is permitted 3 days a week with mandatory availability from 10 AM to 3 PM."
    ]
}

dataset = Dataset.from_dict(data)

# 2. Run the evaluation using Ragas
# Note: Ensure you have OPENAI_API_KEY set in your environment variables, 
# as Ragas uses LLMs under the hood to grade these metrics.
result = evaluate(
    dataset,
    metrics=[
        faithfulness,
        answer_relevancy,
        context_precision,
        context_recall
    ]
)

# 3. Output the results
print("Evaluation Results:")
print(result)
# Expected Output format:
# {'faithfulness': 1.0, 'answer_relevancy': 0.95, 'context_precision': 1.0, 'context_recall': 1.0}

Explanation

  • datasets: Ragas leverages the Hugging Face datasets library for efficient data handling. Your dataset must include question, answer, contexts, and (optionally) ground_truth.
  • LLM-as-a-Judge: Ragas uses an LLM (defaulting to OpenAI’s models) to evaluate the responses. This allows it to understand semantic meaning rather than relying on rigid exact-string matching.
  • Continuous Integration: By wrapping this Python script in a CI/CD pipeline, you can automatically run Ragas evaluations on a golden dataset every time you update your prompt or change your vector search parameters.

Conclusion

“Vibes-based testing” is the enemy of production AI. If you cannot measure your pipeline, you cannot improve it. By integrating Ragas into your workflow, you gain deterministic, component-level observability into your RAG architecture. You will know exactly when to blame the retriever, when to blame the LLM prompt, and most importantly, when your system is truly ready for users.

Suggested Reading

This post is licensed under CC BY 4.0 by the author.