Skip to content

14 min read

Grounding commitments and measured rates

On this page

The request usually arrives as a sentence from outside engineering: confirm that the assistant will not state anything that is not present in the source documents. Read literally it asks for a universal negative over an unbounded input space — for every question any customer will ever ask, no claim in the response falls outside the supplied documents. Nothing in the system establishes that, and the honest reason fits in one breath: the component that decides what to emit is a probability model over token sequences, and no configuration of it produces a proof about the content of every future output.

The reason that is a structural limit rather than a maturity problem is worth being able to state without hedging. A proof about every output requires either enumerating the outputs, which is impossible over an unbounded input space, or deriving the property from the mechanism, which requires the mechanism to contain the property. The mechanism here selects tokens by probability, and a probability distribution has no zero it can be relied on to keep: the token that would begin a fabricated clause number is never assigned zero mass, only small mass, and small mass over enough requests is a certainty rather than a risk. Any guarantee that reaches every output therefore has to come from a component outside the model, and the rest of this chapter is about which guarantees such a component can actually support.

Everything measured in this topic says the same thing from a different angle. An instruction moves the wording, retrieval removes the need to invent without compelling the model to read, and a verifier converts some failures into abstentions while leaving a residual. So the commitment that can be written is a different shape from the one being asked for, and the work of this chapter is to build it: find out what the request is actually protecting against, separate the claims that admit an absolute promise from the ones that do not, measure a rate with its uncertainty, and write the whole thing down in a form that survives the first incident review rather than being read back as an overclaim.

What is actually being asked for

What legal needs is usually narrower than what they wrote, and finding out which is the first move rather than the last. Behind the sentence there is normally a specific exposure: a regulator who will ask what controls exist, a contractual liability if the assistant states a wrong price or entitlement, a card scheme's rules on disputed charges and the chargebacks that follow them, a support organisation that needs to know when to trust a draft, or a board question about AI risk. Each of those is satisfiable, and none of them requires a universal negative. A regulator wants evidence of a control and a monitoring regime. A liability owner wants the error rate bounded and the high-cost subset handled deterministically. A support organisation wants to know which drafts were verified and which were escalated. Ask which one is driving the request and the conversation changes from "can you promise perfection" to "what can you demonstrate".

Three things you could sign

Instruction-backed guaranteeMechanism-backed guaranteeMeasured-rate commitment
Wording"The assistant only states facts present in the sources.""No response containing a clause or section identifier absent from the retrieved documents is returned to a customer.""The unsupported-claim rate stays at or below 3.0%, measured monthly on a stratified sample of 400 responses."
What enforces itNothing. A sentence in a prompt.A deterministic check in the response path, plus a test suite over it.An annotation process, a threshold, and an escalation path when the threshold is breached.
How you verify itYou cannot. There is no observation that would confirm it holds.Unit tests, plus the invariant that the check runs before the response is emitted.Re-run the labelling; publish the number and its confidence interval.
ScopeEvery claim, allegedly.A narrow, mechanically decidable subset.Every claim, probabilistically.
What happens at the first incidentThe commitment is falsified by one transcript.The check either fired or there is a bug in a specific, testable component.The incident is expected within the stated rate, or it is a breach that triggers the defined response.

The second and third columns are both signable, they cover different things, and a serious commitment document contains both. The first column is the one that gets teams into trouble, and its distinguishing feature is that it has no verification row.

What separates a committable promise from an uncommittable one is exactly that row, and the test is short enough to apply in a meeting. Ask what observation would show the commitment being kept, and what observation would show it broken. For the deterministic control both answers exist: a test suite demonstrates the check runs, and a returned response containing an unmatched identifier would falsify it. For the measured rate both exist as well, though probabilistically: re-running the annotation produces a number, and a number above the threshold is the breach. For the instruction-backed wording neither exists. No observation confirms it, because it is a universal claim; and a single bad transcript refutes it, because it is a universal claim. A sentence that cannot be confirmed and can be refuted by one example is the worst available shape for a promise.

The subset you can guarantee outright

Some claims carry their own decidable handle, and those admit absolute promises. A clause identifier, a section number, a price, a date, an order number, an account status, an SKU — anything that is a literal string or a value drawn from a system of record — can be checked against the supplied context or against the record itself, deterministically, before the response leaves the building. The identifier check from chapter 5 is exactly this, and its four months without a false positive is not luck; string equality does not have a false-positive rate.

