DEV Community

dubleCC
dubleCC

Posted on • Originally published at heycc.cn

RAG Citations and Fallbacks: Grounding, Abstention, and the Feedback Loop in 2026

Originally published at heycc.cn. This is a mirrored copy — the canonical version is kept up to date at the source.

RAG Citations and Fallbacks: Grounding, Abstention, and the Feedback Loop in 2026

A retrieval-augmented generation (RAG) system that renders a footnote next to every sentence looks trustworthy. It often is not. Benchmarks that actually check the link between a claim and its cited source find that roughly 30% of individual statements can be unsupported by the context they cite, and about 25% of citations do not support the response at all — they are incorrect or unrelated. A blue superscript is a UI affordance, not evidence of grounding.

Turning that blue superscript into a verifiable contract takes three mechanisms working together: generating and scoring citations, making the system refuse to answer (abstention) when grounding is weak, and wiring user feedback back into the evaluation set so the loop closes. What follows assumes you already have a working RAG pipeline and now need it to be honest about what it knows.

Why citation rendering is not grounding

Free-form citation generation — letting the model write [1] wherever it feels appropriate — is exactly as prone to hallucination as the rest of the answer. The fix is to constrain citations at generation time. Use structured outputs or a context-free grammar so the model can only reference document IDs that retrieval actually returned. The model emits prose plus a separate citations array of IDs; it is never free to invent a source label.

A clean implementation is the anchor-tag pattern. Lightweight tags such as <c>2.1</c> (read as page.reading-order) are injected into chunk text, and the matching spatial metadata is stored separately as chunk metadata:

"citations": {
  "2.1": { "page": 23, "bbox": { "x1": 12, "y1": 15, "x2": 149, "y2": 328 } }
}
Enter fullscreen mode Exit fullscreen mode

The model is instructed to ignore the tags in its prose and only list the IDs it relied on. After generation you resolve each ID into a deep link or a highlighted bounding box on the source page. The user verifies a specific span, not a vague document reference — and recent sub-sentence attribution work (LAQuer, concise span-level citation) pushes this provenance below the sentence level so a reader can check one phrase.

Scoring citations: recall and precision

Rendering is step one. To know whether citations are good, evaluate them. The ALCE framework scores citation quality with two complementary NLI-based metrics:

  • Citation recall — does the concatenation of the cited documents entail the generated sentence? If the sentence makes a claim no cited source supports, recall drops.
  • Citation precision — is each cited document actually needed? Remove one citation at a time; if the remaining set still entails the claim, the removed citation added nothing and is penalized.

Together these catch the two failure modes that "looks cited" hides: under-citing (a claim with no real support) and over-citing (padding the footnote list with irrelevant documents to look thorough).

The ALCE paper's own numbers show how much these scores move with dataset difficulty and retrieval quality. On ASQA, ChatGPT with vanilla prompting scored 73.6 citation recall / 72.5 precision on 5 retrieved passages; adding a reranking step pushed that to 84.8 / 81.6. On ELI5 — a harder, more open-ended dataset — the same vanilla setup scored only 51.1 / 50.0, meaning roughly half of generated claims lacked full support from their cited passages, even from a strong model. The lesson generalizes past ALCE's specific benchmarks: citation quality is not a property of the model alone, it moves with how good your retrieval is, and a number reported on one dataset does not transfer to a harder one.

Two kinds of hallucination — and only one is fixed by retrieval

A common mistake is assuming RAG eliminates hallucination. It does not, because hallucinations split into two kinds that need different fixes:

Failure type Definition What it contradicts Primary fix
Factuality hallucination Claim is wrong about the world External reality Retrieval (RAG)
Faithfulness hallucination Claim is not supported by the context you gave The retrieved chunks Verification + tighter context

Retrieval addresses factuality by injecting real documents. It does nothing for faithfulness — the model can still drift from the chunks it was handed. So a faithfulness check against the retrieved chunks remains mandatory even in a fully retrieval-grounded system. This is the single most under-built part of most production RAG stacks.

Don't use cosine similarity as your faithfulness gate

The tempting shortcut is to threshold embedding similarity between the answer and the chunks. It does not work. On real ChatGPT hallucinations, the distributions of faithful and hallucinated answers overlap so heavily that catching 95% of hallucinations forces the threshold so low it flags every faithful response too. Embedding similarity measures topical relatedness, not entailment. Use a dedicated NLI/entailment check instead.

A concrete reference design is HALT-RAG, a post-hoc verification framework. It scores faithfulness with a calibrated dual-NLI ensemble (RoBERTa-large-mnli and DeBERTa-v3-large) plus lexical signals, then enables selective prediction: abstain on low-confidence cases. The published results are strong on both metrics that matter, and they're not the same number — don't conflate them. Without abstention, out-of-fold F1 runs around 0.98 on QA and 0.78 on summarization (HaluEval). With abstention turned on, precision on the answers it still chooses to emit climbs further — from 0.984 to 0.998 on QA, and from 0.712 to 0.798 on summarization, at roughly 89–91% coverage (see Provenance below for the exact figures). You give up a sliver of coverage and buy a large gain in how often the answers you do emit are correct.

Abstention as a first-class output

The right behavior when verification fails is not to soften the answer — it is to refuse. Make abstention an explicit output. Instruct the model to return something like "I don't have enough authoritative source data to answer this" when the conflict-detection or faithfulness step fires, and route low-confidence outputs to a human.

