Skip to main content

Runtime hallucination detection middleware for RAG applications

Project description

raguard

Runtime hallucination detection middleware for RAG applications.

raguard intercepts LLM responses and flags claims not supported by your retrieved documents — before they reach the user.

Install

pip install raguard
python -m spacy download en_core_web_sm

Usage

from raguard import verify

result = verify(
    query="What is the Q3 2024 deadline?",
    retrieved_docs=["Q2 project was delivered on June 15. Next milestone is Q4 planning."],
    llm_response="The Q3 2024 deadline is September 30, 2024.",
)

print(result.action)   # "review"
print(result.warnings[0].text)       # "September 30, 2024"
print(result.warnings[0].suggestion) # '"September 30, 2024" not found in retrieved documents.'

result.action is either "proceed" (no high-severity issues) or "review" (at least one high-severity warning). Your application decides what to show the user.

What it detects

Type Severity Example
unsupported_date high Response says "September 30" — not in any doc
missing_entity high Response names "John Smith" — not in any doc
vague_reference medium Response says "the recent report" — phrase not in docs
input_error high Empty response, empty docs, or input exceeds size limit

VerifyResult shape

@dataclass
class VerifyResult:
    action: Literal["proceed", "review"]
    warnings: list[Warning]
    summary: Summary  # {high: int, medium: int, low: int}

@dataclass
class Warning:
    severity: Literal["high", "medium", "low"]
    type: Literal["unsupported_date", "missing_entity", "vague_reference", "input_error"]
    text: str        # the problematic span in the response
    suggestion: str  # human-readable explanation

verify() never raises — guard-layer violations return VerifyResult(action="review", warnings=[{type:"input_error", ...}]).

Multiple documents

Pass each chunk as a separate list item. Chunks are joined internally with a \n\n---\n\n separator. Order matters: boundary artifacts can occur if a number at the end of one chunk runs into text at the start of the next. Keep each chunk self-contained.

result = verify(
    query="Who approved the budget?",
    retrieved_docs=[
        "The budget was reviewed in Q1.",
        "Alice Johnson approved the final budget on March 10.",
    ],
    llm_response="Alice Johnson approved the budget.",
)
# result.action == "proceed"

Source attribution per chunk is a v2 feature. Passing list[Document] instead of list[str] will be a breaking API change at that point.

How it works

v1 is rule-based — no LLM calls, no API key required, p95 < 10ms:

  1. Guard layer — validates inputs, returns early on empty or oversized content
  2. Date check — extracts dates from the response with regex, looks for each in the docs
  3. Entity check — runs spaCy NER on the response, checks every PERSON/ORG/GPE/LOC/MONEY entity against the docs
  4. Vague reference check — matches a curated phrase list against the response and docs

Rules are derived from public hallucination datasets (RAGTruth, HaluEval, TruthfulQA). v2 will add an optional LLM grounding pass for semantic hallucinations the rule engine misses.

Performance

Measured on Python 3.12, Apple M-series, after warm-up:

Metric Value
p50 ~4.5ms
p95 ~5.2ms

First call loads the spaCy model (~200ms). Subsequent calls are fast.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

raguard_py-0.1.0.tar.gz (6.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

raguard_py-0.1.0-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

Details for the file raguard_py-0.1.0.tar.gz.

File metadata

  • Download URL: raguard_py-0.1.0.tar.gz
  • Upload date:
  • Size: 6.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for raguard_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 2d0df13b4edbf6f1eb4ba842999179446c139d9044e1c48246d18d50f95ebccf
MD5 4d3679a059a8da7e63328340e3019c75
BLAKE2b-256 64ac100e609b5d3653a528c880d8bdf34331237da609d9d05aa2a9a2ed668d10

See more details on using hashes here.

File details

Details for the file raguard_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: raguard_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.7

File hashes

Hashes for raguard_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 26bc6c52712e3b22886c0297b9a3f6c2462432f88d53a7b92c20d4a2c6aa2fa0
MD5 6cf0c131a8576a491994269b24a5b5a5
BLAKE2b-256 8014ed6551719113800f4fae1202f45fc3025cc7f3eda5bdca7017d8f2941327

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page