{"slug": "9-rag-techniques-that-actually-improve-retrieval-quality", "title": "9 RAG Techniques That Actually Improve Retrieval Quality", "summary": "A developer's guide details nine techniques to improve retrieval quality in Retrieval-Augmented Generation (RAG) systems, including reranking, hybrid search, and context compression. The techniques address common production issues such as irrelevant documents, buried information, and vague queries, emphasizing the importance of how information is retrieved and presented to the LLM.", "body_md": "Retrieval-Augmented Generation (RAG) is often described as a simple pipeline:\n\nQuery → Retrieve documents → Send context to an LLM → Generate answer\n\nIn production, however, retrieval is rarely that simple.\n\nThe retriever can return irrelevant documents. Important information may be buried in the middle of a document. A query may be too vague for semantic search. Retrieved chunks may lose their surrounding context. And sometimes the model does not need retrieval at all.\n\nThe quality of a RAG system therefore depends heavily on **how information is retrieved, filtered, ranked, compressed, and presented to the model**.\n\nThis guide covers nine techniques that address different parts of the RAG pipeline:\n\nRetrieve candidates. Reranking finds the best.\n\nA vector database may search through hundreds or thousands of documents and return the top 20 candidate chunks.\n\nBut the first result from vector search is not necessarily the best result.\n\nFor example, suppose the correct answer is ranked at position #19.\n\nIf the application only sends the top 3–5 chunks to the LLM, the correct information never reaches the model.\n\n```\n                100 Pages\n                    ↓\n              Vector Search\n                    ↓\n           20 Candidate Chunks\n                    │\n        ┌───────────┴───────────┐\n        ↓                       ↓\n  Without Reranking       With Reranking\n        ↓                       ↓\n  Top 3–5 Chunks             Reranker\n        ↓                       ↓\n        │                 Top 5 Relevant\n        │                     Chunks\n        ↓                       ↓\n        ↓                       ↓\n       LLM                     LLM\n```\n\nWithout reranking, the most relevant chunk might be ranked #19 and never reach the model.\n\nWith reranking, a reranker evaluates the retrieved candidates using both the query and the content of each chunk, promoting the most relevant results to the top.\n\nThe reranker can move a previously low-ranked but highly relevant chunk to the top.\n\nA reranker essentially asks:\n\nWhich of these retrieved chunks actually answers the user's question best?\n\nUnlike basic vector similarity, a reranker can inspect the relationship between the entire query and the retrieved document.\n\nThis helps it:\n\nCommon approaches include:\n\n**Cross-Encoder**\n\n**Bi-Encoder + Rerank Model**\n\n**LLM-based Reranker**\n\nSuppose a developer asks:\n\nHow can I make a Node.js API handle thousands of simultaneous connections?\n\nA basic vector search might initially return chunks about HTTP status codes, API authentication, or general Node.js syntax.\n\nA reranker can compare each candidate directly against the question and prioritize content discussing connection handling, asynchronous I/O, event loops, connection pooling, and horizontal scaling.\n\nRetrieve more. Rerank intelligently. Let the LLM see the best context, not merely the first context.\n\nMeaning + Keywords = Better Retrieval\n\nSemantic vector search and keyword search solve different problems.\n\nVector search understands **meaning**.\n\nKeyword search understands **exact words**.\n\nUsing only one can cause important documents to be missed.\n\nConsider this query:\n\n```\n\"Redis connection timeout\"\n```\n\nA semantic search might return:\n\nThese documents may be semantically related, but the exact phrase `Redis connection timeout`\n\nmight not appear.\n\nA keyword search such as BM25 can find:\n\nBut keyword search may fail when the document uses different terminology.\n\nHybrid search combines both approaches:\n\n```\n                User Query\n                    │\n          ┌─────────┴─────────┐\n          ↓                   ↓\n    Vector Search        Keyword Search\n     (Semantic)              (BM25)\n          │                   │\n          └─────────┬─────────┘\n                    ↓\n              Merge & Rank\n                    ↓\n              Final Results\n```\n\nThe results from both searches are combined and ranked.\n\nPopular approaches include:\n\nVector search is good at understanding intent:\n\n```\n\"cache performance troubleshooting\"\n```\n\nKeyword search is good at exact terms:\n\n```\n\"Redis MISCONF\"\n```\n\nA production search system often needs both.\n\nHybrid search is particularly useful for:\n\nDon't choose between meaning and keywords. Use both.\n\nGood chunks → Better Retrieval → Better Answers\n\nChunking is one of the most important decisions in a RAG system.\n\nDocuments are usually too large to embed and retrieve as a single unit, so they must be divided into smaller pieces.\n\nBut chunk size matters.\n\nIf a chunk is too large:\n\nIf a chunk is too small:\n\nThe goal is:\n\nKeep chunks as small as possible for precision, but as large as necessary for completeness.\n\nThe document is divided into chunks of a fixed number of tokens.\n\nFor example:\n\n```\nDocument\n   ↓\n400 tokens\n   ↓\n400 tokens\n   ↓\n400 tokens\n   ↓\n...\n```\n\nAn overlap can be added between chunks.\n\nInstead of splitting at arbitrary token boundaries, the system splits around sentence boundaries.\n\n```\nSentence 1\nSentence 2\nSentence 3\n\nSentence 4\nSentence 5\nSentence 6\n```\n\nSentence lengths can vary significantly.\n\nSemantic chunking groups sentences or paragraphs based on their meaning.\n\nConceptually:\n\n```\nTopic A\n  ├── Authentication configuration\n  ├── Token validation\n  └── Session management\n\nTopic B\n  ├── Database indexing\n  ├── Query planning\n  └── Connection pooling\n```\n\nSmall chunks are used for retrieval, but the larger parent section is returned to the LLM.\n\n```\n    Large Parent Document\n              │\n   ┌──────────┼──────────┐\n   ↓          ↓          ↓\n Small      Small      Small\n Chunk      Chunk      Chunk\n```\n\nThe small chunks provide retrieval precision while the parent document provides context.\n\nA moving window is used to create overlapping chunks.\n\n```\nWindow 1\n████████\n\n    Window 2\n    ████████\n\n        Window 3\n        ████████\n```\n\nThis preserves more context across chunk boundaries.\n\nMore chunks mean more storage and potentially more retrieval cost.\n\nThe document's structure is used to determine chunk boundaries.\n\nFor example:\n\n```\n# Authentication\n    ↓\nChunk 1\n\n## Token Validation\n    ↓\nChunk 2\n\n- Access token\n- Refresh token\n    ↓\nChunk 3\n\nConfiguration Table\n    ↓\nChunk 4\n\nCode Block\n    ↓\nChunk 5\n```\n\nThis works particularly well for:\n\nThere is no universally best chunking strategy.\n\nThe right strategy depends on the data.\n\nA production system may combine multiple approaches:\n\n```\nStructure-aware splitting\n        +\nSemantic grouping\n        +\nParent document retrieval\n```\n\nYou should also experiment with chunk sizes such as:\n\n```\n256 tokens\n512 tokens\n1024 tokens\n```\n\nand measure actual retrieval performance.\n\nGood chunks bring the right context. The right context helps the LLM produce the right answer.\n\nOne question. Multiple perspectives. Better results.\n\nA single query can fail because documents may describe the same concept using completely different language.\n\nEven if query expansion improves the wording, searching in only one direction can still miss relevant documents.\n\nInstead of searching once, ask the LLM to generate multiple versions of the query.\n\nFor example:\n\nOriginal question:\n\nHow does OAuth token refresh work?\n\nThe system might generate:\n\n```\nWhat is OAuth token refresh?\n\nHow does a refresh token work?\n\nWhat happens when an access token expires?\n\nHow does an application obtain a new access token?\n\nWhat is the OAuth refresh-token flow?\n```\n\nEach query is searched independently.\n\n```\n               Original Question\n                     ↓\n               Generate Queries\n                     ↓\n        ┌────────┬────────┬────────┐\n        ↓        ↓        ↓        ↓\n      Search   Search   Search   Search\n        └────────┴────────┴────────┘\n                     ↓\n               Merge & Rerank\n                     ↓\n                Final Chunks\n```\n\nDifferent documents use different terminology.\n\nOne document might say:\n\n```\nOAuth token refresh\n```\n\nwhile another says:\n\n```\nrenewing an expired access token\n```\n\nand another says:\n\n```\nobtaining a new bearer token using a refresh credential\n```\n\nMultiple queries give the retriever more opportunities to find relevant information.\n\nThese concepts are related but not identical.\n\n| Feature | Query Expansion | Multi-Query |\n|---|---|---|\n| Main goal | Better wording | Different viewpoints |\n| Queries | Similar variations | More diverse queries |\n| Focus | Query improvement | Retrieval coverage |\n| Recall | Good | Often higher |\n| Typical use | General search | Production RAG |\n\nMulti-query retrieval is particularly useful for:\n\nDon't ask once. Ask in multiple smart ways.\n\nMore angles give the retriever more chances to find the right information.\n\nSmall chunks = better search. Parent documents = better understanding.\n\nSmall chunks are useful because they make retrieval precise.\n\nBut small chunks have a problem:\n\n**They can lose context.**\n\nConsider retrieving this chunk:\n\n```\n\"... it automatically retries failed operations ...\"\n```\n\nThe chunk might be relevant, but by itself it doesn't tell us what \"it\" refers to.\n\nThe original section might say:\n\n```\n\"The job processor automatically retries failed operations when a worker temporarily loses access to the message queue.\"\n```\n\nThe parent document provides the missing context.\n\n```\nDocument\n   ↓\nChunk 1\nChunk 2\nChunk 3\nChunk 4\n...\n```\n\nThe vector database retrieves the most relevant chunks.\n\n```\nTop Chunks:\n1\n2\n8\n9\n10\n```\n\nEach chunk stores a reference to its parent section or document.\n\n```\nChunk 8\n   ↓\nParent Document / Section\n```\n\nInstead of giving the LLM only the tiny chunk, provide the relevant parent section.\n\n```\nSmall chunks → Search\n\nParent document → Context\n```\n\nThis creates a useful separation:\n\nRetrieve small. Read big.\n\nParent document retrieval is useful when:\n\nStore a `parent_id`\n\nwith each chunk.\n\nFor example:\n\n```\nChunk:\n{\n  id: \"chunk_123\",\n  parent_id: \"section_42\",\n  embedding: [...]\n}\n```\n\nAfter retrieval, use `parent_id`\n\nto fetch the larger context.\n\nChunks help you find information. Parent documents help the model understand it.\n\nToo much context can be as bad as too little.\n\nImagine a retriever returns 40 chunks, but your LLM can effectively process only 8 useful chunks.\n\nSending all 40 creates several problems:\n\nThis is related to the **lost-in-the-middle** problem: important information can become harder for the model to use when surrounded by large amounts of irrelevant context.\n\n```\n40 Retrieved Chunks\n        ↓\n     Compress\n        ↓\nKeep Relevant Information\n        ↓\n8 Clean Chunks\n        ↓\n       LLM\n```\n\nThe compressor attempts to remove everything that does not contribute meaningfully to answering the question.\n\nCommon targets include:\n\nSummarize each chunk into a smaller representation.\n\n```\nLarge chunk\n    ↓\n1–2 sentence summary\n```\n\nKeep the most important terms and phrases.\n\nRemove information that appears repeatedly across retrieved documents.\n\nKeep only the sentences that directly contribute to answering the query.\n\nScore individual sentences or chunks and keep only high-scoring content.\n\nSuppose retrieval returns 40 chunks.\n\nAfter compression:\n\n```\n40 chunks\n   ↓\n8 chunks\n   ↓\n~75% token reduction\n   ↓\nBetter focused context\n```\n\nThe exact improvement depends on the data and compression method, but the goal is to make the context **smaller without losing useful information**.\n\nMore context is not always better. Relevant context is better.\n\nThink before you search.\n\nHyDE stands for **Hypothetical Document Embeddings**.\n\nIt addresses a common retrieval problem:\n\n**The user's query may be too short or vague to produce a strong embedding.**\n\nFor example:\n\n```\n\"message queue retries\"\n```\n\nThe query contains only a few terms.\n\nA better search signal could be a hypothetical answer generated by an LLM.\n\nInstead of embedding the original question:\n\n```\nUser Question\n     ↓\nEmbedding\n     ↓\nVector Search\n```\n\nHyDE introduces an intermediate generation step:\n\n```\nUser Question\n     ↓\nGenerate Hypothetical Answer\n     ↓\nEmbed Hypothetical Answer\n     ↓\nVector Search\n     ↓\nRetrieve Documents\n     ↓\n    LLM\n```\n\nFor example, the user asks:\n\nHow does a message queue retry failed jobs?\n\nThe LLM might generate a hypothetical answer such as:\n\nA message processing system can retry a failed job when the worker encounters a temporary error. Retry policies commonly use a maximum attempt count and exponential backoff before moving permanently failed messages to a dead-letter queue.\n\nThe hypothetical answer contains more meaningful domain terms than the original question.\n\nThe system embeds that hypothetical answer and uses the embedding to search the knowledge base.\n\nThe generated answer may contain:\n\nThis can improve semantic matching.\n\nThe hypothetical answer is not used as the final answer.\n\nIt is primarily a **search representation**.\n\nThe actual answer still comes from retrieved documents.\n\n```\nQuestion\n   ↓\nHypothetical Answer\n   ↓\nEmbedding\n   ↓\nRetrieve Real Documents\n   ↓\nGenerate Final Answer\n```\n\nQuery expansion usually creates multiple alternative queries.\n\nHyDE generates a hypothetical document or answer and embeds that representation.\n\n```\nQuery Expansion\n→ Multiple queries\n\nHyDE\n→ One hypothetical answer\n→ One embedding\n```\n\nHyDE can help with:\n\nHyDE turns a weak question into a stronger search signal.\n\nWhy search every time? Let the model decide first.\n\nTraditional RAG often retrieves documents for every query.\n\nBut not every question needs external retrieval.\n\nFor example:\n\n```\nWhat is the square root of 144?\n```\n\nRetrieving documents from a vector database would be unnecessary.\n\nAlways retrieving causes:\n\nSelf-RAG introduces a decision step.\n\n```\n      User Question\n            ↓\n   Should I retrieve?\n            ↓\n   ┌────────┴────────┐\n  NO                YES\n   ↓                 ↓\nAnswer            Retrieve\nDirectly             ↓\n                  Generate\n```\n\nThe model first considers:\n\nThe model answers using its internal knowledge.\n\nExample:\n\n```\nWhat is 15 × 8?\n```\n\nNo retrieval is required.\n\nThe system retrieves relevant documents.\n\nExample:\n\n```\nWhat changed in our company's API documentation this week?\n```\n\nRetrieval is useful because the information is recent and internal.\n\nTypical cases include:\n\nTypical cases include:\n\nSelf-RAG can:\n\nTraditional RAG retrieves every time. Self-RAG decides whether retrieval is needed before acting.\n\nNot every retrieved chunk is useful. CRAG checks the quality before trusting it.\n\nA retriever is not perfect.\n\nIt can return:\n\nIf the LLM blindly trusts those chunks, it can produce a confident but incorrect answer.\n\nCRAG introduces a quality-control step.\n\n```\n      User Question\n           ↓\n   Retrieve Documents\n           ↓\nEvaluate Retrieved Documents\n           ↓\n   ┌───────┴───────┐\n GOOD              BAD\n   ↓                ↓\nUse Docs     Correct Retrieval\n                    ↓\n             Refine / Re-query\n                    ↓\n              Retrieve Again\n                    ↓\n               Final Context\n                    ↓\n                   LLM\n```\n\nThe retrieved documents are evaluated before they are trusted.\n\nPotential criteria include:\n\nIf the documents are good enough, they can be passed to the LLM.\n\nIf they are poor, the system can attempt corrective actions.\n\nExamples include:\n\nSuppose the user asks:\n\nWhich database is a good choice for high-volume event analytics?\n\nThe retriever returns:\n\n```\n1. Introduction to relational databases\n2. Key-value cache configuration\n3. Columnar database architecture for analytics\n4. Basic SQL CRUD operations\n```\n\nThe evaluator can determine that only some of these documents directly address the question.\n\nThe system can then remove weak results and perform additional retrieval if necessary.\n\nThe goal is:\n\n```\nRetrieve\n   ↓\nCheck\n   ↓\nCorrect\n   ↓\nAnswer\n```\n\nCRAG can:\n\nCRAG is particularly useful for:\n\nNormal RAG:\n\n```\nRetrieve → Answer\n```\n\nCRAG:\n\n```\nRetrieve → Evaluate → Correct → Answer\n```\n\nThe fundamental difference is that CRAG does not blindly trust the retriever.\n\nCRAG verifies the retrieved context before allowing the model to rely on it.\n\nThese techniques do not need to be used independently.\n\nA production RAG system can combine several of them.\n\nFor example:\n\n```\n                    User Query\n                        │\n                        ▼\n                 Self-RAG Decision\n                  /            \\\n                 NO             YES\n                 │               │\n                 ▼               ▼\n             Direct Answer   Multi-Query\n                                 │\n                                 ▼\n                           Hybrid Search\n                           Vector + BM25\n                                 │\n                                 ▼\n                             Retrieval\n                                 │\n                                 ▼\n                              Reranking\n                                 │\n                                 ▼\n                          CRAG Evaluation\n                          /             \\\n                       GOOD              BAD\n                        │                 │\n                        │         Re-query/Correct\n                        │                 │\n                        └───────┬─────────┘\n                                ▼\n                      Parent Document Retrieval\n                                │\n                                ▼\n                       Context Compression\n                                │\n                                ▼\n                               LLM\n                                │\n                                ▼\n                           Final Answer\n```\n\nNot every application needs every component.\n\nThe correct architecture depends on:\n\nEach technique solves a different failure mode.\n\n| Problem | Technique |\n|---|---|\n| Correct chunk is retrieved but ranked too low | Reranking |\n| Exact keywords and semantic meaning both matter | Hybrid Search |\n| Documents are difficult to split correctly | Better Chunking |\n| One query misses relevant terminology | Multi-Query Retrieval |\n| Retrieved chunk lacks surrounding context | Parent Document Retrieval |\n| Too many retrieved chunks overwhelm the model | Context Compression |\n| Query is vague or lacks useful search terms | HyDE |\n| Retrieval isn't necessary for every question | Self-RAG |\n| Retriever returns poor or misleading documents | CRAG |\n\nA practical system might start with something relatively simple:\n\n```\nDocuments\n   ↓\nStructure-Aware Chunking\n   ↓\nEmbeddings + Keyword Index\n   ↓\nHybrid Search\n   ↓\nReranking\n   ↓\nParent Context\n   ↓\nContext Compression\n   ↓\nLLM\n```\n\nThen add more advanced techniques only where measurements show they are needed.\n\nFor example:\n\n```\nSelf-RAG\n```\n\ncan reduce unnecessary retrieval.\n\n```\nMulti-Query Retrieval\n```\n\ncan improve recall for difficult questions.\n\n```\nHyDE\n```\n\ncan help with vague queries.\n\n```\nCRAG\n```\n\ncan add a validation and correction loop.\n\nThe biggest mistake when building RAG systems is treating retrieval as a single operation:\n\n```\nQuery → Vector DB → LLM\n```\n\nReal-world retrieval is closer to a pipeline of decisions:\n\n```\nShould I retrieve?\n        ↓\nWhat should I search for?\n        ↓\nWhere should I search?\n        ↓\nHow should I split the documents?\n        ↓\nWhich results are actually relevant?\n        ↓\nWhich results should be ranked highest?\n        ↓\nHow much context should I provide?\n        ↓\nIs the retrieved context trustworthy?\n        ↓\nCan the LLM answer from this context?\n```\n\nThe quality of the final answer is often determined **before the LLM generates a single token**.\n\nBetter retrieval → Better context → Better answers.\n\nAnd the goal isn't to build the most complicated RAG pipeline.\n\nThe goal is to build the **simplest retrieval architecture that reliably provides the right context for your workload**.", "url": "https://wpnews.pro/news/9-rag-techniques-that-actually-improve-retrieval-quality", "canonical_source": "https://dev.to/bibekkakati/9-rag-techniques-that-actually-improve-retrieval-quality-36jh", "published_at": "2026-08-22 19:36:18+00:00", "updated_at": "2026-08-22 19:43:25.775203+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "large-language-models", "natural-language-processing", "ai-tools"], "entities": ["RAG", "LLM", "BM25", "Node.js", "Redis"], "alternates": {"html": "https://wpnews.pro/news/9-rag-techniques-that-actually-improve-retrieval-quality", "markdown": "https://wpnews.pro/news/9-rag-techniques-that-actually-improve-retrieval-quality.md", "text": "https://wpnews.pro/news/9-rag-techniques-that-actually-improve-retrieval-quality.txt", "jsonld": "https://wpnews.pro/news/9-rag-techniques-that-actually-improve-retrieval-quality.jsonld"}}