زیادہ تر RAG ٹیوٹوریلز بالکل وہیں ختم ہو جاتے ہیں جہاں سے پروڈکشن کا آغاز ہوتا ہے۔ آپ اپنی دستاویزات کو 512-ٹکن چنکس (chunks) میں تقسیم کرتے ہیں، انہیں ایک ہی ایمبیڈنگ ماڈل کے ذریعے گزارتے ہیں، اور سادہ top-k ریٹریول کے ساتھ ویکٹر ڈیٹا بیس کو کال کرتے ہیں۔ ایک ڈیمو میں، یہ چیزیں قائل کرنے والی لگتی ہیں۔ بوٹ سے اپنی کمپنی کی چھٹیوں کی پالیسی کے بارے میں پوچھیں اور وہ ایک مربوط پیراگراف واپس کرتا ہے۔ ہر کوئی سر ہلاتا ہے۔ بدقسمتی سے، ڈیمو جھوٹ بولتے ہیں۔

پروڈکشن ہر شارٹ کٹ کو بے نقاب کر دیتی ہے۔ فکسڈ چنکس (Fixed chunks) قانونی معاہدوں کو تلافی کی شقوں (indemnification clauses) کے درمیان سے کاٹ دیتے ہیں۔ API دستاویزات ایسے ہمکلام شور (overlapping noise) میں بدل جاتی ہیں جو اس سگنل کو دبا دیتے ہیں جس کی آپ کو اصل میں ضرورت ہوتی ہے۔ لیٹنسی (Latency) اس وقت تک بڑھتی رہتی ہے جب تک صارفین جواب آنے سے پہلے ہی سوال چھوڑ نہیں دیتے۔ ہم اس دیوار سے ٹکرائے اور ہمیں اسے دوبارہ سے بنانا پڑا۔ ہمارا ریٹریول لیئر "سیمنٹک سرچ اور امید" سے ارتقاء پا کر ایک ناپا ہوا اور انسٹرومینٹڈ پائپ لائن بن گیا۔ اس کا نتیجہ 95% ریکال (recall) اور لیٹنسی میں 40% کمی کی صورت میں نکلا۔ یہاں وہ چیزیں ہیں جو حقیقت میں کام آئیں۔

چنکنگ اسٹریٹیجی کو دستاویز کے مطابق بنائیں

512-ٹکن کا ڈیفالٹ اس لیے برقرار ہے کیونکہ یہ آسان ہے، اس لیے نہیں کہ یہ درست ہے۔ مختلف دستاویزات مختلف طریقوں سے معنی رکھتی ہیں، اور آپ کی چنکنگ اسٹریٹیجی کو اس کی عکاسی کرنی چاہیے۔

قانونی معاہدوں (legal contracts) کے لیے، ریکرسو چنکنگ (recursive chunking) کا استعمال کریں جو ساختی حدود کا احترام کرے۔ قانونی زبان پیچیدہ اور مربوط ہوتی ہے۔ ایک شق (clause) اپنے اوپر والے سیکشن پر منحصر ہوتی ہے، اور جملے کے درمیان میں ایک فکسڈ کٹ منطق کو تباہ کر دیتا ہے۔ ریکرسو چنکنگ ٹوکن کی حد نافذ کرنے سے پہلے قدرتی تقسیم کرنے والوں—پہلے پیراگراف، پھر جملے—پر تقسیم کرنے کی کوشش کرتی ہے۔ یہ تلافی یا ذمہ داری کی شقوں کو مکمل رکھتی ہے۔

API دستاویزات کے لیے، فنکشن کے لحاظ سے چنکنگ (function-aware chunking) کا استعمال کریں۔ ڈویلپرز بے ترتیب پیراگراف تلاش نہیں کرتے؛ وہ اینڈ پوائنٹس (endpoints)، پیرامیٹرز (parameters)، اور ایرر سگنیچرز (error signatures) تلاش کرتے ہیں۔ ایک چنک میں مکمل فنکشن سگنیچر، اس کی تفصیل، اور ریٹرن اسکیمہ (return schema) ایک منطقی اکائی کے طور پر ہونا چاہیے۔ اگر آپ اس بلاک کو آدھا تقسیم کرتے ہیں، تو ریٹریول سسٹم آدھا سیاق و سباق واپس کرتا ہے اور جنریشن ماڈل باقی حصے کے بارے میں غلط معلومات (hallucinate) دیتا ہے۔

