अधिकांश RAG ट्यूटोरियल ठीक वहीं समाप्त हो जाते हैं जहाँ से प्रोडक्शन शुरू होता है। आप अपने दस्तावेज़ों को 512-टोकन के चंक्स (chunks) में विभाजित करते हैं, उन्हें एक सिंगल एम्बेडिंग मॉडल के माध्यम से भेजते हैं, और सरल top-k रिट्रीवल के साथ एक वेक्टर डेटाबेस को कॉल करते हैं। एक डेमो में, यह विश्वसनीय लगता है। बॉट से अपनी कंपनी की लीव पॉलिसी के बारे में पूछें और यह एक सुसंगत पैराग्राफ लौटा देता है। हर कोई सिर हिलाता है। दुर्भाग्य से, डेमो झूठ बोलते हैं।

प्रोडक्शन हर शॉर्टकट को उजागर कर देता है। फिक्स्ड चंक्स कानूनी अनुबंधों (legal contracts) को क्षतिपूर्ति क्लॉज (indemnification clauses) के बीच से काट देते हैं। API डॉक्यूमेंटेशन ओवरलैपिंग शोर (noise) में बदल जाता है जो उस सिग्नल को दबा देता है जिसकी आपको वास्तव में आवश्यकता है। लेटेंसी (latency) बढ़ती जाती है जब तक कि उपयोगकर्ता उत्तर आने से पहले ही क्वेरी छोड़ नहीं देते। हम इस दीवार से टकराए और हमें सब कुछ फिर से बनाना पड़ा। हमारा रिट्रीवल लेयर "सिमेंटिक सर्च और उम्मीद" (semantic search and hope) से विकसित होकर एक मापा हुआ, इंस्ट्रुमेंटेड पाइपलाइन बन गया। परिणाम 95% रिकॉल और लेटेंसी में 40% की कमी थी। यहाँ बताया गया है कि वास्तव में क्या काम आया।

चंकिंग रणनीति को दस्तावेज़ के अनुसार मिलाएं

512-टोकन का डिफॉल्ट इसलिए बना हुआ है क्योंकि यह आसान है, इसलिए नहीं कि यह सही है। अलग-अलग दस्तावेज़ अलग-अलग तरह से अर्थ रखते हैं, और आपकी चंकिंग रणनीति को उसे प्रतिबिंबित करना चाहिए।

कानूनी अनुबंधों (legal contracts) के लिए, रिकर्सिव चंकिंग (recursive chunking) का उपयोग करें जो संरचनात्मक सीमाओं का सम्मान करती है। कानूनी भाषा नेस्टेड (nested) होती है। एक क्लॉज अपने ऊपर वाले सेक्शन पर निर्भर करता है, और वाक्य के बीच में एक फिक्स्ड कट किसी दायित्व (obligation) के तर्क को नष्ट कर देता है। रिकर्सिव चंकिंग टोकन सीमा लागू करने से पहले प्राकृतिक विभाजकों—पहले पैराग्राफ, फिर वाक्य—पर विभाजन करने का प्रयास करती है। यह क्षतिपूर्ति (indemnification) या उत्तरदायित्व (liability) क्लॉज को बरकरार रखता है।

API डॉक्यूमेंटेशन के लिए, फंक्शन-अवेयर चंकिंग (function-aware chunking) का उपयोग करें। डेवलपर्स रैंडम पैराग्राफ नहीं खोजते; वे एंडपॉइंट्स, पैरामीटर्स और एरर सिग्नेचर खोजते हैं। एक चंक में पूरा फंक्शन सिग्नेचर, उसका विवरण और रिटर्न स्कीमा एक लॉजिकल यूनिट के रूप में होना चाहिए। यदि आप उस ब्लॉक को आधा काट देते हैं, तो रिट्रीवल सिस्टम आधा कॉन्टेक्स्ट लौटाता है और जनरेशन मॉडल बाकी के लिए hallucinate करता है।

सपोर्ट टिकटों के लिए, सिमेंटिक चंकिंग (semantic chunking) पर भरोसा करें जो बातचीत के दौर (conversation turns) का पालन करती है। सपोर्ट थ्रेड्स लीनियर और दोहराव वाले होते हैं। एक ग्राहक समस्या को दोहराता है, एक एजेंट लॉग मांगता है, ग्राहक उन्हें अटैच करता है। प्रत्येक दौर अपना स्वयं का सिमेंटिक यूनिट होता है। दौरों के आधार पर चंकिंग यह सुरक्षित रखती है कि किसने क्या और कब कहा, जो तब महत्वपूर्ण होता है जब उपयोगकर्ता पूछता है, "एजेंट ने मंगलवार को क्या सुझाव दिया था?"

