Proofrag
Evaluate a RAG or LLM app. Use when the user wants to test, score, benchmark, or catch regressions in a retrieval/RAG/LLM system, generate an evaluation/golden dataset from their docs, measure hallucination/groundedness/correctness, or gate CI on answer quality. Generates a golden set from the user's own corpus, runs LLM-as-judge plus retrieval metrics, and produces a shareable HTML scorecard.From its SKILL.md
npx -y skills add unshDee/proofrag --skill proofragAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.4 KB, as published. Nobody here has run it
proofrag
Turn "did my change make the RAG better or worse?" into one reproducible command. You (the agent) wire the user's app to the kit; the kit does dataset generation, judging, and reporting.
When to use
- User changed a prompt, model, chunker, embedder, or retriever and wants to know if quality moved.
- User has docs/a knowledge base but no evaluation set.
- User wants a hallucination/groundedness number, or a CI gate on answer quality.
Install the engine
This skill drives the proofrag CLI. Make sure it's on PATH (install once), or run
it ad-hoc with uvx:
uv tool install "proofrag[anthropic]" # or: pipx install "proofrag[anthropic]"
# no install needed: uvx "proofrag[anthropic]" demo
Use [openai] instead of [anthropic] for an OpenAI-compatible/local backend.
Credentials: ANTHROPIC_API_KEY (default, cheap Haiku judge) or OPENAI_API_KEY
(OPENAI_BASE_URL for local/Ollama). No key? proofrag demo renders a sample scorecard.
If both keys exist, auto-detection chooses Anthropic; use PROOFRAG_PROVIDER=openai
to override. Proofrag does not auto-load .env, so source it first.
The loop
-
Inspect and generate from the user's corpus.
proofrag corpus ./docsUse
--include,--exclude, and--no-gitignorewhen the docs tree is noisy. PDF loading needs theproofrag[pdf]extra; HTML is supported by default.Then generate:
proofrag generate --corpus ./docs --out goldenset.jsonl --n 20Produces JSONL:
{id, question, gold_answer, gold_contexts[], difficulty, sources[]}with tierssingle_doc/multi_doc/unanswerable, pluscontext_metadatafor each gold context. Commit this file — it is versioned. -
Validate the golden set before committing it.
proofrag validate --goldenset goldenset.jsonl --corpus ./docs --out validation.jsonThis checks the JSONL contract, duplicate ids/questions, answerable cases without gold contexts, unanswerable cases that still cite context, source coverage, and a stable fingerprint. It exits non-zero on hard errors; add
--strictto fail on warnings too.Manually search the full corpus for every
unanswerablecandidate, and verify both distinct sources are necessary for everymulti_doccase. Schema validation cannot prove either semantic property. -
Run the user's RAG over every question to produce predictions. Prefer
proofrag runwhen the app exposes a local HTTP endpoint or Python callable:proofrag run --goldenset goldenset.jsonl \ --endpoint http://localhost:8000/ask \ --out predictions.jsonl proofrag run --goldenset goldenset.jsonl \ --callable myapp.rag:answer \ --out predictions.jsonlHTTP mode POSTs
{"id": "...", "question": "..."}. Callable mode callsanswer(question)by default; add--call-style recordto pass the full golden record. The adapter may return an answer string,(answer, contexts), or:{"id": "q000", "answer": "<system answer>", "retrieved_contexts": ["<chunk>", "..."]}retrieved_contextsare the chunks their retriever returned (used for retrieval metrics). If neither adapter fits, write a small driver script that emits the same JSONL shape. If you can't find their entrypoint, ask the user where their "ask a question" function lives. -
Judge.
proofrag evaluate --goldenset goldenset.jsonl --predictions predictions.jsonl --out results.jsonScores groundedness, correctness, completeness, citation_quality (LLM-as-judge, pinned + fingerprinted) and rank-aware retrieval metrics — Recall@k, Precision@k, NDCG@k, MRR (
--ksets the cutoff; Jaccard by default,--exactfor original chunks, or--semanticfor embeddings). Evaluation fails if prediction IDs do not exactly cover the golden set or any judge call fails. To score generation with DeepEval instead, add--backend deepeval(needs theproofrag[deepeval]extra; metrics become faithfulness / answer_relevancy / correctness). To score with Ragas instead, add--backend ragas(needs theproofrag[ragas]extra; metrics become faithfulness / factual_correctness, plus answer_relevancy when OpenAI-compatible embeddings are configured). Retrieval metrics and everything downstream stay the same. DeepEval metric reasons, when available, are preserved in the scorecard's weakest-case notes. -
Report.
proofrag report --results results.json --out scorecard.html proofrag summary --results results.json # optional markdown for CI/logsSelf-contained HTML — open it, attach it to a PR, screenshot it. Surfaces overall score, per-metric bars, and the weakest cases with the judge's rationale. The markdown summary gives CI systems a compact score table without opening the HTML.
CI gate
Absolute floor:
proofrag evaluate --goldenset goldenset.jsonl --predictions predictions.jsonl \
--out results.json --fail-under 0.7 # exits 1 if overall generation score < 0.7
Regression vs a committed baseline (a known-good results.json):
proofrag diff --baseline baseline.json --candidate results.json --tolerance 0.02
To wire this into GitHub Actions, use the bundled composite action
uses: unshDee/[email protected] (see the repo README / examples/ci/). Tell the user to
commit a baseline results.json from a good run, then diff every PR against it. The
action writes a GitHub Actions job summary and uploads the scorecard/results artifact
by default, including when a gate fails.
Diff rejects mismatched datasets, backends, cutoffs, matchers, and metric schemas.
A/B comparison (blind)
To compare two variants (vector vs GraphRAG, two prompts, two models), run each over the same golden set to produce two prediction files, then:
proofrag compare --goldenset goldenset.jsonl \
--a vector_preds.jsonl --a-name vector \
--b graphrag_preds.jsonl --b-name graphrag \
--out comparison.json --html comparison.html
The same pinned judge picks the better answer per question, blind — answers are
shown in randomized order so it never knows which variant is which. Output: win
counts + per-variant retrieval metrics + an HTML report. Render later with
proofrag report --results comparison.json (it auto-detects the comparison format).
Credibility rules (state these to the user)
- Judge model is pinned; mixing judges makes scores non-comparable.
- LLM-as-judge has variance — treat single-point differences cautiously; the retrieval metrics are deterministic and separate retriever from generator faults.
- A low score on
unanswerablecases means the system hallucinates instead of refusing. citation_qualitymeans attribution to retrieved context, not literal citation syntax or URL verification.
Reference
- Engine + source: https://github.com/unshDee/proofrag (
src/proofrag/). - Runnable end-to-end example:
examples/docs-rag/in that repo (corpus + naive RAG driver). proofrag --helplists all commands and flags.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.
Gives 0 of the 12 instructions most evals benchmarks skills give
Counted across 499 of the 513 authors here whose files we hold, read 2026-09-06
- Spawn with-skill and baseline runs in the same turnin 31 of 499, across 24 files
- Keep SKILL.md under 500 linesin 31 of 499, across 24 files
- Draft assertions while test runs are in progressin 31 of 499, across 24 files
- Compare against the baseline after changesin 31 of 499, across 13 files
- Define evals before codingin 26 of 499, across 17 files
- Run evals frequently during developmentin 25 of 499, across 16 files
- Keep evals fastin 24 of 499, across 15 files
- Version evals with codein 24 of 499, across 15 files
- Generate the eval viewer before evaluating outputs yourselfin 24 of 499, across 17 files
- Generate an eval report after runsin 24 of 499, across 15 files
- Track pass@k metrics over timein 22 of 499, across 14 files
- Save a baseline before making changesin 21 of 499, across 9 files
Said here and by no other author read
- generate a golden dataset from the user's corpus
- validate the golden set before committing it
- manually verify unanswerable and multi_doc cases
- run the user's RAG over every question
- ask the user where their entrypoint lives
- judge predictions with the pinned judge
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once.