Being precise about the boundary of that subset is what makes it worth signing. "No returned response contains a section identifier of the form [A-Z]{2,4}-\d{2,4} or Section \d+(\.\d+)? that does not appear verbatim in the retrieved passages" is a sentence you can defend under questioning, because there is a function in the codebase that implements it and a test file that exercises it. Extending the same treatment to prices and dates — extract every currency amount and every date in the draft, require each to appear in the context or in the order record — took another two days on one deployment and brought roughly 40% of the high-cost claim types under deterministic control.

The remaining 60% is prose: entitlements, eligibility judgements, explanations and process descriptions, where the claim is not a token you can grep for. That part gets the verifier from chapter 7 and a measured rate, and no amount of engineering converts it into the first kind.

The number, and the interval around it

The rate you commit to has to be one you have measured, with the uncertainty stated. A full annotation pass covering 400 responses and 4,981 claims found 120 unsupported and 328 contradicted, giving an unsupported-claim rate of 2.41%. A Wilson 95% interval — the standard confidence interval for a proportion, and the one that stays sensible when the count is small relative to the sample — on 120 out of 4,981 runs from 2.02% to 2.87%. The honest statement is therefore "between roughly 2.0% and 2.9%", and a threshold of 3.0% sits just above the top of that interval. Committing to 2.5% would mean breaching on a month where nothing changed except which questions customers happened to ask.

The interval is doing work that the point estimate cannot, and it is worth saying what that work is. The 2.41% was computed from one sample of claims drawn from a much larger population of possible claims, so it is an estimate of a rate rather than the rate itself. Draw a different 400 responses next month and the figure moves, even with the system frozen, because a different set of questions came in. The interval is the range within which the underlying rate plausibly sits given a sample of this size, and its width falls as the sample grows — which is why the threshold has to be set against the top of the interval rather than against the estimate. A threshold placed at the estimate is a threshold that will be breached about half the time by nothing at all.

That is also why smaller improvements need so much more annotation. What a sample can resolve is a difference larger than the noise in its own estimate, and the noise shrinks slowly with sample size while the difference you are chasing shrinks in your control. Halving the improvement you want to detect therefore costs far more than twice the claims, which is the gap between the 4,300 claims needed to see a drop to 1.5% and the 22,000 needed to see one to 2.0%. The arithmetic is worth running before promising an improvement rather than afterwards, because it decides whether the promise is one a quarterly pass can ever demonstrate.

Sample size determines what you can detect, and it is worth working out before promising to demonstrate improvement. At a 2.4% base rate, detecting a drop to 1.5% at 80% power and a 5% significance level — an 80% chance of seeing the improvement if it is genuinely there, against a 5% chance of reporting one that is not — needs about 4,300 claims per arm, which is roughly 350 responses and comfortably within what a quarterly annotation pass can produce. Detecting a drop to 2.0% needs about 22,000 claims per arm, which is a person-month of annotation for a change nobody would feel. That arithmetic tells you which promises about future improvement are cheap and which are not, and it is better to know before the number is in a document.

Two design choices in the measurement need writing down alongside the rate, because they change it. The sample is stratified — proportional across question types, including the absent-fact slice that a naturally-sampled month would under-represent — so the published rate is not the raw production rate and should not be compared to one.

Saying why the two differ takes one step and prevents an argument later. Stratifying means fixing the proportions of the sample by question type rather than letting traffic set them, and the absent-fact slice is where almost all unsupported claims come from. Production traffic contains fewer such questions than the stratified sample does, so the stratified rate is deliberately higher than what customers experience. That is the right choice for a commitment, because it means the bound holds even in a month when hard questions arrive more often than usual. It is the wrong number to quote as "our hallucination rate" to somebody who will read it as a description of ordinary traffic, and the document has to say which one it is. And the rate is per claim, not per response; the per-response figure of 41% is much larger, describes something real, and belongs in the same document rather than being quietly omitted.

What goes in the document

text
LAUNCH COMMITMENT — SUPPORT ASSISTANT v4, GROUNDING

1. Deterministic controls. No response reaches a customer if it contains a
   section identifier, currency amount, or date that does not appear verbatim
   in the retrieved passages or the customer's order record. Enforced in the
   response path; see tests/test_identifier_gate.py.

2. Verification and abstention. Every factual claim is emitted with a cited
   span and checked for entailment against that span before release. A claim
   that fails twice causes the response to be withheld and the ticket routed
   to a human agent. Withholding is logged and counted.

3. Measured rate. The unsupported-claim rate, measured per claim on a
   stratified sample of 400 responses annotated by two reviewers, will remain
   at or below 3.0%. Current measurement: 2.41% (95% CI 2.02-2.87%),
   n = 4,981 claims, 2026-07-14. Inter-annotator agreement kappa = 0.79.

