LLM applications and RAG

Citations and Grounding: Making Answers Checkable

Grounding and citation are two different engineering problems with two different tests. Here is what a citation has to survive, the five properties that make one useful, and how to verify them automatically.

On this page
  1. A citation is a mechanism, not a trust signal
  2. Grounding and citation are two different jobs
  3. Granularity: document, chunk, or span
  4. The Checkable Five: what a citation has to satisfy
  5. Two ways to produce citations, and the honest trade-off
  6. The output contract
  7. Verifying citations automatically
  8. Where the citation surface leaks things it should not
  9. Adding citations to a system that does not have them

A citation is a mechanism, not a trust signal

The short answer

A citation exists so a reader can verify one claim in about ten seconds without asking anybody. That is the whole specification. If clicking it opens a forty page PDF at page one, or a document that has since been edited, or a file the reader has no permission to see, it has failed at its job while still buying the trust that comes with looking rigorous. Unverifiable citations are worse than no citations, because they move a reader from healthy scepticism to false confidence.

  • Ten secondsThe design target: a reader verifies one claim without leaving what they were doing. Anything slower and citations become decoration nobody clicks.
  • Span, not documentDocument-level citation shifts the search back to the human. Chunk level is the working minimum, span level is what regulated work needs.
  • Two different testsGrounding asks whether the claim came from retrieved evidence. Citation asks whether a human can check it. A system can pass either and fail the other.
  • Durability decides month sixA citation pointing at an id from a nightly rebuild resolves perfectly in testing and silently rots in production.
Grounding vocabulary, defined for use in a spec
Grounding
The property that every claim in an answer derives from evidence retrieved at query time, rather than from what the model memorised in training.
Attribution
The mapping from a specific claim in an answer to the specific passage that supports it. Grounding is about where content came from, attribution is about proving it per claim.
Span citation
A citation identifying an exact character range inside a named version of a source document, so the reader lands on the supporting sentence rather than on the document.
Citation precision
The share of cited passages that genuinely support the claim they are attached to. Low precision means the answer is decorated with sources it did not use.
Citation recall
The share of factual sentences in an answer that carry at least one supporting citation. Low recall means uncited claims are hiding among cited ones.
Entailment
The relation where a passage establishes a claim, such that a reader accepting the passage must accept the claim. This is the test a verification pass runs.

Grounding and citation are two different jobs

Separate them, because they fail independently and the tests are not interchangeable. An answer can be perfectly grounded and uselessly cited, which happens whenever a correct answer points at a document name and leaves the reader to search it. An answer can be neatly cited and completely ungrounded, which happens when the model writes a plausible claim and attaches a source id that was sitting in its context looking relevant.

StateWhat the user experiencesHow you detect it
Grounded and citedClaim, link, span highlighted, verified in secondsEntailment check passes for every claim and every span string-matches its source
Grounded, poorly citedThe answer is right, but checking it means reading a whole documentCitations resolve to documents rather than to character ranges
Cited, not groundedA confident claim with a plausible source attached that does not actually say itThe entailment check returns UNRELATED or PARTIAL, which is the check's entire purpose
NeitherA fluent answer with no sources, or with sources invented outrightNo ids present, or ids that were never in the retrieved context
Four states a cited answer can be in, and how each is detected

Granularity: document, chunk, or span

Cite at the smallest unit you can resolve reliably. Every step down in granularity moves verification work from the reader back to your system, which is where it belongs, and every step costs engineering effort at ingest that you cannot retrofit cheaply later.

