ServicesWorkAboutBlog Contact Start a project

Retrieval ·

Why your RAG system gives wrong answers, in order of likelihood

Nearly every wrong answer is a retrieval failure wearing a generation costume. Work the list in order and you will spend your effort where the defects are.


Nearly every wrong answer from a retrieval system is a retrieval failure wearing a generation costume. Work the causes in order — content missing from the corpus, chunking that severed the answer, ranking that buried it, filters that excluded it, context assembly that dropped it, extraction that ignored it, source documents that are simply wrong — and only then consider the model. The taxonomy in Seven Failure Points When Engineering a Retrieval Augmented Generation System (Barnett et al., arXiv 2401.05856, January 2024; IEEE/ACM CAIN 2024) maps closely onto what we find in client systems. The ordering below is ours, from running the triage repeatedly.

First: is the answer in the corpus at all

Before anything else, check whether the text that answers the question exists in the ingested data. Barnett et al. call this missing content, and it is the most common single cause we find, because ingestion fails quietly.

Ingestion pipelines drop things without complaining. A PDF extractor returns empty strings for scanned pages and the job reports success. A file type nobody handled is skipped by a glob pattern. An access filter excluded a whole folder. A crawl hit a rate limit on the third of five sources and moved on. In every case the index looks healthy and the answer was never there.

The diagnostic is direct: search the raw ingested text — not the vector store, the raw text — for a distinctive phrase from the document that should hold the answer. If it is absent, stop. Nothing downstream recovers content that was never indexed. Make the check permanent: record document, page, character and failure counts per source on every run and alert on a change. Inherited corpora almost always contain a source that stopped updating months earlier.

  • Search raw extracted text first, not the index
  • Log per-source document, page, character and failure counts on every run
  • Alert on a drop, not only on an error — silent partial success is the normal failure mode

Second: chunking severed the answer from what makes it meaningful

The passage exists but the chunk containing it is unusable, because fixed-size splitting cut a table away from its header, a clause away from its defined terms, or a figure away from the sentence stating its units.

This cause rewards a few minutes of manual reading. Retrieve the chunk that ought to answer the question and read it cold, as the model sees it, with no surrounding document. If you cannot answer from that text alone, neither can the model, and the problem is upstream of everything else.

The patterns are consistent across domains. Tables lose their header row and become columns of numbers with no labels. Policy documents put the qualifying condition in a heading three levels up. Contracts refer to terms defined earlier. Rate cards attach a footnote that changes the row above it. Fixed-size splitting destroys all four.

What works is parsing structure before splitting: tables intact with their headers, splits on document semantics rather than character counts, each chunk prefixed with its heading path so it is self-describing. Parent-child retrieval helps — match on the small chunk, return the parent.

  • Read the retrieved chunk cold; if a human cannot answer from it, fix chunking first
  • Prefix each chunk with its heading path
  • Keep tables whole, with their headers
  • Match on the small chunk, hand the model the parent

Third: the right passage was retrieved but not ranked high enough

The answer is in the index and in the candidate set, and it sits at rank 23 while you take the top five. Barnett et al. list this separately from missing content, because the fixes are entirely different.

The diagnostic that separates them is recall at two depths. Compute recall at five and recall at fifty over questions with known answer passages. If recall at fifty is high and recall at five is poor, retrieval works and ranking does not — add a reranker and most of the problem disappears. If recall at fifty is also poor, the embedding or the query is the issue and a reranker will not save you.

The usual cause is vocabulary mismatch. The user asks about a cancellation charge; the document says pre-closure fee. Dense embeddings handle paraphrase well and handle acronyms, product codes and company jargon badly, because those tokens carry meaning only inside your organisation. Hybrid retrieval fixes much of it: lexical search alongside dense search, fused, then reranked with a cross-encoder. Query rewriting helps where phrasing is short or pronoun-laden, which in a chat interface is most of the time.

Fourth: a filter excluded it, or there was no filter and should have been

Metadata is where the two opposite failures live. Either a filter quietly excluded the right document, or no filter existed and the index returned last year's version of a policy that has since changed.

Twelve near-identical revisions of one procedure are hard for any similarity search: they are all similar to the query and to each other. Without an effective-date field the ranking between them is arbitrary, and arbitrary means wrong roughly eleven times out of twelve. Deduplicate at ingestion, carry an effective date, filter on it before the vector search runs.

The opposite failure is a filter applied too aggressively. Access control is the usual culprit: a service account cannot see the folder the answer lives in, so the system reports that the policy does not cover this case — a correct-looking refusal that is really a permissions bug. Log which filters ran and how many candidates each removed.

Filters are also how tenancy should be enforced in a multi-customer system. A rule in the system prompt telling the model not to discuss other customers is a request; a metadata filter that prevents the passage entering the context is a constraint. That distinction has a regulatory dimension, covered in what the DPDP Act actually requires of an AI system.

  • Effective-date and version metadata, filtered before vector search
  • Deduplication at ingestion so near-identical revisions do not compete
  • Log filter hit counts; a filter removing almost everything is a bug
  • Enforce tenancy at the filter, never in the prompt

Fifth: it reached the shortlist and never reached the model

