Book a consult
Services

Production SI, engineered end to end, six eval-gated service lines.

Visit Services →
Solutions

The same playbook, tuned to the constraints of the sectors we ship into most.

Visit Solutions →
Live Projects

Proof, not promises, selected case studies and recognition.

Visit Live Projects →
How we work

A transparent, 3-phase playbook from first audit to embedded team.

Visit How we work →
Studio

The senior team behind the work, and how to reach us.

Visit Studio →
octalcode
Services
Solutions
Live Projects
How we work
Studio
● OCTALCODE · INFINITE SOLUTIONS · ONE AGENCYBook a consult ↗

Design · 6 min · November 11, 2026

RAG Citations UI: How to Show Sources in a RAG Chatbot

Sources are how users check a RAG answer. How to choose between inline markers and a sources panel, group chunks by document, deep-link to the passage, respect permissions and stream citations cleanly.

OCTALCODE JOURNALINLINE MARKERSOURCES PANELUSER CAN OPEN ITShow whereanswers come from.

A RAG system answers from your documents, and the sources under each answer are the user's only practical way to check it. Get them right and people verify the answers that matter and trust the rest. Get them wrong and the citations do active harm: a confident answer with a footnote pointing at the wrong page looks more reliable than it is.

This guide covers the design decisions behind showing sources, and the engineering each one depends on. It assumes retrieval already works; if it does not, start there, because no interface can cite a passage that was never retrieved.

What is a citation in a RAG answer actually for?

Citations do three jobs, in order of importance. First, they let a user check one specific claim without rereading the whole document. Second, they let a user read further around a passage. Third, they show the scope of what was searched, which tells the user what the answer could not have known. Design for the first job. A tidy list of documents at the bottom does the second and third, but leaves the user guessing which sentence came from where.

How should I show sources in a RAG chatbot?

Attach a small numbered marker to each sentence that relies on a retrieved passage, and list the documents in a sources panel below the answer. Group chunks from the same document under one entry, show the exact cited passage, and link to the page or section it came from. Check the user's permission to open every source before displaying it, including its title. If no passage supports a claim, show no marker at all, because a wrong citation misleads more than a missing one.

Inline markers or a sources panel?

Most products need both, doing different work. Inline markers (small numbers or chips after a sentence) connect a claim to its evidence. A sources panel under or beside the answer lists the documents, so users can scan what was used and open any of them.

  • Place markers at the end of the sentence or clause they support, not at the end of the paragraph. A marker that covers four sentences proves none of them.
  • Number by document, not by chunk, so the same document keeps the same number throughout the answer.
  • On hover or tap, show the cited passage in a small popover or bottom sheet, with a link to open the source. Users should not have to leave the conversation to check a claim.
  • Keep markers keyboard reachable and give them accessible names that include the document title, not just "1".
  • For very short answers drawn from one document, a single source line under the answer can replace inline markers without losing anything.

Why group chunks by document?

Retrieval works on chunks, but users think in documents. If five chunks from the same employee handbook reach the model, showing five separate sources makes the answer look better supported than it is and buries the one source that came from somewhere else. Group chunks under their parent document, list each cited passage beneath it, and deduplicate by a stable document ID plus version, not by file name, since two different policies can share a name.

Grouping also exposes a retrieval problem worth fixing: when one long document dominates every answer, your ranking may be favouring it for the wrong reasons. Our guide to hybrid search and reranking in RAG covers how the passages that reach the model, and so the ones that can be cited, are chosen.

How should snippets and deep links work?

The most useful thing a citation can show is the exact passage it relies on. Some provider APIs return this directly. Anthropic's citations feature, for example, returns the cited text along with a location: a character range for plain text, a page range for PDFs (1-indexed, with an exclusive end page), or a content block range for custom documents. OpenAI's file search attaches file citation annotations to the output text, with the file ID and file name. Whatever your stack, keep the passage and its location, not just the document ID.

