बहुतेक RAG ट्युटोरियल्स केवळ डेमोपर्यंतच मर्यादित असतात. तुम्ही टोकन काउंटनुसार चंकिंग करता, सर्व काही व्हेक्टर डेटाबेसमध्ये भरता आणि काम संपल्यासारखे मानता. जेव्हा एखादा वापरकर्ता स्वच्छ FAQ मध्ये "रिटर्न पॉलिसी काय आहे?" असा प्रश्न विचारतो, तेव्हा हे काम करते. परंतु, जेव्हा कोणी अर्धा करार पेस्ट करतो आणि तिसऱ्या कलमाबद्दल विचारतो, किंवा जेव्हा एखादा डेव्हलपर तुमच्या डॉक्युमेंटेशन सर्चमध्ये एखादा क्लिष्ट एरर कोड टाईप करतो, तेव्हा हे मॉडेल कोलमडते.

ठराविक टोकन विंडोजमुळे कायदेशीर करारांची वाक्ये मध्येच कापली जातात. मोठ्या चंक्समुळे API संदर्भ परिच्छेदांच्या गोंधळात दबले जातात. सर्वात वाईट म्हणजे, संथ रिट्रिव्हलमुळे (slow retrieval) मॉडेलने जनरेट करायला सुरुवात करण्यापूर्वीच वापरकर्ते क्वेरी सोडून देतात. आम्ही हा धडा कष्टाने शिकलो. जेव्हा आम्ही आमचा रिट्रिव्हल लेयर केवळ आशेवर न ठेवता मोजमापावर आधारित केला, तेव्हा आम्ही लॅटन्सी (latency) चाळीस टक्क्यांनी कमी केली आणि रिकॉल (recall) पंच्याण्णव टक्क्यांपर्यंत नेला. नेमके काय बदलले ते खाली दिले आहे.

स्मार्ट चंकिंग (Smart Chunking)

चंक साइजला (chunk size) एक जादूची संख्या मानणे थांबवा. ५१२-टोकन विंडो अशा कायदेशीर दस्तऐवजासाठी अर्थहीन आहे जिथे एकच कलम अनेक परिच्छेदांमध्ये पसरलेले असते, आणि API डॉक्ससाठी देखील ती तितकीच निरुपयोगी आहे जिथे फंक्शन सिग्नेचर आणि त्याचे दोन ओळींचे वर्णन एकत्र असणे आवश्यक आहे. आम्ही स्ट्रक्चर-अवेअर स्प्लिटिंगकडे (structure-aware splitting) वळलो.

कायदेशीर मजकुरासाठी, रिकर्सिव्ह चंकिंग (recursive chunking) दस्तऐवजाच्या श्रेणीबद्ध रचनेचा (hierarchy) आदर करते. यामुळे कलमे (clauses) अखंड राहतात. API डॉक्युमेंटेशनसाठी, आम्ही फंक्शन-अवेअर स्प्लिटिंगचा वापर करतो जे सिग्नेचर, पॅरामीटर्स आणि उदाहरणे एकत्र 'अॅटॉमिक युनिट्स' म्हणून ठेवते. सपोर्ट तिकीट आणि संवादात्मक डेटासाठी सिमँटिक सीमांची (semantic boundaries) आवश्यकता असते, जिथे कोणताही कोणताही कॅरेक्टर काउंट न पाहता विषय बदलतो तिथे विभाजन केले जाते. याचा परिणाम असा होतो की प्रत्येक चंक उपयुक्त ठरण्याइतपत पुरेसा संदर्भ वाहून नेतो, पण तो इतका जास्तही नसतो की मूळ माहितीचा अर्थच बदलून जाईल. तुमच्या एम्बेडिंग मॉडेलचे (embedding model) लक्ष केंद्रित करण्याची क्षमता मर्यादित असते. त्याचा वापर शहाणपणाने करा.

हायब्रिड रिट्रिव्हल (Hybrid Retrieval)

