সোমবার সকালে আপনি পাঁচটি গুরুতর বাগ রিপোর্ট (bug reports) নিয়ে জেগে উঠলেন। আপনার রিভিউ মনিটরিং টুলটি তার কাজ ঠিকঠাক করেছে। এটি প্রতিটি ক্র্যাশ রিপোর্ট, প্রতিটি ক্ষুব্ধ এক-স্টার রিভিউ, এবং প্রতিটি "সেভ করার সময় অ্যাপ ফ্রিজ হয়ে যায়" এমন অভিযোগ ধরে ফেলেছে। আপনি জানেন ঠিক কী ভেঙেছে। কিন্তু আপনি জানেন না কোথায় খুঁজতে হবে।
আমার প্রথম পাইপলাইন তৈরির পর আমি ঠিক এই দেয়ালের সামনে এসে দাঁড়িয়েছিলাম। এটি কোনো সমস্যা ছাড়াই অ্যাপ রিভিউ এবং আসা ক্র্যাশ লগগুলো মনিটর করত এবং প্রতিটি ফিডব্যাককে সুন্দরভাবে সাজিয়ে ফেলত: বাগ, ক্র্যাশ বা ফিচার রিকোয়েস্ট। ড্যাশবোর্ডটি দেখতে সুস্থ মনে হচ্ছিল। কিন্তু আসল ডিবাগিং প্রক্রিয়াটি ছিল না।
একটি বাগ আছে তা জানা মানে মাইলের পথের প্রথম এক ইঞ্চি অতিক্রম করা মাত্র। আমাকে এখনও IDE খুলতে হতো, মডিউলগুলোর মধ্যে grep করতে হতো, বর্তমান কোডবেসের সাথে স্ট্যাক ট্রেসগুলো মিলিয়ে দেখতে হতো এবং আমার মাথায় ফেইলর পাথ (failure path) পুনর্গঠন করতে হতো। যখন টিকিটের পাহাড় জমে যায় এবং কফি তখনও গরম থাকে, তখন এই ম্যানুয়াল প্রত্নতাত্ত্বিক কাজ (manual archaeology) এমন সময় নষ্ট করে যা আপনার কাছে নেই। আমার পাইপলাইনের শুধু সমস্যা চিহ্নিত করার চেয়েও বেশি কিছু করা প্রয়োজন ছিল। আমার প্রয়োজন ছিল এটি যেন সমস্যাগুলো তদন্ত (investigate) করতে পারে।
তাই আমি একটি মাত্র লক্ষ্য নিয়ে সিস্টেমটি নতুন করে তৈরি করেছি: একটি কাঁচা বাগ রিপোর্ট গ্রহণ করা এবং একটি যাচাইকৃত রোগনির্ণয় (validated diagnosis) প্রদান করা। কোনো LLM এর দীর্ঘ অনুচ্ছেদ নয়। বরং একটি সুসংগঠিত ফলাফল যা ফাইলের নাম বলবে, লাইনের দিকে নির্দেশ করবে, ঝুঁকির মাত্রা অনুমান করবে এবং একটি সমাধানের পরামর্শ দেবে। এটি যেভাবে সম্পন্ন হলো তা নিচে দেওয়া হলো।
কেন চ্যাট লগ-এর চেয়ে স্ট্রাকচার বা কাঠামো ভালো
আমি PydanticAI ব্যবহার করে ইনভেস্টিগেটিং এজেন্টটি তৈরি করেছি। কারণটি সহজ ছিল। যখন আপনি একটি ল্যাঙ্গুয়েজ মডেলকে কোড নিয়ে যুক্তি দিতে বলেন, এর ডিফল্ট আউটপুট হয় টেক্সটের একটি বন্ধুত্বপূর্ণ প্রবাহ। এটি একজন মানুষের জন্য সাহায্যকারী হতে পারে, কিন্তু একটি ডাউনস্ট্রিম স্ক্রিপ্টের জন্য এটি অকেজো। আমার প্রয়োজন ছিল একটি মেশিন-রিডেবল কন্ট্রাক্ট (machine-readable contract)।
এজেন্টটি চারটি নির্দিষ্ট ফিল্ডসহ একটি যাচাইকৃত ডেটা মডেল প্রদান করে: রুট কজ (root cause), প্রভাবিত ফাইলগুলো (affected files), প্রস্তাবিত পরিবর্তন (proposed changes), এবং জটিলতা ও ঝুঁকির মূল্যায়ন (assessment of complexity and risk)। যদি মডেলে কোনো ফিল্ড বাদ পড়ে বা এটি কোনো ভুল ফাইলপাথ (filepath) তৈরি করে, তবে ভ্যালিডেশন ব্যর্থ হয় এবং আমি তা সাথে সাথে ধরে ফেলতে পারি। এই কঠোরতা পাইপলাইনটিকে নির্ভুল রাখে।
আসল গোয়েন্দাগিরি করার জন্য, এজেন্টটি চারটি রিড-অনলি (read-only) টুল পায় এবং অন্য কিছু নয়। এটি grep-এর মাধ্যমে কোড সার্চ করতে পারে, একটি ফাইল থেকে নির্দিষ্ট লাইনের রেঞ্জ পড়তে পারে, ডিরেক্টরি কন্টেন্ট লিস্ট করতে পারে এবং ক্লাস বা ফাংশনের মতো সিম্বলগুলো খুঁজে পেতে পারে। 'রিড-অনলি' হওয়াটাই সবচেয়ে গুরুত্বপূর্ণ অংশ। আমি চাইনি রাত ২টোর সময় কোনো এজেন্ট আমার রিপোজিটরিতে রাইট অ্যাক্সেস নিয়ে ঘুরে বেড়াক। আগে বুঝতে হবে, তারপর এডিট করতে হবে।
রেপো ম্যাপ: টুলের আগে কনটেক্সট
এজেন্টের প্রথম সংস্করণটি নির্ভুল ছিল কিন্তু অত্যন্ত ব্যয়বহুল ছিল। এটি টোকেন এমনভাবে খরচ করত যেন কোনো পর্যটক গোল গোল ঘুরছে। মডেলটি প্রথমে list-dir কল করত, তারপর grep, তারপর একটি ফাইল পড়ত, তারপর আবার list-dir করত—এভাবে একটি একটি করে দামী টোকেন খরচ করে প্রজেক্ট স্ট্রাকচারের একটি মানসিক মডেল তৈরি করার চেষ্টা করত।
এর সমাধান ছিল এজেন্ট শুরু করার আগেই একটি কম্প্যাক্ট রেপো ম্যাপ (repo map) তৈরি করা। এই ম্যাপটি হলো রিপোজিটরির একটি সারসংক্ষেপ: মূল ফাইলগুলো, তাদের প্রাথমিক ফাংশন বা ক্লাস এবং প্রধান মডিউলগুলো কীভাবে একে অপরের সাথে যুক্ত। এটিকে এজেন্টের হাতে একটি GPS তুলে দেওয়ার মতো ভাবুন, পরিবর্তে তাকে ভুল পথে চলতে চলতে রাস্তা খুঁজে বের করতে বলা।
তার কনটেক্সট উইন্ডোতে সেই ম্যাপটি থাকলে, এজেন্ট src/utils/parser.ts ফাইলটি আছে কি না তা বোঝার জন্য অপ্রয়োজনীয় কল করবে না। সে ইতিমধ্যেই ভূখণ্ড সম্পর্কে জানে। সে সরাসরি সেই চূড়ার দিকে যাবে যেখানে ধোঁয়া উড়ছে। এই একটি পরিবর্তন এজেন্টের লক্ষ্যহীনভাবে ঘুরে বেড়ানোর ধাপটি পুরোপুরি দূর করে দিয়েছে।
টুল ফানেল: একটি সিদ্ধান্তে পৌঁছাতে বাধ্য করা
ম্যাপ থাকলেও এজেন্ট দ্বিধাদ্বন্দ্বে ভুগতে পারত। সে একটি সন্দেহজনক ফাইল খুঁজে পেত, তারপর নিজের ওপর সন্দেহ করত, তারপর আবার সার্চ করত, তারপর অন্য একটি ফাইল পড়ত—এভাবে "আর মাত্র একটি চেক" করার অন্তহীন লুপে আটকে যেত। আমার এমন একটি উপায় প্রয়োজন ছিল যা তাকে গতিশীল করতে বাধ্য করবে।
আমি একটি তিন-ধাপের টুল ফানেল (tool funnel) বাস্তবায়ন করেছি যা এজেন্ট অগ্রসর হওয়ার সাথে সাথে তার কাজের পরিধি সীমিত করে দেয়।
প্রথম ধাপ হলো এক্সপ্লোরেশন (exploration)। এজেন্টের চারটি টুলের পূর্ণ অ্যাক্সেস থাকে। তার যুক্তির মাধ্যমে বাগটি পুনরায় তৈরি করতে যা প্রয়োজন তা সে সার্চ, ব্রাউজ এবং রিড করতে পারে।
দ্বিতীয় ধাপ হলো ডিপ-ডাইভ (deep-dive)। একবার এজেন্ট সম্ভাব্য ত্রুটিগুলো শনাক্ত করে ফেললে, সে ডিসকভারি টুলগুলো হারায়। সে কেবল ফাইল পড়তে পারে। আর কোনো grep বা ডিরেক্টরি লিস্ট করার সুযোগ নেই। এই পর্যায়ে তাকে ইতিমধ্যে খুঁজে পাওয়া কোডটি নিয়ে পড়াশোনা করতে হবে এবং তার প্রমাণের ধারা তৈরি করতে হবে।
তৃতীয় ধাপ হলো আউটপুট (output)। সব টুল লক করে দেওয়া হয়। এজেন্ট আর কোডবেস কুয়েরি করতে পারে না। তাকে বসতে হবে এবং রিপোর্টটি লিখতে হবে। এটি "আমাকে আর একটি জিনিস চেক করতে দাও" এই অন্তহীন চক্রকে প্রতিরোধ করে।
এই ফানেলটি প্রতি অ্যানালাইসিসে টুলের গড় কল সংখ্যা চল্লিশের বেশি থেকে কমিয়ে প্রায় দশের কাছাকাছি নামিয়ে এনেছে। এজেন্ট আরও দ্রুত, সাশ্রয়ী এবং আশ্চর্যজনকভাবে আরও আত্মবিশ্বাসী হয়ে উঠেছে কারণ তাকে একটি সিদ্ধান্তে পৌঁছাতে বাধ্য করা হচ্ছে।
ব্যাকএন্ড পরিবর্তনযোগ্য রাখা
আমি সিস্টেমটিকে কোনো একটি নির্দিষ্ট মডেল প্রোভাইডারের ওপর হার্ডকোড করে রাখতে চাইনি। কাজের ধরন অনুযায়ী আমি বিভিন্ন ইঞ্জিন ব্যবহার করি। কখনও Claude Code, কখনও Grok Build, আবার কখনও সেই মুহূর্তে যেটি সবচেয়ে সস্তা সেটি ব্যবহার করি। মূল লজিকটিকে প্রোভাইডার-নিরপেক্ষ (provider-agnostic) রাখতে আমি কাজটিকে দুটি পর্যায়ে ভাগ করেছি।
প্রথম পর্যায় হলো এক্সপ্লোরেশন (exploration)। কোডিং এজেন্ট, যা যেকোনো সক্ষম মডেল হতে পারে, সেটি রিপো ম্যাপ (repo map) পড়ে, টুলসগুলো ব্যবহার করে এবং একটি র (raw) মার্কডাউন রিপোর্ট তৈরি করে। এটি হলো ব্যয়বহুল চিন্তাশীল অংশ।
দ্বিতীয় পর্যায় হলো স্ট্রাকচারিং (structuring)। একটি সস্তা ও দ্রুতগতির LLM সেই মার্কডাউনটি গ্রহণ করে এবং সেটিকে একটি কঠোর Pydantic মডেলে রিফরম্যাট করে। এই পর্যায়ের জন্য প্রায় কোনো যুক্তিনির্ভর চিন্তার (reasoning) প্রয়োজন হয় না। এটি কেবল তথ্য আহরণ (extraction) এবং ফরম্যাটিংয়ের কাজ, তাই এটি হালকা হার্ডওয়্যারেও চালানো সম্ভব।
যেহেতু কাজের সীমানা বা বাউন্ডারিটি পরিষ্কার, তাই ভ্যালিডেশন লজিক পরিবর্তন না করেই আমি ব্যাকএন্ড বদলে ফেলতে পারি। মার্কডাউন রিপোর্টটি এক্সপ্লোরেটরি ব্রেন (exploratory brain) এবং আমার ব্যবহৃত স্ট্রাকচার্ড আউটপুটের মধ্যে একটি ইউনিভার্সাল অ্যাডাপ্টার হিসেবে কাজ করে।
যা আসলে কাজ করেছে
এই সেটআপটি আগত ইস্যুগুলো হ্যান্ডেল করার পদ্ধতি বদলে দিয়েছে। ক্লাসিফিকেশন লেয়ার এখনও বাগ (bug) এবং ফিচার রিকোয়েস্টের মধ্যে পার্থক্য করে, কিন্তু এখন অ্যানালাইসিস লেয়ারটি তার ঠিক পরেই কাজ শুরু করে দেয়। আমি যখন আমার এডিটর খুলি, ততক্ষণে ফাইল পাথ, লাইনের রেঞ্জ এবং একটি প্রস্তাবিত পরিবর্তন আমার জন্য অপেক্ষা করতে থাকে। আমি এখনও সবকিছু ম্যানুয়ালি রিভিউ করি। এটি সহায়তা মাত্র, অটোপাইলট নয়। কিন্তু কনটেক্সট সংগ্রহ করার যে প্রক্রিয়াটি আগে