Then link as close to the passage as the format allows:

  • PDFs: RFC 8118 describes a page=N fragment for PDF links, so a link can open on the cited page. It is an informational RFC and viewer support varies, so test it in the viewers your users actually have.
  • Web pages and HTML documents: text fragments (#:~:text=) can scroll to and highlight the cited words. MDN notes that browsers without support simply ignore the fragment and open the page at the top, so it degrades safely. They only work on user-initiated navigation.
  • Internal systems (wikis, ticketing, document stores): link to the section or record ID if the system supports it, and record that anchor at ingestion time, when the structure is still known.
  • Versioned documents: link to the version that was cited. If the source has since changed, say so next to the citation.

How do permissions affect citations?

The rule is simple: never show a source the user cannot open. That includes the title, because titles leak too. A citation reading "Restructuring plan, draft 3" discloses something even if the link returns an access error.

The first line of defence is filtering at retrieval, so restricted documents never reach the model for that user; our guide to per-user access control in RAG covers how. The citation layer needs its own check as well, because permissions change after documents are indexed and conversations outlive the moment they were created.

  • Re-check access when citations are rendered, not only when the answer was generated.
  • When a conversation is shared, check each source against the viewer, not the original asker. If the viewer cannot see a source, the answer itself may need to be hidden too, since it was built from that source.
  • Do not cache rendered source panels across users.
  • If a source has been deleted, show that it is no longer available rather than a broken link.

When is no marker better than a wrong one?

A citation is a promise that the passage supports the sentence. Breaking that promise once teaches users to stop checking. So set a firm rule: a sentence gets a marker only when a retrieved passage actually supports it.

Be precise about what your tooling guarantees. Anthropic's documentation says its parsed citations are guaranteed to contain valid pointers to the provided documents. That means the cited passage really exists in the document; it does not mean the passage proves the sentence it is attached to. Whether the support is real is something you measure.

  • Sentences that are connective or general ("Here is a summary of the policy") need no marker. Do not decorate them to look thorough.
  • Never attach the nearest chunk to fill a gap. If the model made a claim no passage supports, treat it as a quality problem, not a citation problem.
  • If retrieval found nothing relevant, say that plainly instead of answering with weak sources. Our guide on what an SI assistant should say when it does not know covers the wording.
  • Add citation checks to your evaluation set: does each cited passage support its sentence, and are supported claims cited? The approach in RAG evaluation metrics extends naturally to this.

How do citations work when the answer streams?

Streaming adds a timing problem: text and citations arrive separately. In Anthropic's streaming API, citations arrive as their own delta events, each adding one citation to the current text block. OpenAI's Responses API emits a separate event when an annotation is added to output text. Either way, the marker arrives after, or between, pieces of the sentence it belongs to.

  • Reserve space for markers, or attach them when the sentence completes, so text does not jump sideways as numbers appear.
  • Assign document numbers in order of first appearance and never renumber mid-stream. A marker that changes from 2 to 3 while someone is reading destroys trust in all of them.
  • Fill the sources panel as documents are first cited, but mark it as final only when the stream completes.
  • Load passage previews when the user opens a marker, not during the stream, to keep the answer rendering smoothly.
  • If a stream is stopped or fails, keep the citations already received and label the answer as incomplete.

A short checklist before launch

  1. Every marker points to a passage that supports its sentence, checked in your evaluation set.
  2. Chunks are grouped by document, with stable numbering.
  3. Each citation shows the passage and links as close to it as the format allows.
  4. Access is checked at render time, including titles and shared conversations.
  5. Unsupported claims have no marker, and "nothing found" has its own message.
  6. Streaming never reorders or renumbers citations.
A missing citation costs the user a search. A wrong one costs you their trust.

Where Octalcode fits

Octalcode builds RAG systems and the interfaces around them, from a studio in Lahore with a US presence in Austin. Citations sit exactly where those two meet: the interface can only be as honest as the retrieval and evaluation behind it.

If your RAG product answers well but users still do not trust it, our SI-augmented design work reviews how sources are shown, checked and permissioned, and gives you a written list of changes in priority order.

Available for new engagements

Have a production SI problem to solve?

30 minutes, one of our seniors, no slide deck. By the end of the call you will know whether we are the right team, and if not, who is.

Or call +1 (512) 710-5701

Let's scope it.Instant answers · free project scoping