ज्यादातर RAG प्रोटोटाइप आंतरिक रूप से एक जैसे ही दिखते हैं। कोई एक PDF को पाइपलाइन में डालता है, टेक्स्ट को व्यवस्थित 512-टोकन के चंक्स (chunks) में काटता है, उन्हें एक वेक्टर डेटाबेस में डाल देता है, और काम पूरा मान लेता है। एक साधारण डेमो के लिए, यह प्रभावशाली लग सकता है। लेकिन प्रोडक्शन में, यह विफल हो जाता है।

एक फिक्स्ड चंक (fixed chunk) इस बात की परवाह नहीं करता कि वह क्या काट रहा है। यह एक कानूनी अनुबंध (legal contract) को क्षतिपूर्ति खंड (indemnity clause) के बीच में ही काट सकता है। यह पांच असंबंधित API एंडपॉइंट्स को एक ही कॉन्टेक्स्ट विंडो में भर सकता है और मॉडल को शोर (noise) से भर सकता है। यह आपको आवश्यकता से अधिक फ्रैगमेंट (fragments) रिट्रीव करने के लिए मजबूर करेगा, जिससे लेटेंसी (latency) बढ़ेगी और टोकन खर्च होंगे। इसका परिणाम आधे-अधूरे जवाब, मतिभ्रम (hallucinations) और निराश उपयोगकर्ता होते हैं।

हमने अपने रिट्रीवल लेयर को पूरी तरह से बदलकर फिर से बनाया। इसका परिणाम एक ऐसा सिस्टम था जिसने लेटेंसी को 40 प्रतिशत कम करते हुए 95 प्रतिशत रिकॉल (recall) हासिल किया। यहाँ बताया गया है कि हमने इसे ठीक कैसे किया।

प्रोडक्शन में फिक्स्ड चंक्स (Fixed Chunks) क्यों विफल हो जाते हैं

512-टोकन का डिफॉल्ट कोई डिज़ाइन विकल्प नहीं है। यह शुरुआती एम्बेडिंग मॉडल कॉन्टेक्स्ट विंडो और लाइब्रेरी के डिफॉल्ट सेटिंग्स का एक उप-उत्पाद (by-product) है। इसे लागू करना आसान है, लेकिन इस पर भरोसा करना विनाशकारी हो सकता है।

दस्तावेज़ एक समान नहीं होते हैं। एक कानूनी खंड बिना किसी स्पष्ट ब्रेक के सात सौ टोकन तक चल सकता है। यदि आप इसे पांच सौ बारह पर काटते हैं, तो आप दो अनाथ टुकड़े (orphaned fragments) बना देते हैं। जब कोई वकील या अनुपालन अधिकारी (compliance officer) लायबिलिटी कैप्स (liability caps) के बारे में पूछता है, तो सिस्टम केवल आधी बाध्यता ही वापस करता है। लैंग्वेज मॉडल गायब आधे हिस्से का मतिभ्रम (hallucinate) करता है, या इससे भी बुरा, यह कह देता है कि कैप मौजूद ही नहीं है।

API डॉक्यूमेंटेशन के साथ इसके विपरीत समस्या होती है। एक पांच सौ टोकन का चंक पूरे मॉड्यूल को निगल सकता है: ऑथेंटिकेशन हेडर, एरर कोड, रेट लिमिट्स और वेबहुक स्कीमा। जब एक डेवलपर पूछता है कि AUTH_4027 को कैसे हैंडल करें, तो रिट्रीवर असंबंधित फंक्शन्स का एक मिश्रण पेश कर देता है। मॉडल के पास उन्हें मिलाकर एक सामान्य और अस्पष्ट जानकारी बनाने के अलावा कोई विकल्प नहीं बचता।

खराब चंकिंग लेटेंसी को भी बढ़ाती है। कमजोर फ्रैगमेंट का मतलब है कि किसी विषय को कवर करने के लिए आपको बड़े top-k की आवश्यकता होगी। अधिक चंक्स का मतलब है लंबे प्रॉम्प्ट्स। लंबे प्रॉम्प्ट्स का मतलब है धीमी जनरेशन और अधिक बिल। उपयोगकर्ता अनुभव धीरे-धीरे पूरी तरह से खराब हो जाता है।

चंक को दस्तावेज़ के अनुरूप बनाएँ

हमने टोकन गिनना बंद कर दिया और सामग्री को पढ़ना शुरू किया। सही चंकिंग रणनीति स्रोत की संरचना पर निर्भर करती है।

कानूनी दस्तावेज़ों (Legal documents) के लिए क्लॉज-अवेयर बाउंड्रीज़ (clause-aware boundaries) के साथ रिकर्सिव कैरेक्टर चंकिंग (recursive character chunking) की आवश्यकता होती है। स्प्लिटर पदानुक्रम (hierarchy) का सम्मान करता है: यह पहले सेक्शन हेडर, फिर नंबर वाले पैराग्राफ और फिर प्राकृतिक वाक्य ब्रेक को देखता है। यह कभी भी किसी सब-क्लॉज को अलग नहीं करता या किसी बाध्यकारी वाक्यांश को चंक्स के बीच में नहीं काटता। जब आप क्षतिपूर्ति (indemnification) के बारे में कोई अंश रिट्रीव करते हैं, तो आपको पूरा क्लॉज, कैप और अपवाद मिलते हैं।

