সারাটা দিন ল্যাংচেইনগো (LangChainGo) নিয়ে মাথা ঠুকেও যখন দেখলাম লোকাল মডেলগুলো ঠিকমতো টুল কল করতে পারছে না, তখন হাল ছেড়ে দিয়েছিলাম। মডেল আউটপুট দিচ্ছিল "Action: web_search", কিন্তু প্রয়োজনীয় "Action Input" দিতে ভুলে যাচ্ছিল। এই ধরনের ফ্রেমওয়ার্কগুলো সাধারণত নির্দিষ্ট কিছু প্যাটার্ন ফলো করে, যা লোকাল মডেলের জন্য বেশ কঠিন হয়ে দাঁড়ায়। তখনই মনে হলো, এই জটিলতায় না গিয়ে সরাসরি Go ব্যবহার করে Multi-Agent Orchestration ইমপ্লিমেন্ট করা অনেক বেশি কার্যকর।
ফিক্সটা আসলে প্রম্পট টিউনিংয়ে ছিল না, ছিল পুরো ফ্রেমওয়ার্কটাই বাদ দেওয়াতে। সরাসরি এলএলএম (LLM) কল আর স্ট্রাকচার্ড ডেটা পাস করার মাধ্যমে আমি অনেক বেশি কন্ট্রোল পেয়েছি।
অযথা জটিলতা বাদ দিন
একই এজেন্ট দিয়ে লয়ার, অ্যাকাউন্ট্যান্ট আর শেফ—সব কাজ করানোর চেষ্টা করা মানেই হলো সবগুলোতে গড়পড়তা রেজাল্ট পাওয়া। এর চেয়ে স্পেশালিস্ট এজেন্টদের ভাগ করে দিলে প্রম্পটগুলো আরও পরিষ্কার হয় এবং প্যারালালাইজ করা সহজ হয়। আমি প্রথমে সুপারভাইজার প্যাটার্ন ট্রাই করেছিলাম, কিন্তু ছোট প্রজেক্টে সেটা অযথাই জটিলতা বাড়ায়। আমার অভিজ্ঞতায় পাইপলাইন প্যাটার্ন (Researcher → Writer → Editor) সবচেয়ে সহজে কাজ করে।
ল্যাংচেইনগোর মতো ফ্রেমওয়ার্কে একটা বড় সমস্যা হলো এরা মডেল থেকে একদম নিখুঁত ফরম্যাট আশা করে:
Thought: I need to search for this
Action: web_search
Action Input: AI impact on software engineeringলোকাল মডেলগুলো প্রায়ই এই ফরম্যাটটা উল্টাপাল্টা করে ফেলে। সরাসরি এলএলএম কল করলে এই সমস্যা থাকে না। আপনি আপনার মতো করে টুল ইনভোক করতে পারেন এবং রেজাল্ট পাস করতে পারেন। এতে কোড যেমন সিম্পল হয়, ডিবাগিংও অনেক সহজ হয়ে যায়।
কোড স্ট্রাকচার
নিচে আমার প্রজেক্টের একটা বেসিক স্ট্রাকচার দেওয়া হলো যেখানে একটা BaseAgent ব্যবহার করে বাকি এজেন্টগুলো তৈরি করা হয়েছে:
2-multi-agent-pipeline/
├── main.go
├── internal/
│ ├── agents/
│ │ ├── base.go # Shared LLM Calling Logic
│ │ ├── simple_researcher.go # Research Agent
│ │ ├── writer.go # Writer Agent
│ │ ├── editor.go # Editor Agent
│ │ ├── errors.go # Structured Error Types
│ │ ├── options.go # Configuration Options
│ │ └── pipeline.go # Pipeline Runner Abstraction
│ └── tools/
│ └── search.go # Brave Search Tool
├── go.mod
└── go.sumBase Agent: মূল ভিত্তি
সব এজেন্টই BaseAgent স্ট্রাক্ট শেয়ার করে, যা কমন এলএলএম ইন্টারঅ্যাকশন লজিক হ্যান্ডেল করে। এতে কোড ডুপ্লিকেশন কমে এবং স্ট্রিমিং বা রিট্রাই করার সুবিধা পাওয়া যায়।
// (Code remains same as original)এরর হ্যান্ডলিং: যেখানে আমি ভুল করেছিলাম
আমি শুরুতে এরর হ্যান্ডলিং ঠিকমতো না করার কারণে কোন এজেন্ট কেন ফেইল করছে তা বুঝতে পারতাম না। পরে স্ট্রাকচার্ড এরর টাইপ ব্যবহার করে ডিবাগিং অনেক সহজ হয়েছে।
package agents
import (
"errors"
"fmt"
)
// (Remaining error handling code)কেন Multi-Agent Orchestration এত সময় সাপেক্ষ?
আমার মনে হয়, মাল্টি-এজেন্ট সিস্টেমের সবচেয়ে বড় সমস্যা হলো ল্যাটেন্সি (Latency)। একটা প্রম্পট থেকে আউটপুট এসে সেটা পরের এজেন্টে যেতে যে সময় লাগে, তাতে পুরো প্রসেসটা অনেক স্লো হয়ে যায়। বিশেষ করে যদি আপনি বড় কোনো এলএলএম ব্যবহার করেন। এছাড়া টোকেন কস্টের ব্যাপারটা তো আছেই। প্রতিটি এজেন্ট তার নিজের প্রম্পট আর হিস্ট্রি নিয়ে কাজ করে, যা দ্রুত বিল বাড়িয়ে দিতে পারে।
আরও একটা বিরক্তিকর বিষয় হলো 'কন্টেক্সট ব্লিড' (Context Bleed)। আগের এজেন্টের ভুল বা অপ্রাসঙ্গিক তথ্য পরের এজেন্টে চলে গেলে আউটপুট একদম নষ্ট হয়ে যায়। এটা এড়াতে এক্সপ্লিসিট হ্যান্ডঅফ (Explicit Handoff) খুব জরুরি।
মডেল বাছাই করার কৌশল
সব কাজের জন্য একই মডেল ব্যবহারের কোনো মানে হয় না। রিসার্চের জন্য হয়তো ফাস্ট কোনো মডেল (যেমন Qwen বা Llama) ভালো কাজ করে, কিন্তু রাইটিংয়ের ক্ষেত্রে ক্লড (Claude) বা জিপিটি-৪ (GPT-4) এর কোনো বিকল্প নেই। আমি সাধারণত এডিটিংয়ের জন্য মিড-টিয়ার মডেল ব্যবহার করি অথবা যদি রাইটার ভালো আউটপুট দেয়, তবে এডিটর স্কিপ করি।
মাল্টি-এজেন্ট অর্কেস্ট্রেশন (Multi-Agent Orchestration) নিয়ে কাজ করার সময় সবসময় ২-এজেন্ট পাইপলাইন দিয়ে শুরু করা ভালো। এরপর প্রয়োজন অনুযায়ী জটিলতা বাড়ানো উচিত।
গো (Go) ল্যাঙ্গুয়েজ ব্যবহার করে কীভাবে দক্ষ Multi-Agent Orchestration সিস্টেম তৈরি করবেন, ফ্রেমওয়ার্কের জটিলতা এড়িয়ে সরাসরি LLM কল করার সুবিধা ও কোডসহ বিস্তারিত জানুন।
