Most teams build their first retrieval system the same way: slice every document into fixed 512-token chunks, push them into a vector database, and hope the embedding model does the hard work. That hope gets you through a demo. It does not survive contact with real users.

In production, a legal contract falls apart when you sever a liability clause from its exceptions. API documentation turns useless when a code sample gets detached from its function signature. A customer support thread becomes noise when you rip a single complaint out of its conversational history. The problem is rarely the language model sitting at the end of the pipeline. The problem is what you feed it.

We learned this the hard way. Our initial retrieval layer looked standard but behaved inconsistently. So we rebuilt it around a simple idea: treat retrieval as measured infrastructure, not magic. Here is exactly what changed, and how we pushed recall to 95 percent while cutting the 95th-percentile latency from 850 ms to 320 ms.

The Fixed-Chunk Trap

Uniform token counts are easy to code and easy to explain. That convenience masks a basic truth: documents have structure. When you ignore that structure, you destroy signal.

Consider a ten-page master service agreement. A fixed 512-token slice will land mid-obligation, splitting a clause from the very cap table that limits it. The retrieval step then returns half a thought. The generator hallucinates the rest. In API documentation, a chunk that is too large dilutes the embedding with boilerplate headers, burying the specific method a developer needs. In support tickets, a fixed window treats a conversation as a bag of sentences, stripping away the back-and-forth that reveals what actually failed.

We stopped treating chunk size as a hyperparameter we guessed. We started treating it as a mapping exercise between the document type and the information architecture inside it.

Match Your Chunking to the Data

The fix is not one perfect chunk size. The fix is three distinct strategies tuned to three distinct data shapes.

Legal documents now go through recursive splitting. The algorithm first looks for the largest natural boundaries—sections, then subsections, then numbered clauses—and only falls back to smaller splits when necessary. This keeps a termination clause attached to its survival conditions. The retrieval step sees complete logical units, which sharply reduces the model’s temptation to invent missing exceptions.

API and code documentation get structure-aware chunking. Markdown headers, code fences, and parameter tables are parsed as atomic units. We do not split inside a code block. We keep docstrings adjacent to their signatures. The result is that a query for a specific class method retrieves the full context a developer needs: the description, the typed parameters, and the working example.

Support and conversational data use semantic chunking. Instead of counting tokens, we look for shifts in topic or intent. If a customer describes a bug in message three and pastes a stack trace in message seven, we chunk by meaning, not by message index. The retrieval layer then returns the full arc of the problem rather than a orphaned sentence.

Why Vector Search Alone Fails

Even perfect chunks die in a pure vector search. Dense embeddings excel at capturing meaning and synonymy, but they are notoriously fuzzy on exact strings. If an engineer searches for the precise error code ERR_CONNECTION_REFUSED, vector similarity might return a dozen conceptual neighbors and miss the exact match buried at rank fourteen.

Keyword search with BM25 has the opposite problem. It finds exact tokens but misses semantic intent. A user asking “why is my database down” will never match a document that says “troubleshooting connection timeouts.”

We now run both. Vector and keyword results are fed into Reciprocal Rank Fusion, which blends the two ranked lists without requiring calibrated scores. The fused list is then passed through a cross-encoder reranker. The reranker is slower than the initial retrieval, but it is far more precise because it judges query-document relevance directly rather than through compressed embeddings. That hybrid pipeline alone lifted our recall by 15 percent.

Fixing Bad Queries Before They Hit the Index

کاربران پرس‌وجوهای جستجوی ایده‌آل نمی‌نویسند. آن‌ها خطوط لاگ ناقص را کپی می‌کنند. می‌گویند «خراب شده است». از اصطلاحاتی استفاده می‌کنند که در مستندات شما هرگز به کار نرفته است. اگر به پرس‌وجوی خام اعتماد کنید، در واقع به نویز اعتماد کرده‌اید.

ما اکنون هر پرس‌وجوی ورودی را قبل از ارسال به لایه بازیابی (retrieval layer)، به سه تا پنج تغییر (variation) گسترش می‌دهیم. یک تغییر می‌تواند یک بازنویسی مستقیم باشد. دیگری می‌تواند یک عنوان ایده‌آل برای سند باشد. سومی کلمات پرکننده (filler) محاوره‌ای را حذف کرده و کلمات کلیدی فنی را استخراج می‌کند. هر نسخه امبد (embed) و جستجو می‌شود. سپس موارد تکراری را حذف کرده و مجموعه‌های کاندیدا را با هم ادغام می‌کنیم.

این کار رایگان نیست. آن فراخوانی‌های اضافی امبدینگ (embedding) هزینه دارد و چند میلی‌ثانیه به زمان اضافه می‌کند. اما تأثیر آن بر فراخوانی (recall) چشمگیر بود: ما با گسترش پرس‌وجوها قبل از بازیابی، از ۷۸ درصد به ۹۶ درصد رسیدیم. از آنجایی که بازیابی بهتر، پنجره تولید (generation window) را کوچک‌تر کرده و مدل را در بافت (context) صحیح مستقر می‌کند، در نهایت باعث صرفه‌جویی در هزینه‌های مراحل بعدی شد. یک مرحله بازیابی کمی گران‌تر، ارزان‌تر از یک مرحله تولید طولانی و توهم‌آمیز (hallucinated) است.

حدس زدن را متوقف کنید. جستجو را شروع کنید.