इंटरनल विकी (internal wikis) के लिए, एजेंटिक चंकिंग (agentic chunking) आज़माएँ। एक LLM को एक सेक्शन दें और उसे यह तय करने के लिए कहें कि एक विषय कहाँ समाप्त होता है और दूसरा कहाँ शुरू होता है। इसमें इनजेस्ट समय (ingest time) पर अधिक लागत आती है, लेकिन विकी अस्त-व्यस्त होते हैं। पेजों में विभिन्न टीमों से असंबंधित अपडेट होते हैं, और मानव-परिभाषित सीमा शायद ही कभी मदद करती है। टॉपिक शिफ्ट के आधार पर मॉडल को सीमाएं खींचने देने से शोर (noise) में नाटकीय रूप से कमी आती है।

एक ही पाइपलाइन में कई रणनीतियों को चलाने के लिए इनजेस्ट के समय दस्तावेज़ों को प्रकार के अनुसार टैग करने की आवश्यकता होती है। स्कीमा अनुशासन का वह छोटा सा हिस्सा तुरंत लाभ देता है।

खोज विधियों को मिलाएं, केवल एक को न चुनें

वेक्टर सर्च इरादे (intent) को समझता है, लेकिन यह नियमित रूप से सटीक मिलान (exact matches) में विफल रहता है। एरर कोड ERR_CONNECTION_REFUSED या किसी विशिष्ट SKU के लिए पूछें, और डेंस एम्बेडिंग्स (dense embeddings) अक्सर वैचारिक रूप से समान लेकिन तथ्यात्मक रूप से गलत परिणाम लौटाते हैं। BM25, क्लासिक कीवर्ड स्पार्स रिट्रीवल (keyword sparse retrieval) विधि, सटीक स्ट्रिंग्स को खूबसूरती से संभालती है लेकिन सिमेंटिक बारीकियों (semantic nuance) को छोड़ देती है। आपको दोनों की आवश्यकता है।

हाइब्रिड रिट्रीवल (hybrid retrieval) का उपयोग करें। वेक्टर सर्च और BM25 को समानांतर में चलाएं। फिर उन्हें रेसिप्रोकल रैंक फ्यूजन (RRF) के साथ मिलाएं। RRF उन दस्तावेज़ों को पुरस्कृत करता है जिन पर दोनों विधियाँ प्रासंगिक होने के लिए सहमत होती हैं, जबकि किसी भी दृष्टिकोण से मजबूत उम्मीदवारों को सामने लाता रहता है। गणित सरल है और परिणाम स्थिर है: कोई भी एकल रिट्रीवल विधि अंतिम रैंकिंग पर हावी नहीं होती है।

फ्यूजन के बाद, एक क्रॉस-एनकोडर रीरैंकर (cross-encoder reranker) जोड़ें। पहला चरण — वेक्टर प्लस स्पार्स रिट्रीवल — तेज़ और व्यापक है। क्रॉस-एनकोडर फिर पूर्ण ध्यान (full attention) के साथ प्रत्येक क्वेरी-दस्तावेज़ जोड़ी को स्कोर देता है, जिसका अर्थ है कि यह वास्तव में मूल प्रश्न के विरुद्ध उम्मीदवार को पढ़ता है। हाँ, इससे लेटेंसी बढ़ती है। हमारे मामले में, लगभग पचास से एक सौ मिलीसेकंड। लेकिन सटीकता (precision) में वृद्धि इतनी अधिक है कि यह सौदा स्पष्ट है। यदि आप रिकॉल (recall) की परवाह करते हैं, तो आप इसे छोड़ने का जोखिम नहीं उठा सकते।

इंडेक्स को ठीक करने से पहले क्वेरी को ठीक करें

उपयोगकर्ता आपके सर्च इंजन के लिए क्वेरी नहीं लिखते हैं। वे उन्हें मनुष्यों के लिए लिखते हैं। "यह काम नहीं करता" एक सामान्य सपोर्ट क्वेरी है। एक अस्पष्ट फीचर विवरण एक सामान्य इंटरनल विकी सर्च है। यदि आप उस कच्चे इनपुट के साथ इंडेक्स को खोजते हैं, तो आपको कचरा (garbage) वापस मिलता है।

रिट्रीवर तक पहुँचने से पहले क्वेरी को ट्रांसफॉर्म करें।

उपयोगकर्ता के प्रश्न के कई संस्करण बनाने के लिए query expansion का उपयोग करें। यदि कोई "server down" टाइप करता है, तो आपके सिस्टम को "service unavailable," "502 error," और "connection timeout" के लिए भी खोजना चाहिए। इन intent variants को कवर करने से हमारा recall 78% से बढ़कर 96% हो गया। यह एक एकल चरण है, और इसके लाभ की तुलना में इसकी लागत लगभग कुछ भी नहीं है।

जटिल प्रश्नों के लिए query decomposition का उपयोग करें। जब कोई उपयोगकर्ता कुछ ऐसा पूछता है जैसे “How do I migrate from the legacy billing API to the new one and what breaking changes affect enterprise accounts?,” तो इसे उप-प्रश्नों (sub-questions) में तोड़ दें। एक उप-प्रश्न माइग्रेशन चरणों (migration steps) को लक्षित करता है। दूसरा enterprise-specific breaking changes को लक्षित करता है। प्रत्येक इंडेक्स के एक अलग हिस्से तक पहुँचता है। डाउनस्ट्रीम लैंग्वेज मॉडल शोर वाले context window में अनुमान लगाने के बजाय अच्छी तरह से रिट्रीव किए गए chunks से अंतिम उत्तर तैयार करता है।