LevelWhat the reader must doWhat it costs to buildAcceptable for
DocumentOpen the document and search it themselves, which most people will not doAlmost nothing, you already have the file pathInternal exploratory search where the reader knows the corpus well
ChunkRead one passage and judge it, usually under a minuteStable chunk ids, a way to render a chunk, and a link that opens itMost internal knowledge systems, and the working minimum for anything customer facing
SpanRead one highlighted sentence in its surrounding contextCharacter offsets preserved through parsing and chunking, plus a viewer that can highlight a rangeRegulated content, financial and legal answers, anything that could be disputed later
Quote onlyRead the quoted text, with no way to see its surroundingsTrivial, and it is a trap: an accurate quote with the following sentence removed can invert the meaningNothing on its own. Always pair a quote with a resolvable location
Citation granularity compared by verification cost and engineering cost
Character offsets have to be preserved from the very first parse

Span citation is decided at ingest, not at answer time. If your parser normalises whitespace, strips headers and merges hyphenated line breaks without recording the mapping back to the original bytes, span offsets are unrecoverable and you are permanently limited to chunk citation. Keep the original document, the extracted text, and the offset mapping between them. Retrofitting means re-processing the whole corpus, the migration described in chunking strategies.

The Checkable Five: what a citation has to satisfy

Five properties separate a citation that does its job from one that looks like it does. Teams reliably build the first three and skip the last two, and the last two are the ones that produce incidents rather than complaints.

Framework

The Checkable Five

Take one real citation from your system and test all five by hand. Any clause you fail is a specific engineering task, not a matter of judgement, and the last two are the ones that bite in month six rather than in week one.

01
Resolvable

One click lands the reader at the exact place, inside a system they already have access to. Test: click a citation from a two week old log entry, on a colleague's machine. If it opens a login wall, a download dialog or page one of a long document, nobody will use it twice.

02
Specific

It points at a passage, not a container. A citation naming a two hundred page handbook has handed the search back to the reader with extra steps. Test: count the words a reader must read before reaching the supporting sentence.

03
Sufficient

The cited span, read alone, establishes the claim. Test by showing a colleague only the claim and the span, with the answer hidden, and asking whether the span proves it. The common failure is a span that works only in combination with a heading or an earlier sentence that is not included.

04
Permitted

The reader can open the source, and the citation reveals nothing they were not entitled to see. A citation to a restricted document leaks its existence, its title and usually a quoted extract, all before any access check runs. Test: run the same question as a low-privilege user and read every citation.

05
Durable

It still resolves in six months, after the index was rebuilt and the document edited. Cite a stable address plus a version, and store the retrieved span text beside the pointer. Test: rebuild the index and reopen a citation captured before the rebuild. If it breaks, your ids are a build artefact rather than an address.

Two ways to produce citations, and the honest trade-off

You can have the model emit citations as it writes, or you can align citations to the finished answer afterwards. Both are legitimate, they fail differently, and the strongest systems run both because the second one catches what the first one invents.

Cite while generatingAttribute after generating
How it worksThe model returns structured claims, each carrying the source ids it usedA separate pass matches each sentence of the answer to the best supporting span
Main failureThe model attaches a plausible id to a claim it did not take from that passageIt finds a passage that resembles the claim, which quietly legitimises an invented sentence
LatencyNone added, it is part of the same callOne extra pass over every claim, so it scales with answer length
CostSlightly more output tokensA second model call, or a small dedicated entailment model you host
Paraphrase across two sourcesHandled naturally, the model can list both idsHarder, since no single span entails the merged sentence and the matcher picks one
IndependenceNone, the writer is grading itselfGenuine, which is exactly why it catches the first method's failures

The output contract

Write the schema before the prompt. A cited answer is a data structure with claims and supports, not a paragraph with brackets in it, and treating it as free text is what makes verification impossible later. Enforce the shape with structured output or a tool schema rather than an instruction, which is covered in structured output from LLMs.

Cited answer schema plus the verifier rubricjson
// The output contract for a cited answer. Enforce it with structured
// output or a tool schema. Do not ask for it politely in the prompt and
// hope, because the one call that ignores it is the one a user screenshots.

