যখন আমাদের AI প্রদানকারী মডেলটা বন্ধ করে দিল
একটা মডেল বদল, ত্রুটি ছাড়াই খালি উত্তর, আর একটা বিল যা হঠাৎ কয়েকগুণ বেড়ে গেল। কী ভেঙেছিল, আর কারণটা দেখা কেন এত কঠিন ছিল।

2026 সালের জুলাইয়ে একসাথে কয়েকটি ফিচার কাজ করা বন্ধ করে দিল: AI চ্যাট, টিকিটে AI উত্তর, টিকিটের সারাংশ, সার্ভার বিল্ডার, আর সাথে আইডিয়া ও বাগ রিপোর্টের মডারেশন ও অনুবাদ।
কারণ আমাদের কোড ছিল না। আমাদের AI প্রদানকারী যে মডেলটা আমরা ব্যবহার করছিলাম সেটা বন্ধ করে দিয়েছিল।
প্রথম অংশ: মডেলটা নেই
এটা স্পষ্ট অংশ, আর দ্রুত ঠিক হয়েছিল। একজন প্রদানকারী একটা মডেল বন্ধ করে, আপনি উত্তরসূরিটা লিখে দেন, হয়ে গেল।
আসল ঘটনা শুরু হলো এর পরে।
দ্বিতীয় অংশ: খালি উত্তর, ত্রুটি ছাড়া
বদলের পর উত্তর আসছিল। শুধু মাঝে মাঝে সেগুলো খালি ছিল। কাটা নয়, বিকৃত নয়, বরং কোনো ত্রুটি ছাড়াই সম্পূর্ণ খালি একটা উত্তর।
কারণটা এমন এক পার্থক্যে যা মডেলের নাম প্রকাশ করে না: উত্তরসূরিটা একটা যুক্তি করা মডেল। আসল উত্তরের আগে সে প্রথমে একটা আলাদা ক্ষেত্রে একটা অভ্যন্তরীণ চিন্তার ধারা লেখে। দুটোই একই টোকেন বাজেট থেকে খরচ করে।
চিন্তায় বাজেট শেষ হয়ে গেলে এমন একটা উত্তর ফেরে যা আনুষ্ঠানিকভাবে ঠিকঠাক: প্রদানকারী জানায় "দৈর্ঘ্যে পৌঁছেছে" আর বিষয়বস্তুর ক্ষেত্রটা খালি। কোনো ত্রুটি নয়, কোনো ইঙ্গিত নয়, এমন কিছুই নয় যা একটা try/catch দেখতে পেত।
আমরা একটা আসল পরীক্ষা দিয়ে এটা পুনরুৎপাদন করেছি: পাঁচ টোকেনের বাজেটই প্রতিটি অনুরোধে একটা খালি উত্তর তৈরি করতে যথেষ্ট।
তৃতীয় অংশ: বিল
সবচেয়ে ব্যয়বহুল কলের জায়গায়, AI সার্ভার বিল্ডারে, আমরা একটা উদার বাজেট দিয়েছিলাম কারণ সেখানে লম্বা উত্তর তৈরি হয়। তাই চিন্তাটা কোনো সীমায় ধাক্কা খায়নি, এটা শুধু চলতেই থাকল।
পরিণতি এল দুই দিক থেকে একসাথে। অনুরোধগুলো এত সময় নিল যে টাইমআউটে পড়ল। আর সেগুলোর খরচ কয়েকগুণ বেশি হলো, কারণ প্রতিবার একটা সম্পূর্ণ অদৃশ্য চিন্তার ধারার জন্য টাকা দিতে হচ্ছিল। শেষে এল একটা ত্রুটির বার্তা যার পরিকল্পনা আমরা করিনি: অপর্যাপ্ত ব্যালেন্স।
সমাধানটা এক লাইনের। অনুরোধের বডিতে চিন্তা বন্ধ করা যায়, আর তখন মডেলটা আবার পুরোনোটার মতো আচরণ করে। তখন থেকে সেই লাইনটা প্রতিটি কলের জায়গায় থাকে, আর রিপোজিটরিতে এমন জায়গা হাতে গোনা কয়েকটার বেশি।
চতুর্থ অংশ: পরিষ্কার করার সময় যা পেলাম
প্রতিটি AI কলের জায়গায় যখন হাত দিতেই হচ্ছে, তখন সেগুলো দেখাও হয়। এতে একটা দ্বিতীয় বিষয় উঠে এল, ঘটনার সাথে সম্পর্কহীন কিন্তু একইরকম ব্যয়বহুল।
প্রদানকারীরা এমন প্রম্পটের জন্য অনেক কম টাকা নেয় যার শুরুটা অপরিবর্তিত থাকে আর একটা ক্যাশ থেকে দেওয়া যায়। হিট আর মিসের মধ্যে পার্থক্য মোটামুটি ত্রিশগুণ।
এই ছাড় একটা ফ্ল্যাগ দিয়ে পাওয়া যায় না। আমরা নির্দিষ্টভাবে পরীক্ষা করেছি: এর জন্য তৈরি অনুরোধের বডির একটা ক্ষেত্রের শূন্য প্রভাব ছিল, ক্যাশ এমনিতেই স্বয়ংক্রিয়ভাবে প্রযোজ্য হয়। একমাত্র লিভার হলো প্রম্পটের ভেতরের ক্রম, স্থির থেকে পরিবর্তনশীলের দিকে।
চারটি জায়গা যেখানে আমরা ঠিক উল্টোটা করেছিলাম:
নির্দিষ্ট নির্দেশনা ব্লকের ভেতরে একটা পরিবর্তনশীল মান। বাগ রিপোর্টের ডুপ্লিকেট যাচাইয়ে নির্দেশনার লেখায় মডিউলের নাম ছিল। এতে অন্যথায় একই রকম একটা ব্লক প্রতিটি মডিউলের জন্য নিজস্ব ক্যাশ লাইন পেত। মানটার জায়গা পরিবর্তনশীল অংশে, যেখানে এটা এমনিতেই বদলায়।
স্থির জিনিসের আগে নতুন জিনিস। একই যাচাই নতুন বাগ রিপোর্টটা তুলনার জন্য সর্বোচ্চ পঞ্চাশটি প্রার্থীর আগে পাঠাত। এতে API-এর সবচেয়ে বড় প্রম্পটটা স্থায়ীভাবে সম্পূর্ণ মিস হয়ে থাকত।
নির্দিষ্ট অংশে প্রত্যেক ব্যবহারকারীর ডেটা। পাবলিক AI চ্যাটে প্রত্যেক ব্যবহারকারী সম্পর্কে নোট নির্দেশনা ব্লকে ছিল, অর্থাৎ যৌথ চ্যানেল ইতিহাসের আগে। এতে একই চ্যানেলের প্রত্যেক ব্যবহারকারী নিজস্ব শুরু পেতেন, আর যৌথ ইতিহাসের জন্য প্রত্যেক ব্যবহারকারীর ক্ষেত্রে আলাদা টাকা দিতে হতো।
ইতিহাসের ওপর একটা চলমান জানালা। প্রতিটি মেসেজে শেষ N মেসেজ পাঠালে প্রতিটি মেসেজে শুরুটা সরে যায়। তখন পুরো ইতিহাস একটা স্থায়ী মিস হয়ে থাকে। সঠিক পদ্ধতি হলো ব্লকে ছাঁটা, অর্থাৎ কদাচিৎ আর বেশি করে।
সাথে একটা খুঁটিনাটি যা খুঁতধরা মনে হয় অথচ নয়: একটা প্রম্পটের ভেতরের তালিকা যদি শুধু একটা মানদণ্ডে সাজানো থাকে, সমান হলে তার ক্রম বদলে যেতে পারে। নির্দেশনা ব্লকের মাঝখানে একটা মাত্র অদলবদল হওয়া লাইন তার পরের সবকিছুর হিট নষ্ট করে। প্রম্পটের ভেতরের সাজানোর জন্য একটা দ্ব্যর্থহীন নিষ্পত্তিকারী মানদণ্ড দরকার।
আমরা কী নিয়ে এলাম
মডেল বদল কোনো কনফিগারেশন বদল নয়। নামটা একটা ভেরিয়েবলের মানের মতো দেখায়। এর পেছনে ছিল ভিন্ন আচরণ, আর সেই আচরণ আমাদের কোড ভেঙেছে, ইন্টারফেস নয়।
বিপজ্জনক ব্যর্থতা ছিল নীরবটা। পুরোনো মডেল চলে যাওয়া সঙ্গে সঙ্গে দেখা গিয়েছিল আর কয়েক মিনিটে ঠিক হয়েছিল। খালি উত্তরগুলো আনুষ্ঠানিকভাবে বৈধ উত্তর হিসেবে ফিরত আর অনির্দিষ্টকাল এভাবে থাকতে পারত।
পরিমাপযোগ্যতার জায়গা কলের জায়গায়। এখন আমরা প্রতিটিতে ক্যাশ হিটের হার লগ করি। সঠিকভাবে বানানো জায়গা প্রথম অনুরোধের পর উঁচু হারে স্থির হয়, খারাপভাবে বানানোটা শূন্যে থাকে। এটা একটা লগ লাইনে দেখা যায় আর অন্য কোথাও নয়, কারণ দুটোই কাজ করে।
আর অস্বস্তিকর উপসংহার: অন্যের মডেল ব্যবহার করা মানে আপনার পণ্যের একটা অংশ অন্য কোথাও নেওয়া সিদ্ধান্তের ওপর নির্ভর করে। সেজন্যই আগস্ট থেকে যেকোনো সার্ভার আমাদেরটার ওপর নির্ভর না করে AI ফিচারগুলোকে নিজস্ব এন্ডপয়েন্টের দিকে নির্দেশ করতে পারে।
আরও নিবন্ধ
4,000টি Discord সার্ভারের ওপর নজর: Grafana, PostHog আর এরা আমাদের যা দেখাল
একটা লুপ যা চুপচাপ আমাদের অর্ধেক ট্রাফিক তৈরি করত, দিনে তিন মিলিয়ন অর্থহীন অনুরোধ আর একটা আক্রমণ যা এক মিনিটে শেষ হয়ে গেল। আমাদের মনিটরিং কী দেখে, আর কী ইচ্ছে করেই দেখে না।
পর্দার আড়ালে2,000+ Discord সার্ভারে একটা বট চালিয়ে আমরা যা শিখেছি
চারটি জিনিস যা বড় পরিসরে কোড লেখার সময় যা মনে হয় তার থেকে আলাদাভাবে কাজ করে।
পর্দার আড়ালেআমাদের কোডের ভেতরের আইন
একটা বাতিল বাটন যা লগইন ছাড়াই কাজ করতে হবে। একটা ফর্ম যা কখনো আপনাকে প্রত্যাখ্যান করতে পারবে না। আমাদের কাছে আইনি দায়িত্ব কেন বাঁধা গৎ নয়, বরং স্থাপত্য।