4. Cadence. Measurement is repeated monthly, and after any change to the
   model, the retrieval corpus, or the system prompt.

5. Breach. A measurement above 3.0% pauses the weekly release train and
   opens a P2. Any customer-reported fabricated entitlement or price opens a
   P1 within one business day regardless of the measured rate.

6. Not claimed. This document does not assert that the assistant is free of
   unsupported statements. It states a bounded, monitored rate and a defined
   response when the bound is exceeded.

Clause 6 is the one people want to delete and the one that makes the rest of it survivable. Without it, clauses 1 through 5 read as supporting detail under an implied guarantee, and the first bad transcript becomes an argument about whether the document was misleading. With it, that transcript is an event the document already anticipated and assigned a response to.

The commitment is only real if it is wired to something that runs, which means the threshold lives in a config file that a job reads, rather than in a slide.

yaml
grounding_slo:
  metric: unsupported_claims_per_claim
  threshold: 0.030
  sample:
    responses: 400
    stratified_by: [answerable, ambiguous, absent]
    annotators: 2
    min_kappa: 0.70
  cadence: monthly
  also_on_change_to: [model_id, retrieval_corpus, system_prompt]
  on_breach:
    - pause: release_train
    - open_incident: P2
  report:
    include: [rate, wilson_ci_95, n_claims, per_response_rate, kappa]

The framing that lands with non-engineers is one they already accept everywhere else in the business. Fraud detection does not promise zero fraud; it promises a detection rate, a false-positive rate, and a review queue for the cases it flags. Manufacturing does not promise zero defects; it promises a defect rate, an inspection regime, and a recall procedure. Nobody finds those commitments evasive, because the mechanism is legible and the response to failure is defined. Say the same thing in the same shape — here is the rate, here is how it is measured, here is the part of the surface where the guarantee is absolute because a deterministic check enforces it, here is what happens when the bound is exceeded, and here is what we are not claiming — and the conversation stops being about whether the technology can be trusted. The last item is what buys the credibility of the others.

Ownership, and where a rate is the wrong answer

A commitment with no owner decays into a paragraph nobody reads. The measurement needs a named owner who runs the pass, publishes the rate with its interval, and has the standing to pause a release; the annotation needs two people who are not the people who wrote the prompt, because a prompt author labelling their own outputs is grading their own homework and the kappa will not save you; and the checker's thresholds need review whenever the model version changes, because a threshold validated against one model's output distribution is not automatically right for another's.

The cadence in clause 4 is doing specific work. Monthly catches drift in the question mix and in the corpus. The on-change trigger catches the thing that actually breaks these systems, which is a routine upgrade — a new model version, a re-chunked corpus, a system prompt edit made to fix something unrelated — landing without anyone re-running the measurement. A model upgrade that improves every public benchmark can move your unsupported-claim rate in either direction, because your rate depends on your corpus, your prompt and your question distribution, none of which the benchmark saw. The one thing not to do is publish the rate on a dashboard that nobody has to sign: a number on a dashboard is watched enthusiastically for three weeks and then becomes wallpaper, while a number in a document with a threshold and a named consequence gets looked at the week before launch and the day after an incident.

There are also domains where none of this is sufficient, and recognising them is part of doing the work honestly. If a single unsupported claim can cause harm that no amount of subsequent correction undoes — a dosage, a legal filing deadline, a safety instruction, an irreversible financial action — then a 2.4% rate is not a small risk to be monitored, it is an unacceptable design. The answer there is not a lower number, because the number does not go to zero and pretending otherwise is how the instruction-backed guarantee gets written in the first place. The answer is a different system: narrow the scope until every claim falls into the deterministically checkable subset, put a qualified human between the output and the action, or use the model for retrieval and drafting while a person makes every assertion. That is a product decision, and engineers are the ones who have the evidence to force it.

The frame that survives all of this is the one the measurements have been pointing at since chapter 3. Hallucination is not a prompting problem, because prompting reaches the wording and the failure is in the content. It is an evaluation problem first, because until claims are labelled against evidence there is no rate to move and no way to tell whether a change helped, and a grounding problem second, because the interventions that move the rate are the ones that put evidence in front of the model and check the output against it. Every number in this topic came from the same procedure, and every intervention was judged by what it did to those numbers.

Which leaves the work itself. Take fifty real questions from whatever system you are responsible for, including ten the documents genuinely cannot answer, run them, and label the claims against the passages by hand. It takes an afternoon, and it produces the first two honest numbers anybody on the team has had.

Hallucination — read the current version at https://daviddominguez.dev/learn/en/hallucination/grounding-commitments-and-measured-rates

Back to top