سپورٹ ٹکٹس کے لیے، سیمنٹک چنکنگ (semantic chunking) پر بھروسہ کریں جو گفتگو کے مراحل (conversation turns) کی پیروی کرے۔ سپورٹ تھریڈز لکیری اور تکراری ہوتے ہیں۔ ایک صارف مسئلہ دہراتا ہے، ایجنٹ لاگز مانگتا ہے، صارف انہیں منسلک کرتا ہے۔ ہر مرحلہ اپنا ایک سیمنٹک یونٹ ہے۔ مرحلوں کے لحاظ سے چنکنگ اس بات کو محفوظ رکھتی ہے کہ کس نے کیا اور کب کہا، جو اس وقت اہم ہوتا ہے جب صارف پوچھے، "ایجنٹ نے منگل کو کیا مشورہ دیا تھا؟"

اندرونی وکی (internal wikis) کے لیے، ایجنٹک چنکنگ (agentic chunking) آزمائیں۔ ایک LLM کو ایک سیکشن دیں اور اس سے پوچھیں کہ ایک موضوع کہاں ختم ہوتا ہے اور دوسرا کہاں شروع ہوتا ہے۔ یہ انگیجمنٹ کے وقت زیادہ خرچ کرتا ہے، لیکن وکی بہت بکھری ہوئی ہوتی ہے۔ صفحات میں مختلف ٹیموں کی غیر متعلقہ اپ ڈیٹس ہوتی ہیں، اور انسانی طور پر طے شدہ حد شاذ و نادر ہی مددگار ہوتی ہے۔ موضوع کی تبدیلیوں کی بنیاد پر ماڈل کو حدود مقرر کرنے دینے سے شور (noise) میں نمایاں کمی آتی ہے۔

ایک ہی پائپ لائن میں متعدد اسٹریٹیجیز چلانے کے لیے انگیجمنٹ کے وقت دستاویزات کو ان کی قسم کے لحاظ سے ٹیگ کرنا ضروری ہے۔ اسکیمہ کی یہ تھوڑی سی نظم و ضبط فوری طور پر فائدہ مند ثابت ہوتی ہے۔

تلاش کے طریقوں کو ملا کر استعمال کریں، صرف ایک کا انتخاب نہ کریں

ویکٹر سرچ نیت (intent) کو سمجھتی ہے، لیکن یہ اکثر درست مماثلت (exact matches) کے معاملے میں ناکام ہو جاتی ہے۔ اگر آپ ایرر کوڈ ERR_CONNECTION_REFUSED یا کسی مخصوص SKU کے بارے میں پوچھیں، تو ڈینس ایمبیڈنگز (dense embeddings) اکثر تصوراتی طور پر ملتی جلتی لیکن حقیقت میں غلط نتائج واپس کرتی ہیں۔ BM25، جو کہ کلاسک کی ورڈ اسپارس ریٹریول (keyword sparse retrieval) طریقہ ہے، درست اسٹرنگز کو بہت اچھے طریقے سے سنبھالتا ہے لیکن سیمنٹک باریکیوں کو نظر انداز کر دیتا ہے۔ آپ کو دونوں کی ضرورت ہے۔

ہائبرڈ ریٹریول (hybrid retrieval) کا استعمال کریں۔ ویکٹر سرچ اور BM25 کو متوازی طور پر چلائیں۔ پھر انہیں Reciprocal Rank Fusion (RRF) کے ساتھ ملا دیں۔ RRF ان دستاویزات کو اہمیت دیتا ہے جن پر دونوں طریقے اتفاق کرتے ہیں کہ وہ متعلقہ ہیں، جبکہ دونوں طریقوں سے مضبوط امیدواروں کو بھی سامنے لاتا ہے۔ ریاضی سادہ ہے اور نتیجہ مستحکم ہے: کوئی بھی ایک ریٹریول طریقہ حتمی رینکنگ پر حاوی نہیں ہوتا۔