{
  "type": "object",
  "required": ["status", "claims", "unsupported"],
  "properties": {
    "status": { "enum": ["answered", "partial", "conflict", "no_source"] },

    "claims": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["text", "support"],
        "properties": {
          "text":    { "type": "string",
                       "description": "One factual proposition, so a compound sentence is split in two." },
          "support": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "required": ["chunk_id", "doc_uri", "doc_version", "quote"],
              "properties": {
                "chunk_id":    { "type": "string" },
                "doc_uri":     { "type": "string",
                                 "description": "Stable address, not a nightly row id" },
                "doc_version": { "type": "string" },
                "start":       { "type": "integer" },
                "end":         { "type": "integer" },
                "quote":       { "type": "string",
                                 "description": "Verbatim span that must string-match the source." }
              }
            }
          }
        }
      }
    },

    "unsupported": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Claims the model wanted to make and could not source. Log these, they are your content backlog."
    }
  }
}


---- Verifier rubric, per claim, on a model that did not write the answer ----

You are checking one CLAIM against one QUOTE. You have no other knowledge.
Reply with a single word.

SUPPORTED    the quote states the claim, or states it with only wording changes
PARTIAL      the quote supports part of it, or supports it with a condition or
             scope limit the claim omits
CONTRADICTED the quote states something incompatible with the claim
UNRELATED    the quote neither supports nor contradicts the claim

# A quote about a different entity, date, version or region is UNRELATED,
# however similar the wording. That is the case this check exists to catch.
# Any number or date in the claim must appear in the quote to be SUPPORTED.

CLAIM: {claim_text}
QUOTE: {quote}

Verifying citations automatically

Run four checks in order of cost. The first three are deterministic, cost nothing, and catch the failures that embarrass you most. Only what survives them needs a model.

  1. Existence checkfree, run always

    Every cited chunk id must have been in the retrieved context for this specific call. An id that was not is fabricated. This single check catches the worst failure mode and takes a set membership test.

  2. Quote matchfree, run always

    Every verbatim quote must appear in the cited source, allowing whitespace normalisation only. A quote that does not match is either invented or paraphrased while presented as exact, and both should fail the answer rather than warn.

  3. Numeral and entity checkfree, high value

    Every number, amount and date in the claim must appear in the cited span. Any that does not was computed or recalled, and computed figures are the errors most likely to end up in a formal complaint.

  4. Entailment checkone model call per claim

    Ask a model that did not write the answer whether the span supports the claim, using a four way rubric rather than yes or no, so PARTIAL and UNRELATED stay distinguishable. PARTIAL usually means a dropped scope condition, the most common quiet error in summarised answers.

  5. Coverage checkcomputed, not called

    Citation recall is the share of factual sentences carrying a support. Citation precision is the share of cited spans that passed entailment. Track both, because recall alone rewards citing everything and precision alone rewards citing almost nothing.

  6. Decide the action per stakes tierthe part people skip

    Define the failure action in advance. Low stakes: show the claim marked unverified. Medium: drop the claim and answer with what remains. High: refuse and route to a human. Writing this down before launch stops it being decided during an incident.

Where the citation surface leaks things it should not

Citations expose your corpus. That is the point of them and also the risk, because every citation is a small disclosure waiting for a permission bug. The leak is rarely the document body. It is the title, the path, the author, the existence of the document, and the snippet rendered before any access check has run.

  • Filter at retrieval, never after generation. A restricted passage that reaches the model has already shaped the answer, and removing the citation leaves the leaked content in the text.
  • Treat document titles as content. A citation reading 'Redundancy plan, Q4, Manufacturing' discloses the substance without opening anything.
  • Re-check permissions at render time. Access changes between indexing and reading, and a cached answer with stale citations outlives the permission that justified it.
  • Watch the shared answer. A forwarded link carries citations to documents the recipient may not open. Decide whether shared answers re-check against the viewer or degrade to claims without sources.
  • Redact traces on the same rules. Your logs contain retrieved spans, so they inherit the sensitivity of the most restricted document in them, which is covered in what to log in AI systems.

