Which is the cleanest way to log citation linkage between answer and chunks?
Have the model emit citation markers that map to stable chunk ids. Then store the resolved mapping as a structured citations attribute on the span, for groundedness checks and user-facing UIs.
Imagine a research essay where every paragraph ends with a tiny footnote number. The numbers connect back to a bibliography at the end, and the bibliography lines up with actual books on a shelf. A reader can pick any footnote and walk to the exact book to verify the claim. If the essay had no footnote numbers, the reader has to trust the writer. If the footnotes referenced 'book 3' but the bibliography did not exist, the reader is stuck. RAG citation linkage builds the same chain inside an answer. The model emits the footnote numbers, the trace stores the bibliography, and a verifier can trace every claim back to a real retrieved chunk.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Citation linkage in RAG observability looks easy until you need to verify a claim three weeks after the fact. Then the trace tells you 'here is the answer, here are some chunks that were retrieved'. The link between specific claims and specific chunks has to be a structured object on the span. Without it, you are left with fuzzy matching.
Three components and why each is non-negotiable
A citation linkage system has three small pieces.
Stable chunk ids
Every retrieved chunk needs a deterministic id that survives across the lifecycle of the trace. Content-addressed hashing (SHA-256 over normalized text plus document and version) is the standard. Database row ids work in steady state but break when the index re-builds and ids shift. Free text snippets are unworkable because the model paraphrases.
The id has to travel from the retriever through the reranker into the LLM context and back out as part of the generated answer's citation markers.
Marker in the answer
The model emits a citation marker after each factual claim. The system prompt instructs the format. Modern frontier models follow the instruction reliably once a few-shot example is provided. The marker is the link. It lives inside the freeform answer text but maps deterministically to a chunk id.
Structured citations attribute on the span
The generation span carries a typed list of citation objects. Minimum shape: {marker, chunk_id}. The producer parses the answer once at emission, resolves each marker to a chunk id, validates that every marker resolves, and writes the list as a typed attribute.
What you lose without any one of them
- No stable ids: you have markers and an unsearchable answer text. Reconstruction requires storing chunk text on the span (expensive) or re-running retrieval (lossy).
- No markers: you have ids and an answer with no link. You have to guess which chunk grounded which claim.
- No structured attribute: you have markers in text. Every consumer re-parses, and format drift breaks everyone.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
Real products, models, and research that use this idea.
- Perplexity renders inline numbered citations that map to indexed sources.
- Anthropic's Claude with the 'citations' API parameter emits structured citation objects natively. Pass them through to the span and you have linkage for free.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow do you detect when the model invents a citation marker for a chunk that was not retrieved?
Parse markers from the answer and try to resolve each against the retrieval set. Emit a 'hallucinated citation' counter on the span and alarm on its rate.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Logging only the answer text and the chunks separately, with no mapping from marker to id. You can see both lists but cannot tell which chunk grounded which claim.
60 second bullets to scan on the way to the call.
Three components: stable id, marker in answer, structured attribute
Content-addressed hashing for chunk ids
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.