Why Your RAG System Doesn't Need a Better LLM—It Needs Better Retrieval
Upgrading your LLM won't fix a Retrieval-Augmented Generation (RAG) system if the retrieval pipeline is flawed. This post breaks down common retrieval pitfalls—like poor chunking, missing metadata, and weak reranking—and offers practical tips to boost answer quality without chasing bigger models.
Why Your RAG System Doesn't Need a Better LLM—It Needs Better Retrieval
When a Retrieval-Augmented Generation (RAG) system starts hallucinating or missing the point, most teams default to blaming the LLM. It’s a common mistake: upgrading to GPT-4, Gemini, or whatever’s newest seems like the fix. But in reality, if your retrieval is bad, no LLM—no matter how powerful—can consistently produce solid answers. A better model might sound more fluent, but it won’t conjure facts from thin air.
If your RAG system isn’t giving good answers, the problem is almost always in the retrieval pipeline, not the language model. I’ve seen “bad” answers from GPT-3.5 with good retrieval outperform GPT-4 when the latter was fed garbage. I’ve also seen teams burn weeks upgrading models and fiddling with system prompts when a simple retrieval tweak would have fixed 80% of their issues.
Breaking Down the RAG Retrieval Pipeline: From Ingestion to Context Assembly
A RAG pipeline has several moving parts, and the retrieval side isn’t a black box. Here’s the typical flow:
Chunks too big/small, no overlap, splitting mid-table or code block
Embeddings
Poor model choice, misaligned to data, low-quality vectors
Indexing
Incorrect schema, stale indices, missing metadata
Retrieval
Wrong query format, no filtering, only one retrieval method (dense or sparse)
Reranking
Skipped entirely, or done with weak heuristics
Context Assembly
Concatenating too much, wrong context order, no deduplication
It only takes one broken stage to tank your answers. Most RAG failures I’ve debugged came down to chunking, retrieval method, or context selection—not the language model.
How Chunking Mistakes Undermine Retrieval Quality
Chunking is where a lot of RAG systems quietly shoot themselves in the foot.
Oversized chunks? The retrieval step grabs “relevant” text, but it’s surrounded by unrelated content, diluting the signal. Imagine retrieving a whole 5,000-token HTML spec section when you only wanted a single tag definition.
No overlap? Now the context for a given fact is split across two chunks, and your query never retrieves both together. The LLM is forced to guess or invent connections.
Improper splitting of tables or code? You end up with half a function or a mangled table—useless for retrieval, and the LLM can’t reconstruct what’s missing.
The fix is rarely more complicated than tuning chunk size, adding overlap (stride), or writing smarter parsers for structured content. But it’s amazing how often these basics are skipped.
# Example: Overlapping chunker with table/code awareness (pseudo-code)defsmart_chunk(text, size=512, overlap=128):
chunks = []
i = 0while i < len(text):
# Avoid splitting inside code blocks or tables
end = find_safe_split(text, i, i+size)
chunks.append(text[i:end])
i = end - overlap
return chunks
Boosting Retrieval with Metadata: What to Track and Why It Matters
Metadata is often overlooked, but it can dramatically improve retrieval quality. Tracking document source, version, section, and timestamps enables smarter filtering, better relevance, and easier debugging.
Suppose you have API docs across several versions. Without version metadata, every query risks returning the wrong syntax or deprecated endpoints. Add version as a filterable field, and suddenly your retrieval is precise.
Section granularity (e.g., “chapter”, “header”) lets you bias toward more relevant content. Timestamps let you prioritize recent updates or filter out stale knowledge.
Here’s a practical schema for a vector database like Qdrant:
Field
Type
Example Value
Use Case
content
string
"foo()"
Chunk text
source
string
"api_docs"
Filter by document collection
version
string
"v2.1"
Ensure correct API version
section
string
"Initialization"
Bias or rerank by section
timestamp
datetime
"2024-05-01T12:00"
Prefer fresh content
Adding metadata isn’t just about search—it also helps you diagnose why bad chunks get retrieved, and tune your filters accordingly.
Dense Search, BM25, or Hybrid Search: Which Retrieval Method Should You Use?
There’s no one retrieval method that always wins. Here’s how each stacks up:
Method
Strengths
Weaknesses
Dense (Embeddings)
Semantic matches, robust to paraphrase
Misses on rare terms, can get “fuzzy”
BM25 (Sparse)
Precise keyword matching
Misses paraphrase, brittle to synonyms
Hybrid
Best of both: semantic + keyword
Extra complexity, tuning required
Dense retrieval (vector search) shines when users ask in natural language, or when queries don’t share vocabulary with source docs. BM25 (classic keyword search) is unbeatable for exact term matches, technical jargon, or code.
Hybrid search—combining both, often by score fusion or reranking—almost always improves recall and precision. Qdrant, for example, has built-in hybrid search. LangChain makes it straightforward to combine methods and rerank results, though integrating and tuning hybrid search still takes some effort.
You’ll rarely regret trying hybrid before buying more GPU hours.
Why Reranking Delivers Outsized Gains in RAG Quality
Reranking is the unsexy workhorse of top-performing RAG systems. Retrieval gives you a candidate set (say, top 20 chunks); reranking sorts them by real relevance.
Most vector databases let you plug in a cross-encoder model (like Cohere’s reranker, or OpenAI’s embedding-based reranker) to rerank retrieved chunks using the full query-context pair. This step is expensive per chunk, but you’re only reranking a shortlist.
Why does this matter? Initial retrieval—especially dense or hybrid—can be noisy. Reranking cuts the noise and surfaces the chunks the LLM actually needs.
Here’s a LangChain snippet for reranking with Cohere:
If you want the quickest, highest-ROI fix for a “bad” RAG system, add reranking.
Context Engineering: Selecting the Right Chunks for Your LLM
It’s tempting to shovel more context into the LLM—“just raise the token limit!” But more isn’t better. The real art is context engineering: picking the smallest, most relevant set of chunks.
Why? Token bloat dilutes signal. The LLM has to wade through more noise, and important details get buried. If you’ve ever seen answers that reference the wrong section or hallucinate details, that’s often context overload.
The best systems assemble context with care: deduplicate overlapping chunks, order them by relevance, and cap the number of tokens well below the LLM’s maximum. Sometimes, less is more.
Example: If your top-3 chunks cover 90% of relevant facts, resist the urge to send 10. Experiment with context assembly logic—not just bigger context windows.
How to Measure and Improve Retrieval Quality in Your RAG System
Evaluating RAG by “does the LLM sound good?” is a trap. You need retrieval metrics:
Recall@K: What fraction of answer-relevant chunks are retrieved in the top K?
Precision@K: Of top-K retrieved, how many are actually relevant?
Retrieval evaluation sets: Annotated queries with ground-truth relevant chunks.
Don’t just judge by LLM answers. Measure retrieval directly, e.g.,
# Pseudocode: Calculate Recall@K for annotated test set
relevant_chunks = get_ground_truth(query)
retrieved_chunks = retrieve_top_k(query, K=5)
recall = len(set(relevant_chunks) & set(retrieved_chunks)) / len(relevant_chunks)
If your retrieval metrics aren’t high, upgrading your model just masks the problem.
Practical Tips to Improve Retrieval Before Upgrading LLMs
Tune chunk size and overlap (512-1024 tokens, 10-20% overlap as a starting point)
Add and filter by metadata (e.g., version, section)
Switch from dense-only to hybrid retrieval
Add a reranking model
Build retrieval evaluation sets and track Recall@K
Takeaways: Why Great Retrieval Makes Even Average LLMs Shine
I’ve yet to see a RAG system with mediocre retrieval and perfect answers, no matter how fancy the LLM. But I have seen plenty where average models—GPT-3.5, small open-source LLMs—perform surprisingly well when fed the right context.
If your RAG app isn’t giving good answers, don’t reach for a better LLM first. Audit your retrieval pipeline. Fix chunking, add metadata, try hybrid search and reranking, and measure retrieval quality directly.
Great retrieval makes your models look smart. Bad retrieval makes even the best models look clueless. Invest accordingly.
Join the discussion
Nothing here yet — be the first to weigh in.