व्हेक्टर सर्च संकल्पनादृष्ट्या समान मजकूर शोधण्यात उत्कृष्ट आहे. संथ डेटाबेस क्वेरींबद्दल विचारले तर ते परफॉर्मन्स ट्यूनिंग गाईड्स समोर आणते. परंतु "Error 0x80070057" बद्दल विचारले तर सिमँटिक सर्च असंबंधित क्षेत्रात जाऊ शकते, कारण डेन्स एम्बेडिंग्स (dense embeddings) अचूक मॅचेस हाताळण्यात फारसे सक्षम नसतात. दुसरीकडे, BM25 अचूक स्ट्रिंग्स आणि दुर्मिळ शब्द अचूकपणे शोधते, तरीही "latency" आणि "slow response time" यांचा अर्थ एकच आहे हे त्याला समजत नाही.

आम्ही दोन्ही पद्धती समांतरपणे चालवतो आणि त्यांना Reciprocal Rank Fusion (RRF) द्वारे एकत्रित करतो. RRF सोपे आणि प्रभावी आहे. ते प्रत्येक पद्धतीतून मिळालेल्या रँक्ड लिस्ट घेते आणि त्यांच्या स्थानावर आधारित कागदपत्रांना स्कोअर देते, ज्यामुळे दोन्ही सिस्टममधील मजबूत उमेदवारांना समान संधी मिळते. फ्यूजननंतर, आम्ही एकत्रित निकालांवर क्रॉस-एन्कोडर रँकर (cross-encoder reranker) चालवतो आणि फक्त टॉप पाच निकाल परत करतो. रँकरमुळे सुमारे पन्नास मिलीसेकंद लॅटन्सी वाढते, परंतु यामुळे आमचा रिकॉल पंधरा टक्क्यांनी सुधारला. जनरेशनच्या गुणवत्तेत मिळणारा फायदा या लॅटन्सीच्या तुलनेत कित्येक पटीने जास्त आहे.

क्वेरी एक्सपान्शन (Query Expansion)

वापरकर्ते क्वेरी करण्यात फारसे कुशल नसतात. ते शब्दांचे लघुरूप वापरतात, स्पेलिंग चुकवतात किंवा एकाच लांब वाक्यात तीन प्रश्न विचारतात. जर तुम्ही त्यांनी टाईप केलेले अगदी तसेच शोधले, तर तुम्हाला त्यांच्या खरोखर आवश्यक असलेल्या दस्तऐवजांची उणीव भासेल.

आम्ही आता इंडेक्सवर पोहोचण्यापूर्वी प्रत्येक क्वेरीमध्ये बदल करतो. पहिले, समानार्थी शब्द आणि पर्यायी शब्दरचना कव्हर करण्यासाठी आम्ही मूळ प्रश्नाचे अनेक पुनर्रचित (rephrased) प्रकार तयार करतो. दुसरे, आम्ही जटिल प्रश्नांचे लहान उप-प्रश्नांमध्ये विभाजन करतो. "आंतरराष्ट्रीय ग्राहकांसाठी रिफंड का अयशस्वी होत आहे आणि मी ते कसे दुरुस्त करू शकतो?" सारखी क्वेरी दोन वेगळ्या शोधांमध्ये विभागली जाते: एक आंतरराष्ट्रीय रिफंड अपयशाबद्दल आणि दुसरी सुधारणेच्या उपायांबद्दल. केवळ क्वेरी एक्सपान्शनमुळे आमचा रिकॉल अठ्ठ्याहत्तर टक्क्यांवरून चौर्याण्णव टक्क्यांपर्यंत पोहोचला. धडा साधा आहे: वापरकर्त्याच्या पहिल्या मसुद्यावर विश्वास ठेवू नका. त्यांना मदत करा.

अंदाज लावणे थांबवा, शोधणे सुरू करा

चंक साइज, ओव्हरलॅप टक्केवारी, top-k कटऑफ आणि रँकर डेप्थ या गोष्टी अशा प्रकारे एकमेकांशी संबंधित असतात की त्या मॅन्युअली ट्यून करणे अशक्य असते. आम्ही २५६ टोकन्स ५१२ पेक्षा चांगले आहेत की नाही यावर चर्चा करण्यात खूप वेळ घालवला, परंतु ओव्हरलॅप सेटिंगकडे दुर्लक्ष केले जे प्रत्यक्षात सुसंगतता (coherence) नष्ट करत होते.

