Almost every RAG failure is a retrieval failure
When a RAG system answers badly, the instinct is to blame the model and start
rewriting prompts. In our experience that is the wrong place to look roughly nine
times out of ten. The model usually did its job faithfully — it summarised the
passages it was given. The passages were simply the wrong ones.
This matters because it changes where the engineering effort goes. Prompt
iteration produces small, unstable gains. Fixing retrieval — better chunking,
adding keyword search alongside vectors, reranking a wider candidate pool,
filtering on metadata — produces large and durable ones.
It also explains why so many teams plateau. They have built a single-stage vector
search, they are measuring only end-to-end answer quality, and so they cannot see
that their recall at k is 60%. No amount of prompt work recovers information that
was never retrieved.
Measure the two stages separately
The most valuable instrumentation you can add is a retrieval metric that is
independent of the answer. For a labelled set of questions, each with the
passages that genuinely contain the answer, you can compute:
- Recall at k — how often the correct passage appears in the top k results.
If this is low, nothing downstream can save the answer.
- Precision at k — how much of what you retrieved is actually relevant.
Low precision means you are paying for tokens that dilute the context.
- Grounding rate — what share of sentences in the final answer are supported
by retrieved text.
- Refusal accuracy — how often the system correctly declines when the corpus
does not cover the question.
With those four numbers, a quality change becomes diagnosable. Without them,
every discussion about accuracy is someone’s impression from six sample queries.
Why hybrid search is the default, not an optimisation
Dense vector search is good at meaning and bad at exact strings. That is not a
tuning problem; it is what embeddings are. Ask for “contract AC-8871” and a vector
index will happily return semantically similar contracts while missing the exact
one, because the identifier carries almost no semantic signal.
Real users do both kinds of query constantly — conceptual questions and precise
lookups — often in the same session. So the reliable architecture is:
- Retrieve a wide candidate set using both BM25 keyword search and vector
search, fused with tuned weighting.
- Rerank that candidate set with a cross-encoder, which reads query and
passage together and orders them far more accurately than either retriever.
- Pass only the top few passages to the expensive generation model.
Step three is where the cost savings come from. Retrieving broadly and reranking
cheaply, then generating narrowly, gives better accuracy than dumping twenty
passages into a frontier model’s context — and costs a fraction as much.
Chunking decides more than the vector database does
Teams spend weeks comparing vector databases and an afternoon on chunking. The
weighting should be reversed. Any competent vector store will serve a mid-size
corpus adequately; a bad chunking strategy caps your accuracy regardless of what
is underneath.
The failure mode is splitting on a fixed token count. It cuts tables in half,
separates a clause from the heading that scopes it, and produces passages that are
meaningless out of context. What works better:
- Split on document structure — sections, headings, list boundaries, table rows.
- Keep the parent context with the child chunk, so a retrieved paragraph arrives
with the heading it sat under.
- Extract tables separately and preserve their structure rather than flattening
them into prose.
- Attach metadata — source, date, version, owning team, jurisdiction — so
retrieval can filter before it ranks.
Refusal is a feature, and it has to be measured
A system that always produces an answer is a system that invents one when the
corpus is silent. For any use case where the answer has consequences, “this is not
covered in the documents I have access to” is the correct output, and it needs to
be treated as a scored behaviour in the evaluation set rather than as an
embarrassing edge case.
This is usually the point where a compliance or clinical reviewer decides whether
to approve the tool. A system that cites its sources and admits its gaps is
auditable. One that answers everything fluently is not, no matter how high its
average accuracy looks.