فیوژن کے بعد، ایک کراس انکوڈر ری رینکر (cross-encoder reranker) شامل کریں۔ پہلا مرحلہ — ویکٹر پلس اسپارس ریٹریول — تیز اور وسیع ہے۔ پھر کراس انکوڈر ہر کوئری-دستاویز جوڑے کو مکمل توجہ کے ساتھ اسکور کرتا ہے، جس کا مطلب ہے کہ یہ اصل سوال کے مقابلے میں امیدوار کا اصل مطالعہ کرتا ہے۔ جی ہاں، اس سے لیٹنسی بڑھ جاتی ہے۔ ہمارے معاملے میں، تقریباً پچاس سے سو ملی سیکنڈ۔ لیکن درستگی (precision) میں حاصل ہونے والا اضافہ اتنا زیادہ ہے کہ یہ سودا واضح ہے۔ اگر آپ ریکال کی پرواہ کرتے ہیں تو آپ اسے چھوڑنے کا خطرہ نہیں مول لے سکتے۔

انڈیکس کو ٹھیک کرنے سے پہلے کوئری کو ٹھیک کریں

صارفین آپ کے سرچ انجن کے لیے کوئری نہیں لکھتے۔ وہ انسانوں کے لیے لکھتے ہیں۔ "یہ کام نہیں کر رہا" ایک عام سپورٹ کوئری ہے۔ کسی فیچر کی مبہم تفصیل ایک عام اندرونی وکی سرچ ہے۔ اگر آپ اس خام ان پٹ کے ساتھ انڈیکس تلاش کرتے ہیں، تو آپ کو کچرا (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?"، تو اسے ذیلی سوالات میں تقسیم کر دیں۔ ایک ذیلی سوال ہجرت (migration) کے مراحل پر توجہ دیتا ہے۔ دوسرا انٹرپرائز کے مخصوص breaking changes پر توجہ دیتا ہے۔ ہر سوال انڈیکس کے ایک مختلف حصے تک پہنچتا ہے۔ ڈاؤن اسٹریم لینگویج ماڈل شور زدہ context window میں اندازہ لگانے کے بجائے، بہتر طریقے سے حاصل کردہ حصوں (chunks) سے حتمی جواب تیار کرتا ہے۔

ہائپر پیرامیٹرز کا اندازہ لگانا بند کریں

جب آپ کے پاس متعدد chunking حکمت عملی، hybrid retrieval، اور query transformation موجود ہوں، تو آپ کو ایک ترکیبی (combinatorial) مسئلے کا سامنا کرنا پڑتا ہے۔ Chunk size، overlap، fusion weights، reranker depth، اور expansion count سب ایک دوسرے کے ساتھ جڑے ہوئے ہیں۔ کسی ایک میں تنہا تبدیلی کرنے سے دوسرا متاثر ہوتا ہے۔ اس جگہ (space) پر grid search کرنا فضول اور سست ہے۔

اس کے بجائے Bayesian optimization کا استعمال کریں۔ اسے مشین لرننگ ٹیوننگ کے کام کی طرح سمجھیں۔ اپنے مقصد کو واضح طور پر بیان کریں: لیٹنسی (latency) کو ایک حد کے اندر رکھتے ہوئے ریکال (recall) کو زیادہ سے زیادہ کریں۔ ایک "golden dataset" بنائیں — چند سو نمائندہ سوالات جہاں آپ کو بالکل معلوم ہو کہ کون سے chunks حاصل کیے جانے چاہئیں۔ پھر Bayesian search کو مؤثر طریقے سے کنفیگریشن اسپیس تلاش کرنے دیں۔ یہ اس بات کا ایک احتمالی ماڈل (probabilistic model) بناتا ہے کہ کیا کام کرتا ہے اور پھر اگلے سب سے امید افزا علاقوں کا تجربہ کرتا ہے۔

ہر امیدوار کنفیگریشن کو اسٹیجنگ (staging) تک پہنچنے سے پہلے گولڈن ڈیٹا سیٹ سے گزرنا چاہیے۔ اگر نیا chunk size ریکال کو کم کرتا ہے یا ایک بھاری reranker آپ کو لیٹنسی بجٹ سے تجاوز کرنے پر مجبور کرتا ہے، تو آپٹیمائزیشن اسے خود بخود پکڑ لیتی ہے۔ یہ بحث و مباحثے کا خاتمہ کر دیتا ہے۔ آپ اس بات پر بحث کرنا بند کر دیتے ہیں کہ 256 یا 512 ٹوکنز "بہتر" ہیں اور نتائج پڑھنا شروع کر دیتے ہیں۔

نتیجہ

پائپ لائن میں ہونے والی تبدیلیاں بالکل ویسے ہی مرکب ہوئیں جیسا کہ ہم نے امید کی تھی۔

  • Recall@10 78% سے بڑھ کر 95% ہو گیا۔
  • P95 latency 850 ms سے کم ہو کر 320 ms ہو گئی۔
  • Hallucination rate 12% سے گر کر 3% رہ گیا۔
  • Cost per query میں 38% کمی آئی، جس کی بڑی وجہ یہ تھی کہ بہتر ریٹریول نے ہمیں ایک چھوٹے جنریشن ماڈل اور کم پرامپٹ ٹوکنز کے استعمال کی اجازت دی۔

لیٹنسی میں کمی نے ٹیم کے کچھ لوگوں کو حیران کر دیا۔ rerankers اور query expansion شامل کرنے سے ایسا لگتا ہے کہ چیزیں سست ہو جائیں گی۔ لیکن چونکہ ریٹریول کے معیار میں بہتری آئی، اس لیے جنریشن ماڈل کو کم پرامپٹنگ، کم اندازوں اور کم کوششوں (retries) کی ضرورت پڑی۔ اچھا ریٹریول ڈاؤن اسٹریم کی ہر چیز کو سستا بنا دیتا ہے۔

ریٹریول کو انفراسٹرکچر کی طرح سمجھیں

ریٹریول کوئی ایسی نوٹ بک نہیں ہے جسے آپ ایک بار چلائیں اور بھول جائیں۔ یہ انفراسٹرکچر ہے، اور اسے کوڈ کی طرح مینیج کیا جانا چاہیے۔ اپنی chunking حکمت عملیوں کا ورژن بنائیں۔ جب لیگل ٹیم ایک نیا کنٹریکٹ ٹیمپلیٹ جاری کرے، تو اپنے recursive splitter کو پروڈکشن تک پہنچنے سے پہلے ٹیسٹ کریں۔ اپنے گولڈن ڈیٹا سیٹ کو زندہ دستاویزات (living documents) کے طور پر برقرار رکھیں، نہ کہ گزشتہ سہ ماہی کی کوئی ساکن (static) CSV فائل کے طور پر۔ اپنی ایویلیوایشنز کو CI میں خودکار بنائیں تاکہ جب کوئی پل ریکوسٹ (pull request) ایمبیڈنگ ماڈل یا فیوژن ویٹ میں تبدیلی کرے، تو اسے کسی انسان کے جائزہ لینے سے پہلے ریکال اور لیٹنسی کے اعداد و شمار کے ساتھ ایک تبصرہ مل جائے۔

آپ کے صارفین کبھی نہیں پوچھیں گے کہ آپ کون سا ایمبیڈنگ ماڈل چلا رہے ہیں۔ انہیں آپ کی chunking ہیورسٹک (heuristic) یا آپ کے reranker آرکیٹیکچر سے کوئی سروکار نہیں ہوگا۔ انہیں اس سے فرق پڑتا ہے کہ آیا جواب درست ہے، آیا وہ تیزی سے پہنچتا ہے، اور کیا وہ اس پر بھروسہ کر سکتے ہیں۔ ایک ایسا پائپ لائن بنائیں جو وہ بھروسہ حاصل کرے، اسے ایمانداری سے ناپیں، اور ریٹریول کو محض ایک ضمنی خیال (afterthought) سمجھنا بند کریں۔

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