← Writing

March 20267 min read

Building AI That Cites or Refuses

Most AI systems are optimised to always produce an answer. The systems I build for high-stakes work are optimised for something different: every claim traces to a record, and when the evidence isn’t there, the system says so instead of guessing. This post walks through how that contract, cite or refuse, actually gets enforced in an architecture rather than just promised in a prompt.

Why “probably right” isn’t good enough

Some environments can’t tolerate a confident guess. When an answer will inform a real decision (a payment, a compliance call, an investigation), the cost structure inverts: a fast wrong answer is worse than no answer, because it spends trust the system needs later. A model answering from parametric memory alone can’t provide that guarantee, no matter how capable it is. It has no record to point to, and no reliable sense of when it doesn’t know.

So the design problem isn’t “make the model smarter.” It’s architectural: build a system that reasons over retrieved evidence, shows its working, and declines rather than fabricates. The model is one component inside that system, not the system itself.

The contract

The contract has two clauses. If the retrieved evidence supports an answer, every surfaced claim ships with the records that back it: cite. If it doesn’t, the system states exactly what’s missing and stops: refuse. There is no third path where the model fills a gap with something plausible.

The important word is enforced. This isn’t a system-prompt instruction the model can drift away from; it’s a gate that sits after reasoning and before display. When an answer lacks defensible evidence, the gate doesn’t downgrade it to a hedge. It blocks it.

Decision flow: a question is routed and evidence retrieved; the required evidence categories feed a sufficiency gate; sufficient evidence leads to cite, then faithfulness verification, then human review; insufficient evidence leads to a refusal that names the gaps. questionroute + retrieverequired evidencesufficiency gaterefuse · gaps namedciteverify faithfulnesshuman review
Evidence sufficiency picks the branch; verification and review sit after cite, and a refusal names exactly what was missing.

What the gate actually checks

The mechanism is simpler than it sounds. Each question, once routed, carries a set of required evidence categories: the kinds of records you’d need before you’d let a person assert the answer. Retrieval surfaces candidate records, each tagged with the categories it satisfies. The gate then asks one question: is every required category satisfied by something actually retrieved?

If yes, the answer is assembled as discrete claims, each linked to its supporting records. Not one blob of prose with a bibliography at the end, but claim-level attribution that a reviewer can check line by line.

If any category is unsatisfied, the system refuses, and the refusal is informative. It names the missing category and points at the nearest records it did find, so the reviewer knows whether the gap is real or a retrieval problem. A refusal that just says “I can’t answer that” wastes the work retrieval already did.

One rule matters more than the rest: absence of evidence is not evidence. If the records establish who a vendor is but say nothing about its history before a certain date, the system doesn’t infer from silence. That inference is exactly where language models are most fluent and most dangerous.

Verification, because generation lies politely

The gate decides whether to answer. A second layer checks what was answered: an independent faithfulness verifier re-reads each generated claim against the text of the records it cites and asks whether the evidence actually supports the claim. It’s deliberately constrained: it sees the claim and the retrieved records, not the generator’s output beyond that, so a citation is treated as a hypothesis to test rather than a fact to trust. Citing a real record is necessary but not sufficient; the claim has to say what the record says.

Claims the verifier can’t align with their cited evidence are blocked before display. The design goal is that unsupported assertions get stopped at this layer, not discovered in a post-mortem.

And a person stays in the decision path. The system proposes; a reviewer decides. Every answer carries an auditable decision trace: which route was taken, what was retrieved, which claims cite which records, why the gate chose cite or refuse. That’s a record of what the system did, not exposed model chain-of-thought. And it’s replayable, so a bad output can be traced to its inputs rather than argued about. That audit trail is what makes the system defensible in front of people who don’t trust AI, which in high-stakes domains is correctly everyone.

The tradeoffs are real and worth naming

Defensibility over latency. Retrieval and verification passes cost time. Acceptable when a fast wrong answer is worse than useless; wrong tradeoff for a chatbot.

Restraint over recall. Tuned this way, the system sometimes refuses questions it could technically have answered. You accept some “can’t support that” to eliminate confident fabrication. Stakeholders learn quickly that an answer, when it comes, means something.

Control over peak capability. Sensitive-domain work often means local-first models and no external APIs. Smaller models cost capability; tiering (cheap local models for routing and classification, heavier reasoning only where the task earns it) buys most of it back without sending data anywhere.

If you’re building one of these

Make refusal a first-class output with its own structure (missing categories, nearest evidence), not an error state. Put the sufficiency check in code, not in the prompt. Attribute at claim level, because answer-level citations hide exactly the fabrications you care about. Verify faithfulness mechanically, and log enough to replay every decision.

None of this needs a frontier model. It needs the discipline to treat the model as a component with a defined contract, and to make “I don’t know” a success state instead of a failure to be papered over. If you want to see the shape of it end to end, there are recorded live runs of this decision contract on this site: the same model answering with and without the harness, failures included.