Better reading made the failure harder to see
There is a version of this argument that says hallucination is the
price of using generative models on documents, and that the previous
generation of tools was safer because it was dumber. That version is
wrong in a specific and useful way. Template-based extraction failed
constantly — it just failed loudly. A coordinate-anchored field on a
supplier invoice that shifted its layout returned an empty string or the
label instead of the value, and the pipeline stopped. Classical OCR on a
low-contrast scan returned 1O0.O0 and a parser rejected it.
The errors were visible because the systems had no capacity to produce
something convincing.
Vision-language models removed that capacity limit. They read a page the way a person skims it: they use layout, they use context, they infer what a truncated header probably says, and they fill gaps with what usually goes in gaps. That inference is exactly why they generalise across layouts without a template per supplier, and it is exactly why they will produce a due date for an invoice that has none. The capability and the failure are the same mechanism pointed at different inputs. You cannot prompt one away without losing the other, which is why the fix has to sit outside the model rather than inside the instruction.
The practical consequence is that error detection stopped being a property of the output and became a property of the system. A number is no longer suspicious because it looks wrong. It has to be suspicious because the system cannot show where it came from.
Five failures wearing one name
"Hallucination" is used for everything a document system gets wrong, which makes it useless as an engineering category — the controls that catch one of these do nothing for the others. Pulling them apart is the first step, because a team that has only built for fabrication will keep shipping the other four.
| Failure | What it looks like | The control that catches it |
|---|---|---|
| Fabrication | A value that appears nowhere on the page — an invented invoice number, a tax ID with a valid format and no source. | Source binding: the field must resolve to a location and a literal string on the page, verified after generation. |
| Misattribution | A real value in the wrong field — the ship-to postcode read as bill-to, the second table's subtotal read as the invoice total. | Geometry and cross-field validation: does the source region belong to the block this field is supposed to come from. |
| Normalization drift | Silent helpfulness — 03/04 becomes April 3, a comma decimal becomes a thousands separator, an entity name gets tidied into its parent company. | Keeping raw and normalized values as separate stored fields, with the transformation rule named and reversible. |
| Completion of absence | A required field that the document does not contain, filled with something plausible rather than left empty. | A schema that permits absence, and an abstention path that downstream systems actually accept. |
| Inherited error | The extraction is faithful and the page is wrong — a supplier's own arithmetic error, a stale address, a superseded revision. | Deterministic cross-checks against arithmetic, external references and prior documents; correctness is not the same as fidelity. |
Two things follow from the table. The first is that only one of the five is fabrication in the strict sense, and it is usually the rarest in production — misattribution and normalization drift are far more common and far less discussed, because they produce values that exist on the page and therefore survive any check that asks only "is this string here?" The second is that inherited error is not a model failure at all, and no amount of grounding will catch it. A system that verifies every field against the page will faithfully reproduce a total that the supplier computed wrong. That is a validation problem, not a hallucination problem, and conflating them is how teams end up believing that grounding alone is a sufficient answer.
The six layers
An anti-hallucination architecture is not a feature. It is a set of constraints applied at six points, each of which removes a class of invention that the layers above it cannot see. The order matters: grounding without a schema produces sourced nonsense, and abstention without thresholds produces a review queue that nobody staffed.
1. Source binding: every field carries its origin
The foundational rule is that an extracted value is not a value. It is a value plus the evidence for it: the page, the region on that page, the literal text that was read there, and the step that produced it. A field without those is a claim, and a claim that cannot be located is indistinguishable from an invention — including to the system itself, which is the point.
Binding has to be verified rather than requested. Asking a model to return bounding boxes alongside its answers is useful and insufficient, because the coordinates are generated by the same process that generated the value and can be wrong in the same direction. The check that earns its cost is mechanical: take the returned value, take the returned region, and confirm that the text actually present in that region supports it — exact match for identifiers and codes, normalized match for dates and amounts, fuzzy match with a stated distance for names and addresses. When the match fails, the value does not get corrected. It gets flagged as unsourced, which is a different and more honest state than low confidence.
This is also what makes a result reviewable at human speed. A reviewer who has to hunt for the value on a 40-page contract will approve on plausibility after the third document. A reviewer who is shown the value and the highlighted span it came from is checking, not guessing, and the difference shows up in error rates within a week.
2. A schema that permits absence
Most extraction schemas are written as a list of fields the business wants, which quietly encodes the assumption that every field exists on every document. Handed that schema, a model does the reasonable thing and produces all of them. The schema itself created the pressure to invent.
A schema built for this problem states four things per field: the type and format, whether the field may be absent and what absence looks like, the permitted value set where one exists, and the consequence tier — whether being wrong here costs a rounding error or costs a payment. Enumerations do more work than they get credit for: a currency field constrained to a tenant's actual currencies cannot drift, and a document type constrained to a known set forces an explicit "unclassified" rather than the nearest neighbour. This is the data-contract discipline applied one layer earlier than usual — not to the handoff between services, but to the moment a page becomes a record.
The absence rule is the one teams skip, and it is the one that
matters most. If null is not representable in the schema,
no downstream layer can distinguish "not on the document" from "not
found" from "found and empty," and the model has been told, structurally,
that abstention is not an option.
3. Deterministic validation: the part that cannot hallucinate
Everything generative in the pipeline can be wrong in a way that looks right. Deterministic checks cannot, and that asymmetry makes them the most valuable component per unit of engineering effort in the whole architecture. They are also unglamorous, which is why they are under-built.
- Arithmetic — line items sum to the subtotal, subtotal plus tax equals the total, quantities times unit prices reconcile, balances carry forward across statement pages.
- Format and checksum — IBAN and VAT check digits, date parses under a stated locale, identifiers match their structural pattern rather than merely looking like one.
- Cross-field consistency — issue date precedes due date, effective date precedes termination, currency on the total matches currency on the line items.
- Cross-document consistency — the purchase order number exists, the amount matches the goods receipt within tolerance, the counterparty matches the one on the master agreement.
- External reference — the supplier exists in the vendor master, the bank account is one already on file for that supplier, the tax ID resolves in a registry.
These checks catch what grounding cannot. A fabricated total fails source binding; a faithfully transcribed but wrong total fails arithmetic; a real value in the wrong field frequently fails cross-field consistency even when it passes both. Running them in that order also produces something better than a pass/fail — it produces a reason, which is what a reviewer and an auditor both need. Some of these belong earlier still: a check that runs at the moment of capture can ask for a better photograph while the person is still holding the document, which is cheaper than every downstream correction combined.
4. Abstention as a first-class output
Abstention is the right to return nothing, and it is the layer that separates systems that manage hallucination from systems that merely detect it after the fact. It requires four things to exist at once, and it fails if any one is missing: a schema that can represent absence, a signal the system can act on, a threshold that says when to act, and a downstream consumer that accepts an incomplete record without substituting a default.
The fourth is where this usually dies. A pipeline that returns
null to an ERP integration that requires a due date will
have that null turned back into a guess by an integration layer, a
default value, or a person under time pressure — and the abstention
bought nothing except a longer path to the same wrong number. Designing
for abstention means designing the exception path first: where the
incomplete record goes, who owns it, what SLA it carries, and what
happens if nobody touches it.
There is also a middle state worth building deliberately, between answering and abstaining: try again differently. A field that fails source binding on the first pass can be re-read at higher resolution, with a crop around the expected region, or by a second model, and only then abstain. That is the extraction loop doing what it exists to do — but the loop needs a termination rule, because a system that retries until something passes has converted an abstention into a confident answer by attrition.
5. Thresholds set per field, not per platform
One confidence threshold applied across a platform is a statement that every field costs the same to get wrong, which is never true. A misread line-item description on a $40 invoice is noise. A misread bank account number on the same invoice is a fraud loss. The threshold is not a technical setting; it is a pricing of consequences, and it belongs per field, per document type, and often per tenant.
Three of those consequence classes are worth naming explicitly, because they lead to different designs. Fields that are reversible and cheap can auto-release at a low bar and be corrected on exception. Fields that are expensive but detectable — a wrong amount that reconciliation will catch next week — can auto-release with a compensating downstream control. Fields that are irreversible — payment destinations, medication doses, legal counterparties — should not have a threshold that permits auto-release at all, regardless of how good the score looks. That last category is the one where teams discover, usually once, that a 99.4% field accuracy figure describes the 0.6% they are about to wire somewhere.
Thresholds also change, and they should change deliberately. When they live as constants in a worker, nobody can state what the threshold was when a given document was processed eleven months ago. When they live in the pipeline's control plane, resolved per tenant and per document type and logged with the job, the change is an auditable event with an author and a date.
6. The explanation log: why this value was allowed through
The last layer records the decision. For each released field: the value, the source region and the literal text matched there, which validations ran and what each returned, the score and the threshold it was compared against, the model and prompt version, the policy version in force, and — where a person was involved — who approved it and what they changed.
That record does two jobs. Operationally, it is the only way to debug a bad extraction after the fact, because reproducing a non-deterministic pipeline from inputs alone does not work; you need what the system saw and what it was permitted to do. Evidentially, it is the difference between logging outputs and holding a record that reconstructs a decision, which is the standard a regulated buyer is increasingly required to meet rather than merely prefer — the same evidence the technical documentation file has to be able to produce on demand.
The only component in a document AI system that cannot hallucinate is the one that does not generate. Build more of those, and make the generating parts prove themselves to them.
Confidence is not the signal you think it is
Almost every anti-hallucination design routes through a number somebody calls confidence, and the number is usually one of three things with very different meanings.
Token probability tells you how sure the model was about the next token given everything before it. It measures fluency, not truth. A fabricated invoice number in a familiar format can carry higher token probability than a correctly read one that happens to be unusual, because the model is confident about the shape of the string rather than its presence on the page.
Self-reported confidence — asking the model to rate its own certainty — is a generated value produced by the same process that produced the answer. When the answer is invented, the rating is invented alongside it, and it is invented to be reassuring, because that is what a confidence field looks like in the training distribution. It is not useless, but it should never be the sole gate on a consequential field.
Agreement is the one that carries real information: two independent reads of the same region converging, a second model agreeing with the first, a value matching an external system, a deterministic check passing. Agreement is expensive because it means doing the work more than once, and it is honest for exactly the same reason. The useful version is selective — spend the second read on the fields whose consequence tier justifies it, not on every field of every page.
The property that makes any of these safe to act on is calibration: whether a field released at a 0.95 bar is actually wrong about 5% of the time on your documents. That is measurable, on a labelled set, per document type, and it drifts when the model changes, when a supplier changes their layout, and when a new tenant sends a different mix. A threshold set from a vendor's benchmark and never re-measured is a number with the appearance of rigour. This is the same argument as verifiable reasoning: a chain of thought that sounds sound is not evidence, and neither is a score that sounds high.
Four ways the architecture gets built wrong
The failures below are common enough to be predictable, and three of them share a root — a control that depends on the same generation it is supposed to be checking.
Prompting instead of architecting. "Do not make anything up. If a field is not present, return null." Instructions like these help at the margin and are not controls, because compliance with them is itself probabilistic and unverifiable — the model that ignores the instruction gives no sign of having done so. An instruction is a preference expressed to the component that is failing. A control is a check performed by a component that cannot fail the same way.
Grading the work with the same model that did it. A second pass that asks a model to review its own extraction on the same evidence finds formatting errors and misses exactly the errors that matter, because the errors are correlated — the same misread of the same ambiguous layout produces the same wrong answer twice, now with a second opinion attached. A reviewing pass earns its cost only when something is genuinely independent: a different model, a different modality, a different region of the page, or a deterministic rule.
Treating unsourced and low-confidence as the same state. They call for different actions. A low-confidence value has evidence and is uncertain; the right response is usually a re-read or a human check against the highlighted span. An unsourced value has no evidence at all; the right response is to discard it, because there is nothing for a reviewer to verify and a confirmation screen showing a plausible number with no highlight is an invitation to approve a fabrication. Collapsing both into one score is how invented values reach people who have no way to catch them.
Letting the automation rate set the thresholds. Every control described here reduces the share of documents that finish without a person, and straight-through rate is the metric most often reported upward. The predictable outcome is a quarterly negotiation in which thresholds fall a little, each time for a defensible reason, until the architecture is nominally present and functionally disabled. The defence is to report the pair — automation rate alongside escalation-caught error rate and post-release defect rate — so that a rising automation number with a rising defect number reads as the regression it is, in the spirit of cost per successful task rather than cost per document processed.
The overhead nobody puts in the diagram
This architecture is expensive in ways that a block diagram hides, and the honest version of the argument states them. Schemas have to be authored and maintained per document type, with consequence tiers agreed by someone who understands the business risk rather than the code. Validation rules are business logic and they rot: a tolerance that was right when it was written becomes wrong when a tenant changes suppliers. Source binding costs storage and latency, and the geometry work is fiddly on tables that span pages. Calibration needs a labelled set that someone has to build and re-build, per document type, on a cadence. Explanation logs are the largest artifact class the pipeline produces and they need their own retention policy.
And the biggest cost is not engineering at all. It is that a system which abstains honestly will show a lower straight-through rate than one that does not, on day one and every day after — the same documents, fewer finished alone. That comparison is unfavourable in every dashboard that counts automation, and favourable in every measurement that counts outcomes, which is why the decision to build this has to be made by someone willing to defend the first number using the second. Teams that cannot make that argument internally should not start, because the architecture will be dismantled by degrees.
There are also cases where it genuinely buys nothing. High-volume, low-value documents where an individual error costs less than the check — routing mail, tagging attachments, extracting a reference number that a person will confirm anyway two steps later — do not need six layers. Nor does a workflow where a downstream system already performs a hard reconciliation that catches every consequential error and catches it fast. The architecture earns its cost where an error is expensive, irreversible, or invisible until it is expensive, and the useful test is the third one: how long would a wrong value survive here before anyone noticed? If the answer is measured in weeks, build the layers. If it is measured in minutes, do not.
What this changes for buying and operating
Three consequences are worth stating plainly, because they change the evaluation more than they change the code.
The demo is the wrong test. A vendor evaluation run on clean documents measures reading, which stopped being the differentiator. The test that discriminates is adversarial and cheap to run: submit a document that is missing a field the schema requires and see whether the system returns null or a plausible value; submit one with a supplier's arithmetic error and see whether validation catches it; submit a page with two similar tables and see which subtotal comes back; ask, for every field returned, where on the page it came from. A platform that cannot fail gracefully on the first of those will fail silently on all of them in production. The same instinct applies to documents that contain instructions rather than data — the adversarial case is the one worth submitting.
Field-level accuracy replaces document-level accuracy. A single accuracy number for a platform is close to meaningless, because it averages the field that costs nothing with the field that costs a payment. What matters is accuracy per field per document type, measured against a frozen test set, with the abstention rate reported alongside it — a system that is 99% accurate on the 80% of fields it answers is a different proposition from one that is 97% accurate on all of them, and which is better depends entirely on what the exception path costs.
The exception path is the product. Once abstention is real, a meaningful share of documents arrive at a person, and the quality of that handoff decides whether the architecture is an improvement or a tax. Showing the reviewer the document, the highlighted span, the specific check that failed and the field's history takes the decision from thirty seconds to five. Handing them a form with a blank field and no context means the abstention was converted into a guess by a human instead of a machine, which is not an improvement — it just moves the fabrication to somewhere with a name attached.
Closing thought
The uncomfortable part of this argument is that the fix does not arrive with the next model. Better readers make the first failure rarer and every remaining failure harder to spot, which is a net improvement only for systems that were already checking. A pipeline with no source binding, no deterministic validation and no way to abstain does not become trustworthy when its model improves; it becomes wrong less often and less visibly, which is a worse position to be in than it sounds. What separates a document system you can put in front of an auditor from one you cannot is not how well it reads. It is whether it can point at the page, show its working, and say nothing when there is nothing to say.
At Cogneris we build extraction as a ReAct loop with the checks outside the model: fields bound to their source on the page, schemas that permit absence, deterministic validation before release, configurable thresholds per field and document type, human review on what does not clear them, and tamper-evident audit metadata that records why each value was allowed through. If you are running document AI on decisions where a confident wrong answer is expensive, send us the adversarial cases rather than the clean ones — see how the API models these boundaries, the pricing page, or talk to our team. A system that always has an answer is not a system that is always right. It is a system that has never been given permission to stop.