Retriever Failure or Generator Failure?
Part VI โ Debugging Prompts, Retrieval, and Hallucinations
Same wrong refund answer, three different culprits
Chapter 3 previewed this triple in miniature; Chapter 32 staged the pipeline. Now the full attribution runs. The symptom is fixed: “Your refund was processed on September 2; reference RB-8814.” The corpus truth is fixed: ledger line “refund PENDING, no reference issued,” no RB-8814 anywhere. Three incidents in three weeks produced this identical sentence โ and each had a different first divergence.
Concrete failure. Incident A: the retrieval log has no ledger chunk. Incident B: the retrieval log has it, the sent context does not. Incident C: the sent context has it, the answer contradicts it. One symptom, three repairs โ and every team that “fixed” all three by tuning the prompt fixed none of them twice.
OBSERVATION: output string identical across A/B/C (contains “processed” + “RB-8814”); ledger line byte-absent from output’s support in all three; per-handoff artifacts differ (frozen below). HYPOTHESIS H1 (retrieval failure): ledger chunk absent from the retrieval log. H2 (assembly failure): present in retrieval log, absent from sent context. H3 (generation failure): present in sent context, contradicted in output. INFERENCE: none yet โ H1/H2/H3 predict mutually exclusive artifact diffs and are separable only by diffing all three artifacts on the pinned input.
This chapter’s question: which handoff boundary diverged first โ retrieval, assembly, or generation โ for this incident?
Why “the RAG is hallucinating” fails first
The obvious move โ labeling the symptom “hallucination” and constraining generation โ fails because the label erases the boundary. Five defects hide behind the single word:
- Boundary blindness. “Hallucination” describes the output, not the handoff. It prescribes the same repair (prompt constraints, lower temperature) for a chunk that was never retrieved and a chunk that was retrieved but truncated.
- Missing-artifact diagnosis. Without the retrieval log, H1 and H2 are indistinguishable; without the sent context, H2 and H3 are indistinguishable. Opinions fill the unlogged gaps.
- Score substitution. A relevance score of 0.91 on the ticket chunk is cited as “retrieval worked.” Scores do not show whether the ledger chunk crossed each boundary; only artifact diffs do.
- Self-report contamination. The model says “I retrieved the ledger and it confirms RB-8814” (Chapter 3’s rule applies at full force here). The sentence is behavior to quarantine, never a handoff record.
- Single-fix superstition. Raising top-k “fixed” incident B once (the truncated chunk happened to survive that run’s packing). The assembly truncation remains; the next long context re-breaks it.
OPINION: “hallucinating” is a symptom word wearing a diagnosis costume. Take it off. Diff the handoffs.
The retrieval-versus-generation split is not this book’s idea; it is standard RAG-evaluation practice. RAGAS scores a pipeline on context relevance (was the retrieved material on point?) and faithfulness (is each atomic claim in the answer grounded in that material?) as separate axes (Es et al., 2024). Those two axes are H1 and H3. This chapter’s contribution is the byte-level, per-incident version: RAGAS gives you a continuous fleet-wide signal; the three-artifact diff gives you a causal verdict for one incident.
The mental model: three-artifact attribution โ retrieval log vs. sent context vs. output, diffed in order, first divergence convicts. The book’s A/B/C triple is not three theories about models; it is three predictions about bytes at boundaries.
The method: freeze three artifacts, diff two boundaries
Pin the input bytes, corpus snapshot, prompt hashes (Chapters 30โ31), top-k and assembly budget, model identifier and parameters. Then:
- Freeze the retrieval log. Exact chunk IDs + content hashes + ranks returned for the pinned query. H1 predicts: ledger chunk hash
d4e2absent (rank > k or unreturned). - Freeze the sent context. Exact bytes assembled and sent to the model (post-truncation, post-template). H2 predicts:
d4e2present in (1) but byte-absent here, with the truncation record showing where it was cut. Chapter 20 established how evidence is lost at this boundary โ the length ledger, the cut simulation, the shorten/reorder/budget probes; there the job is to debug the context-window boundary itself. Here that same failure is one candidate location inside a larger question: which evidence boundary โ retrieval, assembly, or generation โ is responsible for the observed answer. Run Chapter 20’s forensics once this diff convicts assembly. - Freeze the output. Raw generation bytes. H3 predicts: ledger line byte-present in (2) yet output asserts “processed, RB-8814” โ direct contradiction on the pinned context.
- Diff in order and stop at the first divergence. Retrieval boundary first, then assembly, then generation. Distinct numeric predictions per hypothesis (counts, ranks, byte lengths) are written before diffing; the first failed prediction convicts its stage and suspends the rest for this incident.
flowchart TD
FZ["freeze the triple per incident: retrieval log, sent context, raw output โ all hashed"] --> R{"needed chunk (by hash) present in the retrieval log within top-k?"}
R -->|no| H1["H1 retrieval failure โ Ch32 stage repair + an abstention path for the miss"]
R -->|yes| A{"chunk bytes present in the sent context?"}
A -->|"no, cut before its offset"| H2["H2 assembly failure โ fix truncation accounting (run Ch20 forensics)"]
A -->|yes| G{"output contradicts the byte-present supporting line?"}
G -->|yes| H3["H3 generation failure โ is the supporting line itself correct?"]
H3 --> H3a["H3a: context correct, output contradicts it (confirmation-bias distractor)"]
H3 --> H3b["H3b: output follows an incorrect context โ really a retrieval / corpus failure"]
G -->|no| RE["all boundaries hold โ re-examine the 'supporting' line"]
TRIPLE ARTIFACT DIFF (input frozen; snapshot idx-2026-08-14; top-k=5; budget 8K tokens):
ledger chunk d4e2 ("refund PENDING, no reference issued"):
incident A: retrieval log ABSENT (rank 47/50, below k=5) | sent: absent | output: "processed RB-8814" -> H1
incident B: retrieval log PRESENT (rank 3/50) | sent: ABSENT (cut at 8,192 tokens; d4e2 at offset 9,104) | output: "processed RB-8814" -> H2
incident C: retrieval log PRESENT (rank 2/50) | sent: PRESENT (offset 1,204, intact) | output: "processed RB-8814" vs sent "PENDING, no reference" -> H3
RULE: presence is byte-presence (hash match), not topical resemblance. Resemblance is not retrieval.
OBSERVATION (constructed illustration, not a measured run): A shows rank 47/50 below cutoff; B shows retrieval rank 3 with assembly cut at 8,192 tokens against chunk offset 9,104; C shows the intact ledger line at sent-offset 1,204 contradicted verbatim in output. UPDATED BELIEF: H1 supported for incident A, H2 for B, H3 for C โ each for its instance only; the other two hypotheses rejected per incident, not universally. No cross-incident generality claimed.
No paraphrase similarity, confidence, agreement across re-asks, single green retry, or downstream symptom (“finance saw no complaint”) moves any of these verdicts. Only the byte diffs do.
Example: running the split test on the refund triple
One script, three incidents, pre-written numeric predictions:
# retriever-vs-generator split test: artifact diffs (no model re-asks yet)
for incident in (A, B, C):
rlog = load_retrieval_log(incident) # OBSERVATION: chunk IDs + hashes + ranks
sent = load_sent_context(incident) # OBSERVATION: exact bytes, hash c55e etc.
out = load_output(incident) # OBSERVATION: raw generation bytes
# H1 predicts: hash d4e2 not in rlog. H2 predicts: d4e2 in rlog, not in sent
# (with truncation offset < chunk offset). H3 predicts: ledger line in sent,
# contradicted in out. Record per-boundary PRESENT/ABSENT by hash, not topic.
log(incident, present(rlog, "d4e2"), present(sent, LEDGER_LINE), contradicts(out, LEDGER_LINE))
# Discriminating intervention per verdict (one boundary each):
# H1 -> raise top-k / reshape query, re-run pinned input x3. H2 -> fix truncation
# accounting, re-run x3. H3 -> constrain generation to context, re-run x3.
# Each predicts recovery ONLY on its incident; cross-incident recovery is exoneration failure.
In the constructed triple the interventions behave discriminantly: top-k=5โ20 recovers A across three trials but leaves B’s truncation and C’s contradiction intact; truncation accounting recovers B only; context-constraining recovers C only. That discriminant pattern is the proof the attribution was correct โ a repair that “fixes everything” on the first try is evidence of confounding, not mastery.
Research lineage: H3 is a knowledge conflict, and H1 is a rejection failure
When the context says “PENDING” and the answer says “processed,” that is a context-memory conflict. Xie and colleagues studied how models behave when retrieved evidence contradicts their parametric knowledge and found two things at once: models can be swayed by coherent external evidence, but they show a strong confirmation bias โ when the context also contains something that agrees with the model’s prior (here, ticket chatter mentioning a completed refund), the model leans on that and discounts the conflicting ledger line (Xie et al., 2024). That is one of two modes. Wu and colleagues’ ClashEval measured the tug-of-war directly and found the dominant failure runs the other way: models override their own correct prior and adopt incorrect retrieved content more than 60% of the time โ the more so when the model was unconfident in its own answer to begin with, and the less so when the false content is blatantly unrealistic (Wu et al., 2024; corroborated by Huang et al., 2025). So an H3 verdict splits: H3a, the output contradicts a correct context (Xie’s case โ it needs a co-present prior-matching distractor, which is why the Chapter 32 finding about distractor cost matters here); H3b, the output faithfully follows an incorrect context. Before routing an H3 verdict to generation repair, confirm the byte-present supporting line is actually right โ an H3b is a retrieval or corpus failure wearing a generation costume.
Incident A is a negative-rejection failure. When nothing relevant was retrieved, the correct behavior is to abstain โ “I don’t have a record of that refund.” Benchmarks of RAG behavior measure exactly this negative rejection capacity, and models frequently fail it, generating a confident answer from parametric priors instead (Chen et al., 2024). So the H1 repair is two-part: fix retrieval (Chapter 32), and add an abstention path so the next retrieval miss produces “no record found” rather than an invented reference.
Second artifact: the incident-pairing rule
Identical outputs tempt incident-merging (“same RB-8814 bug again โ apply last week’s fix”). The pairing rule forbids merging without a fresh triple, and it pays for itself the first time two identical sentences diverge:
- Every incident gets its own triple, even carbon copies. Retrieval log, sent context, output โ frozen and hashed per incident. Reuse of a prior incident’s artifacts as this incident’s evidence is contamination, not efficiency.
- Compare triples before comparing outputs. Two incidents pair (same repair applies) only when their per-boundary PRESENT/ABSENT patterns match. Same output + different pattern = different incident wearing the same sentence.
- Track the pairing ledger.
INC-118 (H2, cut 8,192) pairs with INC-121 (H2, cut 8,192) โ shared truncation repair confirmed 3/3 both.When a third identical output arrives with an H1 pattern, the ledger shows exactly why the shared repair must not auto-apply. - Expire pairings on config change. Any change to top-k, budget, prompt hash, or snapshot version voids open pairings; the next incident re-attributes from scratch. Config drift silently re-sorts which boundary breaks first โ OBSERVATION from re-runs after budget changes, not assumption.
PAIRING LEDGER (constructed illustration):
INC-114: H1 (rank 47>k5) | INC-115: H2 (cut 8,192 vs off 9,104) | INC-116: H3 (sent intact, contradicted)
INC-117 (same sentence): triple matches INC-115 pattern -> paired, truncation repair, 3/3
INC-118 (same sentence): triple matches INC-114 pattern -> NOT paired with 115/117; cutoff repair
RULE: sentences don't pair. Triples pair.
OBSERVATION (constructed illustration): pairing INC-117 with INC-115 by triple (not sentence) ships the right repair first try; sentence-pairing would have applied the H1 cutoff fix and left truncation intact. UPDATED BELIEF: triple-pairing supported as routing discipline for this pipeline-instance; no claim about incident frequencies. Routing correct is not cause explained.
Lab 33: three-artifact split test with discriminant predictions (proposed)
PROPOSED, not executed: no author-measured results are reported. The evidence this chapter requires is the reader’s own frozen triple.
Setup. Take one wrong RAG answer where the supporting source line is byte-known. Pin the input, snapshot, prompt hashes, top-k, assembly budget, and model parameters. Freeze all three artifacts before reading any model self-explanation. The boundary is the independent variable; input, snapshot, and config are controlled.
Task.
- Before diffing, write H1/H2/H3 with distinct numeric predictions: H1: “ledger hash absent from retrieval log (rank ___ > k=___)”; H2: “present in log at rank ___, absent from sent context (cut at ___ tokens vs. offset ___)”; H3: “present in sent context at offset ___, contradicted in output (quote both).”
- Diff in order, โฅ3 trials for any stochastic step (re-query for rank stability). Record OBSERVATION (hashes, ranks, offsets verbatim) and UPDATED BELIEF per hypothesis.
- Apply the single-boundary repair and predict discriminant recovery: it must fix this incident and need not fix others.
| Boundary | Predicted artifact pattern | FORECAST | OBSERVATION (ร3 where stochastic) | UPDATED BELIEF |
|---|---|---|---|---|
| retrieval (H1) | log ABSENT, rank ___>k | ___ | ___ ___ ___ | H1 live/exonerated |
| assembly (H2) | log PRESENT, sent ABSENT (cut ___) | ___ | ___ | H2 live/exonerated |
| generation (H3) | sent PRESENT, output contradicts | ___ | ___ ___ ___ | H3 live/exonerated |
Success criterion. A frozen triple with per-boundary PRESENT/ABSENT by hash plus a single-boundary repair that recovers the pinned input โฅ3/3. A “hallucination fix” with no triple is explicitly not completion.
Companion tool: Retriever-vs-Generator Split Test
What it accepts: the pinned input, corpus snapshot, the byte-known supporting line, the three frozen artifacts (retrieval log, sent context, raw output) with hashes, and the rank/cutoff/offset configuration. What it performs: it diffs the two boundaries in order by hash (not topic), checks truncation records against chunk offsets, flags output-vs-context contradiction verbatim, and requires the discriminant-repair prediction before any fix ships. What it can establish: which boundary diverged first for the examined incident โ retrieval, assembly, or generation. What it cannot establish: corpus quality in general, generator reliability in general, or cross-incident causes. It never treats scores, confidence, agreement, single-run outcomes, model self-reports, or downstream symptoms as attribution evidence. How its output changes your next action: H1 routes to Chapter 32 stage repair (cutoff, query shaping, filters); H2 routes to assembly repair (budget accounting, ordering, truncation guards); H3 routes to generation repair (context grounding, claim constraints โ Chapter 34); all-present-and-consistent routes to re-examining the “supporting” line itself.
Paper form, sufficient for this chapter:
Input hash: ___ Supporting line hash: ___ (d4e2)
Retrieval log: PRESENT/ABSENT (rank ___/___ vs k=___)
Sent context: PRESENT/ABSENT (offset ___ vs cut ___) Output: SUPPORTS/CONTRADICTS (quote ___)
FIRST DIVERGENCE: retrieval / assembly / generation REPAIR (one boundary): ___
Re-run x3: ___ ___ ___ NEXT: ___
Where a software implementation does not yet exist in the reader’s stack, this record is the tool. Three artifacts or no attribution.
Reusable procedure: attribute every wrong RAG answer
- Freeze the triple โ retrieval log, sent context, output, all hashed, before explanations.
- Predict numerically โ ranks, cutoffs, offsets per hypothesis, written first.
- Diff in order โ retrieval boundary, then assembly, then generation; stop at the first divergence.
- Repair one boundary โ single-handoff fix, pinned input re-run โฅ3 times.
- Demand discriminant recovery โ the fix should track its boundary, not everything.
Failure modes
- Label-and-constrain. Calling everything hallucination and tightening generation. Repairs B with C’s medicine.
- Log-free attribution. Verdicts without one or more artifacts. Gaps filled by self-report are contamination (Chapter 3 rule).
- Topic-matching. “The ticket chunk is about refunds, so retrieval worked.” Support is byte-presence of the needed line, not topical nearness.
- Score conviction. Citing similarity or faithfulness numbers as the verdict. Numbers locate; diffs convict.
- Pan-repair. Changing top-k, budget, and prompt together. Three boundaries moved, zero learned.
- Cross-incident generalization. “Incident A was retrieval, so this identical sentence is retrieval.” Same output, different break โ diff every incident.
- Merged incidents. Pooling two “same-sentence” cases into one repair ticket. Merged evidence is contaminated evidence; pair by triple, work per incident.
- Boundary-blind metrics. Tracking “RAG accuracy” as one number across H1/H2/H3 causes. A rising average can hide a worsening boundary โ report recovery per boundary.
Limits, per contract: one split test covers one incident under one snapshot and config; it does not certify any stage, does not transfer to the next identical-looking answer, and stays UNKNOWN where any artifact is unlogged.
References
- Shahul Es, Jithin James, Luis Espinosa-Anke, and Steven Schockaert. RAGAS: Automated Evaluation of Retrieval Augmented Generation. Proceedings of EACL: System Demonstrations, 2024, pp. 150โ158. https://aclanthology.org/2024.eacl-demo.16/
- Jian Xie, Kai Zhang, Jiangjie Chen, Renze Lou, and Yu Su. Adaptive Chameleon or Stubborn Sloth: Revealing the Behavior of Large Language Models in Knowledge Conflicts. International Conference on Learning Representations (ICLR), 2024. https://arxiv.org/abs/2305.13300
- Jiawei Chen, Hongyu Lin, Xianpei Han, and Le Sun. Benchmarking Large Language Models in Retrieval-Augmented Generation. Proceedings of the AAAI Conference on Artificial Intelligence, 2024. https://arxiv.org/abs/2309.01431
- Kevin Wu, Eric Wu, and James Zou. ClashEval: Quantifying the Tug-of-War Between an LLM’s Internal Prior and External Evidence. arXiv:2404.10198, 2024. https://arxiv.org/abs/2404.10198
- Yukun Huang, Sanxing Chen, Hongyi Cai, and Bhuwan Dhingra. To Trust or Not to Trust? Enhancing Large Language Models’ Situated Faithfulness to External Contexts. International Conference on Learning Representations (ICLR), 2025 (arXiv:2410.14675). https://arxiv.org/abs/2410.14675
Debugging Checklist
- Input, snapshot, prompt hashes, top-k, budget, model params pinned?
- All three artifacts frozen with hashes before explanations read?
- H1/H2/H3 numeric predictions pre-written (ranks, cutoffs, offsets)?
- Boundaries diffed in order by hash (not topic)?
- Model self-report quarantined (never cited as handoff evidence)?
- H1 repair includes an abstention path (retrieval miss โ “no record found”, not invention)?
- H3 sub-mode identified (H3a contradicts a correct context vs H3b follows an incorrect context) โ supporting line’s factual correctness confirmed before generation repair?
- H3a repair accounts for partially-matching distractors in context (confirmation bias)?
- Single-boundary repair re-run โฅ3 times with discriminant prediction?
- Fresh triple frozen per incident (no artifact reuse across incidents)?
- Pairing decided by triple-pattern match (not sentence identity)?
- No scores, confidence, agreement, single runs, or symptoms cited as verdict?
What This Chapter Established
- The full A/B/C attribution: retrieval vs. assembly vs. generation separated by ordered byte-diffs, demonstrated on the constructed refund/RB-8814 triple (rank 47, cut at 8,192 vs. offset 9,104, sent-offset 1,204 contradicted), no measured runs claimed.
- The discriminant-repair criterion: a correct attribution predicts boundary-specific recovery.
- Lab 33 as a proposed triple-diff record the reader executes; the Retriever-vs-Generator Split Test contract (accepts/performs/can-establish/cannot-establish/next-action).
- The incident-pairing rule as the routing discipline: triples pair, sentences do not; pairings expire on config change.
- What was NOT proved: any retriever or generator quality claim, any cross-incident generality, or any certification of the pipeline. Three incidents attributed; nothing universal.
- Research grounding: the retrieval-vs-generation split is standard RAG evaluation (RAGAS context relevance โ H1, faithfulness โ H3); H3 is a context-memory conflict with two modes โ H3a, contradicting a correct context under a partially-matching distractor (confirmation bias โ Xie et al.), and H3b, faithfully following an incorrect context (the dominant mode: models override a correct prior with wrong retrieved content >60% of the time, most when unconfident โ ClashEval, Wu et al.; Huang et al.) โ so an H3 verdict is followed by checking whether the context was actually right; incident A is a negative-rejection failure โ the H1 repair needs an abstention path, not just better retrieval (Chen et al.).
- Position in the arc: Chapter 3’s miniature now run at full depth. Boundaries settled per incident; generation-contradiction cases (H3) open the next question.
Next
Attribution tells you the contradiction happened at generation. It does not give you a method for dissecting a multi-claim answer into checkable pieces โ generation failures arrive as paragraphs, not single lines. Chapter 34, “Debugging Hallucinations,” operationalizes claim-by-claim verification; which claims the evidence supports is its chapter’s to establish, not this one’s.