பெரும்பாலான RAG முன்மாதிரிகள் (prototypes) உள்ளுக்குள் ஒரே மாதிரியாகவே இருக்கும். யாராவது ஒரு PDF-ஐ ஒரு pipeline-க்குள் செலுத்தி, உரையைத் துல்லியமான 512-token துண்டுகளாகப் பிரித்து, அவற்றை ஒரு vector database-ல் போட்டுவிட்டு, வேலை முடிந்துவிட்டது என்று கூறிவிடுவார்கள். ஒரு சிறிய டெமோவிற்கு இது சிறப்பாகத் தெரியலாம். ஆனால், உண்மையான பயன்பாட்டில் (production), இது தோல்வியடையும்.
ஒரு நிலையான துண்டு (fixed chunk) எதை வெட்டுகிறது என்பதைக் கவலைப்படுவதில்லை. அது ஒரு சட்ட ஒப்பந்தத்தை (legal contract) இழப்பீடு நிபந்தனையின் (indemnity clause) நடுவிலேயே பிரித்துவிடும். அது தொடர்பில்லாத ஐந்து API endpoints-களை ஒரே context window-க்குள் திணித்து, மாடலை தேவையற்ற இரைச்சலில் (noise) மூழ்கடிக்கும். இது தேவையற்ற பல துண்டுகளைத் தேட வேண்டிய கட்டாயத்தை உருவாக்கி, தாமதத்தை (latency) அதிகரித்து, tokens-களை வீணடிக்கும். இதன் விளைவாக அரைகுறை பதில்கள், மாயத்தோற்றங்கள் (hallucinations) மற்றும் ஏமாற்றமடைந்த பயனர்கள் கிடைப்பார்கள்.
நாங்கள் எங்கள் retrieval layer-ஐ முழுமையாகத் தகர்த்து மீண்டும் கட்டமைத்தோம். அதன் விளைவாக, latency-ஐ 40 சதவீதம் குறைக்கும் அதே வேளையில், 95 சதவீத recall-ஐ எட்டிய ஒரு அமைப்பைப் பெற்றோம். நாங்கள் அதை எப்படிச் செய்தோம் என்பதை இங்கே விரிவாகக் காண்போம்.
ஏன் நிலையான துண்டுகள் (Fixed Chunks) பயன்பாட்டில் தோல்வியடைகின்றன?
512-token என்பது ஒரு திட்டமிட்ட வடிவமைப்பு அல்ல. இது ஆரம்பகால embedding model context windows மற்றும் எளிமையான library defaults ஆகியவற்றின் விளைவாகும். இதைச் செயல்படுத்துவது எளிது, ஆனால் இதை மட்டுமே நம்பியிருப்பது பேரழிவைத் தரும்.
ஆவணங்கள் சீரானவை அல்ல. ஒரு சட்ட நிபந்தனை (legal clause) எந்தத் தடையும் இன்றி எழுநூறு tokens வரை நீளமாக இருக்கலாம். அதை 512-ல் வெட்டினால், இரண்டு தனித்தனித் துண்டுகளை உருவாக்கிவிடுவீர்கள். ஒரு வழக்கறிஞரோ அல்லது இணக்க அதிகாரியோ (compliance officer) பொறுப்பு வரம்புகள் (liability caps) பற்றி கேட்டால், சிஸ்டம் பாதி கடமைகளை மட்டுமே வழங்கும். மொழி மாடல் (language model) விடுபட்ட பாதியைத் தானாகவே கற்பனை செய்து சொல்லும் (hallucinate), அல்லது மோசமாகப் பார்த்தால், அந்த வரம்பு இல்லை என்று மறுக்கும்.
API ஆவணங்கள் இதற்கு நேர்மாறான சிக்கலைச் சந்திக்கின்றன. ஒரு 500-token துண்டு ஒரு முழு தொகுதியையும் (module) விழுங்கிவிடக்கூடும்: authentication headers, error codes, rate limits மற்றும் webhook schemas போன்றவை. ஒரு டெவலப்பர் AUTH_4027-ஐ எவ்வாறு கையாள்வது என்று கேட்டால், retriever தொடர்பில்லாத பல செயல்பாடுகளைக் கலந்து வழங்கும். மாடலுக்கு அவற்றை ஒரு பொதுவான குழப்பமான பதிலாக மாற்றுவதைத் தவிர வேறு வழியில்லை.
தவறான chunking தாமதத்தையும் (latency) அதிகரிக்கிறது. பலவீனமான துண்டுகள் இருந்தால், ஒரு தலைப்பைப் புரிந்துகொள்ள அதிக top-k தேவைப்படும். அதிக துண்டுகள் என்பது நீண்ட prompts என்பதைக் குறிக்கும். நீண்ட prompts என்பது மெதுவான உருவாக்கம் (generation) மற்றும் அதிக செலவு ஆகியவற்றைக் குறிக்கும். இது பயனரின் அனுபவத்தை மெல்ல மெல்லச் சிதைத்துவிடும்.
ஆவணத்திற்கு ஏற்ப துண்டுகளைத் தேர்ந்தெடுங்கள்
நாங்கள் tokens-களை எண்ணுவதை நிறுத்திவிட்டு, உள்ளடக்கத்தைப் படிக்கத் தொடங்கினோம். சரியான chunking உத்தி என்பது மூல ஆவணத்தின் கட்டமைப்பைப் பொறுத்தது.
சட்ட ஆவணங்களுக்கு (Legal documents) நிபந்தனைகளை உணர்ந்த எல்லைகளுடன் கூடிய recursive character chunking தேவைப்படுகிறது. இந்த splitter படிநிலையை (hierarchy) மதிக்கிறது: முதலில் பிரிவுத் தலைப்புகளைத் (section headers) தேடுகிறது, பின்னர் எண்ணிடப்பட்ட பத்திகள், பிறகு இயல்பான வாக்கியப் பிரிவுகளைக் கவனிக்கிறது. இது ஒரு துணை நிபந்தனையையோ (sub-clause) அல்லது ஒரு கடமை சார்ந்த வாக்கியத்தையோ துண்டுகளுக்கு இடையில் பிரிக்காது. நீங்கள் இழப்பீடு (indemnification) பற்றிய ஒரு பகுதியைத் தேடும்போது, முழு நிபந்தனை, அதன் வரம்பு மற்றும் விதிவிலக்குகள் ஆகியவற்றை முழுமையாகப் பெறுவீர்கள்.
API ஆவணங்களுக்கு (API documentation) கட்டமைப்பை உணர்ந்த chunking தேவைப்படுகிறது. நாங்கள் token வரம்பைப் பார்க்காமல், function definition-ஐப் பொறுத்து பிரிக்கிறோம். ஒவ்வொரு துண்டிலும் ஒரு முழுமையான function signature, அதன் parameter விளக்கங்கள் மற்றும் அதற்கு அருகிலுள்ள error handling குறிப்புகள் இருக்கும். ஒரு டெவலப்பர் ஒரு குறிப்பிட்ட முறையைத் (method) தேடினால், அவர்களுக்குத் தெளிவான முழுமையான தகவல் கிடைக்கும், ஏதோ ஒரு இடத்தில் வெட்டப்பட்ட துண்டு கிடைக்காது.
ஆதரவுத் டிக்கெட்டுகள் (Support tickets) இரைச்சலானவை மற்றும் நேரியல் அல்லாதவை (nonlinear). ஒரு உரையாடல் ஒரு bug report-உடன் தொடங்கி, ஒரு மாற்று வழிமுறை (workaround) மற்றும் ஒரு உள்முறைத் தகவல் (internal escalation note) ஆகியவற்றோடு முடியலாம். Semantic chunking என்பது வாக்கியங்களுக்கு இடையிலான embedding similarity-ஐ அளவிடுவதன் மூலம் தலைப்பு மாற்றங்களைக் கண்டறிகிறது. நாங்கள் இயல்பான கருப்பொருள் எல்லைகளில் (thematic boundaries) மட்டுமே பிரிவுகளை அனுமதிக்கிறோம், இதனால் login failures பற்றிய உரையாடல், billing cycles பற்றிய அடுத்தகட்டத் தகவலில் இருந்து தனித்து இருக்கும்.
விக்கி பக்கங்கள் (Wikis) மிகவும் கடினமானவை. அவை பரந்து விரிந்தவை, ஒன்றோடொன்று இணைக்கப்பட்டவை மற்றும் ஒழுங்கற்றவை. நாங்கள் agentic chunking முறையைப் பயன்படுத்தினோம், இதில் ஒரு இலகுரக LLM ஒரு பக்கத்தைப் படித்து, கருப்பொருள் ஒற்றுமையின் அடிப்படையில் பிரிவுகளைத் தீர்மானிக்கிறது. இது தரவுகளைச் சேர்ப்பதில் (ingestion time) சற்று கூடுதல் செலவைச் செய்தாலும், resulting chunks முழுமையானதாகவும் தேடுவதற்குத் தயாராகவும் இருக்கும். deployment best practices பற்றிய ஒரு பக்கம், ஏதோ ஒரு இடத்தில் வெட்டப்பட்ட உரைத் தொகுப்புகளாக இல்லாமல், pre-flight checks, rollback procedures மற்றும் monitoring setup போன்ற தர்க்கரீதியான அலகுகளாகப் பிரிக்கப்படும்.
Hybrid Retrieval: முக்கியச் சொற்களும் (Keywords) வெக்டர்களும் (Vectors) இணைந்து
Dense vector search பொருளைப் புரிந்துகொள்கிறது. ஆனால் துல்லியமான சொற்களைக் (exact strings) கையாள்வதில் இது பலவீனமானது. ஒரு பயனர் AUTH_4027 போன்ற துல்லியமான error code அல்லது "Stark Industries" போன்ற வாடிக்கையாளர் பெயரைத் தேடினால், vector embeddings இலக்கைத் தவறவிடக்கூடும். ஏனெனில் அவை எழுத்துக்களின் துல்லியத்தை விட, கருத்தியல் நெருக்கத்தை (conceptual proximity) மட்டுமே முன்னிறுத்துகின்றன.
BM25 மூலம் செய்யப்படும் தூய keyword search-ல் இதற்கு நேர்மாறான குறைபாடு உள்ளது. அது AUTH_4027-ஐத் துல்லியமாகக் கண்டறியும், ஆனால் "authorization failure" மற்றும் "login denied" ஆகியவற்றிற்கு இடையிலான கருத்தியல் தொடர்பைக் கண்டறியத் தவறிவிடும்.
நாங்கள் இரண்டையும் இணையாக இயக்குகிறோம். BM25 மற்றும் vector search ஆகிய இரண்டும் ஒரே தொகுப்பில் (corpus) தனித்தனியாகச் செயல்படுகின்றன. அவற்றின் முடிவுப் பட்டியல்கள் Reciprocal Rank Fusion மூலம் இணைக்கப்படுகின்றன, இது வேட்பாளர்களின் இடவரிசை நிலைகளை (positional ranks) சமநிலைப்படுத்துவதன் மூலம் அவற்றை மறுவரிசைப்படுத்துகிறது. உங்களுக்குச் சரிசெய்யப்பட்ட எடைகள் (calibrated weights) தேவையில்லை. நீங்கள் ஒரே வரிசைப் பட்டியலில் துல்லியமான பொருத்தத்தின் (exact match) துல்லியத்தையும், semantic search-ன் உள்ளுணர்வையும் எளிதாகப் பெறலாம்.
பிறகு, நாங்கள் ஒரு cross-encoder reranker-ஐச் சேர்க்கிறோம். இது ஒரு தனித்த மாதிரியாகும் (separate model), இது ஒவ்வொரு பத்தியையும் அசல் வினாவிற்கு (original query) எதிராக மதிப்பிட்டு, தனித்தனி மீட்டெடுப்பவர்களை (retrievers) விட மிக நுணுக்கமான பொருத்தத் தகவலை (relevance signal) வழங்குகிறது. இது சுமார் 50 மில்லி விநாடிகள் தாமதத்தை (latency) ஏற்படுத்துகிறது. இது recall-ஐ 15 சதவீதம் அதிகரிக்கிறது. நீங்கள் பதிலின் தரத்தில் அக்கறை கொண்டிருந்தால், அந்தத் தாமதத்தை ஏற்க வேண்டியது அவசியம்.
Query Expansion: தேடல் தொடங்குவதற்கு முன்பே அதைச் சரிசெய்யுங்கள்
மோசமான வினாவுகள் (Bad queries) என்பது ஒவ்வொரு மீட்டெடுப்பு அமைப்பின் (retrieval system) மறைமுகப் பிரச்சனையாகும். பயனர்கள் உங்கள் embedding space-ஐப் போல எழுதுவதில்லை. அவர்கள் "it broke" என்று தட்டச்சு செய்கிறார்கள். அவர்கள் முழுமையற்ற stack traces-களைப் பதியச் செய்கிறார்கள். உங்கள் குறியீட்டில் (index) இதுவரை இல்லாத உள்நாட்டுத் தொழில்நுட்பச் சொற்களை (internal jargon) அவர்கள் பயன்படுத்துகிறார்கள்.
வினாவானது குறியீட்டைத் (index) தொடுவதற்கு முன்பே நாங்கள் அதை மாற்றியமைக்கிறோம். முதலில், ஒரு தனி வினாவை மூன்று முதல் ஐந்து மாறுபட்ட தேடல் சொற்களாக விரிவுபடுத்துகிறோம். அசல் வினாவானது "payment failed" என்று இருந்தால், நாங்கள் "transaction error", "billing declined" மற்றும் "charge unsuccessful" ஆகியவற்றுக்கும் தேடுகிறோம்.
