Skip to main content

rag-eval-harness

CI

RAGAS with a memory and a diff view.

What this proved: a weaker retriever on a 40-question Nimbus help-center set cut mean context recall from 0.880 to 0.740. rag-eval regress --threshold 0.05 exited 1. Full write-up: Nimbus case study. 90-second recording: ./scripts/demo.sh.

Chunking the same corpus doubled lexical precision and failed the recall gate. Production stayed on whole articles. Chunking case study. ./scripts/demo-chunking.sh.

Upload a golden RAG dataset, run a pipeline (precomputed traces or HTTP), score with RAGAS, lexical overlap, or a keyless stub evaluator, persist runs, and fail CI when mean metrics drop versus a tagged baseline.

This is not a RAG framework. There is no ingestion or retrieval stack. Evaluation orchestration is the product.

10-minute path

Requires Python 3.11+ (uv recommended) and, for the UI, Node 20+.

git clone https://github.com/JohnCarl-30/rag-eval-harness.git && cd rag-eval-harness
uv sync
./scripts/demo.sh

You should see context_recall FAIL (0.880 → 0.740) and the script exit 0. That red rag-eval regress is the product. No API key. Then score dummy traces if you want a green run:

uv run rag-eval eval examples/dummy-rag/traces.jsonl --evaluator stub -o /tmp/rag-eval-head.json

Optional. Call a live HTTP SUT (the canned FAQ server):

python3 examples/dummy-rag/server.py --port 8080 &
uv run rag-eval eval examples/dummy-rag/golden.csv \
  --sut-url http://127.0.0.1:8080/query \
  --evaluator stub

UI (dev):

uv run rag-eval serve          # API on 127.0.0.1:8000, open on loopback (no API key)
cd web && npm install && npm run dev   # Vite on :5173, proxies /api

Open http://127.0.0.1:5173, upload examples/dummy-rag/traces.jsonl or golden.csv, create a run, tag a baseline, open Diff.

Docker:

cp .env.example .env          # set RAG_EVAL_API_KEY (required: the API binds 0.0.0.0)
docker compose up --build
# UI+API: http://127.0.0.1:8000   dummy RAG: http://127.0.0.1:8080/query

Install

pip install git+https://github.com/JohnCarl-30/rag-eval-harness.git
pip install 'rag-eval-harness[ragas]'   # after a PyPI release, or: pip install '.[ragas]' from a clone
rag-eval eval traces.jsonl --evaluator stub
rag-eval eval golden.csv --sut-url https://your-rag.example/query --sut-token "$TOKEN"
rag-eval baseline <run-id>
rag-eval regress --baseline <run-id-or.json> --head <run-id-or.json> --threshold 0.05
rag-eval diff --baseline <run-id-or.json> --head <run-id-or.json>
rag-eval investigate --baseline <run-id-or.json> --head <run-id-or.json>   # needs [agent]
rag-eval investigate ... --mode supervisor --trace trace.json
rag-eval serve

regress exits 1 if any mean drops by more than --threshold (default 0.05), or if head has more errored rows than baseline (means skip errored rows, so a timing-out SUT would otherwise pass). diff prints the same means plus the worst per-row drops (rows paired by question) and always exits 0 on a successful compare.

investigate runs the regress gate, then a LangGraph fan-out of Pydantic AI agents explains a failure: one diagnosis per failing stage (retrieval, generation), then a summary. --mode supervisor swaps the fixed graph for one agent that picks its own tools. --trace writes every agent run as JSON; --otel sends spans via Logfire. Same exit codes as regress. Install with pip install 'rag-eval-harness[agent]'. See docs/agent.md.

Contracts

Piece Behavior
Columns question required. Optional ground_truth. Traces also need answer and retrieved_contexts (JSON list or | / newline delimited). Aliases: user_input, reference, response, contexts.
HTTP SUT POST {"question"} → {"answer","retrieved_contexts"}. Optional bearer. Per-row timeout; a failed row is an error, the run continues.
Metrics Always faithfulness + answer relevancy. Context precision + context recall when ground_truth is present.
Evaluators stub (stable hashes, CI smoke), lexical (token overlap vs context, use this for real gates), ragas (OPENAI_API_KEY, optional OPENAI_BASE_URL).
Store SQLite default (DATABASE_URL). Postgres via postgresql+psycopg://….
Jobs In-process. 100-row cap. No Redis.
Auth Open on loopback. RAG_EVAL_API_KEY required when binding a non-loopback address. No cross-origin access unless RAG_EVAL_CORS_ORIGINS lists origins (comma-separated).
Regression Tag a run as baseline. Gate on mean delta. Per-row diffs are UI-only.

Docs: adapters · metrics · CI · investigator · storage · Nimbus case study · Chunking case study · Cost and p95 · Lexical vs judge

GitHub Action

stub is keyless CI smoke. Hashes look healthy on junk contexts. Use lexical for a real gate.

- uses: JohnCarl-30/rag-eval-harness@v0.2.0
  with:
    traces: tests/golden/traces.jsonl
    evaluator: lexical
    baseline: tests/golden/baseline.json
    threshold: "0.05"

Public consumer: Relaydesk fails PRs when Nimbus recall drops. See docs/ci.md.

Development

uv sync --extra agent   # without the extra, tests/test_agent.py is skipped
uv run pytest
uv run ruff check src tests
cd web && npm install && npm run build
docker compose up --build   # then ./scripts/smoke.sh

License

MIT. See CHANGELOG and CONTRIBUTING.

Metadata

Release files for rag-eval-harness 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rag-eval-harness 0.2.0
File Size Uploaded Provenance Actions
rag_eval_harness-0.2.0.tar.gz 32.0 kB With provenance Details for rag_eval_harness-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for rag-eval-harness 0.2.0
File Interpreter ABI Platform Actions
rag_eval_harness-0.2.0-py3-none-any.whl Python 3 none any Details for rag_eval_harness-0.2.0-py3-none-any.whl

Total release size: 77.4 kB

Release files / rag_eval_harness-0.2.0.tar.gz

Download URL rag_eval_harness-0.2.0.tar.gz
Size 32.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c4a3a8f554257bfc2b10d38fab59f0d5cb60f340ce6f7a069de8975b64325d87
BLAKE2b-256 checksum
How to use checksums
cf96324604bac0b42cf9f089ee687082a75911a4854853b6d2c65f82e0d37f50
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 29, 2026.

Transparency log

Release files / rag_eval_harness-0.2.0-py3-none-any.whl

Download URL rag_eval_harness-0.2.0-py3-none-any.whl
Size 45.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
816a8278a2fed0fec9abab4524db22da1338b6b5f396c0c7dac976cb7b37b828
BLAKE2b-256 checksum
How to use checksums
d8706014a682305067c20b17f7179f3b215d8445a3cb1ae0885262d60c93235c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.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 Sep 29, 2026.

Transparency log

Security for rag-eval-harness 0.2.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for rag_eval_harness-0.2.0.tar.gz

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 Sep 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page