যখন আপনি কোনো দায়িত্বপ্রাপ্ত ব্যক্তি ছাড়াই একটি বড় প্রজেক্ট পরিকল্পনা করেন তখন কী ঘটে? বেশিরভাগ সফটওয়্যার স্ট্যাক একটি একক অর্কেস্ট্রেটর (orchestrator) ধরে নেয়। একটি প্রসেস স্টেট (state) ধরে রাখে, কাজের কিউ (queue) তৈরি করে এবং টাস্ক বণ্টন করে। যদি সেই কোঅর্ডিনেটর রিস্টার্ট নেয়, তবে পুরো ওয়ার্কফ্লো থমকে যায়। একটি নতুন প্রজেক্ট এই ধারণাটিকে সম্পূর্ণ উল্টে দেয়। এটি দেখায় কীভাবে AI এজেন্টদের একটি দল "জাপানে দুই সপ্তাহের ভ্রমণের পরিকল্পনা করুন" এর মতো একটি লক্ষ্যকে একটি পূর্ণাঙ্গ টাস্ক ট্রি-তে (task tree) বিভক্ত করতে পারে, যেখানে কোনো একক নোড কোনো মুহূর্তেই সম্পূর্ণ পরিকল্পনাটি নিজের কাছে রাখে না।

কেন একটি লিডারলেস (Leaderless) সিস্টেম তৈরি করবেন?

সেন্ট্রালাইজড প্ল্যানারগুলোর ধারণা করা সহজ। আপনি একটি সার্ভারে রিকোয়েস্ট পাঠান, এটি কাজটিকে ভাগ করে দেয় এবং ওয়ার্কাররা রিপোর্ট করে। সমস্যা হলো, সার্ভারটি একটি কগনিটিভ (cognitive) এবং ফিজিক্যাল বটleneck বা প্রতিবন্ধক হয়ে দাঁড়ায়। এটিই সব তথ্যের মালিক।

একটি ডিস্ট্রিবিউটেড সেটআপে, সত্য বা তথ্য একটি শেয়ার্ড পিকচারে পরিণত হয় যা নেটওয়ার্ক 'গসিপ' (gossip)-এর মাধ্যমে অর্জন করে। এই নির্দিষ্ট Python ইমপ্লিমেন্টেশনটি দুটি ভিন্ন ধারণাকে একত্রে যুক্ত করে। প্রথমটি হলো একটি ইটারেটিভ রিফাইনমেন্ট লুপ (iterative refinement loop): একটি এজেন্ট একটি প্রস্তাব লেখে, অন্যটি সেটিকে স্কোর করে এবং তৃতীয়টি সেটিকে আরও উন্নত বা পলিশ করে। দ্বিতীয়টি হলো libp2p-এর ওপর ভিত্তি করে তৈরি একটি পিয়ার-টু-পিয়ার (peer-to-peer) নেটওয়ার্কিং লেয়ার, যা এজেন্টদের কোনো রেজিস্ট্রি বা লোড ব্যালেন্সার ছাড়াই স্বয়ংক্রিয়ভাবে একে অপরকে খুঁজে পেতে সাহায্য করে। এর ফলাফল হলো এমন একটি ক্লাস্টার যেখানে পিয়াররা কোনো অর্কেস্ট্রা কন্ডাক্টর ছাড়াই আবির্ভূত হয়, প্রস্তাব দেয়, ভোট দেয় এবং কাজ সম্পাদন করে।

চারটি ভূমিকা