आम्ही अंतर्ज्ञानाच्या (intuition) जागी बेयसियन ऑप्टिमायझेशनचा (Bayesian optimization) वापर केला. ग्रिड सर्चऐवजी, जे स्पष्टपणे खराब असलेल्या भागांवर कॉम्प्युट वाया घालवते, बेयसियन पद्धती काय काम करते याचे संभाव्यता मॉडेल (probabilistic model) तयार करतात आणि लॅटन्सी कमीत कमी ठेवून रिकॉल जास्तीत जास्त वाढवणारा 'पारेटो फ्रंटियर' (Pareto frontier) शोधण्याचा प्रयत्न करतात. आमच्या स्टॅकसाठी, याचा अर्थ चंक साइज, ओव्हरलॅप आणि top-k चे असे विशिष्ट संयोजन शोधणे होता ज्यामुळे आमचा लॅटन्सी बजेट न बिघडवता पंच्याण्णव टक्के रिकॉल मिळाला. विविध वापराच्या गरजांनुसार (use cases) त्या फ्रंटियरवर वेगवेगळे बिंदू मिळाले. ग्राहक-केंद्रित चॅटबॉट्सनी वेगाला प्राधान्य दिले. अंतर्गत कायदेशीर संशोधनाने रिकॉलला प्राधान्य दिले. ऑटोमेटेड ऑप्टिमायझेशनमुळे आम्हाला कॉन्फिग फाइल्स मॅन्युअली कॉपी-पेस्ट न करता दोन्ही सेवा प्रदान करणे शक्य झाले.

निकाल (The Results)

आकडेवारी स्पष्टपणे बोलते. आमचा Recall@10 ७८ टक्क्यांवरून ९५ टक्क्यांपर्यंत वाढला. p95 latency ८५० मिलीसेकंदातून ३२० मिलीसेकंदपर्यंत कमी झाली. आणि मॉडेलला शेवटी गोंधळण्याऐवजी (noise) संबंधित संदर्भ (relevant context) मिळत असल्याने, hallucination rate १२ टक्क्यांवरून ३ टक्क्यांपर्यंत खाली आला. उत्तम रिट्रिव्हल केवळ उत्तरे जलद करत नाही, तर ती अचूक देखील बनवते.

पुढे काय करावे

जर तुम्ही तुमचे रिट्रिव्हल लेयर (retrieval layer) पुन्हा तयार करत असाल, तर इथून सुरुवात करा:

  • टोकन संख्येऐवजी दस्तऐवजाच्या रचनेनुसार चंक (chunk) करा. तुमची स्प्लिटिंग स्ट्रॅटेजी तुमच्या डेटाच्या स्वरूपाशी जुळवून घ्या.
  • हायब्रिड रिट्रिव्हलचा वापर करा. वेक्टर सर्च आणि BM25 एकत्र करा, Reciprocal Rank Fusion ने ते विलीन करा आणि जनरेट करण्यापूर्वी रँक पुन्हा करा (rerank).
  • चांगल्या कव्हरेजसाठी क्वेरीजचा विस्तार करा. सर्च सुरू होण्यापूर्वी त्या पुन्हा शब्दांत मांडून (rephrase) आणि त्यांचे विभाजन (decompose) करा.
  • चाचणीसाठी एक गोल्डन डेटासेट तयार करा. तुम्ही ज्या गोष्टीचे मोजमाप करू शकत नाही, तिचे ऑप्टिमायझेशन करू शकत नाही.
  • स्वयंचलित साधनांद्वारे पॅरामीटर्स ऑप्टिमाइझ करा. तुमच्या अंतर्ज्ञानापेक्षा Bayesian search अधिक चांगले सेटिंग्ज शोधून देईल.

रिट्रिव्हल ही अशी कॉन्फिगरेशन फाईल नाही जी तुम्ही एकदा सेट करून विसरून जाल. हे एक इन्फ्रास्ट्रक्चर आहे, आणि इन्फ्रास्ट्रक्चरला प्रोडक्शन कोडप्रमाणेच तितक्याच काटेकोरपणाची गरज असते: चाचण्या, मोजमाप आणि सततचे ऑप्टिमायझेशन. याकडे त्याच दृष्टीने पहा, आणि तुमची RAG सिस्टीम केवळ एक डेमो न राहता एक प्रॉडक्ट बनू लागेल.

पर्यायी लर्निंग कम्युनिटी: GyaanSetu AI