আপনি একটি অভ্যন্তরীণ টুল তৈরি করেছেন যা একটি টিমের জন্য মডেলের API কল না করেই একটি LLM-চালিত ফিচারের ওপর ২৮টি ইউনিট টেস্ট চালানোর সুযোগ দেয়। আপনি এটি করেছেন মডেলটিকে একটি fakeable interface-এ মুড়িয়ে এবং তিনটি স্তর—deterministic, heuristic এবং LLM-ভিত্তিক মূল্যায়নের মাধ্যমে।

স্ট্যান্ডার্ড অ্যাসারশন (assertions) তখনই ভেঙে পড়ে যখন একটি LLM গদ্য বা টেক্সট তৈরি করে। একই প্রম্পট প্রতিবার ভিন্ন ভিন্ন বাক্য তৈরি করতে পারে, তাই assertEqual(output, expected) একটি ব্যর্থতা হিসেবে চিহ্নিত করে, এমনকি যখন মডেলটি সঠিকভাবে কাজ করছিল। বেশিরভাগ ইঞ্জিনিয়ারিং গ্রুপ হয় যাচাইকরণ ছাড়াই ফিচারটি শিপ করে অথবা মডেলটিকেই টেস্ট করার চেষ্টা করে, যেন এটি একটি স্থির লাইব্রেরি (static library)।

কেন এই সমস্যাটি গুরুত্বপূর্ণ

LLM এখন কাস্টমার-ফেসিং ওয়ার্কফ্লোর—যেমন ইমেল আউটরিচ, সাপোর্ট রিপ্লাই, কন্টেন্ট জেনারেশন—ভেতরে কাজ করছে। একটি মাত্র কাল্পনিক তথ্য (hallucinated fact) বা ফাঁস হওয়া আইডেন্টিফায়ার ব্র্যান্ডের সুনাম নষ্ট করতে পারে, ব্যক্তিগত তথ্য প্রকাশ করতে পারে বা কমপ্লায়েন্স লঙ্ঘন করতে পারে। একটি নির্ভরযোগ্য টেস্ট স্ট্র্যাটেজি ছাড়া, টিমগুলো অহেতুক ব্যর্থতা (flaky failures) খুঁজতে সময় নষ্ট করে অথবা এমন বাগ শিপ করে যা কেবল প্রোডাকশনে গিয়ে ধরা পড়ে।

পদ্ধতি: মডেলের দায়িত্ব কমিয়ে আনা

প্রথম পদক্ষেপ ছিল LLM আসলে কী করতে পারে তা সীমিত করা। লেখকের সিস্টেমে মডেলটি কেবল আউটরিচ মেসেজ ড্রাফট করে। সমস্ত রাউটিং লজিক, স্টেট ম্যানেজমেন্ট এবং সেফটি চেক সাধারণ কোডেই থাকে। মডেলটিকে একটি নির্দিষ্ট এবং সুসংজ্ঞায়িত আউটপুটের মধ্যে সীমাবদ্ধ রাখার মাধ্যমে, আশেপাশের সিস্টেমটি ডিটারমিনিস্টিক এবং টেস্টযোগ্য থাকে।

এটি সম্ভব করার জন্য, LLM একটি প্রোভাইডার ইন্টারফেসের পেছনে থাকে, যা টেস্টের ক্ষেত্রে একটি ফেক ভার্সন ব্যবহার করার অনুমতি দেয়। প্রোডাকশনে ইমপ্লিমেন্টেশনটি এক্সটার্নাল API কল করে; টেস্ট সুইটে একটি লাইটওয়েট ফেক একটি canned response প্রদান করে। যেহেতু বাকি কোড শুধুমাত্র ইন্টারফেসের সাথে যোগাযোগ করে, তাই পুরো ওয়ার্কফ্লোটি এমন ইউনিট টেস্টের মাধ্যমে পরীক্ষা করা সম্ভব যা কখনোই নেটওয়ার্ক স্পর্শ করে না। এর ফলে একটি প্রেডিক্টেবল কোর তৈরি হয় যা ২৮টি টেস্ট যাচাই করে।

একটি স্বচ্ছ মূল্যায়ন হারনেস (evaluation harness)

