बहुतेक टीम्स अजूनही त्यांचे पहिले रिट्रिव्हल पाईपलाईन (retrieval pipeline) एकाच पद्धतीने तयार करतात. ते ५१२ सारखी एक ठराविक टोकन मर्यादा निवडतात, कागदपत्रांचे समान ब्लॉक्समध्ये विभाजन करतात आणि ते ब्लॉक्स वेक्टर डेटाबेसमध्ये फीड करतात. साध्या प्रश्नांच्या लहान डेटासेटवर हे जादूई वाटते. परंतु प्रोडक्शनमध्ये (production), हे पूर्णपणे कोलमडते.

जेव्हा एखादा क्लॉज (clause) वाक्याच्या मध्यभागी कापला जातो, तेव्हा कायदेशीर करार (legal contracts) अर्थहीन तुकड्यांमध्ये विभागले जातात. जर एकाच चंकमध्ये (chunk) तीन असंबद्ध फंक्शन्स आले, तर API डॉक्युमेंटेशन गोंधळात टाकणारे बनते. सेगमेंटमधील ओव्हरलॅप (overlap) नसल्यामुळे कस्टमर सपोर्ट तिकीटमधील संदर्भाचा धागा तुटतो. याचे परिणाम आधीच समजण्यासारखे आहेत: वाढलेली लॅटन्सी (latency), कमकुवत रिकॉल (recall) आणि अशी उत्तरे ज्यामुळे जनरेटरला हॅलुसिनेट (hallucinate) करावे लागते.

आम्ही आमचा रिट्रिव्हल लेयर (retrieval layer) पूर्णपणे काढून पुन्हा तयार केला. याचा परिणाम म्हणजे रिकॉल ७८ टक्क्यांवरून ९५ टक्क्यांपर्यंत वाढला, लॅटन्सीमध्ये ६२ टक्क्यांची घट झाली आणि आमची पाईपलाईन शेवटी एखाद्या 'वीकेंड हॅक'ऐवजी खऱ्या इन्फ्रास्ट्रक्चरसारखी काम करू लागली. प्रत्यक्षात काय यशस्वी झाले ते खालीलप्रमाणे आहे.

स्मार्ट चंकिंग: टोकन्सपेक्षा स्ट्रक्चरला महत्त्व

पहिली चूक म्हणजे प्रत्येक दस्तऐवज एकाच भाषेत बोलतो असे मानणे. ५१२-टोकनचा चंक (chunk) कथात्मक गद्यासाठी (narrative prose) योग्य असू शकतो, पण इतर कुठेही नाही. आम्ही अशा रणनीतीकडे वळलो जी मूळ स्त्रोताच्या रचनेचा (anatomy) आदर करते.

कायदेशीर कागदपत्रांसाठी, आम्ही रिकर्सिव्ह चंकिंग (recursive chunking) वापरतो. अल्गोरिदम प्रथम विभाग (sections) आणि कलमे (articles) यांसारख्या उच्च-स्तरीय सीमांवर विभागण्याचा प्रयत्न करतो. जर एखादा विभाग अजूनही खूप मोठा असेल, तर तो उपविभाग (subsections), मग परिच्छेद (paragraphs) आणि नंतर वाक्यांचा शोध घेतो. यामुळे क्लॉजचे तार्किक स्वरूप (logical nesting) जपले जाते. 'नॉन-कम्पिट अग्रीमेंट' (non-compete agreement) अखंड राहते. व्याख्या (definitions) नुकसान भरपाईच्या अटींमध्ये (indemnity terms) मिसळत नाहीत.

API डॉक्युमेंटेशनसाठी स्ट्रक्चर-अवेअर चंकिंगची (structure-aware chunking) गरज असते. फंक्शन सिग्नेचर, त्याचे पॅरामीटर टेबल आणि त्याचे उदाहरण रिक्वेस्ट हे सर्व एकत्र असणे आवश्यक आहे. ठराविक टोकन काउंटनंतर विभागल्यामुळे अनेकदा पॅरामीटर्स एका चंकमध्ये आणि उदाहरणे दुसऱ्या चंकमध्ये राहतात. त्याऐवजी आम्ही डॉक्युमेंट ऑब्जेक्टनुसार चंकिंग करतो. एक चंक एक पूर्ण एंडपॉइंट (endpoint) किंवा एक सिंगल फंक्शन धारण करतो. त्यानंतर रिट्रिव्हर (retriever) असा एक स्वावलंबी संदर्भ देऊ शकतो जो खरोखर प्रश्नाचे उत्तर देतो.

सपोर्ट तिकीटसाठी 'सिमँटिक चंकिंग' (semantic chunking) नैसर्गिकरित्या योग्य ठरते. टोकन बाउंड्रीवर कापण्याऐवजी, विषय कुठे बदलतो हे आम्ही शोधतो. लॉगिन तक्रारीने सुरू होऊन बिलिंग प्रश्नाकडे वळणारे तिकीट दोन सुसंगत भागांमध्ये विभागले जाते. प्रत्येक भागात आवश्यक मेटाडेटा (metadata) असतो आणि मॉडेलला वापरकर्त्याला नेमकी कोणती समस्या आहे याचा अंदाज लावण्याची गरज पडत नाही.

अंतर्गत विकी (Internal wikis) अधिक गुंतागुंतीच्या असतात. त्यामध्ये गद्य, तक्ते, आकृत्या आणि एम्बेड केलेले थ्रेड्स यांचे मिश्रण असते. यासाठी आम्ही एजेंटिक चंकिंग (agentic chunking) वापरतो. एक लहान लँग्वेज मॉडेल (small language model) मजकूर वाचते आणि थीमॅटिकदृष्ट्या पूर्ण युनिट कुठे संपते हे ठरवते. यासाठी डेटा इनजेशन (ingestion) वेळी थोडा जास्त खर्च येतो, परंतु यामुळे प्रत्येक नवीन पेज फॉरमॅटसाठी नियम हाताने सेट करण्याचे मानवी कष्ट वाचतात.

हायब्रीड रिट्रिव्हल: सर्व बाजूंचा विचार करा

वेक्टर सर्च (Vector search) अस्पष्ट अर्थ (fuzzy meaning) समजून घेण्यात उत्कृष्ट आहे. जर तुम्ही 'स्लो अपलोड्स'बद्दल विचारले, तर ते लॅटन्सी आणि बँडविड्थबद्दलचे परिच्छेद आनंदाने परत करेल. परंतु, अचूक मॅचेस (exact matches) चुकवण्यासाठी ते कुप्रसिद्ध आहे. जर एखाद्या डेव्हलपरने ERR_CONNECTION_REFUSED हा एरर कोड शोधला, तर डेंस एम्बेडिंग्स (dense embeddings) अनेकदा त्याला सामान्य गोंधळ (generic noise) मानतात.

BM25, हा क्लासिक कीवर्ड अल्गोरिदम, याच्या अगदी उलट काम करतो. तो अचूक स्ट्रिंग्स आणि दुर्मिळ शब्द अचूकपणे शोधतो, तरीही तो सिमँटिक बारकावे (semantic nuance) misses करतो. करार स्वाक्षरी करण्याबद्दलच्या (signing the agreement) क्वेरीमुळे 'कॉन्ट्रॅक्ट एक्झिक्युट करणे' (executing the contract) असे टॅग असलेले कंटेंट कदाचित कधीच समोर येणार नाही.