جب آپ کسی بھی ذمہ دار کے بغیر ایک بڑا منصوبہ بناتے ہیں تو کیا ہوتا ہے؟ زیادہ تر سافٹ ویئر اسٹیکس ایک واحد آرکیسٹریٹر (orchestrator) کا تصور کرتے ہیں۔ ایک عمل (process) اسٹیٹ (state) کو سنبھالتا ہے، کاموں کو قطار (queue) میں رکھتا ہے، اور ٹاسک تقسیم کرتا ہے۔ اگر وہ کوآرڈینیٹر دوبارہ شروع (restart) ہو جائے، تو پورا ورک فلو لڑکھڑا جاتا ہے۔ ایک نیا پروجیکٹ اس مفروضے کو مکمل طور پر بدل دیتا ہے۔ یہ دکھاتا ہے کہ کس طرح AI ایجنٹس کا ایک جھنڈ (swarm) "جاپان کے دو ہفتوں کے سفر کی منصوبہ بندی کریں" جیسے مقصد کو ایک مکمل ٹاسک ٹری (task tree) میں تقسیم کر سکتا ہے، بغیر اس کے کہ کسی ایک نوڈ (node) کے پاس کسی بھی لمحے مکمل منصوبہ موجود ہو۔
بغیر سربراہ والا سسٹم کیوں بنائیں؟
مرکزی منصوبہ سازوں (Centralized planners) کے بارے میں سوچنا آسان ہے۔ آپ سرور کو ایک درخواست بھیجتے ہیں، وہ کام کو تقسیم کرتا ہے، اور ورکرز جواب دیتے ہیں۔ مسئلہ یہ ہے کہ سرور ایک علمی اور جسمانی رکاوٹ (bottleneck) بن جاتا ہے۔ وہ حقیقت کا مالک ہوتا ہے۔
ایک تقسیم شدہ سیٹ اپ (distributed setup) میں، حقیقت ایک مشترکہ تصویر میں بدل جاتی ہے جس پر نیٹ ورک 'گاسپ' (gossip) کے ذریعے متفق ہو جاتا ہے۔ یہ مخصوص Python امپلیمنٹیشن دو الگ تصورات کو آپس میں جوڑتی ہے۔ پہلا ایک تکراری بہتری کا لوپ (iterative refinement loop) ہے: ایک ایجنٹ تجویز لکھتا ہے، دوسرا اسے اسکور کرتا ہے، اور تیسرا اسے بہتر بناتا ہے۔ دوسرا libp2p پر مبنی ایک پیئر ٹو پیئر (peer-to-peer) نیٹ ورکنگ لیئر ہے، جو ایجنٹس کو کسی رجسٹری یا لوڈ بیلنسر کے بغیر خود بخود ایک دوسرے کو تلاش کرنے کی اجازت دیتا ہے۔ اس کا نتیجہ ایک ایسا کلسٹر (cluster) ہے جہاں پیئرز (peers) بغیر کسی آرکیسٹرا کنڈکٹر کے ظاہر ہوتے ہیں، تجویز دیتے ہیں، ووٹ دیتے ہیں، اور عمل درآمد کرتے ہیں۔
چار کردار
سسٹم ہر شریک کو چار میں سے ایک شخصیت تفویض کرتا ہے۔ آپ کو چار جسمانی مشینوں کی ضرورت نہیں ہے۔ وہ ایک لیپ ٹاپ پر بھی موجود ہو سکتے ہیں یا ہوم نیٹ ورک پر پھیلے ہوئے ہو سکتے ہیں۔ کردار یہ ہیں:
Decomposer (تقسیم کرنے والا): یہ ایجنٹ اعلیٰ سطح کا مقصد وصول کرتا ہے اور اسے ذیلی مقاصد (subgoals) میں تقسیم کرنے کی تجویز دیتا ہے۔ چونکہ سسٹم بیک وقت کئی decomposers کو چلاتا ہے، اس لیے آپ کو جاپان کے اسی سفر کے لیے تین مختلف طریقے مل سکتے ہیں۔ ایک جغرافیہ کے لحاظ سے سفر کو تقسیم کر سکتا ہے: ٹوکیو، کیوٹو، اوساکا۔ دوسرا سرگرمیوں کے لحاظ سے تقسیم کر سکتا ہے: نقل و حمل، رہائش، کھانا، سیر و تفریح۔ تیسرا دن کے لحاظ سے ترتیب دے سکتا ہے۔ نیٹ ورک ان سب پر غور کرتا ہے۔
Scorer (اسکور کرنے والا): یہ ایجنٹس ادارتی بورڈ کے طور پر کام کرتے ہیں۔ وہ تجویز کردہ تقسیم کا معائنہ کرتے ہیں اور اسے ریٹ کرتے ہیں۔ اسکور اس بات کی عکاسی کرتا ہے کہ آیا ذیلی مقاصد کافی ٹھوس، غیر ہم آہنگ (non-overlapping) اور مجموعی طور پر جامع ہیں۔ اس سے بھی اہم بات یہ ہے کہ اسکورر فیصلہ کرتا ہے کہ آیا کوئی تجویز قبول کرنے کے لیے کافی اچھی ہے۔ اس کی منظوری کے بغیر، تقسیم معلق رہتی ہے۔
Executor (عمل درآمد کرنے والا): جب ٹری (tree) ان پتے والے نوڈز (leaf nodes) تک پہنچ جاتی ہے جو عمل درآمد کے لیے کافی چھوٹے ہوں، تو executors ان پر قبضہ کرنے کے لیے دوڑتے ہیں۔ وہ مرکزی قطار (central queue) سے اجازت کا انتظار نہیں کرتے۔ اس کے بجائے، وہ یہ طے کرنے کے لیے کہ کس کا حق پہلے ہے، ایک ٹائم اسٹیمپ پروٹوکول (timestamp protocol) کا استعمال کرتے ہیں۔ جیتنے والا کام کو مقامی LLM کال کے ذریعے چلاتا ہے اور نتیجہ براڈکاسٹ کرتا ہے۔
Observer (مشاہدہ کرنے والا): یہ وہ خاموش رکن ہے جس کی ہر نیٹ ورک کو ضرورت ہوتی ہے۔ یہ خاموشی سے گاسپ (gossip) سنتا ہے، باتوں سے پلان ٹری کو دوبارہ تعمیر کرتا ہے، اور ایک پڑھنے کے قابل خلاصہ پرنٹ کرتا ہے۔ چونکہ یہ کبھی بولتا نہیں ہے، اس لیے یہ ایک اہم نکتہ ثابت کرتا ہے: دیر سے شامل ہونے والا کوئی بھی شخص صرف باتیں سن کر پورے منصوبے کا اندازہ لگا سکتا ہے۔
حقیقت کے ماخذ کے طور پر گاسپ (Gossip)
libp2p لیئر ڈسکوری اور میسجنگ کو سنبھالتی ہے۔ ایجنٹس پروٹوکول کی بلٹ ان پیئر ڈسکوری کے ذریعے ایک دوسرے کو تلاش کرتے ہیں، پھر ایک مشترکہ موضوع پر پیغامات براڈکاسٹ کرتے ہیں۔ ریکارڈ کے لیے کوئی ڈیٹا بیس نہیں ہے، کوئی Redis کیش نہیں ہے جو مستند منصوبے کو سنبھالے ہوئے ہو۔
ہر پیئر پلان ٹری کی اپنی کاپی رکھتا ہے اور سنی ہوئی گاسپ کی بنیاد پر اسے اپ ڈیٹ کرتا ہے۔ جب ایک decomposer تجویز براڈکاسٹ کرتا ہے، تو ہر دوسرا نوڈ اسے وصول کرتا ہے، فارمیٹ کی تصدیق کرتا ہے، اور شاخ کو اپنے مقامی ٹری میں شامل کر لیتا ہے۔ جب اسکوررز ووٹ ڈالتے ہیں، تو گنتی اسی طرح پھیلتی ہے۔ اگر دو executors ایک ہی ٹاسک کے لیے متضاد دعوے کرتے ہیں، تو ٹائم اسٹیمپ پروٹوکول اس ٹکراؤ کو حل کر دیتا ہے۔ نیٹ ورک پہلے دعوے کو تسلیم کرتا ہے اور دیر سے آنے والے دعوے کو مسترد کر دیتا ہے۔
وقت کے ساتھ ساتھ، ٹری اصل مقصد سے لے کر قبول شدہ ذیلی مقاصد کی تہوں کے ذریعے نیچے کی طرف بڑھتی ہے یہاں تک کہ یہ چھوٹے چھوٹے کاموں تک پہنچ جاتی ہے۔ یہ عمل بلاک چین کے اتفاقِ رائے (consensus) تک پہنچنے سے ملتا جلتا ہے، سوائے اس کے کہ اس کا پی لوڈ (payload) سکوں کے کھاتے کے بجائے ایک سفری پروگرام یا سافٹ ویئر سپیک (spec) ہوتا ہے۔
ووٹنگ اور عمل درآمد کی دوڑ
جمہوریت مہنگی ہے، اور یہ سسٹم اس کی قیمت لیٹنسی (latency) کی صورت میں ادا کرتا ہے۔ ایک تقسیم صرف اسی صورت میں جیتتی ہے اگر کافی اسکوررز متفق ہوں۔ وہ حد ایک سادہ اکثریت یا ایک سخت کورم (quorum) ہو سکتی ہے، اس بات پر منحصر ہے کہ آپ کلسٹر کو کیسے کنفیگر کرتے ہیں۔ decomposers تجاویز دینا بند نہیں کرتے، اس لیے نیٹ ورک اکثر ایک ہی وقت میں کئی مقابلہ کرنے والی ٹریز کا جائزہ لیتا ہے۔ آخر کار ایک مطلوبہ ووٹ حاصل کر لیتی ہے اور اس کے ذیلی مقاصد ڈرافٹ سے قبول شدہ مرحلے میں چلے جاتے ہیں۔
ایگزیکیوٹرز (Executors) ہم آہنگی کی ایک اور تہہ شامل کرتے ہیں۔ چونکہ ٹاسک gossip channel پر عوامی ہوتے ہیں، اس لیے متعدد executors ایک ہی پرکشش leaf node کو حاصل کرنے کی کوشش کر سکتے ہیں۔ Timestamp protocol ایک tiebreaker کے طور پر کام کرتا ہے۔ ہر دعوے کے ساتھ ایک monotonic timestamp ہوتا ہے، اور نیٹ ورک سب سے پہلے آنے والے دعوے کو تسلیم کرتا ہے۔ ہارنے والا محض اگلے دستیاب ٹاسک کی طرف بڑھ جاتا ہے۔ یہ طریقہ سادہ ہے، لیکن یہ database میں rows کو لاک کرنے کے لیے ایک centralized scheduler کی ضرورت سے بچاتا ہے۔
ڈیزائن کے ذریعے لچک (Resilience by Design)
جب چیزیں خراب ہوتی ہیں تو یہ architecture اپنی اہمیت ثابت کرتا ہے۔ اگر کوئی decomposer آدھے subgoals تجویز کرنے کے بعد کریش ہو جائے، تو باقی بچ جانے والے decomposers splits کی پیشکش جاری رکھتے ہیں۔ منصوبہ respawn کے انتظار میں رکتا نہیں ہے۔ اگر کوئی scorer نیٹ ورک سے غائب ہو جائے، تو باقی voters اب بھی quorum تک پہنچ سکتے ہیں، بشرطیکہ آپ نے cluster کا سائز مناسب رکھا ہو۔
اصل فائدہ late joins میں ہے۔ ایک نیا agent جو آدھے راستے میں boot up ہوتا ہے، اسے snapshot یا کسی... کی ضرورت نہیں ہوتی۔
