RagWarden
An inline hallucination gate for production RAG pipelines.
RagWarden doesn't compete with RAGAS or UQLM — it's the runtime enforcement layer that uses signals like theirs (and its own fast detectors) to make a bounded-latency, explainable decision inline in production, with a policy engine enterprises can tune to their own risk tolerance.
An answer generated by any RAG pipeline is broken into atomic, independently-checkable claims. Each claim runs through a cascade of checks ordered cheapest-first:
- Tier 0 — retrieval heuristics (deterministic, near-zero cost, always on)
- Tier 1 — claim-vs-evidence entailment (fast encoder models: NLI, HHEM, LettuceDetect, MiniCheck)
- Tier 2 — uncertainty quantification (consistency sampling; token log-probs if available)
- Tier 3 — LLM-as-judge (structured chain-of-thought, budget-capped, only the ambiguous remainder)
Per-claim verdicts combine into a composite reliability score. A configurable policy engine
turns that score into an action — ALLOW, REDACT_CLAIMS, RETRY, ABSTAIN, or ESCALATE — and
every decision comes with a full explanation trail.
gate() does not fail your request. Every external dependency — a Tier-1 detector, your
generate_fn, your judge_fn — is fault-isolated and time-boxed; an unexpected failure anywhere in
the cascade degrades to a safe ABSTAIN instead of an unhandled exception. See
Running in production.
Status
v0.3.0 — all 13 build phases complete (contracts → cascade → policy → actions → adapters →
observability → docs → release pipeline → hardening), plus a production-hardening pass (fault
isolation, timeouts, an async API, startup warmup). Benchmark numbers are an honest baseline, not
yet competitive. On the path to a v1.0 that locks ragwarden.contracts under semver.
| Phase | Scope | State |
|---|---|---|
| 0 | Contracts + repo skeleton | done |
| 1 | Tier 0 heuristics + policy engine + gate() |
done |
| 2 | Tier 1 NLI detector + real severity-weighted scoring | done |
| 3 | Benchmark harness (RAGTruth) + calibration | done |
| 4 | HHEM / LettuceDetect / MiniCheck detectors + ensembling | done |
| 5 | Tier 2 uncertainty quantification (consistency sampling) | done |
| 6 | Tier 3 LLM-as-judge + full budget-capped cascade | done |
| 7 | Actions (redact/retry/abstain/escalate) + action_payload |
done |
| 8 | Retrieval adapters (OpenSearch, LangChain, Chroma, Docling, LlamaIndex) | done |
| 9 | Observability (OTel spans + versioned JSON logs) | done |
| 10 | MkDocs documentation site | done |
| 11 | Packaging, security, PyPI release readiness (Trusted Publishing, SBOM, pip-audit) | done |
| 12 | Hardening — frozen contracts, decisions documented, coverage audit, semver policy | done |
Current baseline (honest, not competitive yet)
ragwarden benchmark --dataset ragtruth --detector nli on 150 shuffled RAGTruth test rows
(DeBERTa-v3-base NLI, default policy, Tiers 0–1 only):
| Precision | Recall | F1 | |
|---|---|---|---|
| Response-level (overall) | 0.42 | 0.98 | 0.59 |
| Data2txt | 0.73 | 1.00 | 0.85 |
| Summary | 0.28 | 0.93 | 0.43 |
| QA | 0.22 | 1.00 | 0.36 |
The gate currently over-flags (very high recall, low precision) — the expected over-abstention
baseline before Tier 2/3, calibration, and better claim decomposition land. Full run outputs live in
benchmarks/results/.
Install
pip install ragwarden # core: light, no ML dependencies
pip install 'ragwarden[nli]' # + DeBERTa-v3 NLI Tier-1 detector
pip install 'ragwarden[opensearch]' # + OpenSearch adapter
pip install 'ragwarden[all]' # everything (OSI-licensed extras)
The core install pulls only a YAML parser and a pure-Python sentence splitter — no torch,
transformers, or numpy for Tier-0-only usage.
Quickstart
from ragwarden import gate, Policy
from ragwarden.models import Chunk, Context, Answer
context = Context(
query="When was the Eiffel Tower completed?",
chunks=[Chunk(text="The Eiffel Tower was completed in 1889.", score=0.91, source_id="doc-1")],
retrieval_method="hybrid",
)
answer = Answer(text="The Eiffel Tower was completed in 1889.")
result = gate(context, answer, policy=Policy.default())
print(result.action) # GateAction.ALLOW
print(result.reliability_score) # composite 0.0-1.0
print(result.explanation) # human-readable decision trail
How it relates to existing tools
RagWarden is complementary, not competitive — it is the runtime enforcement layer that turns signals (its own, or others') into a bounded-latency, explainable inline decision.
| Tool | What it is | Relationship |
|---|---|---|
| RAGAS, DeepEval | Offline LLM-judge evaluators (faithfulness / groundedness metrics) for CI and batch analysis. | Different job. Their judge-call cost profile is unusable per-request; RagWarden can call a judge like theirs as its Tier 3, on the small ambiguous remainder only. |
| UQLM | Uncertainty-quantification toolkit for LLM outputs. | A signal source. RagWarden's Tier 2 is the same family of idea (consistency sampling); UQLM's methods can feed a custom detector. |
| Vectara HHEM, LettuceDetect, MiniCheck, DeBERTa-v3 NLI | Fast encoder grounding checkers — shipped as raw scorers. | These are RagWarden's Tier-1 building blocks. RagWarden adds decomposition, a cost-tiered cascade, and a decision policy around them. |
| Guardrails AI, NeMo Guardrails | Inline validator / rail frameworks with on-fail actions. | Closest OSS prior art for the policy engine. RagWarden is narrower and deeper: claim-level grounding verification with a tuned cascade, not a general rail system. |
| AWS Bedrock Guardrails, Azure AI Content Safety, Google Vertex check-grounding | Cloud inline grounding gates. | Validate the demand. All closed, vendor-locked, cloud-only. RagWarden is the open, pipeline-agnostic equivalent. |
Honest limitations
- A gate cannot fix bad retrieval. If the wrong evidence was retrieved, no downstream check recovers the right answer — this bounds the whole system's ceiling.
- Every detector has its own error rate. The composite reliability score is a calibrated confidence estimate, not ground truth.
- Over-aggressive gating trades hallucination risk for over-abstention. Calibration against your
own traffic (
ragwarden calibrate) is the actual product experience, not optional polish. - Latency / cost budgets are real constraints. The tiered design exists because "run an LLM judge on everything" is correct but unusable at production scale.
- v0.1 claim decomposition is sentence splitting — a known simplification vs. atomic-claim extraction; it bounds achievable span-level precision. See design decisions.
License
Apache-2.0 (explicit patent grant — matches Transformers, TensorFlow, NeMo, RAGAS). See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ragwarden-0.3.0.tar.gz.
File metadata
- Download URL: ragwarden-0.3.0.tar.gz
- Upload date:
- Size: 82.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7d1d2341869097c9b7f8b0fc3b56519251d212a27db6207c6e9b69af4944c96
|
|
| MD5 |
4f4f89ed70dcfdb101f6923f2fe96ecd
|
|
| BLAKE2b-256 |
123fd4d155e2b08496b86a9cabf75b80779f218098730b5c5c5eeccebff621ab
|
File details
Details for the file ragwarden-0.3.0-py3-none-any.whl.
File metadata
- Download URL: ragwarden-0.3.0-py3-none-any.whl
- Upload date:
- Size: 73.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.10.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b3407422633119c4f82660377b5f374b6d6d95270146baddc4430a7ade5f730
|
|
| MD5 |
ed8bfd6538b98efd0641f734d97117e2
|
|
| BLAKE2b-256 |
8cdbae3b2eb97fb517aa8a3c8c232d21b457411767505263f3e26b5eacf902a7
|