زیادہ تر انجینئرنگ ٹیمیں retrieval-augmented generation کے ساتھ ایک ہی دیوار سے ٹکراتی ہیں۔ وہ ٹیوٹوریل کے طریقے پر عمل کرتی ہیں: دستاویزات کو پانچ سو بارہ یا ایک ہزار چوبیس ٹوکنز کے مقررہ ٹکڑوں (chunks) میں تقسیم کرنا، انہیں ایک ہی embedding model کے ذریعے گزارنا، اور ایک سادہ top-k lookup کے ساتھ vector database کو کال کرنا۔ ایک سلائیڈ ڈیک پر، یہ سب ٹھیک لگتا ہے۔ لیکن پروڈکشن میں، یہ ناکام ہو جاتا ہے۔

مقررہ ٹکڑے (Fixed chunks) مواد کی پرواہ نہیں کرتے۔ وہ خوشی خوشی ایک قانونی معاہدے کو جملے کے درمیان سے تقسیم کر دیں گے، جس سے ذمہ داری کے شقے (liability clauses) متن کے دو غیر متعلقہ حصوں میں لٹکتے رہ جائیں گے۔ وہ ایک مکمل API endpoint کی تفصیل کو ایک ایسے ہی بھاری بھرکم ٹکڑے میں ڈال دیں گے جو اتنا بڑا ہو کہ صارف نے جس مخصوص پیرامیٹر (parameter) کے بارے میں پوچھا ہو، وہ شور میں ڈوب جائے۔ اور جب retrieval سست ہو، تو ہر ملی سیکنڈ کی latency براہ راست صارف کے تجربے کو متاثر کرتی ہے۔ ہم نے یہ سبق مشکل طریقے سے سیکھا۔ پھر ہم نے اپنے retrieval layer کو مکمل طور پر ختم کر کے دوبارہ بنایا۔ ہمارا recall at ten ستراسی فیصد سے بڑھ کر پچانوے فیصد ہو گیا۔ Latency بڑھی نہیں، بلکہ اس میں خاطر خواہ کمی آئی۔

Copy-Paste RAG کے ساتھ مسئلہ

معیاری RAG stack اب ایک طرح کی ڈیفالٹ سیٹنگ بن گیا ہے۔ چھوٹے ٹکڑے، ایک embedding model، vector search، بس ہو گیا۔ یہ طریقہ کار ایک ڈیمو میں تو کامیاب رہتا ہے کیونکہ ڈیمو میں صاف ستھرے سوالات اور ترتیب شدہ دستاویزات استعمال ہوتی ہیں۔ پروڈکشن کا ڈیٹا کبھی بھی ترتیب شدہ نہیں ہوتا۔

قانونی دستاویزات کی ایک درجہ بندی والی ساخت (hierarchical structure) ہوتی ہے۔ سیکشنز میں سب سیکشنز ہوتے ہیں، اور سب سیکشنز میں شقے (clauses) ہوتے ہیں۔ اگر آپ انہیں ایک عام ٹوکن کاؤنٹر کے ذریعے کاٹیں گے، تو آپ ان تعلقات کو ہی تباہ کر دیں گے جن پر ماڈل کو استدلال (reasoning) کرنے کے لیے ضرورت ہوتی ہے۔ API documentation کی بھی اپنی ساخت ہوتی ہے، لیکن وہ مختلف ہے۔ ایک function signature، اس کے parameters، اس کی return value، اور استعمال کی ایک مثال مل کر ایک منطقی اکائی (logical unit) بناتے ہیں۔ اگر آپ اسے ایک مقررہ ٹوکن ونڈو میں زبردستی فٹ کریں گے، تو یا تو مثال ادھوری رہ جائے گی یا ٹکڑے کو غیر متعلقہ فنکشنز سے بھر دیا جائے گا۔ سپورٹ ٹکٹس الجھے ہوئے، بات چیت پر مبنی اور اچانک موضوع کی تبدیلیوں سے بھرپور ہوتے ہیں۔ Wikis پھیلی ہوئی اور ایک دوسرے سے جڑی ہوئی ہوتی ہیں۔ ایک ہی chunking حکمت عملی ان سب کے لیے کارآمد نہیں ہو سکتی، پھر بھی ٹیمیں عام طور پر یہی کرتی ہیں۔ ہم نے یہ دکھاوا کرنا چھوڑ دیا کہ یہ ممکن ہے۔

اسٹریٹجک Chunking: طریقہ کار کو مواد کے مطابق ڈھالنا

ہم content-aware chunking کی طرف منتقل ہو گئے۔ قانونی دستاویزات کے لیے، ہم recursive chunking استعمال کرتے ہیں جو دستاویز کی درجہ بندی کا احترام کرتی ہے۔ یہ شقوں کو مکمل رکھتی ہے اور سیکشنز کے درمیان parent-child تعلقات کو برقرار رکھتی ہے۔ API documentation کے لیے، ہم نے function-aware chunking بنائی ہے جو ہر function یا endpoint کو ایک حد (boundary) کے طور پر لیتی ہے۔ اگر کسی parameter کی تفصیل لمبی ہو جائے، تو ٹکڑا اس function کے گرد پھیل جاتا ہے، نہ کہ کسی ٹوکن کی حد کے گرد۔ سپورٹ ٹکٹس کے لیے، ہم semantic chunking استعمال کرتے ہیں جو موضوع کی قدرتی حدود کا پتہ لگاتی ہے۔ جب کوئی صارف اچانک بلنگ کی شکایت سے تکنیکی خرابی (technical bug) کی طرف منتقل ہوتا ہے، تو تقسیم اسی مقام پر ہوتی ہے۔ Wikis اور غیر منظم نالج بیسز کے لیے، ہم agentic chunking استعمال کرتے ہیں جہاں ایک ہلکا پھلکا LLM متن کا جائزہ لیتا ہے اور فیصلہ کرتا ہے کہ ایک بامعنی حد کہاں ہونی چاہیے۔ یہ character split کے مقابلے میں سیٹ اپ کرنے میں زیادہ وقت لیتا ہے، لیکن یہی وہ فرق ہے جو کام کرنے والے retrieval اور محض اندازہ لگانے والے retrieval کے درمیان ہوتا ہے۔