हाइपरपैरामीटर का अनुमान लगाना बंद करें

एक बार जब आपके पास कई chunking strategies, hybrid retrieval, और query transformation आ जाते हैं, तो आप एक combinatorial समस्या का सामना करते हैं। Chunk size, overlap, fusion weights, reranker depth, और expansion count सभी एक-दूसरे के साथ इंटरैक्ट करते हैं। किसी एक को अलग से बदलने (tweaking) से दूसरा बिगड़ जाता है। इस स्पेस में grid search करना व्यर्थ और धीमा है।

इसके बजाय Bayesian optimization का उपयोग करें। इसे मशीन लर्निंग ट्यूनिंग जॉब की तरह मानें। अपने उद्देश्य को स्पष्ट रूप से परिभाषित करें: latency को एक सीमा के भीतर रखते हुए recall को अधिकतम करें। एक golden dataset बनाएं — कुछ सौ प्रतिनिधि प्रश्न जहाँ आप सटीक रूप से जानते हैं कि कौन से chunks रिट्रीव किए जाने चाहिए। फिर Bayesian search को कुशलतापूर्वक configuration space को एक्सप्लोर करने दें। यह क्या काम करता है इसका एक probabilistic model बनाता है और फिर सबसे आशाजनक क्षेत्रों का परीक्षण करता है।

प्रत्येक संभावित कॉन्फ़िगरेशन (candidate configuration) को staging तक पहुँचने से पहले golden dataset को पास करना होगा। यदि नया chunk size recall को कम करता है या एक भारी reranker आपको latency बजट से बाहर धकेलता है, तो optimization इसे स्वचालित रूप से पकड़ लेता है। यह चर्चा से व्यक्तिगत राय (opinion) को हटा देता है। आप इस बात पर बहस करना बंद कर देते हैं कि 256 या 512 tokens "बेहतर" है और परिणाम पढ़ना शुरू कर देते हैं।

परिणाम

पाइपलाइन में किए गए बदलावों का प्रभाव ठीक वैसा ही रहा जैसा हमने उम्मीद की थी।

  • Recall@10 78% से बढ़कर 95% हो गया।
  • P95 latency 850 ms से घटकर 320 ms हो गई।
  • Hallucination rate 12% से गिरकर 3% हो गया।
  • Cost per query में 38% की कमी आई, जिसका मुख्य कारण यह था कि बेहतर retrieval ने हमें एक छोटे generation model और कम prompt tokens का उपयोग करने की अनुमति दी।

latency में कमी ने टीम के कुछ लोगों को हैरान कर दिया। rerankers और query expansion जोड़ने से ऐसा लग सकता है कि चीजें धीमी हो जाएंगी। लेकिन क्योंकि retrieval की गुणवत्ता में सुधार हुआ, इसलिए generation model को कम prompting, कम अटकलों (speculation) और कम retries की आवश्यकता पड़ी। अच्छी retrieval डाउनस्ट्रीम की हर चीज़ को सस्ता बना देती है।

Retrieval को Infrastructure की तरह मानें

Retrieval कोई ऐसा notebook नहीं है जिसे आप एक बार चलाकर भूल जाएं। यह infrastructure है, और इसे code की तरह प्रबंधित किया जाना चाहिए। अपनी chunking strategies का version बनाए रखें। जब लीगल टीम एक नया कॉन्ट्रैक्ट टेम्पलेट जारी करती है, तो अपने recursive splitter का परीक्षण production तक पहुँचने से पहले करें। अपने golden dataset को जीवित दस्तावेज़ों (living documents) के रूप में बनाए रखें, न कि पिछली तिमाही के किसी static CSV के रूप में। CI में अपने evaluations को automate करें ताकि embedding model या fusion weight को संशोधित करने वाले pull request पर किसी इंसान द्वारा समीक्षा किए जाने से पहले recall और latency नंबरों के साथ एक टिप्पणी (comment) मिल जाए।

आपके उपयोगकर्ता कभी नहीं पूछेंगे कि आप कौन सा embedding model चलाते हैं। उन्हें आपकी chunking heuristic या आपके reranker architecture की परवाह नहीं होगी। उन्हें इस बात की परवाह है कि क्या उत्तर सही है, क्या यह तेज़ी से आता है, और क्या वे इस पर भरोसा कर सकते हैं। एक ऐसा pipeline बनाएं जो वह भरोसा कमाए, उसे ईमानदारी से मापें, और retrieval को केवल एक afterthought की तरह मानना बंद करें।

Source: Optimizing RAG At Scale
Join the discussion: GyaanSetu AI Community