API डॉक्यूमेंटेशन के लिए स्ट्रक्चर-अवेयर चंकिंग (structure-aware chunking) की आवश्यकता होती है। हम टोकन बजट के बजाय फंक्शन डेफिनेशन (function definition) के आधार पर पार्स करते हैं। प्रत्येक चंक में एक पूर्ण फंक्शन सिग्नेचर, उसके पैरामीटर विवरण और उसके ठीक बगल में दिए गए एरर हैंडलिंग नोट्स होते हैं। यदि कोई डेवलपर किसी विशिष्ट मेथड को खोजता है, तो उन्हें पूरा कॉन्ट्रैक्ट मिलता है, न कि किसी मनमाने विभाजन में फंसा हुआ एक टुकड़ा।

सपोर्ट टिकट (Support tickets) शोर भरे और नॉन-लीनियर होते हैं। एक थ्रेड एक बग रिपोर्ट के साथ शुरू हो सकता है, एक वर्कअराउंड पेश कर सकता है, और एक आंतरिक एस्केलेशन नोट के साथ समाप्त हो सकता है। सिमेंटिक चंकिंग (Semantic chunking) वाक्यों के बीच एम्बेडिंग समानता (embedding similarity) को मापकर विषय परिवर्तन का पता लगाती है। हम केवल प्राकृतिक विषयगत सीमाओं (thematic boundaries) पर ही ब्रेक की अनुमति देते हैं, ताकि लॉगिन विफलता के बारे में बातचीत बिलिंग चक्र के फॉलो-अप से अलग रहे।

Wikis सबसे कठिन थे। वे विस्तृत, क्रॉस-लिंक्ड और ढीले ढंग से व्यवस्थित होते हैं। हमने एजेंटिक चंकिंग (agentic chunking) का उपयोग किया, जहाँ एक हल्का LLM एक पेज को पढ़ता है और विषयगत सामंजस्य (thematic coherence) के आधार पर ब्रेक का निर्णय लेता है। इसमें इंजेक्शन टाइम (ingestion time) पर थोड़ा अधिक खर्च होता है, लेकिन परिणामी चंक्स आत्मनिर्भर और रिट्रीवल के लिए तैयार होते हैं। डिप्लॉयमेंट बेस्ट प्रैक्टिसेस के बारे में एक पेज मनमाने टेक्स्ट ब्लॉक के बजाय तार्किक इकाइयों में विभाजित होता है: प्री-फ्लाइट चेक, रोलबैक प्रक्रियाएं और मॉनिटरिंग सेटअप।

हाइब्रिड रिट्रीवल: कीवर्ड्स और वेक्टर्स एक साथ

डेंस वेक्टर सर्च (Dense vector search) अर्थ को समझता है। लेकिन यह सटीक स्ट्रिंग्स (exact strings) के मामले में बहुत खराब है। यदि कोई उपयोगकर्ता AUTH_4027 जैसा सटीक एरर कोड या "Stark Industries" जैसा ग्राहक का नाम खोजता है, तो वेक्टर एम्बेडिंग लक्ष्य को चूक सकती है क्योंकि वे वैचारिक निकटता (conceptual proximity) के लिए ऑप्टिमाइज़ होते हैं, न कि कैरेक्टर-लेवल सटीकता के लिए।

BM25 के माध्यम से शुद्ध कीवर्ड सर्च में इसके विपरीत दोष है। यह AUTH_4027 को पूरी तरह से खोज लेगा, लेकिन यह "authorization failure" और "login denied" के बीच के वैचारिक सेतु (conceptual bridge) को नहीं पहचान पाएगा।

We run both in parallel. BM25 and vector search operate independently over the same corpus. Their result lists are merged using Reciprocal Rank Fusion, which reorders candidates by balancing their positional ranks. You do not need calibrated weights. You simply get the precision of exact match and the intuition of semantic search in a single ranked list.

Then we add a cross-encoder reranker. This is a separate model that scores each passage against the original query, producing a relevance signal far finer than either retriever alone. It adds about 50 milliseconds of latency. It increases recall by 15 percent. If you care about answer quality, that trade is non-negotiable.

Query Expansion: Fix the Search Before It Starts

Bad queries are the dirty secret of every retrieval system. Users do not write like your embedding space. They type "it broke." They paste truncated stack traces. They use internal jargon your index has never seen.

We transform the query before it ever touches the index. First, we expand a single query into three to five diverse search terms. If the original is "payment failed," we also search for "transaction error," "billing declined," and "charge unsuccessful