Ask most AI products how they handle hallucination and you'll get a variant of "we tell the
model not to." That's not wrong — it's just insufficient, and it puts enforcement in the
hands of the exact system doing the generating.
Synthadoc treats hallucination as an architecture problem, not a wording problem. The
distinction matters: a wording fix is hoping the model behaves; an architecture fix is
verifying that it did.
Why Prompt Instructions Aren't Enough
The industry default is a line in a system prompt: don't make things up, answer only from
the provided context, never fabricate. These instructions do nudge model behavior in the
right direction, and we use them too. But they leave enforcement entirely up to the model
doing the generating. A language model producing text token-by-token has no reliable
internal mechanism to audit its own faithfulness to a source.
There's a subtle issue as well. Instructions of the form "don't do X" are easier for a
model to rationalize around than instructions of the form "do only Y." Synthadoc's synthesis
constraint is a positive formulation:
Answer using ONLY these wiki pages. Cite with [[PageTitle]].
That's linguistically harder to rationalize around. But it's still just text in a prompt.
The real work happens at the structural level.
Three Layers, Not One Instruction
Our approach treats hallucination as a systems problem. There are three distinct layers,
each handling a different failure mode:
- Scope filtering at ingest time : Wiki content can only be entered if it is on-domain. It is difficult to produce hallucinations about off-domain topics from content that has never been consumed.
- Retrieval-augmented grounding at query time : Answers are generated from retrieved
wiki pages, not from the model's weights alone. The synthesis prompt shows only the
relevant pages and instructs the model to answer from them exclusively.
- Citation faithfulness audit after the fact : Every claim gets a citation marker
linking it to specific source lines. A separate LLM pass then audits whether each claim
is actually supported by those lines. This is the layer that catches what the other two
miss.
None of these is a complete solution alone. Together they create a system where hallucinations
are detectable and traceable, not just discouraged.
Layer 1: purpose.md as a Content Gate
Every wiki has a wiki/purpose.md file that describes its domain — what it's for, what
topics belong, and what doesn't. When a new source document arrives for ingest, the ingest
agent reads this purpose block before making a decision:
Wiki scope (from purpose.md):
{content of purpose.md}
action="skip" means the source is completely OUTSIDE the wiki's domain
(e.g. spam, medical receipts, unrelated e-commerce).
…
The LLM then decides: skip, create, update, or flag. Out-of-scope content never
becomes a wiki page, which means it can never become the basis for an answer.
Lifecycle isolation for contradicted pages
The scope gate isn't the only place the knowledge base shrinks. When a new source
disagrees with an existing page, the ingest agent issues a flag action and the page
moves to a contradicted lifecycle state, and automatically excluded from retrieval until
the conflict is resolved. This matters because a contradicted page is, by definition,
one where the system can't be confident about what's true. Serving answers from it
would be hallucination with extra steps.
The contradiction resolver in Synthadoc is an interactive agentic workflow: it surfaces
the conflict, shows a diff of the proposed edit, and requires explicit human approval
before writing any change. The approve-before-write gate is unconditional, and the agent
cannot modify a page without a human seeing the diff first.
Layer 2: RAG Grounding at Query Time
When a user asks a question, Synthadoc retrieves the most relevant wiki pages using
hybrid search (BM25 full-text matching with optional vector re-ranking), then builds a
synthesis prompt that includes those pages verbatim:
Answer using ONLY these wiki pages. Cite with [[PageTitle]].
Extract and include all specific facts from the pages — dates, years,
numbers, and names — even when they appear briefly or in passing.
Do not claim a fact is absent unless it is genuinely missing from
every page below.
Question: {question}
Pages:
{retrieved_wiki_pages}
The purpose.md content is prepended to the pages block as ### Wiki Scope, giving the
model a domain reminder during synthesis as well as at ingest time.
Why this isn't enough on its own: A model can still hallucinate within retrieved
content — misattributing which page said what, inventing a specific number close to but
not the same as a number in the source, or synthesizing a conclusion that no single page
actually states. Grounding reduces the search space; it doesn't eliminate drift.
When retrieval confidence falls below threshold, Synthadoc detects the gap and handles
it transparently rather than hallucinating silently. The immediate response answers from
the model's general knowledge while explicitly noting that the wiki lacks dedicated
coverage — the user always knows they're receiving an unverified answer. At the same time,
Synthadoc generates enrichment suggestions: search queries and known URLs scoped to the
domain in purpose.md. Retrieved pages flow through the normal ingest pipeline and stay
in draft state — out of the search corpus — until a human promotes them to active.
Only then do future queries on that topic get answered from verified wiki content rather
than general knowledge.
Layer 3: Citation Faithfulness Audit
This is the layer that makes the system verifiable rather than just hopeful. The citation
faithfulness audit examines each claim in a wiki answer alongside the source lines it cites,
then classifies the relationship:
| Verdict | Meaning |
supported | The claim is directly and accurately supported by the cited source lines. |
drift | The claim is related to the source but overstated, simplified, or shifted in meaning. |
hallucination | The source lines do not support the claim, or directly contradict it. |
Each audit is done by a separate LLM call with the claim text and raw source lines
side-by-side. The auditor never sees the original question — only the claim and the lines.
Why a separate LLM pass? The same model that wrote the answer is likely to defend
it when asked "is this correct?" Separation of duties matters: the auditor has no stake
in validating the original generation.
What we actually see in practice
In our experience, drift is the most common finding — not outright hallucination.
The model summarizes accurately but slightly overstates a confidence level, rounds a
number, or drops a qualifier ("as of 2023" becomes "currently"). These are small errors
individually but compound across a knowledge base that gets queried repeatedly.
True hallucination , where the cited source lines don't support the claim at all ,
is less common in well-grounded RAG, but it happens: specific dates that don't appear
in the source, an attribution switched between two people mentioned in the same paragraph,
a causal relationship inferred from correlation. Those are the findings that matter most,
and the audit surfaces them per-citation so a human knows exactly which source line to
check.
The audit result is cached per-page with staleness detection. If the page is re-ingested
from updated source material, the cache is invalidated and the next audit reflects the new
content. This surfaces in the web UI as an automatically-loaded faithfulness tab alongside
each wiki page.
What This Doesn't Solve
Honesty matters here too. Two failure modes remain outside what the three layers fully
address:
Synthesis across pages. A conclusion drawn by combining facts from multiple pages may
be accurate at each individual step and still misleading in combination. The citation
faithfulness audit operates per-citation, not across synthesized conclusions, so a
cross-page inference that no single page actually states falls outside its scope.
The practical path: when a synthesized answer matters, the cited pages are explicit and
can be verified directly. If the conclusion is important enough to keep, saving it as a
wiki page subjects it to future source ingestion — a new source that disputes it will
trigger the flag action for human review.
Source quality. When a new source disagrees with an existing page, the flag action
fires and the contradiction is surfaced. The harder case is when all available sources
agree on the same wrong answer: no flag fires, no contradiction is detected, and Synthadoc
answers confidently from incorrect material. Two mechanisms make this less likely: the
adversarial review in lint, which uses the model's own knowledge to flag claims that
clearly contradict well-established facts; and re-ingesting from updated authoritative
sources, which will trigger the flag action against any outdated pages. Neither is a
complete solution, but together they make uniform source error less likely to go
unnoticed indefinitely.
Our View
The hallucination debate tends to frame the problem as a model capability question: will
the next model be more faithful than the last? We think that's the wrong frame for a
production knowledge system. Even a perfectly faithful model can only be as accurate as
the content it's grounded in, and even a slightly drifting model can be made accountable
if the output is systematically audited.
Our architectural bet is that the answer to hallucination isn't a better instruction,
it's a feedback loop. Domain scoping controls what enters. Lifecycle states control what
gets queried. Retrieval grounds generation. Citation audit classifies the output. The
contradiction resolver closes the loop: when a conflict is found, a human resolves it, the
page is corrected, and the knowledge base improves. Errors become visible rather than
accumulating silently.
That's a more defensible position than any number of ALL CAPS instructions.
Try It
Synthadoc is open-source. The citation faithfulness audit, contradiction resolver, and
lifecycle system described here are all in the main branch.
→ github.com/axoviq-ai/synthadoc