এজেন্ট «সম্পন্ন» বলল, কিন্তু ফিচার কাজ করছে না: কেন হয় এবং AI এজেন্টের কাজ কীভাবে যাচাই করবেন
এজেন্ট «সম্পন্ন» লেখে কারণ সে নিজের কাজ নিজে মূল্যায়ন করে এবং শুধু যতটুকু যাচাই করেছে তাই দেখে — সাধারণত unit test, যা মডিউলের সংযোগ, migration, কনফিগারেশন ও end-to-end পরিস্থিতি দেখে না। সমাধান প্রম্পটে নয়, কাঠামোতে: AGENTS.md-এ Definition of Done, বাধ্যতামূলক E2E, শুধু একটি যাচাই-স্ক্রিপ্টের passing দেওয়ার অধিকার, এবং পরিষ্কার প্রসঙ্গসহ স্বাধীন মূল্যায়নকারী।
কেন এমন হয়
এজেন্টের সঙ্গে কাজ করা যে কেউ এই পরিস্থিতি চেনেন: এজেন্ট লিখল «সম্পন্ন», কিন্তু ফিচার কাজ করে না। সে ইচ্ছাকৃতভাবে মিথ্যা বলে না। সে জানায় যা সে যাচাই করতে পেরেছে, এবং বিশ্বাস করে তা যথেষ্ট। বক্তব্য ও বাস্তবের ফারাক «সম্পাদক নিজের কাজ নিজে মূল্যায়ন করে» এই কাঠামোর বৈশিষ্ট্য, কোনো নির্দিষ্ট মডেলের ত্রুটি নয়।
তিনটি কারণ আছে। প্রথমত, মডেল অতি-আত্মবিশ্বাসী হতে ঝোঁকে: উত্তরের আত্মবিশ্বাসের মাত্রা তার সঠিকতার চেয়ে বেশি। দ্বিতীয়ত, এজেন্ট নিজের কাজ সেই প্রসঙ্গেই মূল্যায়ন করে যেখানে সে কাজটি করেছে: সে ইতিমধ্যেই নিজেকে বুঝিয়েছে সমাধান ঠিক, এবং «আরও নিরপেক্ষভাবে দেখো» বললেও প্রসঙ্গ বদলায় না। তৃতীয়ত, সবচেয়ে বাস্তব কারণ: এজেন্টের হাতে শুধু আংশিক যাচাই থাকে। unit test দ্রুত সবুজ হয়, কিন্তু end-to-end পরিস্থিতি কেউ চালায়নি।
একটি ভুল «সম্পন্ন»-এর কালানুক্রম
এজেন্টকে পাসওয়ার্ড রিসেটের কাজ দেওয়া হলো। সে database-এর schema বদলাল, একটি endpoint যোগ করল, email টেমপ্লেট যুক্ত করল, unit test চালাল — সব সবুজ। চ্যাটে এল আত্মবিশ্বাসী একটি বাক্য: «সম্পন্ন»।
বাস্তবে যা ঘটেছে:
- migration মাঝপথে ব্যর্থ হয়েছে এবং schema-কে অসঙ্গত অবস্থায় রেখে গেছে;
- email টেমপ্লেট আছে, কিন্তু মেইল সার্ভিস (SMTP) পরিবেশে কনফিগার করা নেই — মেইল যায় না;
- «ব্যবহারকারী লিংকে ক্লিক করল → নতুন পাসওয়ার্ড দিল → লগইন করল» পরিস্থিতি একবারও চালানো হয়নি।
এর কোনোটি unit test ধরতে পারত না: database mock করা ছিল, মেইল পাঠানো mock করা ছিল, এবং কোনো পূর্ণ চালানো ছিল না।
কেন সবুজ test প্রমাণ করে না যে ফিচার কাজ করে
Unit test একটি মডিউলকে আলাদাভাবে যাচাই করে: নির্ভরতাগুলো mock করা, বাইরের জগৎ বন্ধ। এতে গতি ও নির্ভুলতা আসে, কিন্তু একটি পদ্ধতিগত অন্ধত্বও আসে। এই অন্ধত্ব test-এর ত্রুটি নয়, নকশারই অংশ। সবুজ unit প্রমাণ করে শুধু প্রতিটি অংশ আলাদাভাবে কাজ করে, অংশগুলো একসঙ্গে কাজ করে কি না নয়।
চার ধরনের ত্রুটি unit test নীতিগতভাবে দেখতে পায় না:
| ত্রুটির ধরন | উদাহরণ | কেন unit ধরে না |
|---|---|---|
| ইন্টারফেসের অমিল | একটি অংশ আপেক্ষিক পথ দেয়, অন্যটি পরম পথ চায় | প্রতিটি অংশ নিজের mock দিয়ে পরীক্ষিত, যে mock যেকোনো ফরম্যাট «মেনে নেয়» |
| অবস্থার ছড়ানো | database-এর schema বদলেছে, কিন্তু ORM-এর cache পুরনো | unit-এ আসল database বা cache নেই |
| সম্পদের জীবনচক্র | ফাইল হ্যান্ডেল ও সংযোগ বন্ধ হয় না, বড় ফাইলে মেমরি ফাঁস | test ছোট ডেটায় চলে এবং সম্পদ ফুরানোর আগেই শেষ হয় |
| পরিবেশ ও কনফিগারেশন | environment variable নেই, SMTP সেট করা নেই, migration প্রয়োগ হয়নি | test প্রকৃত কনফিগারেশনে অ্যাপ চালায় না |
যাচাইয়ের স্তরগুলো একটি অন্যটির ভেতরে বসে: unit ধরে এমন সবকিছু integration test-ও ধরে, আর integration যা ধরে তা end-to-end (E2E) চালানোও ধরে। প্রতিটি পরবর্তী স্তর বেশি দেখে। তাই «সম্পন্ন» বলার অধিকার শুধু সর্বোচ্চ স্তরের থাকা উচিত।
সমস্যা মাপা: verification gap
ঠিক করার আগে মাপুন। এজেন্টের বন্ধ করা শেষ ১০টি কাজ নিন। প্রতিটির জন্য দুটি প্রশ্নের উত্তর দিন: এজেন্ট কি «সম্পন্ন» বলেছিল, এবং স্বাধীন যাচাই কি তা নিশ্চিত করেছে (আপনি নিজে পরিস্থিতি চালিয়েছেন, অথবা E2E test সবুজ)। অমিলের অনুপাতই আপনার verification gap।
এই সংখ্যা দুটি কারণে কাজের: এটি «হ্যাঁ, মোটামুটি ঠিক আছে» তর্ক ছাড়াই সমস্যার মাত্রা দেখায়। আর এটি একটি মূল-রেখা দেয়: প্রতিটি প্রক্রিয়া-পরিবর্তনের পর অনুরূপ কাজের সেটে আবার হিসাব করে দেখা যায় উন্নতি হলো কি না।
সত্যিকারের যাচাই: তিনটি স্তরের বৈধতা
একটি কার্যকর তুলনা গাড়ির কারখানার। গাড়ি তিনটি স্টেশন পার হয়, কোনোটি বাদ দেওয়া যায় না।
- ডায়াগনস্টিক (সেকেন্ড): syntax, type, linter। বানান ভুল ও স্থূল ত্রুটি ধরে।
- বেঞ্চ (মিনিট): unit ও integration test, অ্যাপ চালু হয়। ইঞ্জিন চলছে, কিন্তু গাড়ি এখনো এক জায়গায়।
- টেস্ট ড্রাইভ: ব্যবহারকারী যেভাবে পরিস্থিতি চালায় — API, browser বা CLI দিয়ে, আসল database ও কনফিগারেশনসহ।
ক্রমের নিয়ম: ডায়াগনস্টিক লাল থাকলে টেস্ট ড্রাইভে যাবেন না, আর টেস্ট ড্রাইভ না পার হলে গাড়ি ছাড়বেন না। সবুজ unit test হলো দ্বিতীয় স্টেশন পার হওয়া, তৃতীয়টি নয়।
সবকিছু একটি প্রবেশপথে জড়ো করা যায়:
# Makefile
check:
ruff check .
mypy app
pytest tests/unit tests/integration
e2e:
docker compose up -d db mailhog
alembic upgrade head
pytest tests/e2e
verify: check e2e
এখানে E2E লক্ষ্য আসল database ও একটি পরীক্ষামূলক mail সার্ভার চালু করে, migration প্রয়োগ করে, এবং পরিস্থিতিটি শুরু থেকে শেষ পর্যন্ত চালায়। ব্যর্থ migration বা কনফিগার না-করা mail সঙ্গে সঙ্গে ধরা পড়ে, গ্রাহকের কাছে নয়।
AGENTS.md-এ Definition of Done
এজেন্ট নিজে ঠিক করতে পারবে না «সম্পন্ন» মানে কী। মানদণ্ড নির্দেশনার ফাইলে লেখা হয়, যাচাইযোগ্যভাবে:
## Definition of Done
ফিচার তখনই সম্পন্ন, যখন নিচের সব পূরণ হয়:
1. make check কোড 0 নিয়ে শেষ হয়েছে
2. make e2e কোড 0 নিয়ে শেষ হয়েছে, ফিচারের পরিস্থিতি tests/e2e-তে আছে
3. Migration খালি database-এ প্রয়োগ ও rollback হয়
4. নতুন environment variable .env.example-এ বর্ণিত
5. PROGRESS.md-এ লেখা আছে কী করা হয়েছে ও কীভাবে যাচাই হয়েছে
এগুলো সম্পন্নতার লক্ষণ নয়:
- «কোড লেখা হয়েছে এবং ঠিক দেখাচ্ছে»
- «unit test পাস করছে»
- «আমার কম্পিউটারে চলছে»
কী নয় তার স্পষ্ট তালিকা আশার চেয়ে বেশি কাজ করে: এজেন্ট প্রথম সবুজ ফলে থামা বন্ধ করে।
«passing» দেওয়ার অধিকার কার
পরের ধাপ হলো সম্পন্নতার স্ট্যাটাস এজেন্টের হাত থেকে পুরোপুরি সরানো। ফিচারগুলো একটি তালিকায় থাকে (যেমন feature_list.json), যার ক্ষেত্র: «আচরণ», «যাচাই-কমান্ড», «অবস্থা»। শুধু একটি স্ক্রিপ্ট ফিচারকে passing-এ নিতে পারে: সে সাধারণ make check চালায়, তারপর ওই ফিচারের যাচাই-কমান্ড, এবং সফল হলে commit hash সহ স্ট্যাটাস প্রমাণ হিসেবে লেখে। ব্যর্থ হলে ফিচার সক্রিয় থাকে — «প্রায় হয়ে গেছে» বলে কিছু নেই।
{
"id": "F04",
"behavior": "ব্যবহারকারী লিংকসহ ইমেইল পায় এবং পাসওয়ার্ড বদলায়",
"verification": "pytest tests/e2e/test_password_reset.py",
"state": "active"
}
এখানে একটি ফাঁদ আছে: স্ক্রিপ্ট শুধু verification-ফিল্ডে লেখা বিষয়টি যাচাই করে। যদি স্থাপত্য-যাচাই Definition of Done-এর অংশ, কিন্তু ফিচারের কমান্ডে নেই, তবে ফাঁকটি অদৃশ্য থেকে যায়। তাই সাধারণ make check-এ সব বাধ্যতামূলক যাচাই থাকতে হবে, শুধু test নয়।
স্বাধীন মূল্যায়নকারী
পরিবেশকের নিজের প্রতিবেদন কখনো স্বাধীন সত্যের উৎস হয় না। সমাধান কাঠামোগত: ভূমিকা আলাদা করুন।
- পরিকল্পনাকারী প্রয়োজনীয়তাকে গ্রহণযোগ্যতার মানদণ্ডসহ ফিচারে ভাঙে এবং কোড লেখে না;
- জেনারেটর একটি ফিচার বাস্তবায়ন করে ও test চালায়, কিন্তু সম্পন্ন কি না তা ঠিক করে না;
- মূল্যায়নকারী মানদণ্ডের তালিকা ধরে রায় দেয়।
মূল্যায়নকারী জেনারেটরের যুক্তি দেখবে না, কারণ তাহলে সে তার আত্মবিশ্বাসও উত্তরাধিকারে পাবে। সে পায় শুধু প্রয়োজনীয়তা, diff ও যাচাইয়ের ফলাফল। Claude Code-এ এটি subagent দিয়ে সহজে করা যায়, কারণ তার নিজস্ব পরিষ্কার প্রসঙ্গ আছে। আরও ভালো, মূল্যায়নকারী যদি অন্য একটি মডেল হয়, কারণ তার অন্ধ জায়গা আলাদা। «দেখতে ঠিক আছে» ধরনের মূল্যায়ন নিষিদ্ধ: প্রতিটি সিদ্ধান্ত একটি ফাইল, লাইন বা লগের সঙ্গে যুক্ত হতে হবে।
এজেন্ট নিজে ঠিক করতে পারে এমন ত্রুটির বার্তা
যাচাই তখনই কাজের, যখন তার আউটপুট সংশোধনের দিকে নিয়ে যায়। «Test failed» বা শুধু AssertionError এজেন্টের কাছে কিছু বোঝায় না। ভালো বার্তা বলে কী ভাঙল, কেন নিয়মটি আছে, এবং কীভাবে ঠিক করতে হবে:
ERROR arch-check: app/services/refund.py আমদানি করছে app/db/session.py
WHY: service সরাসরি database স্পর্শ করবে না, শুধু repository-র মাধ্যমে
FIX: app/repositories/refund.py থেকে RefundRepository ব্যবহার করুন
এই ফরম্যাট যাচাইকে নিষেধ থেকে ইঙ্গিতে পরিণত করে: এজেন্ট আপনার হস্তক্ষেপ ছাড়াই লঙ্ঘন ঠিক করে।
ম্যানুয়াল যাচাই: এখনো কোথায় দরকার
স্বয়ংক্রিয়তা মানুষকে বাদ দেয় না, তার ভূমিকা সংকুচিত করে। ম্যানুয়াল যাচাই দরকার যেখানে মানদণ্ড সহজে আনুষ্ঠানিক করা যায় না: ইন্টারফেসের চেহারা, লেখা, পরিস্থিতির সুবিধা। এটি করুন গ্রহণযোগ্যতার মানদণ্ডের চেকলিস্ট ধরে, «এলোমেলো ক্লিক» করে নয়। একই মন্তব্য এজেন্টকে দ্বিতীয়বার লিখতে হলে সেটিকে স্বয়ংক্রিয় যাচাইয়ে পরিণত করার সংকেত: test, linter-এর নিয়ম, বা make check-এ grep-গার্ড।
E2E চালানোর আগেই এজেন্টের আচরণ বদলায়
End-to-end test-এর মূল্য শুধু ধরা পড়া বাগে নয়। এজেন্ট যদি আগে থেকে জানে তার কাজ E2E পরিস্থিতি দিয়ে যাচাই হবে, সে আলাদাভাবে কোড লেখে: শুধু নিজের ফাংশন নয়, প্রতিবেশী অংশের সঙ্গে চুক্তির কথা ভাবে, ত্রুটির পথগুলো সামলায়, এবং স্থাপত্যের সীমানা লঙ্ঘন করে না, কারণ লঙ্ঘন চালানোর সময়ই ধরা পড়বে। যাচাই শুধু আউটপুটের ফিল্টার নয়, ইনপুটের সীমাবদ্ধতাও।
একটি শর্ত আছে: E2E অর্থবহ হয় যখন সিস্টেমের স্পষ্ট সীমানা থাকে। স্প্যাগেটি স্থাপত্যে end-to-end test শুধু প্রমাণ করে স্প্যাগেটি চলে, নকশার লঙ্ঘন কোথায় তা দেখায় না। তাই আগে স্তর ও নির্ভরতার নিয়ম স্থির করা হয়, তারপর সীমান্ত-পরিস্থিতি বানানো হয়। এজেন্ট সাগ্রহে repository-র বিদ্যমান প্যাটার্ন নকল করে, এমনকি খারাপগুলোও, তাই সীমাবদ্ধতা প্রথম দিন থেকেই চালু করা উচিত।
সাধারণ ভুল
- এজেন্টকে বলা «আরও ভালো করে দেখো»। প্রসঙ্গ একই থাকে, মূল্যায়নও বাড়াবাড়ি থাকে।
- 100% কভারেজকে গ্যারান্টি ভাবা। Unit-কভারেজ সংযোগ ঢাকে না।
- ফিচার নিশ্চিত হওয়ার আগে রিফ্যাক্টর করা। ক্রম কঠোর: সঠিকতা → কার্যকারিতা → স্টাইল।
- E2E-তে সবচেয়ে বেশি ভাঙা অংশ মক করা। Database, migration ও কনফিগারেশন E2E-তে আসল চালাতে হবে; বাইরের পেইড API পরীক্ষামূলক সার্ভার দিয়ে বদলানো যায়।
সারসংক্ষেপ
এজেন্ট «সম্পন্ন» লিখল, কিন্তু ফিচার কাজ করছে না — সমস্যা প্রায় সবসময় যাচাই-প্রক্রিয়ায়, মডেলে নয়। verification gap মাপুন, AGENTS.md-এ Definition of Done রাখুন, E2E বাধ্যতামূলক করুন, সম্পন্নতার স্ট্যাটাস স্ক্রিপ্টকে দিন, এবং একজন স্বাধীন মূল্যায়নকারী যোগ করুন। এই পদ্ধতি হাতে-কলমে harness engineering কোর্সে বিস্তারিতভাবে শেখানো হয়।
সাধারণ প্রশ্ন
এজেন্টকে নিজে থেকে E2E test চালাতে বলা যায় কি?
যায়, যদি কমান্ডটি AGENTS.md-এ Definition of Done-এর বাধ্যতামূলক অংশ হিসেবে লেখা থাকে এবং প্রয়োজনীয় টুল তার কাছে থাকে। আরও নির্ভরযোগ্য হয় যদি hook বা CI-ও একই কমান্ড চালায়, যাতে এজেন্টের স্মৃতির ওপর নির্ভর না করতে হয়।
E2E test ধীর, প্রতিটি পরিবর্তনে কি চালাতে হবে?
না। Lint, type ও unit test সবসময়; E2E চালানো হয় যখন পরিবর্তন একাধিক স্তর ছোঁয় এবং ফিচারকে সম্পন্ন ঘোষণার আগে।
এজেন্টের বানানো ফ্রন্টএন্ড কীভাবে যাচাই করব?
Browser-ভিত্তিক end-to-end test দিয়ে (যেমন Playwright), যা আসল ইন্টারফেসে ক্লিক করে। চেহারা যাচাই হয় চেকলিস্ট বা স্ক্রিনশট দেখে ম্যানুয়ালি, যা মূল্যায়নকারী পর্যালোচনা করে।
মূল্যায়নকারীর বদলে মানুষের code review যথেষ্ট নয় কি?
মানুষের review উপযোগী, কিন্তু ব্যয়বহুল এবং ঘণ্টার পর ঘণ্টা স্বয়ংক্রিয় কাজের সঙ্গে তাল মেলায় না। রুব্রিকসহ মূল্যায়নকারী স্পষ্ট সমস্যাগুলো মানুষের আগে ছেঁকে দেয়, আর বিতর্কিত প্রশ্নে মানুষ সিদ্ধান্ত নেয়।
“Harness Engineering: инженерия надёжности AI-агентов” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।
- Агент написал «готово», а фича не работает: verification gap и Definition of Done
- Все тесты зелёные, а фича сломана: E2E-тесты и архитектурные правила для AI-агента