<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Vector Search &#183; PiniShv</title><link>https://pinishv.com/tags/vector-search/</link><description>Pini Shvartsman leads AI transformation inside a 100+ engineer SaaS org. Field notes on autonomous engineering: AI-powered execution, human accountability.</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>© 2026 Pini Shvartsman</copyright><lastBuildDate>Tue, 23 Sep 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://pinishv.com/tags/vector-search/index.xml" rel="self" type="application/rss+xml"/><item><title>So, You've Built a RAG. Now Let's Make It Not Suck.</title><link>https://pinishv.com/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/</link><pubDate>Tue, 23 Sep 2025 00:00:00 +0000</pubDate><guid>https://pinishv.com/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/</guid><description>Your basic RAG works in the demo. It falls apart with real users. Here&amp;rsquo;s how to upgrade from a fragile prototype to a production system that actually handles the messy reality of user queries.</description><content:encoded>&lt;p>Alright, you read &lt;a
href="../rag-for-developers-a-no-bs-introduction">the intro guide&lt;/a>. You connected an LLM to a vector database, stuffed it with your documents, and built your first Retrieval-Augmented Generation (RAG) app. It works. You ask a question, it spits out an answer backed by your data. High fives all around.&lt;/p>
&lt;p>Then you show it to a real user.&lt;/p>
&lt;p>They ask a question with a typo. The RAG returns garbage. They ask a question that requires info from two different documents. The RAG gets confused. They ask, &amp;ldquo;What are the key differences between product A and B?&amp;rdquo; and it just dumps the full spec sheet for product A.&lt;/p>
&lt;p>Suddenly, your shiny AI marvel feels less like a genius and more like a clumsy intern.&lt;/p>
&lt;p>Welcome to the real work of building RAG systems. The &amp;ldquo;hello world&amp;rdquo; version is easy. The production-grade version that doesn&amp;rsquo;t fall over when a user looks at it funny? That&amp;rsquo;s a different beast. Let&amp;rsquo;s dive into the upgrades that take your RAG from a fragile prototype to a robust powerhouse.&lt;/p>
&lt;h2 class="relative group">Upgrade 1: Your Retriever is a Dumb Metal Detector. Let&amp;rsquo;s Give It a Brain.
&lt;div id="upgrade-1-your-retriever-is-a-dumb-metal-detector-lets-give-it-a-brain" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-1-your-retriever-is-a-dumb-metal-detector-lets-give-it-a-brain" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>The single biggest failure point in a naive RAG is the &amp;lsquo;R&amp;rsquo;, the retrieval. Your first attempt probably just does a simple semantic search. That&amp;rsquo;s a decent start, but it&amp;rsquo;s like using a metal detector to find a specific coin in a junkyard. It finds stuff that&amp;rsquo;s generally similar, but often misses the mark.&lt;/p>
&lt;h3 class="relative group">Fix #1: Hybrid Search
&lt;div id="fix-1-hybrid-search" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#fix-1-hybrid-search" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Pure semantic search is great for understanding the meaning of a query, but it can be surprisingly bad with specific keywords, acronyms, or product codes. Your user types &amp;ldquo;Error Code: 4815162342&amp;rdquo; and the semantic search goes, &amp;ldquo;Hmm, you seem to be interested in numerical sequences and technical issues.&amp;rdquo; Not helpful.&lt;/p>
&lt;p>Hybrid search is the answer. It combines the best of both worlds:&lt;/p>
&lt;p>&lt;strong>Keyword Search (like &lt;a
href="https://en.wikipedia.org/wiki/Okapi_BM25"
target="_blank"
>BM25&lt;/a>):&lt;/strong> The old-school, reliable method that&amp;rsquo;s fantastic at finding exact matches for specific terms.&lt;/p>
&lt;p>&lt;strong>Semantic Search:&lt;/strong> The modern approach that&amp;rsquo;s great for understanding the intent and context behind a query.&lt;/p>
&lt;p>By running both and intelligently merging the results, you get a system that can understand &amp;ldquo;tell me about our database connection pooling issues&amp;rdquo; and also pinpoint the exact log file mentioning &lt;code>DB-CONN-POOL-ERR-8675309&lt;/code>.&lt;/p>
&lt;h3 class="relative group">Fix #2: Add a Reranker
&lt;div id="fix-2-add-a-reranker" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#fix-2-add-a-reranker" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Your retriever&amp;rsquo;s job is to be fast and cast a wide net. It should quickly fetch a bunch of potentially relevant documents (say, the top 25). But fast doesn&amp;rsquo;t always mean accurate.&lt;/p>
&lt;p>A reranker is a second, more powerful (and slower) model that acts as a quality control inspector. It takes that initial list of 25 documents and scrutinizes each one against the original query. Its only job is to ask, &amp;ldquo;How truly relevant is this piece of text to this specific question?&amp;rdquo; It then re-orders the list, pushing the absolute best candidates to the top.&lt;/p>
&lt;p>Think of it this way: retrieval is your broad Google search. Reranking is you actually clicking the top 5 links to see which one has the answer. It&amp;rsquo;s a crucial step for boosting precision.&lt;/p>
&lt;h2 class="relative group">Upgrade 2: Stop Blaming the User. Fix Their Queries.
&lt;div id="upgrade-2-stop-blaming-the-user-fix-their-queries" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-2-stop-blaming-the-user-fix-their-queries" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Users don&amp;rsquo;t write perfect queries. They&amp;rsquo;re vague, they&amp;rsquo;re complex, or they&amp;rsquo;re just plain weird. &amp;ldquo;Garbage in, garbage out&amp;rdquo; applies here. Instead of just passing that garbage to your retriever, you can use an LLM to clean it up first. This is called &lt;strong>Query Transformation&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Query Expansion:&lt;/strong> The user asks, &amp;ldquo;How to handle auth?&amp;rdquo; The LLM can expand this to &amp;ldquo;How to handle user authentication, including login, logout, and token management?&amp;rdquo; providing a richer query for the retriever.&lt;/p>
&lt;p>&lt;strong>Sub-Question Decomposition:&lt;/strong> The user asks a multi-part question like, &amp;ldquo;How does our pricing for the Pro plan compare to the Enterprise plan, and what are the overage fees?&amp;rdquo; A naive RAG will get lost. A smarter system uses an LLM to break this into three separate questions, retrieves answers for each, and then synthesizes a final response. This single technique can dramatically improve answers to complex queries.&lt;/p>
&lt;h2 class="relative group">Upgrade 3: From Simple Pipeline to Autonomous Agent
&lt;div id="upgrade-3-from-simple-pipeline-to-autonomous-agent" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-3-from-simple-pipeline-to-autonomous-agent" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>This is the big leap. A standard RAG is a fixed pipeline: Query → Retrieve → Augment → Generate. It&amp;rsquo;s a one-way street.&lt;/p>
&lt;p>&lt;strong>Agentic RAG&lt;/strong> throws that out the window. An agent is an LLM given a brain and a toolkit. Instead of blindly following a pipeline, it can reason, plan, and use tools to answer a question.&lt;/p>
&lt;p>Here&amp;rsquo;s what that actually means:&lt;/p>
&lt;p>&lt;strong>Planning:&lt;/strong> The agent receives the query and creates a multi-step plan. For &amp;ldquo;Compare product A and B,&amp;rdquo; the plan might be: 1. Find docs about product A. 2. Find docs about product B. 3. Synthesize the findings and highlight differences.&lt;/p>
&lt;p>&lt;strong>Tool Use:&lt;/strong> Your agent isn&amp;rsquo;t limited to just one retriever. You can give it multiple tools. Maybe it has a &lt;code>vector_search_tool&lt;/code> for your tech docs, a &lt;code>sql_database_tool&lt;/code> for user data, and an &lt;code>api_call_tool&lt;/code> for checking real-time stock prices. The agent chooses the right tool for the job based on the query.&lt;/p>
&lt;p>&lt;strong>Self-Correction:&lt;/strong> What if the first retrieval comes back with nothing useful? A naive RAG gives up. An agent can recognize the failure, think &amp;ldquo;Okay, that didn&amp;rsquo;t work,&amp;rdquo; and try something else, like rephrasing the query using one of the transformation techniques we just talked about and running the search again. It&amp;rsquo;s an iterative, self-healing process.&lt;/p>
&lt;p>This is the difference between a simple script and a thinking application. It&amp;rsquo;s how you go from answering simple questions to tackling complex, multi-faceted research tasks.&lt;/p>
&lt;h2 class="relative group">Upgrade 4: Your Data is Probably Garbage. Fix That First.
&lt;div id="upgrade-4-your-data-is-probably-garbage-fix-that-first" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-4-your-data-is-probably-garbage-fix-that-first" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Here&amp;rsquo;s an uncomfortable truth: most RAG failures aren&amp;rsquo;t caused by fancy retrieval algorithms. They&amp;rsquo;re caused by bad data preparation. You can have the world&amp;rsquo;s most sophisticated agentic RAG, but if you&amp;rsquo;re feeding it poorly chunked, inconsistent documents, it&amp;rsquo;ll still give you garbage answers.&lt;/p>
&lt;h3 class="relative group">Chunking Strategy Matters More Than You Think
&lt;div id="chunking-strategy-matters-more-than-you-think" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#chunking-strategy-matters-more-than-you-think" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Your first chunking attempt was probably &amp;ldquo;split on 500 characters with 50 character overlap.&amp;rdquo; That&amp;rsquo;s fine for a demo, but it&amp;rsquo;s terrible for production.&lt;/p>
&lt;p>&lt;strong>Semantic Chunking:&lt;/strong> Instead of arbitrary character limits, break documents at logical boundaries; paragraphs, sections, topics. Libraries like LangChain now support semantic chunking that uses embeddings to detect natural break points.&lt;/p>
&lt;p>&lt;strong>Context-Aware Chunking:&lt;/strong> Each chunk should be self-contained. A chunk that says &amp;ldquo;As mentioned above, the API key should be&amp;hellip;&amp;rdquo; is useless without the context. Add document titles, section headers, and relevant metadata to each chunk.&lt;/p>
&lt;p>&lt;strong>Multi-Scale Chunking:&lt;/strong> Store chunks at different granularities. Maybe you have sentence-level chunks for precise retrieval, paragraph chunks for context, and document-level chunks for broad topics. Different queries need different levels of detail.&lt;/p>
&lt;h3 class="relative group">Clean Your Data Like Your RAG Depends On It
&lt;div id="clean-your-data-like-your-rag-depends-on-it" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#clean-your-data-like-your-rag-depends-on-it" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Normalization:&lt;/strong> Convert everything to consistent formats. Dates, phone numbers, product codes. Standardize them. Your search will thank you.&lt;/p>
&lt;p>&lt;strong>Metadata is Gold:&lt;/strong> Don&amp;rsquo;t just store text. Add document type, creation date, author, department, confidence level, last updated. This metadata becomes powerful filtering criteria during retrieval.&lt;/p>
&lt;p>&lt;strong>Content Cleaning:&lt;/strong> Remove headers, footers, navigation elements, and other noise that dilutes the signal. A chunk that&amp;rsquo;s 80% boilerplate and 20% actual content will hurt your embeddings.&lt;/p>
&lt;h2 class="relative group">Upgrade 5: Stop Flying Blind. Measure What Matters.
&lt;div id="upgrade-5-stop-flying-blind-measure-what-matters" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-5-stop-flying-blind-measure-what-matters" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>You&amp;rsquo;ve built an impressive RAG system, but how do you know if it&amp;rsquo;s actually good? &amp;ldquo;It feels better&amp;rdquo; isn&amp;rsquo;t enough when you&amp;rsquo;re in production.&lt;/p>
&lt;h3 class="relative group">Automated Evaluation is Non-Negotiable
&lt;div id="automated-evaluation-is-non-negotiable" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#automated-evaluation-is-non-negotiable" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Retrieval Evaluation:&lt;/strong> Track metrics like Mean Reciprocal Rank (MRR), Recall@K, and NDCG. Are you actually retrieving the right documents? Create a golden dataset of question-answer pairs and measure against it regularly.&lt;/p>
&lt;p>&lt;strong>Answer Quality:&lt;/strong> Use LLM-as-a-judge evaluation. GPT-5 can score your system&amp;rsquo;s answers against ground truth for relevance, accuracy, and completeness. It&amp;rsquo;s not perfect, but it&amp;rsquo;s consistent and scalable.&lt;/p>
&lt;p>&lt;strong>Human Feedback Loops:&lt;/strong> Build thumbs up/down buttons into your interface. Track which answers users found helpful. This real-world feedback is more valuable than any synthetic benchmark.&lt;/p>
&lt;h3 class="relative group">Production Monitoring
&lt;div id="production-monitoring" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#production-monitoring" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Retrieval Confidence Scores:&lt;/strong> Track when your system returns low-confidence results. If confidence drops below a threshold, surface that to users or trigger human review.&lt;/p>
&lt;p>&lt;strong>Query Pattern Analysis:&lt;/strong> What types of questions is your system struggling with? Are users asking about topics not covered in your knowledge base? This drives content strategy.&lt;/p>
&lt;p>&lt;strong>Hallucination Detection:&lt;/strong> Monitor when your system generates answers that don&amp;rsquo;t match the retrieved content. Some techniques include consistency checking and fact verification against the source material.&lt;/p>
&lt;h2 class="relative group">Upgrade 6: Know When to Say &amp;ldquo;I Don&amp;rsquo;t Know&amp;rdquo;
&lt;div id="upgrade-6-know-when-to-say-i-dont-know" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-6-know-when-to-say-i-dont-know" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>A RAG system that confidently gives wrong answers is worse than one that admits uncertainty. Teaching your system to be humble is a production necessity, not a nice-to-have.&lt;/p>
&lt;p>
&lt;figure>
&lt;img
class="my-0 rounded-md"
loading="lazy"
decoding="async"
fetchpriority="low"
alt="GPT-5 admitting it doesn&amp;rsquo;t know something"
srcset="
/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/gpt-5-do-not-know_hu_6c81db6f7dbfe042.png 330w,
/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/gpt-5-do-not-know_hu_82cf3a0f558d02db.png 660w,
/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/gpt-5-do-not-know_hu_ed305e07621dcd9b.png 1280w
"
data-zoom-src="https://pinishv.com/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/gpt-5-do-not-know.png"
src="https://pinishv.com/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/gpt-5-do-not-know.png">
&lt;/figure>
&lt;/p>
&lt;h3 class="relative group">Confidence Thresholding
&lt;div id="confidence-thresholding" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#confidence-thresholding" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Set minimum confidence thresholds for both retrieval and generation. If your retriever returns documents with low similarity scores, or if your LLM&amp;rsquo;s generation confidence is low, return a &amp;ldquo;I couldn&amp;rsquo;t find sufficient information&amp;rdquo; response instead of hallucinating.&lt;/p>
&lt;h3 class="relative group">Query Coverage Analysis
&lt;div id="query-coverage-analysis" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#query-coverage-analysis" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Build systems to detect when queries fall outside your knowledge base. If someone asks about &amp;ldquo;Project Falcon&amp;rdquo; but your documents only cover &amp;ldquo;Project Eagle,&amp;rdquo; detect that gap and respond appropriately rather than making something up about Falcon.&lt;/p>
&lt;h3 class="relative group">Graceful Degradation
&lt;div id="graceful-degradation" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#graceful-degradation" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>Instead of &amp;ldquo;I don&amp;rsquo;t know,&amp;rdquo; provide helpful alternatives:&lt;/p>
&lt;ul>
&lt;li>&amp;ldquo;I couldn&amp;rsquo;t find specific information about X, but here&amp;rsquo;s related information about Y&amp;hellip;&amp;rdquo;&lt;/li>
&lt;li>&amp;ldquo;Based on the documents available to me, I can only find partial information about&amp;hellip;&amp;rdquo;&lt;/li>
&lt;li>&amp;ldquo;This question might require information not in my knowledge base. You might want to check&amp;hellip;&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;h2 class="relative group">Upgrade 7: Speed vs. Quality: Welcome to Production Trade-offs
&lt;div id="upgrade-7-speed-vs-quality-welcome-to-production-trade-offs" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-7-speed-vs-quality-welcome-to-production-trade-offs" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Your beautiful multi-stage RAG pipeline with reranking and query transformation? It might be taking 8 seconds per query. Users will not wait.&lt;/p>
&lt;h3 class="relative group">Latency Optimization Strategies
&lt;div id="latency-optimization-strategies" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#latency-optimization-strategies" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Caching:&lt;/strong> Cache embeddings, cache frequent queries, cache reranker results. Redis becomes your best friend.&lt;/p>
&lt;p>&lt;strong>Parallel Processing:&lt;/strong> Run retrieval and reranking in parallel where possible. While you&amp;rsquo;re generating embeddings for the query, start your keyword search.&lt;/p>
&lt;p>&lt;strong>Staged Retrieval:&lt;/strong> Use fast, rough retrieval for the first stage (getting 100 candidates), then expensive, precise reranking for the final stage (ranking top 10).&lt;/p>
&lt;p>&lt;strong>Pre-computation:&lt;/strong> For common queries or categories, pre-compute and cache results. Your &amp;ldquo;How do I reset my password?&amp;rdquo; answer doesn&amp;rsquo;t need to be generated fresh every time.&lt;/p>
&lt;h3 class="relative group">Scaling Considerations
&lt;div id="scaling-considerations" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#scaling-considerations" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Multi-Modal Indexing:&lt;/strong> Different document types might need different indexing strategies. PDFs, code, structured data, don&amp;rsquo;t force everything through the same pipeline.&lt;/p>
&lt;p>&lt;strong>Distributed Search:&lt;/strong> As your knowledge base grows, you&amp;rsquo;ll need distributed vector search. Plan for it early.&lt;/p>
&lt;p>&lt;strong>Load Balancing:&lt;/strong> Different queries have different computational costs. A simple FAQ lookup is cheap; a complex multi-document analysis is expensive. Route accordingly.&lt;/p>
&lt;h2 class="relative group">Upgrade 8: Not Everyone Should See Everything
&lt;div id="upgrade-8-not-everyone-should-see-everything" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-8-not-everyone-should-see-everything" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>In the enterprise world, document access control isn&amp;rsquo;t optional. Your RAG system needs to respect the same permissions as your file system.&lt;/p>
&lt;h3 class="relative group">User-Aware Retrieval
&lt;div id="user-aware-retrieval" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#user-aware-retrieval" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Filtered Search:&lt;/strong> Before retrieval, filter your knowledge base based on user permissions. Never retrieve documents the user shouldn&amp;rsquo;t see, even if they&amp;rsquo;re relevant.&lt;/p>
&lt;p>&lt;strong>Department-Based Access:&lt;/strong> Sales shouldn&amp;rsquo;t see engineering docs, finance shouldn&amp;rsquo;t see HR records. Implement role-based filtering at the retrieval level.&lt;/p>
&lt;p>&lt;strong>Dynamic Permissions:&lt;/strong> Permissions change. That project doc that was public last month might be confidential now. Keep your permission metadata synchronized with your source systems.&lt;/p>
&lt;h3 class="relative group">Security Considerations
&lt;div id="security-considerations" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#security-considerations" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Audit Trails:&lt;/strong> Log what users searched for and what documents were accessed. Compliance teams will thank you.&lt;/p>
&lt;p>&lt;strong>Data Residency:&lt;/strong> Know where your embeddings and cached data live. Some enterprises have strict requirements about data geography.&lt;/p>
&lt;p>&lt;strong>Prompt Injection Protection:&lt;/strong> Users will try to trick your system into revealing information they shouldn&amp;rsquo;t see. Implement safeguards against prompt injection attacks.&lt;/p>
&lt;h2 class="relative group">Upgrade 9: Presentation is Half the Battle
&lt;div id="upgrade-9-presentation-is-half-the-battle" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#upgrade-9-presentation-is-half-the-battle" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Having the right answer is only half the problem. Presenting it in a way that builds user trust and provides actionable information is the other half.&lt;/p>
&lt;h3 class="relative group">Citation and Source Attribution
&lt;div id="citation-and-source-attribution" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#citation-and-source-attribution" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Always Cite Sources:&lt;/strong> Every claim should link back to the source document, with page numbers or section references when possible.&lt;/p>
&lt;p>&lt;strong>Confidence Indicators:&lt;/strong> Show users how confident the system is. &amp;ldquo;Based on 3 highly relevant documents&amp;rdquo; vs &amp;ldquo;Based on 1 partially relevant document&amp;rdquo; sets very different expectations.&lt;/p>
&lt;p>&lt;strong>Source Metadata:&lt;/strong> Show document dates, authors, and types. A 5-year-old troubleshooting guide has different credibility than last week&amp;rsquo;s policy update.&lt;/p>
&lt;h3 class="relative group">Answer Formatting
&lt;div id="answer-formatting" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#answer-formatting" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h3>
&lt;p>&lt;strong>Structured Responses:&lt;/strong> Don&amp;rsquo;t just return paragraphs. Use bullet points, tables, step-by-step instructions when appropriate.&lt;/p>
&lt;p>&lt;strong>Progressive Disclosure:&lt;/strong> Start with a concise answer, then offer &amp;ldquo;Show more detail&amp;rdquo; options for users who want to dig deeper.&lt;/p>
&lt;p>&lt;strong>Multi-Modal Responses:&lt;/strong> If your knowledge base includes images, charts, or code snippets, surface them alongside text answers.&lt;/p>
&lt;h2 class="relative group">The Implementation Reality
&lt;div id="the-implementation-reality" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#the-implementation-reality" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Let me be honest: these aren&amp;rsquo;t just academic improvements. They&amp;rsquo;re the difference between a system that works in your demo and one that works when your boss&amp;rsquo;s boss uses it.&lt;/p>
&lt;p>&lt;strong>Start with hybrid search and reranking.&lt;/strong> These are the highest-ROI improvements. Most vector databases now support hybrid search out of the box (Weaviate, Pinecone, Elasticsearch). For rerankers, Cohere has an excellent API, or you can use open-source models like &lt;code>ms-marco-MiniLM-L-12-v2&lt;/code>.&lt;/p>
&lt;p>&lt;strong>But here&amp;rsquo;s the priority order for real production systems:&lt;/strong>&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Fix your data first&lt;/strong> (Upgrade 4). No amount of fancy retrieval will save you from bad chunking and dirty data.&lt;/li>
&lt;li>&lt;strong>Add measurement and monitoring&lt;/strong> (Upgrade 5). You can&amp;rsquo;t improve what you can&amp;rsquo;t measure.&lt;/li>
&lt;li>&lt;strong>Implement hybrid search and reranking&lt;/strong> (Upgrades 1-2). Highest ROI improvements.&lt;/li>
&lt;li>&lt;strong>Handle uncertainty gracefully&lt;/strong> (Upgrade 6). Better to say &amp;ldquo;I don&amp;rsquo;t know&amp;rdquo; than to hallucinate confidently.&lt;/li>
&lt;li>&lt;strong>Optimize for production constraints&lt;/strong> (Upgrades 7-9). Speed, security, and presentation matter.&lt;/li>
&lt;li>&lt;strong>Consider agentic architectures&lt;/strong> (Upgrade 3). Only when you&amp;rsquo;ve hit the limits of linear RAG.&lt;/li>
&lt;/ol>
&lt;h2 class="relative group">The Bottom Line: Production RAG is Systems Engineering
&lt;div id="the-bottom-line-production-rag-is-systems-engineering" class="anchor">&lt;/div>
&lt;span
class="absolute top-0 w-6 transition-opacity opacity-0 ltr:-left-6 rtl:-right-6 not-prose group-hover:opacity-100 select-none">
&lt;a class="group-hover:text-primary-300 dark:group-hover:text-neutral-700 !no-underline" href="#the-bottom-line-production-rag-is-systems-engineering" aria-label="Anchor">#&lt;/a>
&lt;/span>
&lt;/h2>
&lt;p>Building a basic RAG is now table stakes. Building a RAG that survives contact with real users, enterprise security requirements, and production scale? That&amp;rsquo;s systems engineering.&lt;/p>
&lt;p>The difference between a prototype and production isn&amp;rsquo;t just code, it&amp;rsquo;s data quality, monitoring, user experience, security, and operational concerns. The companies winning with RAG aren&amp;rsquo;t the ones with the fanciest algorithms; they&amp;rsquo;re the ones who&amp;rsquo;ve solved these unglamorous but critical problems.&lt;/p>
&lt;p>Your users don&amp;rsquo;t care about your embedding model. They care about getting accurate, fast, trustworthy answers to their questions. Everything else is just implementation details.&lt;/p>
&lt;p>The tools are evolving rapidly; LlamaIndex, LangChain, specialized vector databases, evaluation frameworks. But the fundamentals remain: clean data, good measurement, graceful failure handling, and respect for production constraints.&lt;/p>
&lt;p>The future belongs to RAG systems that are both intelligent and reliable. Make yours one of them.&lt;/p></content:encoded><media:content xmlns:media="http://search.yahoo.com/mrss/" url="https://pinishv.com/articles/so-youve-built-a-rag-now-lets-make-it-not-suck/feature.png"/></item></channel></rss>