وقتی چانک‌بندی (chunking)، بازیابی ترکیبی (hybrid retrieval) و گسترش پرس‌وجو را به درستی پیاده کردیم، باز هم با یک آشفتگی ترکیبیاتی روبرو بودیم. اندازه چانک، هم‌پوشانی چانک (chunk overlap)، عمق بازیابی top-k، محدودیت‌های رنکر (reranker cutoffs) و وزن‌های ادغام (fusion weights) همگی با هم در تعامل هستند. یک جستجوی شبکه‌ای (grid search) دستی هفته‌ها طول می‌کشید و باز هم ما را به یک ماکزیمم محلی می‌رساند.

ما برای کاوش در این فضا به بهینه‌سازی بیزی (Bayesian optimization) روی آوردیم. به جای آزمایش تمام ترکیبات به صورت جامع، الگوریتم جستجو یک باور (belief) نسبت به پیکربندی‌هایی که احتمالاً عملکرد خوبی دارند حفظ می‌کند و به تدریج بر مناطق امیدوارکننده تمرکز می‌کند.

خروجی یک تنظیمات واحد و بی‌نقص نیست؛ بلکه یک مرز پارتو (Pareto frontier) از انتخاب‌هاست. در یک سو، یک پیکربندی سبک داریم که برای نقطه انتهایی پشتیبانی از API با توان عملیاتی بالا بهینه شده است: استنتاج سریع، فراخوانی متوسط و کمترین تأخیر ممکن. در سوی دیگر، یک پیکربندی تهاجمی برای بررسی‌های حقوقی داریم: بازیابی عمیق‌تر، رنکینگ سنگین‌تر و هم‌پوشانی بیشتر، که در آن میلی‌ثانیه‌ها را فدای دقت و جامعیت می‌کنیم. از آنجایی که این مرز مشخص است، می‌توانیم به جای ادعای اینکه «یک نسخه برای همه مناسب است»، نقطه مناسب را برای محصول خود انتخاب کنیم.

اعداد در واقعیت چگونه هستند

این تغییرات سیستم را از یک پروتوتایپ شکننده به یک خط لوله (pipeline) تولیدی سنجیده تبدیل کرد.

  • فراخوانی در ده (Recall at ten) از ۷۸ درصد به ۹۵ درصد بهبود یافت. این بدان معناست که وقتی پاسخ صحیح در مجموعه داده‌های ما وجود دارد، از هر بیست مورد، نوزده بار آن را پیدا می‌کنیم.
  • تأخیر در صدک ۹۵ام از ۸۵۰ میلی‌ثانیه به ۳۲۰ میلی‌ثانیه کاهش یافت. پشته ترکیبی (hybrid stack) روی کاغذ سنگین‌تر به نظر می‌رسد، اما ایندکس‌گذاری هوشمندتر، رنکرهای کوچک‌تر و قابلیت ارائه چانک‌های تهاجمی تنها در زمان نیاز، کل سیستم را سریع‌تر کرد.
  • نرخ توهم (Hallucination rate) — که توسط برچسب‌گذاران انسانی روی یک مجموعه داده طلایی (golden dataset) مجزا ردیابی می‌شود — از ۱۲ درصد به ۳ درصد کاهش یافت. وقتی مدل بافت (context) کامل و مرتبط دریافت می‌کند، از ساختن حقایق دست خود می‌کشد.
  • هزینه هر پرس‌وجو از $0.008 به $0.005 کاهش یافت. بازیابی بهتر به معنای پرامپت‌های LLM کوتاه‌تر و متمرکزتر و تلاش‌های کمتر برای بازیابی مجدد است. هزینه اضافی امبدینگ برای گسترش پرس‌وجو، در برابر صرفه‌جویی در مرحله تولید ناچیز است.

یک مجموعه داده طلایی بسازید و با بازیابی مانند کد رفتار کنید

اگر قرار است یک نکته از این متن یاد بگیرید، آن باید انضباط در اندازه‌گیری باشد. ما یک مجموعه داده طلایی کوچک از سوالات واقعی و مکان‌های پاسخ تأیید شده ساختیم. قبل از اینکه هر تغییری به مرحله تولید برسد، روی آن مجموعه داده اجرا می‌شود. فراخوانی و تأخیر به صورت لحظه‌ای (real-time) نظارت می‌شوند، نه اینکه فقط با نگاه کردن در یک نوت‌بوک تخمین زده شوند.

بازیابی یک دموی تحقیقاتی نیست؛ بلکه زیرساخت است. بازیابی مانند بقیه بخش‌های پشته (stack) شما، مستحق تست‌های واحد (unit tests)، بنچمارک‌های رگرسیون و بهینه‌سازی خودکار است. چانک‌ها را بر اساس ساختار سند تقسیم کنید، نه بر اساس خرافات مربوط به توکن (token). جستجوی برداری (vector) و کلمات کلیدی را با یک رنکر ترکیب کنید. پرس‌وجوهایی را که کاربران واقعاً می‌نویسند، گسترش دهید. سپس اجازه دهید یک الگوریتم جستجو به جای شهود شما، پیچ و مهره‌ها را تنظیم کند.

خط لوله‌ای که توصیف کردیم تئوری نیست. می‌توانید گزارش اصلی را اینجا بخوانید، و اگر می‌خواهید درباره مهندسی بازیابی با جامعه‌ای که به این مسائل اهمیت می‌دهد بحث کنید، گروه GyaanSetu AI باز است.