Context assembly is a stage most teams do not think of as a stage. Barnett et al. name it: documents that contained the answer did not make it into the context used for generation, because of how the retrieved set was consolidated.

Three mechanisms account for most of it. Truncation, where the assembled context exceeded a limit and the tail that held the answer was cut. Compression or deduplication steps that discarded the passage as redundant. And position effects: Liu et al., in Lost in the Middle (Transactions of the ACL, volume 12, 2024), found performance is highest when the relevant information sits at the beginning or the end of the input and degrades significantly in the middle of a long context.

The consequence is direct. Stuffing forty chunks into a long window is not a substitute for ranking. Rerank a shortlist, pass fewer and better passages, position them deliberately. Log the final assembled context, not only the retrieved set — the two diverge more often than teams expect, invisibly unless you record both.

Sixth: the answer was in the context and the model did not use it

This is the first cause where the model is genuinely implicated, and even here the usual culprit is what surrounds the answer rather than the model's capability.

Barnett et al. attribute extraction failures to noise or contradictory information in the context. Contradiction is the case worth dwelling on. If the retrieved set holds both the current rate and last year's rate, the model has no principled way to choose, and will often produce something that is neither. That is a retrieval problem presenting as a generation problem, and it is why the effective-date filter earns its keep.

The rest is prompt design. An instruction to be concise causes omission from a long context. An instruction to always answer removes the option of refusal, and a system that must answer will invent. Ask for span-level citations and check them: a sentence citing a passage that does not support it is a measurable defect, gateable in continuous integration. The paper also separates out wrong format, answers too specific or too general, and answers incomplete despite the information being present — all three respond to prompt and schema work rather than a larger model.

Seventh: the source document is wrong, and the system is working

Retrieval found the right passage, the model quoted it accurately, and the answer is still wrong, because the document says something that is no longer true. This is a data governance failure that will be reported to you as an AI failure.

It is common with internal documentation nobody owns. A wiki page written four years ago by someone who has left; a policy PDF superseded by an email; a rate table a department maintains privately. Retrieval systems surface all of it, because they read everything and remember none of the organisational context that told humans which document to trust.

The only durable fix is ownership: a named owner and a review date per source, with content past its review date refreshed or removed. When a wrong answer traces to a stale source, report it to the owner as a document defect rather than a model bug, and the incentive lands in the right place.

Easy to miss: some questions are not retrieval questions. How many contracts expire next quarter, what the exposure to a counterparty is, which customers hold both products — these are aggregation queries over structured data, and similarity search over chunks cannot answer them reliably. Route them to a query engine and let retrieval decline. That routing is data engineering work more than model work.

Only now, the model

Model capability is a real cause of wrong answers and it belongs at the bottom, because upgrading it is the most expensive intervention and the one most likely to leave the actual defect untouched.

By this point you should have evidence: the answer is in the corpus, it survives chunking, it ranks in the top few, no filter excluded it, it is in the assembled context, nothing contradicts it, and the source is current. If it is still wrong, a stronger model may help, and now you can measure whether it did.

Run the triage as a batch. Take fifty wrong answers and for each one answer three questions: is it in the corpus, is it in the retrieved set, is it in the final context. Three yes-or-no columns split fifty failures into buckets in an afternoon, and the distribution tells you where the next month should go. Teams skip this and spend that month on the wrong layer.

Barnett et al. conclude that validation of a retrieval system is only feasible during operation, and that robustness evolves rather than being designed in at the start. That is not an argument against pre-production testing but for building measurement into the system, so the evolution is directed — the subject of how to evaluate a RAG system before you trust it in production.

  • Is the answer anywhere in the ingested corpus
  • Is it in the retrieved candidate set
  • Is it in the final assembled context

Sources

Every regulatory or measured claim above is attributed here. Where we could not find a source we trust, the sentence says so instead of guessing.

Questions people ask about this

Our answers got worse after we upgraded the embedding model. Why?

Almost certainly because the index was not rebuilt, so queries are embedded with the new model and documents with the old one. The two vector spaces are not comparable and similarity scores become meaningless while still looking plausible. Treat a re-embed as a versioned deployment, and keep the old index until the new one has been evaluated.

Would a larger context window remove the need for good retrieval?

No. Liu et al. found that performance depends significantly on where the relevant information sits within a long context, with the middle handled worst. Longer windows let you be lazier about how much you retrieve, not about how well you rank, and they cost more per query for the privilege.

How do we stop the system answering when it does not know?

Give it an explicit refusal path and make refusal a scored outcome rather than a failure. Check groundedness after generation: match each claim back to the span it cites, and if support falls below a threshold, refuse or escalate. A compliance team will take a refusal over an invented clause every time, provided the refusal rate is monitored.

How many wrong answers do we need before this triage is worth running?

Fifty is enough to see the shape of the distribution, and you can usually collect fifty from a week of logs. The point is not statistical precision. It is finding out whether your failures are ninety per cent retrieval or fifty-fifty, because those two situations call for entirely different work.

Send us fifty answers your system got wrong

That is enough to tell you where the defect actually is. The scoping call is free and you will get the triage back whether or not you hire us to fix it.

Start a conversation See our work