Two thresholds matter in practice:

  • Faithfulness/confidence gate for the answer itself (the HALT-RAG-style abstain band).
  • Intent-confidence gate for human handoff. In human-in-the-loop support systems, when the confidence score for an interpreted intent falls below a configured threshold — typically around 60% — the system triggers a fallback flow or escalates to a live agent rather than guessing (for the structured human-handoff payload, see our AI support bot guide).

Crucially, your abstention rate becomes an operational signal. A rising abstain rate is not a bug; it exposes missing knowledge, unclear policies, or mis-calibrated autonomy limits. Track it like a metric, segment it by topic, and feed the gaps to whoever owns the knowledge base.

The answer / abstain / escalate policy table

Faithfulness (NLI) Retrieval coverage Intent confidence Action
High Strong chunks found High Answer with resolved citations
High Strong chunks found Low Answer, but flag for human review
Low Chunks found Any Abstain: "not enough authoritative data"
Any No relevant chunks Any Abstain + log as knowledge gap
Any Conflicting chunks Any Surface conflict, escalate to human
Borderline (abstain band) Any Any Escalate to live agent

This is a policy you can encode directly in the orchestration layer. The key design choice is that "low confidence" has a defined destination — abstain or escalate — never a confidently-worded guess.

A subtle trap: how your evaluator scores "I don't know"

If you add abstention, you must also decide how your eval harness scores it — because evaluators disagree wildly. A controlled 30-query study found that on the same abstentions, an LLM-as-judge groundedness metric saturates near 1.0 (a refusal has "no unsupported claims," so it looks perfect), DeepEval flags comparatively higher hallucination, and RAGAS lands in between. If you don't define how a graceful "I don't know" is scored, your offline numbers will mislead you: a system that abstains usefully can look either flawless or broken depending on the harness. Pick a convention and document it.

Closing the loop with feedback

Offline metrics drift from reality. Production feedback closes the gap. Attach a "Was this helpful?" thumbs up/down to every answer plus an optional free-text "What was wrong?" field, and back it with a feedback taxonomy — tags like Outdated Information, Missing Context, Too Verbose, and Wrong Source. This taxonomy is where the gold is: a system reporting 95% retrieval accuracy but a 30% "Wrong Source" feedback rate has a problem the automated suite never caught.

Closing the loop means piping that feedback back into the evaluation pipeline:

  1. Low-faithfulness cases and user-corrected answers become new examples in the eval set.
  2. A dashboard shows automated RAGAS-style scores side-by-side with real user correction rates, surfacing exactly where offline metrics and real users disagree.
  3. Abstentions and knowledge-gap logs become a prioritized backlog for the knowledge-base owner.

Underpinning all of this is observability. Trace each pipeline step — retrieval, reranking, generation — as a structured span carrying chunk IDs, similarity scores, document versions, and latency. When a hallucinated answer or a missed retrieval shows up, you can debug it back to the specific chunk that was, or wasn't, surfaced. Without per-chunk tracing, "the answer was wrong" is unactionable.

Diagram of the RAG citation, abstention, and feedback-loop pipeline

A minimal implementation checklist

  • Constrain citation IDs to retrieved documents via structured output or a grammar — never free-form.
  • Store span metadata (page + bbox) separately; resolve IDs to highlights after generation.
  • Score citations with NLI-based recall and precision (ALCE-style), not just "is a number present."
  • Run an NLI faithfulness check against the chunks; do not use a cosine threshold as the gate.
  • Define an abstain band and an escalation threshold (intent confidence ~60% is a common starting point).
  • Decide and document how your evaluator scores abstentions.
  • Capture thumbs + tagged free-text feedback; promote corrected cases into the eval set.
  • Trace every step with chunk IDs and scores so any bad answer is debuggable to a chunk.

For the upstream half of this — defining the fixed regression questions and rubrics that your feedback corrections feed into — see our companion piece on RAG evaluation.

Provenance of the numbers in this piece

The HALT-RAG figures — the dual-NLI ensemble of RoBERTa-large-mnli and DeBERTa-v3-large, QA precision 0.984 → 0.998, summarization 0.712 → 0.798 at ~89–91% coverage — come straight from arXiv 2509.07475. The anchor-tag format <c>2.1</c> and the bbox {x1,y1,x2,y2} structure are the ones documented on the Tensorlake blog. The ALCE recall/precision definitions, like the ASQA/ELI5 recall-precision numbers (73.6/72.5 vanilla, 84.8/81.6 with reranking on ASQA; 51.1/50.0 on ELI5), are read directly from ALCE's own paper and results tables, arXiv 2305.14627; the ~30% unsupported-statement and ~25% unsupported-citation rates come from the Medium citation-generation analysis, which reports them from a study of GPT-4 with RAG on medical questions (arXiv 2402.02008). The feedback-taxonomy tags and the 95%-retrieval-accuracy-vs-30%-Wrong-Source example are from the RAG About It evaluation write-up. The ~60% intent-confidence handoff threshold is Zendesk's documented platform default for AI-agent intent confidence (see the eesel AI guide in Sources), not a fixed standard; it is the one knob here you should set against your own traffic rather than inherit.

Sources

Top comments (0)