সিস্টেমটি প্রতিটি অংশগ্রহণকারীকে চারটি ব্যক্তিত্বের মধ্যে একটি বরাদ্দ করে। আপনার চারটি ফিজিক্যাল মেশিনের প্রয়োজন নেই। এগুলো একটি ল্যাপটপে সহাবস্থান করতে পারে বা একটি হোম নেটওয়ার্ক জুড়ে ছড়িয়ে থাকতে পারে। ভূমিকাগুলো হলো:

  • Decomposer (বিভাজক): এই এজেন্টটি টপ-লেভেল লক্ষ্যটি গ্রহণ করে এবং সেটিকে সাবগোল (subgoals) বা উপ-লক্ষ্যে বিভক্ত করার প্রস্তাব দেয়। যেহেতু সিস্টেমটি সমান্তরালভাবে একাধিক ডিকম্পোজার চালায়, তাই আপনি একই জাপান ভ্রমণের জন্য তিনটি ভিন্ন ভিন্ন পরিকল্পনা পেতে পারেন। একটি ভৌগোলিক অবস্থান অনুযায়ী যাত্রাটিকে ভাগ করতে পারে: টোকিও, কিয়োটো, ওসাকা। অন্যটি কার্যক্রম অনুযায়ী ভাগ করতে পারে: যাতায়াত, আবাসন, খাবার, দর্শনীয় স্থান। তৃতীয়টি দিন অনুযায়ী ক্রম সাজাতে পারে। নেটওয়ার্ক এই সবকটিকেই বিবেচনা করে।

  • Scorer (স্কোরার): এই এজেন্টগুলো এডিটোরিয়াল বোর্ড হিসেবে কাজ করে। তারা প্রস্তাবিত বিভাজনটি পরীক্ষা করে এবং রেটিং দেয়। একটি স্কোর নির্দেশ করে যে সাবগোলগুলো যথেষ্ট সুনির্দিষ্ট, অদ্বৈত (non-overlapping) এবং সম্মিলিতভাবে পূর্ণাঙ্গ কি না। আরও গুরুত্বপূর্ণ বিষয় হলো, একটি প্রস্তাব গ্রহণ করার মতো যথেষ্ট ভালো কি না তা স্কোরার সিদ্ধান্ত নেয়। তার সম্মতি ছাড়া বিভাজনটি অমীমাংসিত অবস্থায় থেকে যায়।

  • Executor (নির্বাহক): যখন ট্রি-টি কাজ করার উপযোগী ছোট লিফ নোড (leaf nodes)-এ পৌঁছায়, তখন এক্সিকিউটররা সেগুলো দখল করার জন্য প্রতিযোগিতা করে। তারা কোনো সেন্ট্রাল কিউ থেকে অনুমতির জন্য অপেক্ষা করে না। পরিবর্তে, তারা কে কোন টাস্কটি পাবে তা নির্ধারণ করতে একটি টাইমস্ট্যাম্প প্রোটোকল (timestamp protocol) ব্যবহার করে। বিজয়ী একটি লোকাল LLM কলের মাধ্যমে কাজটি সম্পন্ন করে এবং ফলাফলটি ব্রডকাস্ট করে।

  • Observer (পর্যবেক্ষক): এটি হলো সেই শান্ত দর্শক যা প্রতিটি নেটওয়ার্কের প্রয়োজন। এটি নিঃশব্দে গসিপগুলো শোনে, কথাবার্তা থেকে প্ল্যান ট্রি পুনর্গঠন করে এবং একটি পাঠযোগ্য স্ন্যাপশট প্রিন্ট করে। যেহেতু এটি কখনোই কথা বলে না, এটি একটি গুরুত্বপূর্ণ বিষয় প্রমাণ করে: কেউ যদি দেরিতে যোগ দেয়, তবে সে কেবল অন্যের কথা শুনেই পুরো পরিকল্পনাটি বুঝে নিতে পারে।

তথ্যের উৎস হিসেবে গসিপ (Gossip)

libp2p লেয়ারটি ডিসকভারি এবং মেসেজিং পরিচালনা করে। এজেন্টরা প্রোটোকলের বিল্ট-ইন পিয়ার ডিসকভারির মাধ্যমে একে অপরকে খুঁজে পায়, তারপর একটি শেয়ার্ড টপিকের ওপর মেসেজ ব্রডকাস্ট করে। এখানে কোনো রেকর্ড ডেটাবেস বা ক্যানোনিকাল প্ল্যান ধরে রাখার জন্য কোনো Redis ক্যাশ নেই।