এমনকি পরিধি সীমিত করার পরেও, মডেলের আউটপুট অনির্ধারিত (nondeterministic) থাকে। তাই লেখক একটি তিন-স্তরের মূল্যায়ন হারনেস তৈরি করেছেন, যেখানে প্রতিটি স্তর ভিন্ন ধরনের ঝুঁকি মোকাবিলা করে।

  • স্তর ১ – ডিটারমিনিস্টিক চেক (Deterministic checks) সাধারণ রেগুলার-এক্সপ্রেশন (regular-expression) নিয়মগুলো ভুল বিল্ডিং আইডি বা নিষিদ্ধ টোকেনের মতো সুনির্দিষ্ট ত্রুটি শনাক্ত করে। এই চেকগুলো দ্রুত এবং একটি বাইনারি পাস/ফেল (pass/fail) ফলাফল দেয়।

  • স্তর ২ – হিউরিস্টিক চেক (Heuristic checks) স্ক্রিপ্টগুলো কাল্পনিক সংখ্যা বা তারিখ খোঁজে এবং স্পষ্ট ভুল তথ্য শনাক্ত করে। এগুলো এমন মিথ্যা দাবি ধরতে পারে না যেগুলোতে কোনো সংখ্যাগত ইঙ্গিত নেই, এবং লেখক এই সীমাবদ্ধতাটি স্পষ্টভাবে স্বীকার করেছেন।

  • স্তর ৩ – LLM জাজ (LLM judge) একটি সেকেন্ডারি মডেল টোন এবং প্রফেশনালিজম রেট করে। যেহেতু এই ধাপটি অন্য একটি প্রোবাবিলিস্টিক সিস্টেমের ওপর নির্ভর করে, তাই এটি কেবল সেই বিষয়গুলোর জন্য ব্যবহার করা হয় যেখানে ডিটারমিনিস্টিক নিয়ম প্রয়োগ করা অসম্ভব।

হারনেসটির মূল চাবিকাঠি হলো মূল্যায়নের জন্য ব্যবহৃত ডেটাসেট। লেখক পরিচিত ব্যর্থতার প্যাটার্নগুলো—নির্দিষ্ট ফাঁদ এবং ডোমেইন নলেজ—এনকোড করেছেন যাতে হারনেসটি ঠিক সেই ভুলগুলোই পরীক্ষা করে যা বাস্তবে দেখা গেছে। এটি কোনো জাদুকরী "সবকিছু ধরার" ব্যবস্থা নয়, বরং একটি টার্গেটেড সেফটি নেট।

টিমের জন্য এর অর্থ কী

  • LLM-এর কাজ ছোট রাখুন। দায়িত্ব যত কম হবে, আইসোলেশন এবং টেস্টিং তত সহজ হবে।
  • রাউটিং, স্টেট এবং সেফটি কোডে রাখুন। প্রথাগত লজিক ডিটারমিনিস্টিক এবং সম্পূর্ণ টেস্টযোগ্য থাকে।
  • মডেলটিকে একটি fakeable interface-এর মাধ্যমে প্রকাশ করুন। ইউনিট টেস্টগুলো এক্সটার্নাল কল ছাড়াই চলে, যা টেস্ট সুইটকে দ্রুত এবং নির্ভরযোগ্য রাখে।
  • মূল্যায়নে স্তর ব্যবহার করুন। ডিটারমিনিস্টিক নিয়ম দিয়ে শুরু করুন, পরিচিত হ্যালুসিনেশনের জন্য হিউরিস্টিক যোগ করুন এবং সাবজেক্টিভ কোয়ালিটি চেকের জন্য LLM জাজ ব্যবহার করুন।
  • সীমাবদ্ধতা উল্লেখ করুন। কোনো স্তরই নিখুঁত হওয়ার নিশ্চয়তা দেয় না; হারনেসটি কেবল সেটুকুই ধরতে পারে যা আপনি স্পষ্টভাবে প্রোগ্রাম করেছেন।

পাল্টা যুক্তি: আপনি তবুও মডেলটিকে ইউনিট-টেস্ট করতে পারবেন না

লেখক স্বীকার করেছেন যে একটি মডেল হলো একটি পরিবর্তনশীল লক্ষ্য (moving target)। এমনকি LLM জাজ লেয়ারটিও সেই একই নন-ডিটারমিনিজম বহন করে যা এটি মূল্যায়ন করার চেষ্টা করে। ফলে, সিস্টেমটি কখনোই গ্যারান্টি দিতে পারে না যে রিলিজের আগে প্রতিটি হ্যালুসিনেশন বা পলিসি লঙ্ঘন ধরা পড়বে। এই পদ্ধতি ঝুঁকি কমায়, কিন্তু পুরোপুরি দূর করে না; এবং এটি নতুন ধরনের ব্যর্থতা দেখা দিলে মূল্যায়ন ডেটা আপডেট রাখার টিমের ক্ষমতার ওপর নির্ভর করে।

সারসংক্ষেপ

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