rag-eval-gate
A CI/CD-integrated evaluation pipeline that acts as a quality gate for RAG (Retrieval-Augmented Generation) systems. Block bad PRs before they ship hallucinating AI to production.
The Problem
You ship a RAG chatbot. A teammate changes the prompt template. The retriever now returns irrelevant context. The LLM starts hallucinating. Nobody catches it until users complain.
rag-eval-gate prevents this by running automated evaluations on every Pull Request — just like unit tests, but for AI output quality.
How It Works
When a pull request is opened, the GitHub Action:
- Loads a curated test dataset (from Hugging Face or a local
.jsonlfile) - Runs each question through your RAG pipeline
- Evaluates outputs using Ragas metrics with a Groq LLM judge
- Computes a custom Token Efficiency metric (quality per output token)
- Checks scores against configurable thresholds in
eval_config.yaml - Pushes metrics to Grafana Cloud for trend tracking
- Posts a formatted score table as a PR comment
- Fails the CI job if any metric drops below threshold — blocking the merge
Evaluation Metrics
| Metric | What It Measures | Default Threshold |
|---|---|---|
| Faithfulness | Are answers grounded in retrieved context? | ≥ 0.75 |
| Context Relevance | Is the retrieved context relevant to the question? | ≥ 0.70 |
| Answer Correctness | How accurate is the answer vs ground truth? | ≥ 0.65 |
| Token Efficiency | Quality per output token (correctness / log(1 + tokens)) |
≥ 0.50 |
The default LLM Judge is groq/llama-3.3-70b-versatile via LiteLLM — fast, free, and swappable.
Quick Start
# Install from PyPI
pip install rag-eval-gate
# Set your Groq API key (free at console.groq.com)
export GROQ_API_KEY="your_api_key"
# Run evaluation
rag-eval run
# View formatted report
rag-eval report
Try the Hallucination Demo 🚨
See rag-eval-gate catch a hallucinating AI in real-time. This demo intentionally forces the mock RAG pipeline to hallucinate an answer about "RLHF", proving that the quality gate works:
python examples/demo.py
GitHub Actions Setup
Add this workflow to .github/workflows/rag_eval.yml:
name: RAG Evaluation
on: [pull_request]
jobs:
eval:
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.11" }
- run: pip install rag-eval-gate
- run: rag-eval run --config eval_config.yaml
env:
GROQ_API_KEY: ${{ secrets.GROQ_API_KEY }}
Set GROQ_API_KEY in your GitHub repository secrets (Settings → Secrets → Actions).
Configuration
Customize thresholds and model settings in eval_config.yaml:
thresholds:
faithfulness_min: 0.75
context_relevance_min: 0.70
answer_correctness_min: 0.65
token_efficiency_min: 0.50
model:
judge: "groq/llama-3.3-70b-versatile"
rag_generator: "groq/llama-3.3-70b-versatile"
embeddings: "sentence-transformers/all-MiniLM-L6-v2"
dataset:
hf_repo: "Manik24/rag-eval-golden"
Architecture
┌─────────────────────────────────────────────────────┐
│ GitHub Actions CI │
├─────────────────────────────────────────────────────┤
│ │
│ Test Dataset (HF Hub / local JSONL) │
│ │ │
│ ▼ │
│ RAG Pipeline (FAISS + Groq LLM via LiteLLM) │
│ │ │
│ ▼ │
│ Ragas Evaluation (Faithfulness, Relevance, etc.) │
│ │ │
│ ▼ │
│ Regression Gate (pass/fail vs thresholds) │
│ │ │
│ ┌────┴────┐ │
│ ▼ ▼ │
│ ✅ Pass ❌ Fail → Block PR merge │
│ │ │ │
│ ▼ ▼ │
│ PR Comment + Grafana Metrics Push │
│ │
└─────────────────────────────────────────────────────┘
Bring Your Own Pipeline
The library ships with a demo RAG pipeline, but you can plug in your own. Subclass BaseRAGPipeline, implement two methods, and point your config at it:
# my_pipeline.py
from rag_eval import BaseRAGPipeline, RAGResult
class MyPipeline(BaseRAGPipeline):
def init(self):
"""Called once before evaluation starts. Load your models here."""
self.db = load_my_vectorstore()
self.llm = load_my_llm()
def query(self, question: str) -> RAGResult:
"""Called for each question in the test dataset."""
docs = self.db.search(question, k=3)
answer = self.llm.generate(question, docs)
return RAGResult(
question=question,
answer=answer,
contexts=[d.text for d in docs],
input_tokens=..., # optional, for token efficiency metric
output_tokens=..., # optional, for token efficiency metric
)
Then set pipeline.class in your eval_config.yaml:
pipeline:
class: "my_pipeline.MyPipeline"
thresholds:
faithfulness_min: 0.75
context_relevance_min: 0.70
answer_correctness_min: 0.65
token_efficiency_min: 0.50
Run it:
export GROQ_API_KEY="..."
rag-eval run --config eval_config.yaml
The evaluator will import your class, call init() once, then call query() for each test question.
Tech Stack
- Evaluation: Ragas for LLM-as-judge metrics
- LLM Provider: Groq via LiteLLM (hot-swappable to OpenAI, Anthropic, etc.)
- Embeddings: sentence-transformers (local, no API calls)
- Vector Store: FAISS (CPU, local)
- Dataset: Hugging Face Datasets
- Observability: Grafana Cloud via Influx Line Protocol
- CLI: Click + Rich
Local Development
git clone https://github.com/ManikBodamwad/RAG-EVAL.git
cd RAG-EVAL
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
# Run local evaluation
rag-eval run
# View formatted report
rag-eval report
# Run unit tests
python -m pytest tests/
Test Dataset
The default test set is hosted at Manik24/rag-eval-golden on Hugging Face. To use your own dataset, create a JSONL file with the following schema:
{"question": "What is X?", "ground_truth": "X is ...", "reference_context": "The passage that answers this..."}
Then specify the local path or your own HF repo in eval_config.yaml.
License
MIT License.
Release files for rag-eval-gate 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rag_eval_gate-0.2.2.tar.gz | 24.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rag_eval_gate-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.7 kB
Release files / rag_eval_gate-0.2.2.tar.gz
| Download URL | rag_eval_gate-0.2.2.tar.gz |
|---|---|
| Size | 24.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3096feeff14e91aa018eef5281728475bdf031d63282b8eb51b261dead7926cc
|
|
BLAKE2b-256 checksum How to use checksums |
a2849d77f21ade44b11fd6cc03fa6b96d1ba3c2ea89fc0906af3234be63ac58f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency logRelease files / rag_eval_gate-0.2.2-py3-none-any.whl
| Download URL | rag_eval_gate-0.2.2-py3-none-any.whl |
|---|---|
| Size | 19.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5c546341f8bf691fee492896b0e0b0413cccb5d47fb0b6e67f0b33acfbc374c7
|
|
BLAKE2b-256 checksum How to use checksums |
67ead44c3e99c906d07cd10d74bccdf1ce03488c81adc084ea53ade96ed8748d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 27, 2026.
Transparency log