Vector search معنی کو سمجھتا ہے، لیکن یہ درست مماثلت (exact matches) کو نظر انداز کر سکتا ہے۔ اگر کوئی صارف ERR_CONNECTION_RESET_0x5F3 جیسا error code پیسٹ کرتا ہے، تو semantic similarity اسے ان پیراگراف سے نیچے رکھ سکتی ہے جو محض نیٹ ورک کی غلطیوں پر عمومی بحث کرتے ہیں۔ دوسری طرف، BM25 درست الفاظ (strings) تلاش کرتا ہے لیکن تصوراتی تعلق (conceptual relatedness) کو نظر انداز کر دیتا ہے۔ آپ کو دونوں کی ضرورت ہے۔

ہم vector search اور BM25 کو متوازی طور پر چلاتے ہیں۔ پھر ہم نتائج کو Reciprocal Rank Fusion، یا RRF کے ذریعے یکجا کرتے ہیں، جو دونوں مختلف سرچ اسپیسز کے اسکورز کو ایک ہی پیمانے پر لائے بغیر نارملائز کرتا ہے۔ فیوژن کے بعد، ہم بہترین امیدواروں (top candidates) کو cross-encoder reranker کے ذریعے بھیجتے ہیں۔ یہ تھوڑی سی latency کا باعث بنتا ہے، لیکن اس سے حاصل ہونے والی درستگی (precision) بہت زیادہ ہے۔ reranker کوئری اور ہر امیدوار کو ایک ساتھ پڑھتا ہے اور ایک ایسا relevance score تفویض کرتا ہے جو ابتدائی embedding کی cosine similarity سے کہیں زیادہ درست ہوتا ہے۔ عملی طور پر، یہ مجموعہ ان درست error codes کو پکڑ لیتا ہے جنہیں خالص vector search چھوڑ دیتا ہے، جبکہ ساتھ ہی ان تصوراتی طور پر متعلقہ troubleshooting اقدامات کو بھی سامنے لاتا ہے جنہیں keyword search نظر انداز کر دیتا۔

Query Expansion: انڈیکس تک پہنچنے سے پہلے صارف کے ان پٹ کو درست کرنا

صارفین مکمل طور پر درست سرچ کوئریز نہیں لکھتے۔ وہ multi-hop سوالات پوچھتے ہیں جیسے کہ "میرا آخری ڈیپلائمنٹ (deploy) کیوں ناکام ہوا اور میں اسے کیسے واپس (roll back) لے جا سکتا ہوں"، جس کے لیے علم کے دو الگ الگ ذخیروں کو تلاش کرنے اور انہیں آپس میں جوڑنے کی ضرورت ہوتی ہے۔ یا وہ مبہم سوالات پوچھتے ہیں جن کا انڈیکس کے ساتھ تعلق بہت کم ہوتا ہے۔

ہم تلاش کرنے سے پہلے کوئریز کو تبدیل کرتے ہیں۔ ایک کثیر الجہتی (multi-hop) سوال کو ذیلی سوالات میں تقسیم کر دیا جاتا ہے۔ ایک مبہم مقصد کو متعدد مخصوص سرچ کوئریز میں پھیلا دیا جاتا ہے۔ ہم نے پایا کہ ایک صارف کی کوئری کو پانچ مختلف سرچ کوئریز میں پھیلانے سے ریکال (recall) اٹھتر فیصد سے بڑھ کر چھانوے فیصد تک جا سکتا ہے۔ یہ LLM کو زیادہ سختی سے پرامپٹ (prompt) کرنے کے بارے میں نہیں ہے۔ یہ ریٹریول سسٹم (retrieval system) کو صحیح سیاق و سباق تلاش کرنے کے لیے زیادہ مواقع فراہم کرنے کے بارے میں ہے۔ ہر تیار کردہ کوئری ایک مختلف زاویے یا اصطلاح کو گرفت میں لیتی ہے، اور ضم شدہ نتائج ایک مکمل تصویر پیش کرتے ہیں۔

بیزین آپٹیمائزیشن (Bayesian Optimization): اندازے لگانا چھوڑ دیں

جب آپ کے پاس متعدد چنکنگ حکمت عملی (chunking strategies)، ہائبرڈ ریٹریول (hybrid retrieval)، اور کوئری ایکسپینشن (query expansion) موجود ہوں، تو آپ کو ایک نئے مسئلے کا سامنا کرنا پڑتا ہے۔ یہاں بہت زیادہ کنٹرولز (knobs) ہیں۔ چنک سائز (chunk size)، اوورلیپ فیصد (overlap percentage)، ویکٹر ویٹ بمقابلہ BM25 ویٹ (vector weight versus BM25 weight)، ری رینکنگ تھریش ہولڈز (reranking thresholds)، اور top-k ویلیوز سب غیر خطی (nonlinear) طریقوں سے ایک دوسرے کے ساتھ عمل کرتے ہیں۔ دستی ٹیوننگ (manual tuning) محض ایک اندازے کا کھیل بن جاتی ہے۔

ہم نے اندازے لگانا چھوڑ دیے۔ ہم اس کا