LLMs hallucinate confidently. They cite files that do not exist, reference line numbers in code that was never written, and stitch together plausible-sounding claims from nothing. Prompting does not fix this. The model does not know it is hallucinating. A new open-source tool called ora-grounding takes a different approach: it checks the model's output after the fact, using no LLM calls in the hot path, and catches fabricated specifics deterministically.
The Two Failure Modes That Matter
The tool targets two specific failure modes. The first is made-up specifics. A chat agent tells you it fixed a bug at services/auth.py:42, but that file does not exist. The second is overconfident synthesis. The model combines real elements from its context into claims that nothing in the context actually supports. Both failures are dangerous because the output sounds authoritative. The user trusts it, acts on it, and discovers the problem later.
Prompting alone cannot solve either problem. Adding "be accurate" or "do not hallucinate" to a system prompt does not give the model a way to verify its own claims. The model has no internal checker that compares its output against a source of truth. It generates text that looks right, and that is all it can do.
Sibling-model review sounds like a solution but has a structural flaw. If GPT-4 generates a response and GPT-4 reviews it, both models share the same training data and the same blind spots. A hallucination that looks plausible to one model looks plausible to the other. Cross-family review, where the reviewer comes from a different model family than the drafter, breaks this symmetry. Different training data means different failure modes.
How the Grounding Check Works
The grounding check is the fast layer. It uses regex and set membership to extract claims from the model's output and compare them against a canonical set of known entities. The canonical set comes from your retrieval context: the files, symbols, line numbers, and commands that your RAG pipeline actually returned.
The check is deterministic. It makes no LLM calls. It extracts file paths, symbol names, and command references from the reply using pattern matching, then tests each one against the canonical set. Claims that appear in the reply but not in the canonical set are flagged as fabricated. The process takes milliseconds.
The example from the tool's README illustrates the point. A production chat agent claimed a file existed that did not. The reply mentioned both payments_client.py and redis_lock.py. The canonical set contained only payments_client.py. The grounding check flagged redis_lock.py as fabricated instantly, with zero LLM calls. This is the kind of bug that would slip past a human reviewer in a long response, because the fabricated file name looks perfectly reasonable in context.
The Adversarial Review Layer
The adversarial review is the slower, opt-in layer. After the grounding check passes, a different-family reviewer LLM reads the draft response and the retrieval context. The reviewer's job is to find claims that the grounding check missed, specifically overconfident synthesis where the model combined real elements into something the context does not support.
The review has a hard deterministic guard against the reviewer itself hallucinating flags. This is the key design decision. Without it, you trade one hallucination problem for another: the reviewer makes up problems that do not exist, and now you have false positives instead of false negatives. The guard ensures that any flag the reviewer raises must be grounded in the retrieval context, just as the original claims must be.
The cross-family requirement is not optional. If the drafter and reviewer come from the same model family, they share failure modes. The review adds latency without adding value. Different families, like GPT and Claude, or Claude and Gemini, have different training data, different failure patterns, and different blind spots. A claim that looks plausible to one family may look suspicious to another.
Production Origins
The tool was extracted from AUREM, an AI-CTO assistant that reads GitHub repositories and ships code. This is a high-stakes application. If the assistant claims a file exists and it does not, the user might merge code that references a nonexistent module. If the assistant claims a function is defined somewhere and it is not, the user might ship a broken build.
The grounding check is designed for exactly this kind of structured output. Code references, file paths, function names, and configuration keys are all discrete, verifiable entities. They either exist in the codebase or they do not. The check does not try to evaluate the quality of the code or the reasoning of the model. It verifies that the specific claims in the output match the facts in the retrieval context.
The tool is zero-dependency and installs with pip. It requires Python 3.10 or later. The grounding check is a pair of functions: extract_claims and classify_claims. The adversarial review is a single function that takes a draft reply, the retrieval context, and an LLM client from a different family than the drafter. The output is structured, validated with Pydantic models, and ready to integrate into any pipeline.
What This Means for Production Agents
The practical lesson is that hallucination defense should be layered. Prompting is the first layer, and it is weak. Deterministic checks are the second layer, and they are fast and reliable for structured claims. Cross-family adversarial review is the third layer, and it catches the subtler failures that pattern matching misses.
The grounding check is cheap enough to run on every response. The adversarial review is expensive enough to run selectively, on high-stakes outputs or as a sampling check on a percentage of responses. Together, they give you two independent defenses against the failure modes that hurt users the most: fabricated specifics and overconfident synthesis.
The tool is MIT licensed and available on GitHub. It was built for a production system serving real users, and it was battle-tested against real regressions. For anyone building agents that interact with codebases, file systems, or any structured data, deterministic grounding checks are not optional. They are the minimum viable defense against a model that does not know when it is lying.