Adding citations to a system that does not have them

Do it in four passes, in this order, because each one depends on the last. Attempting span-level citation before ingest preserves offsets is the usual way this stalls, and the usual way a team concludes that citations are harder than they are.

Pass 1
Make retrieval visible

Log retrieved chunk ids and scores with every answer and render them in an internal debug view. Before building any citation you need to see what the system read. This also shows how often the correct source was never retrieved, which may reassign the whole project.

Pass 2
Give every chunk a durable address

A stable id that survives re-indexing, a document uri, a version and, if you can preserve them, character offsets. Stop using array positions and nightly row ids. This pass is where the real engineering is, and everything after it is easy by comparison.

Pass 3
Change the output contract

Move from a paragraph to a claims structure with per-claim supports, enforced by a schema. Then turn on the free checks: id existence, quote match, numerals. Most systems find real failures within a day, which is uncomfortable and useful.

Pass 4
Add entailment and the interface

Layer the verification model on the surviving claims, then build the reading experience: inline markers, hover preview, one click to the highlighted source. Decide the failure action per stakes tier and set the retention period for stored spans deliberately.

Go-live checklist for cited answers
0 of 10 done
Cite this

A citation exists so a reader can verify one claim in about ten seconds without asking anyone. To do that it must resolve to a span rather than a document, be sufficient on its own, be openable by that reader, and still resolve after the index is rebuilt and the document is edited. Grounding and citation are separate properties and need separate tests.

Questions readers ask next

What is the difference between grounding and citation?
Grounding is the property that a claim derives from evidence retrieved at query time rather than from training. Citation is the mechanism that lets a human check that claim against the evidence. They fail independently: an answer can be grounded while citing only a document name, which pushes verification back onto the reader, and an answer can carry neat citations while the cited passage does not support the claim beside it.
How do I make an LLM cite its sources accurately?
Require a structured output where each claim carries the chunk id, document version and a verbatim quote, enforced by a schema rather than an instruction. Then verify: every cited id was genuinely in the retrieved context, every quote string-matches its source, every numeral appears in the cited span, and the span entails the claim according to a separate model. Prompting alone produces citations nothing checks.
Should citations point to a document or to a specific passage?
A passage, at minimum. Document-level citation returns the search problem to the reader, and most readers will not do it, which makes the citation decoration. Chunk level is the working minimum for anything customer facing. Span level, where a click lands on the highlighted sentence, is what regulated or disputable content needs, and it requires character offsets preserved from the first parse.
How do I stop an AI from citing a source that does not support the claim?
Add an entailment check run by a model that did not write the answer, using a four way rubric of supported, partial, contradicted and unrelated rather than yes or no. Partial and unrelated catch the two common quiet failures: a dropped scope condition, and a passage on a similar topic but a different entity or version. Decide in advance whether a failed claim is dropped, marked unverified, or fails the answer.
Can citations leak documents a user should not see?
Yes, and it is a common oversight. The document title, the file path and the rendered snippet all disclose content before anybody opens anything, and a citation reveals that a document exists at all. Filter by access group at retrieval rather than removing citations afterwards, since a restricted passage that reaches the model has already shaped the answer. Re-check permissions at render time, because access changes.
How do I measure citation quality?
Track two numbers separately. Citation recall is the share of factual sentences carrying at least one supporting citation, which catches uncited claims hiding among cited ones. Citation precision is the share of cited spans that pass an entailment check, which catches sources attached decoratively. Reporting only one creates a perverse incentive, since recall alone rewards citing everything and precision alone rewards citing nothing.
Cite this

ChatGPTalker. "Citations and Grounding: Making Answers Checkable." chatgptalker.com, 2026-08-26. https://chatgptalker.com/guides/citations-and-grounding/

Rather have it built than read about it?

Send the process you want automated. You get a scoped plan back, with the build shape, the stack and a realistic timeline.

Start a project