প্রতিটি পিয়ার প্ল্যান ট্রি-এর নিজস্ব কপি রাখে এবং শোনা গসিপের ভিত্তিতে এটি আপডেট করে। যখন একটি ডিকম্পোজার একটি প্রস্তাব ব্রডকাস্ট করে, তখন প্রতিটি নোড সেটি গ্রহণ করে, ফরম্যাট যাচাই করে এবং তার লোকাল ট্রি-তে সেই শাখাটি যোগ করে। যখন স্কোরাররা ভোট দেয়, তখন সেই গণনাও একইভাবে ছড়িয়ে পড়ে। যদি দুইজন এক্সিকিউটর একই টাস্কের জন্য পরস্পরবিরোধী দাবি প্রকাশ করে, তবে টাইমস্ট্যাম্প প্রোটোকল সেই সংঘর্ষ (collision) নিরসন করে। নেটওয়ার্কটি আগের দাবিটি গ্রহণ করে এবং পরেরটি বাতিল করে দেয়।

সময়ের সাথে সাথে, মূল লক্ষ্য থেকে গৃহীত সাবগোলগুলোর স্তরের মাধ্যমে ট্রি-টি নিচের দিকে বাড়তে থাকে যতক্ষণ না এটি ছোট ছোট টাস্কে পরিণত হয়। এই প্রক্রিয়াটি অনেকটা ব্লকচেইনের কনসেনসাস (consensus) অর্জনের মতো, তবে পার্থক্য হলো এখানে পে-লোডটি কোনো মুদ্রার লেজার নয়, বরং একটি ভ্রমণ পরিকল্পনা বা একটি সফটওয়্যার স্পেসিফিকেশন।

ভোটিং এবং কাজ সম্পাদনের প্রতিযোগিতা

গণতন্ত্র ব্যয়বহুল, এবং এই সিস্টেমটি ল্যাটেন্সির (latency) মাধ্যমে সেই মূল্য পরিশোধ করে। একটি বিভাজন তখনই জয়ী হয় যদি যথেষ্ট সংখ্যক স্কোরার একমত হন। আপনি ক্লাস্টারটি কীভাবে কনফিগার করছেন তার ওপর ভিত্তি করে সেই থ্রেশহোল্ডটি একটি সাধারণ সংখ্যাগরিষ্ঠতা বা আরও কঠোর কোরাম (quorum) হতে পারে। ডিকম্পোজাররা প্রস্তাব দেওয়া বন্ধ করে না, তাই নেটওয়ার্ক প্রায়শই একসাথে বেশ কয়েকটি প্রতিদ্বন্দ্বী ট্রি মূল্যায়ন করে। অবশেষে একটি প্রয়োজনীয় ভোট পেয়ে যায় এবং এর সাবগোলগুলো খসড়া থেকে গৃহীত অবস্থায় উন্নীত হয়।

Executors সমন্বয়ের আরও একটি স্তর যোগ করে। যেহেতু gossip চ্যানেলে টাস্কগুলো পাবলিক থাকে, তাই একাধিক Executor একই আকর্ষণীয় leaf node দখল করার চেষ্টা করতে পারে। Timestamp protocol এখানে tiebreaker হিসেবে কাজ করে। প্রতিটি claim-এর সাথে একটি monotonic timestamp থাকে এবং নেটওয়ার্ক সবচেয়ে পুরনো বা প্রথমটিকেই গ্রহণ করে। পরাজিত পক্ষটি কেবল পরবর্তী উপলব্ধ টাস্কের দিকে এগিয়ে যায়। এটি কিছুটা অমার্জিত পদ্ধতি হলেও, এটি ডেটাবেসে row লক করার জন্য কোনো centralized scheduler-এর প্রয়োজনীয়তা এড়িয়ে চলে।

ডিজাইনগত স্থিতিস্থাপকতা

যখন কোনো সমস্যা দেখা দেয়, তখন এই আর্কিটেকচার তার কার্যকারিতা প্রমাণ করে। যদি অর্ধেক subgoal প্রস্তাব করার পর একটি decomposer ক্র্যাশ করে, তবে টিকে থাকা decomposer-রা split প্রদান করা চালিয়ে যায়। কোনোটির respawn-এর অপেক্ষায় পরিকল্পনাটি থমকে থাকে না। যদি কোনো scorer নেটওয়ার্ক থেকে বিচ্ছিন্ন হয়ে যায়, তবে ক্লাস্টারটি সঠিকভাবে সাইজ করা থাকলে অবশিষ্ট ভোটাররা এখনও quorum অর্জন করতে পারে।

এর আসল সুফল হলো late joins। মাঝপথে চালু হওয়া একটি নতুন agent-এর কোনো snapshot বা