طویل ایجنٹ turns کو context window کے اندر رکھنا
ایک model ایک وقت میں صرف اتنا پڑھ سکتا ہے، یعنی اس کی context window۔ Mythex کا ایجنٹ طویل کام کرتا ہے: بہت سی فائلیں پڑھنا، کمانڈز چلانا، اور محدود کام sub-agents کو سونپنا۔ ہم نے تین طریقے دیکھے جن سے طویل کام ٹوٹتا تھا: sub-agents اتنے بڑھ جاتے تھے کہ model ہر request رد کر دیتا، ایک sub-agent جلد رک جاتا کیونکہ اسے لگتا کہ جگہ ختم ہو گئی، اور روسی، چینی اور جاپانی متن کے لیے ہماری token گنتی بری طرح غلط تھی۔ یہ ہے جو ہم نے بدلا۔
پہلے کچھ اصطلاحات
- Tokens وہ حصے ہیں جو model پڑھتا ہے۔ حدیں اور لاگت انہی میں گنی جاتی ہیں، حروف یا الفاظ میں نہیں۔
- Context window وہ زیادہ سے زیادہ ہے جو model ایک request میں پڑھ سکتا ہے۔ ہم ہر request کے لیے اپنا کم بجٹ بھی رکھتے ہیں، تاکہ لاگت اور رفتار معقول رہیں۔
- Tool results وہ ہیں جو ایجنٹ اپنے tools سے واپس لیتا ہے: کسی پڑھی گئی فائل کا مواد، یا چلائی گئی کمانڈ کا output۔ طویل کام میں یہی وہ چیز ہے جو سب سے زیادہ بھیجی جاتی ہے۔
- Sub-agent ایک مددگار ہے جسے مرکزی ایجنٹ ایک خود مختار کام کے لیے شروع کرتا ہے، جیسے “ان ابواب کو notes کے مقابل چیک کرو”۔ اسے ایک ہدایت ملتی ہے، پھر وہ خود بہت سی tool calls کے ذریعے کام کرتا ہے۔
مسئلہ 1: sub-agents اتنے بڑھ جاتے کہ model انکار کر دیتا
ہر قدم پر ایجنٹ اب تک کی conversation model کو بھیجتا ہے۔ جب وہ بہت بڑی ہو جاتی تو ہمارا کوڈ اسے کاٹتا، مگر صرف ایک user message کی شروعات پر، تاکہ کوئی tool call اور اس کا نتیجہ کبھی الگ نہ ہوں۔ یہ پہلا پیغام رکھتا، ایک نوٹ شامل کرتا کہ پہلے کی گفتگو کاٹ دی گئی ہے، اور نئی مکمل turns رکھتا جو فٹ ہوتی تھیں۔
ایک sub-agent کا بالکل ایک user message ہوتا ہے: اس کی ہدایت۔ وہاں کاٹنے کی کوئی جگہ نہیں تھی۔ اس لیے وہ ہر قدم پر اپنی پوری تاریخ بھیجتا، اور ہر بار بڑھتی جاتی، یہاں تک کہ request اس سے بڑی ہو جاتی جو model قبول کرتا ہے: تقریباً ایک ملین tokens۔ ایک ٹیسٹ میں 8 ایسے sub-agents میں سے سب 8 رد ہو گئے۔
حل: پہلے پرانے tool results صاف کریں
اب requests تین مراحل میں بجٹ میں فٹ ہوتی ہیں، ہر ایک صرف تب آزمایا جاتا ہے جب پچھلا کافی نہ ہو:
- سب سے پرانے tool results صاف کریں۔ ان کا مواد ایک مختصر نوٹ سے بدل دیا جاتا ہے: نتیجہ model کی context window کے اندر رکھنے کے لیے صاف کیا گیا، اور ایجنٹ ضرورت ہو تو tool دوبارہ چلا سکتا ہے۔ ایک گھنٹہ پہلے پڑھی گئی فائل عموماً درخواست میں سب سے بڑی اور سب سے کم کارآمد چیز ہوتی ہے، اور فائل اب بھی دوبارہ پڑھی جا سکتی ہے۔ نئے نتائج پورے رہتے ہیں۔
- مکمل user turns رکھیں۔ پہلے کی طرح: پہلا پیغام، ایک نوٹ، اور نئے مکمل turns جو فٹ ہوں۔
- مکمل tool rounds رکھیں۔ ایک طویل turn کے اندر، جو کہ وہ واحد قسم ہے جو sub-agent کے پاس ہوتی ہے: پہلا پیغام، ایک نوٹ، اور “ایک tool کو کال کرنا، اس کا نتیجہ لینا” والے نئے مکمل rounds۔
یہ صرف بھیجی جانے والی چیز کی شکل بدلتا ہے۔ ایجنٹ کی محفوظ تاریخ سب کچھ رکھتی ہے۔ اسی ٹیسٹ میں 8 میں سے 0 رد ہوئے اور سب 8 مکمل ہو گئے۔
بیچ میں صفائی، تاکہ caching کام کرتی رہے
model providers کسی request کی شروعات کو دوبارہ استعمال کر سکتے ہیں اگر وہ پچھلی request جیسی ہو، یعنی prefix cache۔ اگر ہم ہر call پر ایک اور نتیجہ صاف کرتے تو request کی شروعات ہر call پر بدل جاتی اور cache کبھی مدد نہ کرتا۔
اس لیے پرانے نتائج ایک کے بجائے چار چار کر کے صاف ہوتے ہیں۔ صاف شدہ حصہ کئی calls تک ایک جیسا رہتا ہے۔ جو نتیجہ نوٹ سے بہت زیادہ بڑا نہ ہو اسے چھوڑ دیا جاتا ہے، کیونکہ اسے صاف کرنے سے تقریباً کچھ نہیں بچتا اور پھر بھی request کی شروعات بدل جاتی۔ کتنے نتائج پورے رہیں یہ سائز سے طے ہوتا ہے، گنتی سے نہیں: بجٹ کے ایک چوتھائی میں جو سب سے نئے نتائج فٹ ہوں وہ پورے رہتے ہیں، اور کم از کم ایک ضرور رہتا ہے۔ پہلے ہم ہمیشہ چھ پورے رکھتے تھے، جو چھوٹے کمانڈ آؤٹ پٹ کے لیے ٹھیک تھا، مگر طویل فائل ریڈز کے ساتھ بجٹ کا زیادہ تر حصہ پرانے نتائج کھا جاتا تھا۔
رد ہونے پر اب صاف بتایا جاتا ہے
جو request model غلط قرار دے کر رد کرے اسے اب دوبارہ نہیں بھیجا جاتا؛ وہی request بھیجنے سے وہی جواب ملتا ہے۔ اگر conversation model کے لیے بہت لمبی ہو تو شخص کو یہ دکھتا ہے: “یہ گفتگو model کے ایک بار میں پڑھنے کے لیے بہت لمبی ہو گئی۔ اگلے قدم کے لیے نئی چیٹ شروع کریں، جو کچھ اب تک بنا ہے وہ رہے گا۔” یہ شخص کا فیصلہ ہے، کوئی outage نہیں، اس لیے یہ ہمیں جگاتا نہیں۔
مسئلہ 2: ایجنٹ “کمرہ بچانے” کے لیے رک جاتا تھا
ایک sub-agent کو 40 طویل ابواب پڑھنے کو کہا گیا، وہ 2 کے بعد رک گیا اور کہا کہ وہ جگہ بچانا چاہتا ہے۔ اس نے 400,000 tokens کے بجٹ میں تقریباً 100,000 استعمال کیے تھے۔
اسے کیسے پتا ہوتا کہ اس کے لیے پرانے نتائج اب خود صاف ہو جائیں گے؟ اس لیے ہم نے اسے بتا دیا۔ ایجنٹ کی ہدایات اب کہتی ہیں کہ جب conversation model کی حد سے بڑھ جائے تو سب سے پرانے tool results صاف ہو جاتے ہیں اور نئے پورے رہتے ہیں، تو طویل کام کو جگہ بچانے کے لیے نہ روکیں؛ کام جاری رکھیں، اور اگر صاف شدہ چیز کی ضرورت ہو تو فائل دوبارہ پڑھ لیں۔
جو فکس model کو نظر نہ آئے وہ model کے نقطۂ نظر سے فکس نہیں ہے۔ یہ طریقہ تبھی مدد کرتا ہے جب ایجنٹ اس پر بھروسہ کرے۔
مسئلہ 3: tokens کو ایسے گننا جیسے سب کچھ انگریزی ہو
ہم tokenizer چلائے بغیر tokens کا اندازہ لگاتے تھے: حروف کو چار سے تقسیم کر کے۔ انگریزی کے لیے یہ ایک معقول اندازہ ہے۔ دوسرے رسم الخط کے لیے نہیں: روسی تقریباً 2.2 حروف فی token، اور چینی یا جاپانی تقریباً ایک حرف فی token۔
اس لیے روسی ابواب پڑھنے والے ایک sub-agent نے تقریباً 640,000 tokens کی request بھیجی، جبکہ ہمارا اندازہ کہہ رہا تھا کہ وہ 400,000 کے بجٹ سے کم ہے۔ یہ اندازہ request کو model کی سخت حد سے آگے بھی لے جا سکتا تھا۔
اب اندازہ رسم الخط کے لحاظ سے گنا جاتا ہے: سادہ ASCII چار حروف فی token، چینی، جاپانی اور کورین ایک فی token، اور باقی سب، یعنی سیریلک، یونانی، عربی، لہجے والے حروف اور emoji، دو فی token۔ اس کا مقصد زیادہ کی طرف غلطی کرنا ہے۔ ایک روسی باب پر اب یہ 43,423 tokens کا اندازہ لگاتا ہے، جبکہ ناپے گئے تقریباً 44,600 ہیں؛ پہلے یہ 25,023 کہتا تھا۔ چونکہ ایک پیغام لکھا جانے کے بعد نہیں بدلتا، اس کا اندازہ ایک بار نکالا جاتا ہے اور یاد رکھا جاتا ہے، ہر قدم پر دوبارہ نہیں۔
ہم نے کیا سیکھا
- سائز جہاں ہے وہیں کاٹیں۔ ایجنٹ کے کام میں یہ tool results ہیں، user messages نہیں۔
- ایجنٹ کو اپنے حفاظتی انتظامات کے بارے میں بتائیں۔ ورنہ وہ ایسی حدوں کے گرد منصوبہ بندی کرتا ہے جو اب لاگو نہیں ہوتیں۔
- “حروف ÷ 4” ایک انگریزی مفروضہ ہے۔ ہر وہ چیز جو کثیر لسانی صارفین کے لیے tokens گنتی ہے، اسے رسم الخط کے لحاظ سے گننا ہوگا، یا ایک حقیقی tokenizer استعمال کرنا ہوگا۔
- cache کا خیال رکھیں۔ ہر call پر شروع سے بدلنے والی request زیادہ لاگت اور سست رفتار لاتی ہے۔
اگر آپ اپنی app میں AI features بنا رہے ہیں تو ہماری گائیڈز LLM کیا ہے اور LLM APIs کیسے استعمال کریں شروع سے context windows اور tokens کو کور کرتی ہیں۔ Mythex میں sub-agents کیسے کام کرتے ہیں، اس کے بارے میں مزید sub-agents docs میں ہے۔