A small, multilingual groundedness checker. Given a source (retrieved documents, a transcript, a tool result) and an AI response or claim, it predicts whether the response is supported by the source. Use it to flag RAG answers, summaries and agent outputs that add, change or contradict facts.
Try it in the browser: Horizon-Labs/hallucination-guard demo.
Part of Agent I/O Guards (prompt injection, PII, groundedness). Source code: github.com/horizon-ai-labs/agent-io-guards.
from transformers import pipeline
clf = pipeline("text-classification", model="Horizon-Labs/hallucination-guard-small")
doc = "The Eiffel Tower is 330 metres tall and was completed in 1889 for the World's Fair."
clf({"text": doc, "text_pair": "The tower was finished in 1889."}) # SUPPORTED
clf({"text": doc, "text_pair": "The tower was finished in 1899."}) # UNSUPPORTED
Put the source first and the response or claim second. Labels: UNSUPPORTED (0) and SUPPORTED (1).
The score for SUPPORTED is the support probability.
For long sources, or to find which sentence is unsupported, split the response into sentences and score each one against the source. For a response-level score, take the minimum over sentences:
import re
def check(source, response, clf=clf):
sents = [s for s in re.split(r"(?<=[.!?。!?])\s+", response) if s.strip()]
res = clf([{"text": source, "text_pair": s} for s in sents], truncation=True, max_length=2048)
return [(s, r["label"], r["score"]) for s, r in zip(sents, res)]
Balanced accuracy at a 0.5 threshold. All models were run by us with the same script
(ground/evaluate_ground.py). MiniCheck used context chunking with max over chunks, as its own library does. HHEM
used contexts capped at 12,000 characters, because it ran out of memory on the longest documents. † marks sets that are
in-distribution for our models: we trained on RAGTruth's train split, and those rows use its test split.
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| AggreFact-CNN | 0.607 | 0.618 | 0.664 | 0.622 | 0.629 |
| AggreFact-XSum | 0.644 | 0.622 | 0.709 | 0.688 | 0.706 |
| ClaimVerify | 0.682 | 0.737 | 0.783 | 0.744 | 0.753 |
| ExpertQA | 0.553 | 0.593 | 0.606 | 0.597 | 0.568 |
| FactCheck-GPT | 0.657 | 0.674 | 0.754 | 0.728 | 0.729 |
| LFQA | 0.726 | 0.813 | 0.863 | 0.838 | 0.839 |
| RAGTruth † | 0.796 | 0.815 | 0.788 | 0.773 | 0.734 |
| Reveal | 0.798 | 0.834 | 0.896 | 0.871 | 0.865 |
| TofuEval-MediaS | 0.654 | 0.707 | 0.696 | 0.676 | 0.679 |
| TofuEval-MeetB | 0.677 | 0.736 | 0.765 | 0.724 | 0.721 |
| Wice | 0.719 | 0.732 | 0.717 | 0.664 | 0.751 |
| Mean | 0.683 | 0.716 | 0.749 | 0.721 | 0.725 |
The items were machine-translated with Qwen3.8-27B, keeping their labels. They are disjoint from the English HaluEval items above. Caveat: the translations come from the same model family we used to generate synthetic training data, which may favour our model somewhat.
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| English | 0.657 | 0.720 | 0.589 | 0.670 | 0.701 |
| German | 0.719 | 0.724 | 0.691 | 0.672 | 0.670 |
| Spanish | 0.691 | 0.714 | 0.650 | 0.675 | 0.675 |
| Chinese | 0.713 | 0.738 | 0.627 | 0.621 | 0.546 |
| Japanese | 0.729 | 0.751 | 0.626 | 0.669 | 0.546 |
| Arabic | 0.700 | 0.710 | 0.616 | 0.691 | 0.544 |
| Hindi | 0.730 | 0.740 | 0.595 | 0.670 | 0.564 |
| Mean of the 6 non-English languages | 0.714 | 0.729 | 0.634 | 0.666 | 0.591 |
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| HaluEval QA | 0.691 | 0.782 | 0.635 | 0.768 | 0.762 |
| HaluEval dialogue | 0.643 | 0.635 | 0.522 | 0.524 | 0.625 |
| HaluEval summarization | 0.548 | 0.559 | 0.648 | 0.623 | 0.526 |
| RAGTruth test, response level † | 0.798 | 0.829 | 0.604 | 0.626 | 0.750 |
UNSUPPORTED.UNSUPPORTED. For example, "opened before 2022" given a
source that says "opened in March 2021". The small model also misses some paraphrases ("weekdays" for "Monday to
Friday") that the base model handles.A small, multilingual groundedness checker. Given a source (retrieved documents, a transcript, a tool result) and an AI response or claim, it predicts whether the response is supported by the source. Use it to flag RAG answers, summaries and agent outputs that add, change or contradict facts.
Try it in the browser: Horizon-Labs/hallucination-guard demo.
Part of Agent I/O Guards (prompt injection, PII, groundedness). Source code: github.com/horizon-ai-labs/agent-io-guards.
from transformers import pipeline
clf = pipeline("text-classification", model="Horizon-Labs/hallucination-guard-small")
doc = "The Eiffel Tower is 330 metres tall and was completed in 1889 for the World's Fair."
clf({"text": doc, "text_pair": "The tower was finished in 1889."}) # SUPPORTED
clf({"text": doc, "text_pair": "The tower was finished in 1899."}) # UNSUPPORTED
Put the source first and the response or claim second. Labels: UNSUPPORTED (0) and SUPPORTED (1).
The score for SUPPORTED is the support probability.
For long sources, or to find which sentence is unsupported, split the response into sentences and score each one against the source. For a response-level score, take the minimum over sentences:
import re
def check(source, response, clf=clf):
sents = [s for s in re.split(r"(?<=[.!?。!?])\s+", response) if s.strip()]
res = clf([{"text": source, "text_pair": s} for s in sents], truncation=True, max_length=2048)
return [(s, r["label"], r["score"]) for s, r in zip(sents, res)]
Balanced accuracy at a 0.5 threshold. All models were run by us with the same script
(ground/evaluate_ground.py). MiniCheck used context chunking with max over chunks, as its own library does. HHEM
used contexts capped at 12,000 characters, because it ran out of memory on the longest documents. † marks sets that are
in-distribution for our models: we trained on RAGTruth's train split, and those rows use its test split.
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| AggreFact-CNN | 0.607 | 0.618 | 0.664 | 0.622 | 0.629 |
| AggreFact-XSum | 0.644 | 0.622 | 0.709 | 0.688 | 0.706 |
| ClaimVerify | 0.682 | 0.737 | 0.783 | 0.744 | 0.753 |
| ExpertQA | 0.553 | 0.593 | 0.606 | 0.597 | 0.568 |
| FactCheck-GPT | 0.657 | 0.674 | 0.754 | 0.728 | 0.729 |
| LFQA | 0.726 | 0.813 | 0.863 | 0.838 | 0.839 |
| RAGTruth † | 0.796 | 0.815 | 0.788 | 0.773 | 0.734 |
| Reveal | 0.798 | 0.834 | 0.896 | 0.871 | 0.865 |
| TofuEval-MediaS | 0.654 | 0.707 | 0.696 | 0.676 | 0.679 |
| TofuEval-MeetB | 0.677 | 0.736 | 0.765 | 0.724 | 0.721 |
| Wice | 0.719 | 0.732 | 0.717 | 0.664 | 0.751 |
| Mean | 0.683 | 0.716 | 0.749 | 0.721 | 0.725 |
The items were machine-translated with Qwen3.8-27B, keeping their labels. They are disjoint from the English HaluEval items above. Caveat: the translations come from the same model family we used to generate synthetic training data, which may favour our model somewhat.
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| English | 0.657 | 0.720 | 0.589 | 0.670 | 0.701 |
| German | 0.719 | 0.724 | 0.691 | 0.672 | 0.670 |
| Spanish | 0.691 | 0.714 | 0.650 | 0.675 | 0.675 |
| Chinese | 0.713 | 0.738 | 0.627 | 0.621 | 0.546 |
| Japanese | 0.729 | 0.751 | 0.626 | 0.669 | 0.546 |
| Arabic | 0.700 | 0.710 | 0.616 | 0.691 | 0.544 |
| Hindi | 0.730 | 0.740 | 0.595 | 0.670 | 0.564 |
| Mean of the 6 non-English languages | 0.714 | 0.729 | 0.634 | 0.666 | 0.591 |
| this model | base (308M) | MiniCheck-RoBERTa-L | MiniCheck-DeBERTa-L | HHEM-2.1-open | |
|---|---|---|---|---|---|
| HaluEval QA | 0.691 | 0.782 | 0.635 | 0.768 | 0.762 |
| HaluEval dialogue | 0.643 | 0.635 | 0.522 | 0.524 | 0.625 |
| HaluEval summarization | 0.548 | 0.559 | 0.648 | 0.623 | 0.526 |
| RAGTruth test, response level † | 0.798 | 0.829 | 0.604 | 0.626 | 0.750 |
UNSUPPORTED.UNSUPPORTED. For example, "opened before 2022" given a
source that says "opened in March 2021". The small model also misses some paraphrases ("weekdays" for "Monday to
Friday") that the base model handles.