How do you stop a language model from inventing construction-standard codes? Not with a better prompt. We keep a registry of every code that has ever existed, matched against the edition the document declares, and look up every candidate before it reaches a user. The model proposes; the registry disposes.
The problem
Because a standard code is exactly the kind of thing language models are good at producing. Swedish construction documents hang their requirements on codes from shared reference works: short, structured strings that tell a contractor which technical requirements apply to which part of the work. A code is a few letters and digits with a rigid grammar, and a model that has read millions of them can generate one that looks perfect. A hallucinated code does not look wrong. It looks like every real code around it.
For a review tool, that is disqualifying. An engineer who catches one invented reference stops trusting every comment the system makes, and they are right to. Instructions like "never invent codes" lower the rate. They do not take it to zero, and zero is the requirement, because traceability is the product.
The registry
So we stopped trying to make the model right and started checking it instead. We maintain a ground-truth registry of every code that has ever existed in the reference works Swedish construction documents cite. Every code candidate the pipeline produces is looked up before it reaches a user. In the registry: it ships, with its official description attached. Not in the registry: it does not ship, no matter how confident the model was.
Existence is only half the check. The same code can carry different requirements in different editions: a technical description written under AMA 17 does not mean the same thing read through AMA 20. So the registry match runs against the edition the document itself declares. A code validated against the wrong edition is just a subtler hallucination.
The extraction side has the same shape, inverted. Our best-performing extraction step starts with a regex: a deterministic sweep over the document produces the candidate list, and the model's job is reframed from "find the codes" to "criticize and complete this list". Language models are dramatically better critics than searchers. The mechanical part, spotting structured strings in noisy OCR text, belongs to code.
The footnotes
The registry solved invented codes. The next failure was stranger. During synthesis, when one agent merges findings from several documents, the model would occasionally mangle a file ID: the claim was correct, the quote was correct, but the pointer to the source file was corrupted. For a system whose entire value is traceability, that is the worst possible error. A right answer with a broken reference is indistinguishable from a made-up one.
The fix follows the registry philosophy. File IDs are no longer written by the model at all: they are set programmatically after generation, then verified by set membership against the files actually in the job. If verification fails, the step retries; if it keeps failing, the pipeline fails hard rather than deliver a broken pointer.
Citations needed the same treatment to survive a multi-agent pipeline. Index-based citations ("document 2, sentences 4 to 6") work in every single-model tutorial and die at the first agent hop: once a synthesizer has merged three researchers' answers, "document 2" refers to nothing. Our citations travel as self-contained value types, carrying the source ID and the verbatim excerpt inside the tag itself, so they arrive at the user unchanged no matter how many agents handled them.
| What must be exact | How the model fails | What enforces it |
|---|---|---|
| Standard codes | Invents plausible ones | Registry lookup, matched to the declared edition |
| File IDs | Mangles them during synthesis | Set programmatically, verified by set membership |
| Citations | Loses them between agents | Self-contained value types with verbatim excerpts |
The principle
The three fixes are one pattern. The model is allowed to propose, interpret and judge, because that is what it is good at. It never gets the last word on anything that must be exactly right: identifiers, references, codes, citations. Those go through deterministic code with verification, and when verification fails, the system says so instead of guessing. Prompts shape behaviour; databases and set-membership checks guarantee it. Only one of those is an engineering contract.
What anyone should demand of a machine-generated review comment is concrete: the requirement it rests on, the document revision it read, a location a human can check. This is the machinery that makes those demands satisfiable. Traceability is not a tone the model adopts when asked nicely. It is an architecture, and most of it is a database.
Traceability is built in for exactly this reason: codes, file IDs and sources run through deterministic code, never the model. Get in touch if you'd like to see how it looks in practice.
Book demoNot ready for a demo? Get the next piece in your inbox.
Related