8 মিনিট

AI অ্যাপে ফ্রন্টএন্ড ও ব্যাকএন্ড জুড়ে স্টেট ম্যানেজ করা

এআই অ্যাপগুলিতে UI, সেশন ও ডেটা স্টেট কীভাবে ফ্রন্টএন্ড ও ব্যাকএন্ডের মধ্যে চলাচল করে—সিঙ্ক, পারসিস্টেন্স, ক্যাশিং এবং সিকিউরিটির ব্যবহারিক প্যাটার্নসহ জানুন।

AI অ্যাপে ফ্রন্টএন্ড ও ব্যাকএন্ড জুড়ে স্টেট ম্যানেজ করা

AI-নির্মিত অ্যাপে “স্টেট” বলতে কী বোঝায়

“স্টেট” হলো আপনার অ্যাপটি ঠিকভাবে কাজ করার জন্য যে সমস্ত তথ্য মনে রাখে তা।

যদি একটি ব্যবহারকারী চ্যাট UI-তে Send চাপেন, অ্যাপটি তাদের টাইপ করা বিষয়, অ্যাসিস্ট্যান্ট যা ইতিমধ্যে উত্তর দিয়েছে, কোনো অনুরোধ চলছে কিনা, বা কোন সেটিং (টোন, মডেল, টুলস) চালু আছে—এসব ভুলে গেলে চলবে না। এগুলোই স্টেট।

সহজ ভাষায় স্টেট

স্টেট ভাবার জন্য একটি উপযোগী উপায় হল: অ্যাপের বর্তমান সত্যতা—যে ভ্যালুগুলি ব্যবহারকারীকে কি দেখা যায় এবং সিস্টেম পরবর্তীভাবে কী করবে তা প্রভাবিত করে। এর মধ্যে স্পষ্ট জিনিসগুলো যেমন ফর্ম ইনপুটের পাশাপাশি “অদৃশ্য” বিষয়গুলোও রয়েছে, যেমন:

  • ব্যবহারকারী কোন কনভার্সেশনে আছে
  • শেষ উত্তর স্ট্রিম হচ্ছে নাকি শেষ হয়েছে
  • মেসেজগুলোর তালিকা এবং তাদের ক্রমানুসার
  • টুল কল এবং টুল ফলাফল (সার্চ রেজাল্ট, ডাটাবেস লুকআপ, ফাইল এক্সট্র্যাক্ট)
  • এরর, রিট্রাই, এবং রেট-লিমিট ব্যাকঅফ

কেন এআই অ্যাপগুলোতে বেশি চলাফেরা থাকে

প্যারাম্পরিক (traditional) অ্যাপগুলো সাধারণত ডেটা পড়ে, দেখায়, এবং আপডেট সংরক্ষণ করে। এআই অ্যাপগুলোতে অতিরিক্ত ধাপ এবং মধ্যবর্তী আউটপুট আসে:

  • একটি ব্যবহারকারীর একক অ্যাকশন অনেকগুলো ব্যাকএন্ড অপারেশন ট্রিগার করতে পারে (LLM কল, টুল কল, আরেকটি LLM কল)।
  • উত্তরগুলো আংশিকভাবে আগমন করতে পারে (স্ট্রিমিং টোকেন), তাই UI-কে আংশিক স্টেট ম্যানেজ করতে হবে।
  • কনটেক্সট জরুরি: সিস্টেমকে কনভার্সেশন মেমরি, টুল আউটপুট, এবং মডেল সেটিংস অনুরোধ জুড়ে মিলিয়ে রাখতে হতে পারে।

এই অতিরিক্ত চলাচলই এআই অ্যাপ্লিকেশনগুলোর স্টেট ম্যানেজমেন্টকে প্রায়শই লুকানো জটিলতা করে তোলে।

এই গাইডে কী থাকবে

নিচের অংশগুলোতে আমরা স্টেটকে ব্যবহারিক শ্রেণিতে ভাগ করব (UI স্টেট, সেশন স্টেট, পারসিস্ট করা ডেটা, এবং মডেল/রানটাইম স্টেট) এবং দেখাবো প্রতিটি কোথায় থাকা উচিত (ফ্রন্টএন্ড বনাম ব্যাকএন্ড)। আমরা সিঙ্কিং, ক্যাশিং, দীর্ঘকালীন কাজ, স্ট্রিমিং আপডেট, এবং সিকিউরিটি-ও আলোচনা করব—কারণ স্টেট তখনই উপকারী যখন তা সঠিক এবং সুরক্ষিত হয়।

দ্রুত উদাহরণ

একটি চ্যাট অ্যাপ কল্পনা করুন যেখানে ব্যবহারকারী বলেন: “গত মাসের ইনভয়েসগুলো সারসংক্ষেপ করো এবং অস্বাভাবিক কিছু থাকলে ফ্ল্যাগ করো।” ব্যাকএন্ড সম্ভবত (1) ইনভয়েসগুলো আনবে, (2) একটি বিশ্লেষণ টুল চালাবে, (3) UI-তে সারাংশ স্ট্রিম করবে, এবং (4) চূড়ান্ত রিপোর্ট সংরক্ষণ করবে।

একটি স্নিগ্ধ অভিজ্ঞতা দিতে, অ্যাপটিকে মেসেজ, টুল রেজাল্ট, প্রগতি, এবং সংরক্ষিত আউটপুট ট্র্যাক করতে হবে—কনভার্সেশনগুলোর মধ্যে গুলিয়ে না দেওয়া বা ব্যবহারকারীদের মধ্যে ডেটা লিক করা ছাড়া।

স্টেটের চার লেয়ার: UI, সেশন, ডেটা, এবং মডেল

যখন লোকেরা এআই অ্যাপে “স্টেট” বলে, তারা প্রায়শই খুব ভিন্ন জিনিসগুলো মিশিয়ে দেয়। স্টেটকে চারটি স্তরে ভাগ করলে—UI, সেশন, ডেটা, এবং মডেল/রানটাইম—নিশ্চিত করা সহজ হয় কোথায় কিছু থাকা উচিত, কে তা পরিবর্তন করতে পারে, এবং কীভাবে সংরক্ষিত করা উচিত।

1) UI স্টেট (ব্যবহারকারী এখন কী করছে)

UI স্টেট হলো ব্রাউজার বা মোবাইল অ্যাপে লাইভ, মূহর্ত-প্রতি-মূহর্তের স্টেট: টেক্সট ইনপুট, টগল, নির্বাচিত আইটেম, কোন ট্যাব খোলা আছে, এবং কোন বাটন ডিসেবল আছে কিনা।

এআই অ্যাপগুলো কিছু UI-নির্দিষ্ট বিবরণ যোগ করে:

  • লোডিং ইন্ডিকেটর এবং “চিন্তা করছে” স্টেট
  • স্ট্রিম করা টোকেন (জেনারেট হওয়ার সময় আংশিক টেক্সট দেখা)\
  • লোকাল ড্রাফট মেসেজ (সেন্ড করার আগে)

UI স্টেট রিসেট করা সহজ হওয়া উচিত এবং হারানো নিরাপদ। যদি ব্যবহারকারী পৃষ্ঠা রিফ্রেশ করে, আপনি এটি হারায় ফেলতে পারেন—এটি সাধারণত ঠিক আছে।

2) সেশন / কনভার্সেশন স্টেট (ব্যবহারকারীর ফ্লো শেয়ার করা কনটেক্সট)

সেশন স্টেট ব্যবহারকারীকে একটি চলমান ইন্টারঅ্যাকশনের সাথে বাঁধে: ব্যবহারকারী পরিচয়, একটি কনভার্সেশন আইডি, এবং মেসেজ ইতিহাসের একটি সঙ্গতিশীল ভিউ।

এআই অ্যাপগুলোতে এটির মধ্যে প্রায়শই থাকে:

  • মেসেজ ইতিহাস (বা তার রেফারেন্স)
  • টুল ট্রেস (কোন ফাংশন/টুল কল হয়েছে ও কী রেজাল্ট পেয়েছে)
  • “ওয়ার্কিং সেট” পছন্দগুলো যেমন বর্তমান প্রকল্প/ডকুমেন্ট, নির্বাচিত মডেল, বা ওয়ার্কস্পেস

এই স্তরটি প্রায়শই ফ্রন্টএন্ড এবং ব্যাকএন্ড উভয় জায়গায় বিস্তৃত: ফ্রন্টএন্ড হাল্কা আইডেন্টিফায়ার রাখে, আর ব্যাকএন্ড সেশন ধারাবাহিকতা এবং এক্সেস কন্ট্রোলের কর্তৃপক্ষ।

3) ডাটা স্টেট (স্টোরেজে টিকে থাকা রেকর্ড)

ডাটা স্টেট হলো আপনি ইচ্ছাকৃতভাবে ডাটাবেসে সংরক্ষণ করেন: প্রকল্প, ডকুমেন্ট, এমবেডিং, পছন্দসমূহ, অডিট লগ, বিলিং ইভেন্ট, এবং সংরক্ষিত কনভার্সেশন ট্রান্সক্রিপ্ট।

UI এবং সেশন স্টেটের বিপরীতে, ডাটা স্টেট হওয়া উচিত:

  • টেকসই (রিস্টার্ট সত্ত্বেও টিকে থাকে)
  • কুয়েরি যোগ্য (আপনি এটি সার্চ/ফিল্টার করতে পারবেন)
  • অডিটেবল (পরে আপনি বুঝতে পারবেন কি ঘটেছিল)

4) মডেল / রানটাইম স্টেট (AI কিভাবে কনফিগার করা আছে)

মডেল/রানটাইম স্টেট হলো উত্তর উৎপাদনের জন্য ব্যবহৃত অপারেশনাল সেটআপ: সিস্টেম প্রম্পট, টুলস সক্রিয় আছে কি না, টেম্পারেচার/ম্যাক্স টোকেন, সেফটি সেটিংস, রেট লিমিট, এবং অস্থায়ী ক্যাশ।

কিছু জিনিস কনফিগারেশন (স্থায়ী ডিফল্ট), কিছু অস্থায়ী (শর্ট-লাইভ ক্যাশ বা প্রতি অনুরোধ টোকেন বাজেট)। এগুলোর বেশিরভাগ ব্যাকএন্ডেই থাকা উচিত যাতে একবারে নিয়ন্ত্রণ করা যায় এবং অপ্রয়োজনীয়ভাবে প্রকাশ না হয়।

কেন বিভাজন বাগ কমায়

যখন এই স্তরগুলো ঝাপসা হয়ে যায়, তখন আপনি পাবেন প্রচলিত ব্যর্থতা: UI এমন টেক্সট দেখায় যা সংরক্ষিত হয়নি, ব্যাকএন্ড ফ্রন্টএন্ডের প্রত্যাশার চেয়ে ভিন্ন প্রম্পট সেটিং ব্যবহার করে, বা কনভার্সেশন মেমরি ব্যবহারকারীদের মধ্যে লিক করে। স্পষ্ট সীমানা প্রদান করলে কোনটি স্থায়ী হতে হবে, কোনটি পুনরায় গণনা করা যাবে, এবং কোনটি সুরক্ষিত থাকতে হবে তা পরিষ্কার হয়।

ফ্রন্টএন্ড বনাম ব্যাকএন্ড—কি কোথায় থাকা উচিত (এবং কেন)

AI অ্যাপগুলিতে বাগ কমানোর নির্ভরযোগ্য উপায় হল প্রতিটি স্টেটের টুকরো জন্য সিদ্ধান্ত নেওয়া: ব্রাউজারে (ফ্রন্টএন্ড), সার্ভারে (ব্যাকএন্ড), নাকি উভয় জায়গায়। এই সিদ্ধান্ত নির্ভরযোগ্যতা, সিকিউরিটি, এবং ব্যবহারকারীর রিফ্রেশ/নতুন ট্যাব/নেটওয়ার্ক বিলুপ্তির সময় অ্যাপ কতটা “অবাক করা” হবে তা প্রভাবিত করে।

ফ্রন্টএন্ড স্টেট: দ্রুত, অস্থায়ী, এবং ব্যবহারকারী-চালিত

ফ্রন্টএন্ড স্টেট তাদের জন্য ভাল যারা দ্রুত পরিবর্তিত হয় এবং রিফ্রেশের পরও টিকে থাকতে হবে না। লোকাল রাখা UI-কে রেসপনসিভ করে এবং অপ্রয়োজনীয় API কল প্রতিরোধ করে।

কমন ফ্রন্টএন্ড-ওনলি উদাহরণ:

  • ব্যবহারকারী টাইপ করা ড্রাফট মেসেজ টেক্সট
  • টেবিলে লোকাল ফিল্টার এবং সর্ট অর্ডার
  • মডাল খোলা/বন্ধ, নির্বাচিত ট্যাব, হভার স্টেট

যদি আপনি রিফ্রেশে এই স্টেট হারান, তা সাধারণত গ্রহণযোগ্য।

ব্যাকএন্ড স্টেট: কর্তৃত্বপূর্ণ, সংবেদনশীল, এবং শেয়ারযোগ্য

ব্যাকএন্ড স্টেট হওয়া উচিত যেগুলো বিশ্বাসযোগ্য, অডিটযোগ্য বা ধারাবাহিকভাবে রক্ষা করতে হবে। এতে অন্তর্ভুক্ত এমন স্টেট যা অন্য ডিভাইস/ট্যাবকে দেখতে হবে, বা ক্লায়েন্ট পরিবর্তিত হলেও সঠিক থাকতে হবে।

কমন ব্যাকএন্ড-ওনলি উদাহরণ:

  • পারমিশন ও রোল (ব্যবহারকারী কী করতে পারবে)
  • বিলিং/সাবস্ক্রিপশন স্ট্যাটাস এবং ব্যবহার সীমা
  • দীর্ঘকালীন কাজ (ডকুমেন্ট ইনডেক্সিং, বড় এক্সপোর্ট, ফাইন-টিউন রান) এবং তাদের স্ট্যাটাস

একটি ভাল মানসিকতা: যদি ভুল স্টেট খরচ করা বা ডেটা লিক করার কারণ হতে পারে, বা অ্যাক্সেস কন্ট্রোল ভাঙবে, তাহলে তা ব্যাকএন্ডে রাখা উচিত।

শেয়ার করা স্টেট: সমন্বিত, কিন্তু একটি উৎস-অফ-সত্য থাকা উচিত

কিছু স্টেট স্বভাবতই শেয়ার করা হয়:

  • কনভার্সেশন শিরোনাম
  • চ্যাটের জন্য নির্বাচিত নলেজ সোর্স
  • ডিভাইস জুড়ে ব্যবহার হওয়া ইউজার প্রোফাইল ফিল্ড

শেয়ার করার সময়ও একটি “সোর্স অফ ট্রুথ” বেছে নিন। সাধারণত ব্যাকএন্ডই কর্তৃপক্ষ এবং ফ্রন্টএন্ড দ্রুততার জন্য একটি কপি ক্যাশ করে রাখে।

নিয়মের সংক্ষিপ্তসার (এবং একটি সাধারণ অ্যান্টি-প্যাটার্ন)

স্টেটকে যেখানে প্রয়োজন, সেখানে কাছাকাছি রাখুন, তবে যা রিফ্রেশ, ডিভাইস পরিবর্তন বা বিঘ্নে টিকে থাকতে হবে তা পারসিস্ট করুন।

সাধারণ অ্যান্টি-প্যাটার্নটি হলো সংবেদনশীল বা কর্তৃত্বপূর্ণ স্টেট কেবল ব্রাউজারে রাখা (যেমন ক্লায়েন্ট-সাইড isAdmin ফ্ল্যাগ, প্ল্যান টিয়ার, বা জব কমপ্লিশন স্টেটকে সত্যি ধরে নেওয়া)। UI এই মানগুলো প্রদর্শন করতে পারে, কিন্তু ব্যাকএন্ডকে অবশ্যই যাচাই করতে হবে।

একটি সাধারণ AI অনুরোধ লিফসাইকেল: ক্লিক থেকে সম্পূর্ণ হওয়া পর্যন্ত

একটি এআই ফিচার “একটি কাজ” মনে হয়, কিন্তু আসলে এটি ব্রাউজার ও সার্ভারের মধ্যে স্টেট ট্রানজিশনের একটি চেইন। লাইফসাইকেল বোঝা মিলিয়ে দেয় কীভাবে UI মেলানো যায়, কনটেক্সট নিশ্চিত করা যায়, এবং দ্বিগুণ চার্জ থেকে বাঁচা যায়।

1) ব্যবহারকারীর অ্যাকশন → ফ্রন্টএন্ড উদ্দেশ্য প্রস্তুত করে

ব্যবহারকারী Send চাপলে UI দ্রুত লোকাল স্টেট আপডেট করে: হয়তো একটি “পেন্ডিং” মেসেজ বাবল যোগ করা হবে, সেন্ড বাটন ডিসেবল হবে, এবং বর্তমান ইনপুট (টেক্সট, অ্যাটাচমেন্ট, নির্বাচিত টুলস) ক্যাপচার করা হবে।

এই সময় ফ্রন্টএন্ডকে করিলেশন আইডি জেনারেট বা সংযুক্ত করা উচিত:

  • conversation_id: কোন থ্রেডে এটি যাচ্ছে
  • message_id: ক্লায়েন্টের নতুন ইউজার মেসেজের আইডি
  • request_id: প্রতি চেষ্টা-পাহাড়ে ইউনিক (রিট্রাইয়ের জন্য উপকারী)

এই আইডিগুলো উভয় পক্ষকে একই ইভেন্ট সম্পর্কে কথা বলতে দেয়, এমনকি যখন উত্তর দেরিতে বা দ্বিগুণ এসে পড়ে।

2) API কল → সার্ভার যাচাই ও পরম্পরায় সংরক্ষণ করে

ফ্রন্টএন্ড ইউজার মেসেজ এবং আইডিগুলো নিয়ে একটি API অনুরোধ পাঠায়। সার্ভার অনুমতি, রেট লিমিট, এবং পে লোড শেইপ যাচাই করে, তারপর ইউজার মেসেজটি (অথবা অন্তত একটি ইমিউটেবল লগ রেকর্ড) conversation_id এবং message_id দিয়ে কীড করে সংরক্ষণ করে।

এই পারসিস্টেন্স ধাপটি রিকোয়েস্ট মাঝখানে রিফ্রেশ করলে “ভূত ইতিহাস” প্রতিরোধ করে।

3) সার্ভার কনটেক্সট পুনর্নির্মাণ করে

মডেল কল করার জন্য সার্ভার তার সোর্স-অফ-ট্রুথ থেকে কনটেক্সট পুনর্নির্মাণ করে:

  • conversation_id-এর জন্য সাম্প্রতিক মেসেজ আনুন
  • প্রাসঙ্গিক রেকর্ড টেনে আনুন (ডকুমেন্ট, পছন্দ, টুল আউটপুট)
  • কনভার্সেশন পলিসি প্রয়োগ করুন (সিস্টেম প্রম্পট, মেমরি রুলস, ট্রাঙ্কেশন)

মূল ধারণা: ক্লায়েন্টকে পুরো ইতিহাস দেওয়ার উপর নির্ভর করবেন না। ক্লায়েন্ট স্টেইল হতে পারে।

4) মডেল/টুল কার্যকরী → মধ্যবর্তী স্টেট

সার্ভার টুলগুলো কল করতে পারে (সার্চ, ডিবি লুকআপ) মডেল জেনারেশনের আগে বা চলাকালীন। প্রতিটি টুল কল একটি মধ্যবর্তী স্টেট উৎপন্ন করে যা request_id-এর সাথে ট্র্যাক করা উচিত যাতে এটিকে অডিট ও নিরাপদভাবে রিট্রাই করা যায়।

5) উত্তর (স্ট্রিমিং বা না) → UI সম্পূর্ণতা

স্ট্রিমিং হলে সার্ভার আংশিক টোকেন/ইভেন্ট প্রেরণ করে। UI পরপর pending assistant মেসেজ আপডেট করে, কিন্তু একটি ফাইনাল ইভেন্ট না এলে এটি “চলমান” ধরেই থাকে।

6) ব্যর্থতা পয়েন্ট পরিকল্পনা করা

রিট্রাই, ডাবল-সাবমিট, এবং আউট-অফ-অর্ডার রেসপন্স ঘটে। সার্ভারে ডিউপ করার জন্য request_id ব্যবহার করুন, এবং UI-তে মিলানোর জন্য message_id ব্যবহার করুন (সক্রিয় অনুরোধের সাথে ম্যাচ না করলে দেরিতে আসা চাঙ্ক উপেক্ষা করুন)। সর্বদা স্পষ্ট “failed” স্টেট দেখান এবং একটি নিরাপদ রিট্রাই’opশন দিন যাতে ডুপ্লিকেট মেসেজ তৈরি না হয়।

সেশন ও কনভার্সেশন মেমরি: কনটেক্সট রাখবে কীভাবে (অচলাবস্থা ছাড়া)

ওয়েব ও মোবাইলের প্রোটোটাইপ তৈরি করুন
একই ব্যাকএন্ড স্টেট শেয়ার করা Flutter মোবাইল এবং React ওয়েব ক্লায়েন্ট তৈরি করুন.

সেশন হলো সেই “থ্রেড” যা ব্যবহারকারীর অ্যাকশনগুলোকে একসাথে বেঁধে রাখে: তারা কোন ওয়ার্কস্পেসে আছে, তারা শেষ কী সার্চ করেছে, কোন ড্রাফট এডিট করছিল, এবং কোন কনভার্সেশনে AI-র উত্তর চালিয়ে যেতে হবে। ভালো সেশন স্টেট পেজ বদলালেও অ্যাপটিকে ধারাবাহিক মনে করায়—এবং আদর্শভাবে ডিভাইস জুড়ে—বিনা পটিয়ে ব্যাকএন্ডকে সব কিছু জমে রাখা ছাড়া।

সেশন স্টেটের লক্ষ্য

লক্ষ্য রাখুন: (1) ধারাবাহিকতা (ব্যবহারকারী ছেড়ে এসে ফেরত আসতে পারে), (2) সঠিকতা (AI সঠিক কনটেক্সটে সাড়া দেয়), এবং (3) কনটেইনমেন্ট (এক সেশন অন্যটির মধ্যে লিক না করে)। যদি আপনি একাধিক ডিভাইস সমর্থন করেন, সেশনকে ব্যবহারকারী-স্কোপড প্লাস ডিভাইস-স্কোপড বিবেচনা করুন: “একই অ্যাকাউন্ট” মানে সবসময় “একই খোলা কাজ” নয়।

কুকি বনাম টোকেন বনাম সার্ভার সেশন

আপনি সাধারণত সেশন শনাক্ত করার জন্য নিচের উপায়গুলোর মধ্যে একটি বেছে নেবেন:

  • কুকিজ: ওয়েব অ্যাপের জন্য সহজ কারণ ব্রাউজার এগুলো স্বয়ংক্রিয়ভাবে পাঠায়। প্রচলিত সেশনের জন্য ভালো, কিন্তু আপনাকে সিকিউর ফ্ল্যাগ সেট করতে হবে (HttpOnly, Secure, SameSite) এবং CSRF সমাধান করতে হবে।
  • টোকেন (যেমন JWT): API ও মবাইল অ্যাপের জন্য ভালো কারণ ক্লায়েন্ট এগুলো স্পষ্টভাবে সংযুক্ত করতে পারে। এগুলো ভালো স্কেল করে, কিন্তু রিভোকেশন এবং রোটেশন অতিরিক্ত ডিজাইন প্রয়োজন (এবং টোকেনে সংবেদনশীল স্টেট বসানো উচিত নয়)।
  • সার্ভার সেশন: সার্ভার সেশন ডেটা সংরক্ষণ করে (প্রায়শই Redis-এ), এবং ক্লায়েন্ট কেবল একটি অপ্যাক সেশন আইডি রাখে। রিভোক করা সহজ, আপডেট করা সহজ, কিন্তু আপনাকে সেশন স্টোর চালাতে ও স্কেল করতে হবে।

কনভার্সেশন মেমরি স্ট্র্যাটেজি

“মেমরি” হল কেবলই সেই স্টেট যেটি আপনি মডেলের কাছে ফেরত পাঠাতে বেছে নেন।

  • পূর্ণ ইতিহাস: সবচেয়ে সঠিক, কিন্তু ব্যয়বহুল এবং পুরানো সংবেদনশীল কনটেন্ট সেভ করতে পারে।
  • সংক্ষিপ্ত সারাংশ: একটি চলমান সারাংশ + কিছু সাম্প্রতিক টার্ন রাখুন; সস্তা এবং সাধারণত পর্যাপ্ত।
  • উইন্ডোড কনটেক্সট: কেবল শেষ N মেসেজ; সহজ, কিন্তু গুরুত্বপূর্ণ আগের সিদ্ধান্ত হারিয়ে যেতে পারে।

প্রায়োগিক প্যাটার্ন হল সারাংশ + উইন্ডো: এটি পূর্বাভাসযোগ্য এবং অপ্রত্যাশিত মডেল আচরণ কমায়।

টুল কল: পুনরাবৃত্তি যোগ্য ও অডিটযোগ্য

যদি AI টুল ব্যবহার করে (সার্চ, ডাটাবেস কুয়েরি, ফাইল রিড), প্রতিটি টুল কল সংরক্ষণ করুন: ইনপুট, টাইমস্ট্যাম্প, টুল সংস্করণ, এবং ফিরিয়ে দেওয়া আউটপুট (অথবা তার রেফারেন্স)। এতে আপনি বুঝতে পারবেন “কেন AI সেটা বলল,” ডিবাগিংয়ের জন্য রানগুলিকে রেপ্লে করতে পারবেন, এবং টুল বা ডেটাসেট পরিবর্তনের কারণে ফলাফল পরিবর্তন হলে তা সনাক্ত করতে পারবেন।

প্রাইভেসি গার্ডরেল

ডিফল্টভাবে দীর্ঘমেয়াদী মেমরি সংরক্ষণ করবেন না। কেবল ধারাবাহিকতার জন্য প্রয়োজনীয় জিনিসগুলো রাখুন (কনভার্সেশন আইডি, সারাংশ, টুল লগ), রিটেনশন লিমিট সেট করুন, এবং কাঁচা ব্যবহারকারী টেক্সট সংরক্ষণ করা থেকে বিরত থাকুন যদি না স্পষ্ট প্রোডাক্ট কারণ এবং ব্যবহারকারীর সম্মতি থাকে।

নিরাপদভাবে স্টেট সিঙ্ক করা: সত্যতার উৎস ও কনফ্লিক্ট হ্যান্ডলিং

যখন একই “বস্তু” একাধিক জায়গায় সম্পাদিত হতে পারে—আপনার UI, আরেকটি ব্রাউজার ট্যাব, বা একটি ব্যাকগ্রাউন্ড জব—স্টেট ঝুঁকিপূর্ণ হয়ে ওঠে। সমাধান চতুর কডিংয়ের চেয়ে স্পষ্ট মালিকানার নিয়মে বেশি।

সত্যতার উৎস নির্ধারণ করুন

প্রতিটি স্টেট অংশের জন্য সিদ্ধান্ত নিন কোন সিস্টেম কর্তৃত্বশালী। অধিকাংশ AI অ্যাপ্লিকেশনে ব্যাকএন্ডকে canonical রেকর্ড দেওয়া উচিত যে কোনও কিছুর জন্য যা সঠিক হতে হবে: কনভার্সেশন সেটিংস, টুল পারমিশন, মেসেজ ইতিহাস, বিলিং সীমা, এবং জব স্ট্যাটাস। ফ্রন্টএন্ড কেশ করে কপি রাখতে পারে দ্রুততার জন্য (নির্বাচিত ট্যাব, ড্রাফট প্রম্পট টেক্সট, “টাইপ করছে” নির্দেশ), কিন্তু কোনো মিলবৈরিতা থাকলে ব্যাকএন্ডকে সঠিক ধরুন।

প্র্যাকটিকাল নিয়ম: যদি এটি রিফ্রেশে হারালে আপনি বিরক্ত হবেন, এটি সম্ভবত ব্যাকএন্ডে থাকা উচিত।

অপটিমিস্টিক UI আপডেট (সাবধানে ব্যবহার করুন)

অপটিমিস্টিক আপডেট অ্যাপটিকে তাত্ক্ষণিক মনে করায়: কোনো সেটিং টগল করুন, UI তত্ক্ষণিক আপডেট করুন, তারপর সার্ভারের সাথে কনফার্ম করুন। এটি কম-স্টেকস, উল্টানোযোগ্য অ্যাকশনের (যেমন কোনো কনভার্সেশন স্টার করা) জন্য ভাল কাজ করে।

যখন সার্ভার পরিবর্তন প্রত্যাখ্যান বা রূপান্তর করতে পারে (পারমিশন চেক, কোটা লিমিট, ভ্যালিডেশন, বা সার্ভার-সাইড ডিফল্ট), তখন বিভ্রান্তি সৃষ্টি করে। সেই সব ক্ষেত্রে “saving…” স্টেট দেখান এবং কেবল কনফার্ম হওয়ার পরে UI আপডেট করুন।

কনফ্লিক্ট হ্যান্ডলিং (দুই ট্যাব, একটি কনভার্সেশন)

কনফ্লিক্ট ঘটে যখন দুই ক্লায়েন্ট একই রেকর্ড আলাদা শুরু ভার্সন থেকে আপডেট করে। সাধারণ উদাহরণ: ট্যাব A এবং ট্যাব B উভয়ই মডেল টেম্পারেচার পরিবর্তন করে।

স্টেল রাইট সনাক্ত করার জন্য লাইটওয়েট ভার্শনিং ব্যবহার করুন:

  • updated_at টাইমস্ট্যাম্প (সহজ এবং মানুষের বোঝার মতো)
  • ETags / If-Match হেডার (HTTP-নেটিভ)
  • ইনক্রিমেন্টিং রিভিশন নম্বর (স্পষ্ট কনফ্লিক্ট ডিটেকশন)

যদি ভার্সন মেলে না, একটি কনফ্লিক্ট রেসপন্স (প্রায়শই HTTP 409) রিটার্ন করুন এবং সর্বশেষ সার্ভার অবজেক্ট পাঠান।

API ডিজাইন করে মিলবৈরিতা কমান

কোনও রাইটের পরে API-কে সেভ করা অবজেক্ট রিটার্ন করান (সার্ভার-জেনারেটেড ডিফল্ট, নর্মালাইজড ফিল্ড, এবং নতুন ভার্সন সহ)। এতে ফ্রন্টএন্ড তার ক্যাশ করা কপি তৎক্ষণাত প্রতিস্থাপন করতে পারে—এক উৎস-অফ-ট্রুথ আপডেট, অনুমান করার চেয়ে ভালো।

ক্যাশিং এবং পারফরম্যান্স: দ্রুত করা (স্টেল স্টেট না দিয়ে)

ক্যাশিং অ্যাপটিকে তাত্ক্ষণিক মনে করানোর দ্রুত উপায়গুলোর একটি, কিন্তু এটি একই সময়ে স্টেটের দ্বিতীয় কপি তৈরি করে। যদি আপনি ভুল জিনিস ক্যাচ করেন—অথবা ভুল জায়গায়—তবে আপনি দ্রুত কিন্তু বিভ্রান্তিকর UI পাঠাচ্ছেন।

ক্লায়েন্টে কী ক্যাশ করবেন

ক্লায়েন্ট-সাইড ক্যাশগুলো অভিজ্ঞতার উপর ফোকাস করা উচিত, কর্তৃত্ব নয়। ভালো প্রার্থীরা:

  • সাম্প্রতিক কনভার্সেশন প্রিভিউ (শিরোনাম, শেষ মেসেজ স্নিপেট)
  • UI পছন্দ (থিম, নির্বাচিত মডেল, সাইডবার অবস্থা)
  • অপটিমিস্টিক UI স্টেট (“sending” মেসেজ)

ক্লায়েন্ট ক্যাশ ছোট এবং ডিসপোজেবল রাখুন: যদি এটি মুছে যায়, অ্যাপটিকে সার্ভার থেকে পুনরায় নিয়ে কাজ করতে সক্ষম হতে হবে।

সার্ভারে কী ক্যাশ করবেন

সার্ভার ক্যাশগুলো ব্যয়বহুল বা ঘন ঘন পুনরায় চালিত কাজের উপর ফোকাস করা উচিত:

  • পুনঃব্যবহারযোগ্য টুল রেজাল্ট (যেমন একই শহরের আবহাওয়া ৫ মিনিটের মধ্যে)
  • এমবেডিং লুকআপ এবং ভেক্টর সার্চ রেজাল্ট (অল্প TTL)।
  • রেট-লিমিট স্টেট এবং থ্রটলিং কাউন্টার

এখানেই আপনি ডেরিভড স্টেটও ক্যাশ করতে পারেন যেমন টোকেন কাউন্ট, মনিটরিং ডিসিশন, বা ডকুমেন্ট পার্সিং আউটপুট—যেগুলো ডিটারমিনিস্টিক এবং ব্যয়বহুল।

ক্যাশ ইনভ্যালিডেশন মৌলিক (অতিরিক্ত জটিলতা ছাড়া)

তিনটি ব্যবহারিক নিয়ম:

  1. ইনপুট এনকোড করে ক্লিয়ার ক্যাশ কী ব্যবহার করুন (user_id, মডেল, টুল প্যারামিটার, ডকুমেন্ট ভার্সন)।
  2. TTL সেট করুন কিভাবে আন্ডারলাইন ডেটা বদলে যায় তার ওপর ভিত্তি করে। ছোট TTL জটিল লজিকের চেয়ে ভাল।
  3. যেখানে সঠিকতা গতি চাইছে তাওয়াও বেশি গুরুত্বপূর্ণ—ক্লিয়ার ক্যাশ করুন: ব্যবহারকারী ডকুমেন্ট আপডেট করলে, পারমিশন পরিবর্তন করলে, বা রিফ্রেশ অনুরোধ করলে ক্যাশ বাইপাস করুন।

আপনি যদি ব্যাখ্যা করতে না পারেন কখন কোনও ক্যাশ এন্ট্রি ভুল হয়ে যাবে, সেটিকে ক্যাশ করবেন না।

সিক্রেট বা ব্যক্তিগত ডেটা শেয়ার্ড ক্যাশে রাখবেন না

শেয়ার্ড লেয়ারে (CDN) API কী, অথ টোকেন, কাঁচা প্রম্পট বা ব্যবহারকারী-নির্দিষ্ট কনটেন্ট ক্যাশ করবেন না। যদি ব্যবহারকারীর ডেটা ক্যাশ করতে হয়, তাহলে ব্যবহারকারী অনুযায়ী আলাদা করে এনক্রিপ্টেড রাখুন—অথবা প্রাইমারি ডাটাবেসে রাখুন।

প্রভাব পরিমাপ: গতি বনাম স্টেল UI

ক্যাশিংকে প্রমাণিত করে নিন, অনুমান করে না। p95 ল্যাটেন্সি আগে/পরে মাপুন, ক্যাশ হিট রেট, এবং ব্যবহারকারী-দৃশ্য ত্রুটি ট্র্যাক করুন যেমন “রেন্ডার করার পরে মেসেজ আপডেট হয়েছে”। পরে UI-র সাথে টক্কর খাওয়া একটি দ্রুত প্রতিক্রিয়া সাধারণত ধীরে কিন্তু সামঞ্জস্যপূর্ণ প্রতিক্রিয়ার চাইতে খারাপ।

পারসিস্টেন্স ও দীর্ঘকালীন কাজ: জব, কিউ, এবং স্ট্যাটাস স্টেট

স্টেট নিরাপদ রাখুন
স্টেট রাইটের জন্য সার্ভার-সাইড অথরাইজেশন চেক এবং নিরাপদ ভ্যালিডেশন প্যাটার্ন জেনারেট করুন.

কিছু এআই ফিচার এক সেকেন্ডে শেষ হয়। কিছু মিনিট নেয়: PDF আপলোড ও পার্স করা, নলেজ বেস এম্বেডিং ও ইনডেক্স করা, অথবা বহু-ধাপ টুল ওয়ারফ্লো চালানো। এসবের জন্য, “স্টেট” কেবল স্ক্রিনে থাকা নয়—এটি রিফ্রেশ, রিট্রাই, এবং সময় সইয়ে টিকে থাকা জিনিস।

কি পারসিস্ট করবেন (এবং কেন)

কেবলমাত্র যা প্রকৃত প্রোডাক্ট ভ্যালু Unlock করে তা পারসিস্ট করুন।

কনভার্সেশন হিস্ট্রি হলো স্পষ্ট জিনিস: মেসেজ, টাইমস্ট্যাম্প, ব্যবহারকারী আইডেন্টিটি, এবং প্রায়ই কোন মডেল/টুল ব্যবহৃত হয়েছে। এটি “পরে আবার শুরু করুন”, অডিট ট্রেল, এবং শ্রেষ্ঠ সাপোর্ট চালনায় কাজ করে।

ব্যবহারকারী ও ওয়ার্কস্পেস সেটিংস ডাটাবেসে থাকা উচিত: পছন্দকৃত মডেল, টেম্পারেচার ডিফল্ট, ফিচার টগল, সিস্টেম প্রম্পট, এবং যেগুলো ব্যবহারকারী ডিভাইস জুড়ে অনুসরণ করবে এমন UI পছন্দ।

ফাইল ও আর্টিফ্যাক্ট (আপলোড, এক্সট্র্যাক্ট টেক্সট, জেনারেটেড রিপোর্ট) সাধারণত অবজেক্ট স্টোরেজে রাখা হয়, ডাটাবেস রেকর্ডগুলো তাদের পয়েন্টার হয়। ডাটাবেসে মেটাডেটা থাকে (মালিক, সাইজ, কনটেন্ট টাইপ, প্রসেসিং স্টেট) এবং ব্লব স্টোরে বাইটগুলি।

দীর্ঘকালীন কাজের জন্য ব্যাকগ্রাউন্ড জব

যদি একটি অনুরোধ সাধারণ HTTP টাইমআউটের মধ্যে নির্ভরযোগ্যভাবে শেষ না হতে পারে, কাজটিকে কিউতে সরিয়ে দিন।

টিপিক্যাল প্যাটার্ন:

  • ফ্রন্টএন্ড POST /jobs-এর মতো একটি API কল করে ইনপুট (ফাইল আইডি, কনভার্সেশন আইডি, প্যারামিটার) দিয়ে।
  • ব্যাকএন্ড একটি জব এনকিউ করে (এক্সট্র্যাকশন, ইনডেক্সিং, ব্যাচ টুল রান) এবং সঙ্গে সঙ্গে একটি job_id রিটার্ন করে।
  • ওয়ার্কাররা অ্যাসিনক্রোনাসভাবে জব প্রক্রিয়াকরণ করে এবং ফলাফল পারসিস্টেন্ট স্টোরেজে লিখে।

এটি UI-কে রেসপনসিভ রাখে এবং রিট্রাইলকে নিরাপদ করে।

UI যে স্ট্যাটাসে বিশ্বাস করতে পারে

জব স্টেট স্পষ্ট ও কুয়েরি যোগ্য করুন: queued → running → succeeded/failed (ঐচ্ছিক canceled)। এই ট্রানজিশনগুলো সার্ভার-সাইডে টাইমস্ট্যাম্প ও এরর ডিটেইলসহ স্টোর করুন।

ফ্রন্টএন্ডে স্ট্যাটাস স্পষ্টভাবে প্রতিফলিত করুন:

  • Queued/running: স্পিনার দেখান এবং ডুপ্লিকেট অ্যাকশন নিষ্ক্রিয় করুন।
  • Failed: সংক্ষিপ্ত এরর দেখান এবং Retry বাটন দিন।
  • Succeeded: ফলাফল লোড করুন বা কনভার্সেশন আপডেট করুন।

GET /jobs/{id} (পোলিং) বা আপডেট স্ট্রিম (SSE/WebSocket) এক্সপোজ করুন যাতে UI অনুমান না করে।

আইডেম্পোটেন্সি কীগুলো: রিট্রাইয়ে ডুপ্লিকেট রাইট না হওয়া

নেটওয়ার্ক টাইমআউট হয়। যদি ফ্রন্টএন্ড POST /jobs রিট্রাই করে, আপনি দুটি একই জব চান না (এবং দুটি বিল)।

প্রতি লজিক্যাল অ্যাকশনের জন্য একটি Idempotency-Key বাধ্যতামূলক করুন। ব্যাকএন্ড কীটি রেসপন্স/job_id-এর সাথে স্টোর করে এবং পুনরাবৃত্ত অনুরোধে একই ফলাফল রিটার্ন করে।

ক্লিনআপ ও মেয়াদউত্তীর্ণ নীতিমালা

দীর্ঘমেয়াদী এআই অ্যাপগুলো দ্রুত ডেটা জমা করে। শুরুতেই রিটেনশন রুল নির্ধারণ করুন:

  • পুরনো কনভার্সেশন N দিনের পরে মেয়াদোত্তীর্ণ করুন (অথবা ব্যবহারকারী কনফিগার করতে দিন)।
  • সোর্স মুছে ফেলার সময় ডেরিভড আর্টিফ্যাক্ট মুছুন।
  • ত্রুটিপূর্ণ জব ও মধ্যবর্তী ফাইল সময়ে সময়ে পরিস্কার করুন।

ক্লিনআপকে স্টেট ম্যানেজমেন্টের অংশ হিসেবে বিবেচনা করুন: এটি ঝুঁকি, খরচ, এবং বিভ্রান্তি কমায়।

স্ট্রিমিং রেসপন্স ও রিয়েল-টাইম আপডেট: আংশিক স্টেট ম্যানেজ করা

স্ট্রিমিং মানে “উত্তর” আর একক ব্লব নয়। আপনি আংশিক টোকেন (শব্দে-শব্দে টেক্সট) এবং কখনও কখনও আংশিক টুল কাজের সাথে ডিল করছেন। এর মানে UI ও ব্যাকএন্ডকে অস্থায়ী বনাম চূড়ান্ত স্টেট কী তা নিয়ে একইভাবে সম্মত হতে হবে।

ব্যাকএন্ড: কেবল টেক্সট নয়, টাইপ করা ইভেন্ট স্ট্রিম করুন

একটি পরিষ্কার প্যাটার্ন হল ছোট ইভেন্টগুলোর সিকোয়েন্স স্ট্রিম করা, প্রতিটিতে একটি টাইপ ও পে-লোড থাকে। উদাহরণ:

  • token: ইঙ্ক্রিমেন্টাল টেক্সট (অর্থাৎ ছোট চাঙ্ক)
  • tool_start: একটি টুল কল শুরু হয়েছে (উদাহরণ: “Searching…”, একটি id সহ)
  • tool_result: টুল আউটপুট প্রস্তুত (একই id)
  • done: অ্যাসিস্ট্যান্ট মেসেজ সম্পূর্ণ
  • error: কিছু ব্যর্থ হয়েছে (একটি ব্যবহারকারী-নিরাপদ বার্তা এবং একটি ডিবাগ id অন্তর্ভুক্ত)

এই ইভেন্ট স্ট্রিম কাঁচা টেক্সট স্ট্রিমিংয়ের তুলনায় ভেসণযোগ্য ও ডিবাগ-বান্ধব, কারণ ফ্রন্টএন্ড প্রগতি সঠিকভাবে রেন্ডার করতে পারে (এবং টুল স্ট্যাটাস দেখাতে পারে) অনুমান না করে।

ফ্রন্টএন্ড: অ্যাপেন্ড-অনলি আপডেট, তারপর ফাইনাল কমিট

ক্লায়েন্টে স্ট্রিমিংকে অ্যাপেন্ড-অনলি হিসেবে ধরুন: একটি “ড্রাফট” অ্যাসিস্ট্যান্ট মেসেজ তৈরি করুন এবং token ইভেন্ট আসা মাত্র তা বাড়াতে থাকুন। done এলে একটি কমিট সম্পাদন করুন: মেসেজকে চূড়ান্ত চিহ্নিত করুন, যদি লোকালভাবে সংরক্ষণ করে থাকেন তা পারসিস্ট করুন, এবং কপি/রেট/রিজেনারেট মতো অ্যাকশন আনলক করুন।

এটি ইতিহাস মাঝখানে লিখে ফেলা এড়ায় এবং UI-কে পূর্বানুমানযোগ্য রাখে।

ব্যাঘাত হ্যান্ডলিং (ক্যানসেল, ড্রপ, টাইমআউট)

স্ট্রিমিং মাঝপথে আধা-সম্পন্ন কাজের সম্ভবনা বাড়ায়:

  • ব্যবহারকারী ক্যানসেল করে: একটি ক্যানসেল সিগন্যাল পাঠান; টোকেন রেন্ডার বন্ধ করুন; ড্রাফট দৃশ্যমানভাবে ক্যানসেলড দেখান।
  • নেটওয়ার্ক ড্রপ: স্ট্রিম বন্ধ করুন; “reconnecting…” দেখান; সম্পূর্ণতা ধরে নেবেন না।
  • সার্ভার টাইমআউট/এরর: ড্রাফটকে ফেল হয়ে চূড়ান্ত করুন, এবং একটি রিট্রাই প্রদান করুন যা একটি নতুন অনুরোধ শুরু করে (স্ট্রীম গুলো নির্বিচারে মিলিয়ে দেবেন না)।

রিহাইড্রেশন: লোড ও স্থির স্টেট পুনর্নির্মাণ

পেজ রিফ্রেশ হওয়ার সময় যদি স্ট্রিম চলছে, শেষ স্থিতিশীল স্টেট থেকে পুনর্নির্মাণ করুন: শেষ কমিট করা মেসেজ এবং যে কোনও স্টোর করা ড্রাফট মেটাডেটা (মেসেজ আইডি, জমা হওয়া টেক্সট, টুল স্ট্যাটাস)। যদি আপনি স্ট্রিম পুনরায় শুরু করতে না পারেন, ড্রাফটকে বাধাগ্রস্তভাবে দেখান এবং ব্যবহারকারীকে রিট্রাই করতে দিন—সম্পন্ন হয়েছে বলে ছদ্মবেশ করা থেকে বিরত থাকুন।

সিকিউরিটি ও প্রাইভেসি: এন্ড-টু-এন্ড স্টেট সুরক্ষা

রোলব্যাক সুরক্ষায় শিপ করুন
Koder.ai-তে স্ন্যাপশট এবং রোলব্যাক দিয়ে স্টেট পরিবর্তনে আত্মবিশ্বাসের সঙ্গে পুনরাবৃত্তি করুন.

স্টেট শুধুই “আপনি যা সংরক্ষণ করেন” নয়—এটি ব্যবহারকারীর প্রম্পট, আপলোড, পছন্দ, জেনারেটেড আউটপুট, এবং যে মেটাডাটা সবকিছুকে একত্রে বাঁধে। এআই অ্যাপে সেই স্টেটটি অসাধারণভাবে সংবেদনশীল হতে পারে (ব্যক্তিগত তথ্য, স্বত্বাধীন ডকুমেন্ট, অভ্যন্তরীণ সিদ্ধান্ত), তাই প্রতিটি স্তরে সিকিউরিটি ডিজাইন করা প্রয়োজন।

সিক্রেট সার্ভারে রাখুন

কোনোও জিনিসই যা ক্লায়েন্টকে আপনার অ্যাপ হয়ে ছদ্মবেশ করার অনুমতি দেয় তা ব্যাকএন্ড-অনলি রাখুন: API কী, প্রাইভেট কনেক্টর (Slack/Drive/DB ক্রেডেনশিয়াল), এবং অভ্যন্তরীণ সিস্টেম প্রম্পট বা রাউটিং লজিক। ফ্রন্টএন্ড একটি অ্যাকশন অনুরোধ করতে পারে (“এই ফাইল সারসংক্ষেপ করো”), কিন্তু ব্যাকএন্ড সিদ্ধান্ত নেবে কিভাবে ও কোন ক্রেডেনশিয়াল দিয়ে এক্সিকিউট করা হবে।

প্রতিটি রাইট অথরাইজ করুন (এবং বেশিরভাগ রিডও)

প্রতিটি স্টেট মিউটেশনকে একটি প্রিভিলেজড অপারেশন হিসেবে বিবেচনা করুন। ক্লায়েন্ট যখন মেসেজ তৈরি করে, কনভার্সেশন রিনেম করে, বা ফাইল অ্যাটাচ করে, ব্যাকএন্ড যাচাই করবে:

  • ব্যবহারকারী প্রমাণীকৃত কি না।
  • ব্যবহারকারী রিসোর্সের মালিক কি না (কনভার্সেশন, ওয়ার্কস্পেস, প্রজেক্ট)।
  • ব্যবহারকারী সেই অ্যাকশন করতে অনুমোদিত কি না (রোল, প্ল্যান লিমিট, অর্গ পলিসি)।

এটি “ID guessing” আক্রমণ প্রতিরোধ করে যেখানে কেউ conversation_id বদলে অন্যের ইতিহাস অ্যাক্সেস করে।

ব্রাউজারকে কখনই বিশ্বাস করবেন না: ভ্যালিডেট ও স্যানিটাইজ করুন

কোনো ক্লায়েন্ট-প্রদত্ত স্টেটকে অনুগ্রহ করে অ-ট্রাস্টেড ইনপুট ধরুন। স্কিমা ও সীমা যাচাই করুন (টাইপ, লেন্থ, অনুমোদিত এনাম), এবং গন্তব্য অনুযায়ী স্যানিটাইজ করুন (SQL/NoSQL, লগ, HTML রেন্ডারিং)। যদি আপনি “স্টেট আপডেট” গ্রহণ করেন (যেমন সেটিংস, টুল প্যারামিটার), তাহলে হোয়াইটলিস্টেড ফিল্ডগুলোকেই অনুমতি দিন পরিবর্তে য arbitrary JSON মার্জ করা।

গুরুত্বপূর্ণ অ্যাকশনের জন্য অডিট ট্রেল

যে অ্যাকশনগুলো স্থায়ী স্টেট বদলে দেয়—শেয়ারিং, এক্সপোর্ট, ডিলিট, কনেক্টর অ্যাক্সেস—কারা কী করেছে ও কখন তা রেকর্ড করুন। একটি হালকা অডিট লগ incident response, কাস্টমার সাপোর্ট, ও কমপ্লায়েন্সে সহায়ক।

ডেটা মিনিমাইজেশন ও এনক্রিপশন

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

ব্যবহারিক রেফারেন্স আর্কিটেকচার ও বিল্ড চেকলিস্ট

AI অ্যাপগুলোর জন্য একটি দরকারি ডিফল্ট সহজ: ব্যাকএন্ড হল সোর্স অফ ট্রুথ, এবং ফ্রন্টএন্ড একটি দ্রুত, অপটিমিস্টিক ক্যাশ। UI তাত্ক্ষণিক মনে হতে পারে, কিন্তু আপনি যা হারাতে দুঃখ করবেন (মেসেজ, জব স্ট্যাটাস, টুল আউটপুট, বিলিং-প্রাসঙ্গিক ইভেন্ট) তা সার্ভার-সাইডে নিশ্চিত ও সংরক্ষিত করা উচিত।

আপনি যদি “vibe-coding” ওয়ার্কফ্লো-এ নির্মাণ করেন—যেখানে অনেক প্রোডাক্ট সারফেস দ্রুত জেনারেট হয়—স্টেট মডেল আরও গুরুত্বপূর্ণ হয়ে ওঠে। Koder.ai-এর মতো প্ল্যাটফর্ম টীমকে চ্যাট থেকে পূর্ণ ওয়েব, ব্যাকএন্ড, ও মোবাইল অ্যাপ শিপ করতে সাহায্য করতে পারে, কিন্তু একই নিয়ম প্রযোজ্য: দ্রুত পুনরাবৃত্তি নিরাপদ যখন আপনার সত্যতার উৎস, আইডি, এবং স্ট্যাটাস ট্রানজিশনগুলি প্রথমেই ডিজাইন করা থাকে।

রেফারেন্স আর্কিটেকচার (একটি যেটা আপনি পাঠাতে পারবেন)

ফ্রন্টএন্ড (ব্রাউজার/মোবাইল)

  • UI স্টেট: ওপেন প্যানেল, ড্রাফট প্রম্পট টেক্সট, নির্বাচিত মডেল, অস্থায়ী “টাইপ করছে” ইন্ডিকেটর।
  • ক্যাশ করা সার্ভার স্টেট: সাম্প্রতিক কনভার্সেশন, সর্বশেষ জব স্ট্যাটাস, আংশিক স্ট্রীম বাফার।
  • একটি একক রিকোয়েস্ট পাইপলাইন যা সবসময় সংযুক্ত করে: session_id, conversation_id, এবং একটি নতুন request_id

ব্যাকএন্ড (API + ওয়ার্কার)

  • API সার্ভিস: ইনপুট ভ্যালিডেট করে, রেকর্ড তৈরি করে, স্ট্রীমিং রেসপন্স ইস্যু করে।
  • স্থায়ী স্টোর (SQL/NoSQL): কনভার্সেশন, মেসেজ, টুল কল, জব স্ট্যাটাস।
  • কিউ + ওয়ার্কার: দীর্ঘকালীন কাজ (RAG ইনডেক্সিং, ফাইল পার্সিং, ইমেজ জেনারেশন)।
  • ক্যাশ (ঐচ্ছিক): হট রিড (কনভার্সেশন সারাংশ, এমবেডিং মেটাডেটা), সর্বদা ভার্সন/টাইমস্ট্যাম্প কী-সহ।

দ্রষ্টব্য: একটি প্র্যাকটিকাল উপায় কনসিস্টেন্ট রাখা early: উদাহরণস্বরূপ, Koder.ai-জেনারেটেড ব্যাকএন্ড সাধারণত Go + PostgreSQL ব্যবহার করে (এবং ফ্রন্টএন্ডে React), যা SQL-এ কর্তৃপক্ষ স্টেট কেন্দ্রীভূত করে এবং ক্লায়েন্ট ক্যাশ ডিসপোজেবল রাখে।

প্রথমে আপনার স্টেট মডেল ডিজাইন করুন

স্ক্রিন তৈরি করার আগে, প্রতিটি স্তরে আপনি উপর নির্ভর করবেন এমন ফিল্ডগুলো সংজ্ঞায়িত করুন:

  • আইডি ও মালিকানা: user_id, org_id, conversation_id, message_id, request_id
  • টাইমস্ট্যাম্প ও অর্ডারিং: created_at, updated_at, এবং মেসেজের জন্য একটি স্পষ্ট sequence
  • স্ট্যাটাস ফিল্ড: queued | running | streaming | succeeded | failed | canceled (জব ও টুল কলের জন্য)।
  • ভার্সনিং: কনফ্লিক্ট-সেইফ আপডেটের জন্য etag বা version

এটি সেই ক্লাসিক বাগ প্রতিরোধ করে যেখানে UI “ঠিক মনে হচ্ছে” কিন্তু রিট্রাই, রিফ্রেশ, বা সমান্তরাল এডিট রিকনসাইল করতে পারে না।

কনসিস্টেন্ট API শেপ ব্যবহার করুন

ফিচারজুড়ে এন্ডপয়েন্টগুলো পূর্বানুমানযোগ্য রাখুন:

  • GET /conversations (লিস্ট)
  • GET /conversations/{id} (পাওয়া)
  • POST /conversations (তৈরি)
  • POST /conversations/{id}/messages (অ্যাপেন্ড)
  • PATCH /jobs/{id} (স্ট্যাটাস আপডেট)
  • GET /streams/{request_id} বা POST .../stream (স্ট্রিম)

সব জায়গায় একই এনভেলপ স্টাইল রিটার্ন করুন (এরর সহ) যাতে ফ্রন্টএন্ড ইউনিফর্মলি স্টেট আপডেট করতে পারে।

যেখানে স্টেট ভাঙতে পারে সেখান অবজার্ভেবিলিটি যোগ করুন

প্রতি এআই কলের জন্য লগ ও একটি request_id রিটার্ন করুন। টুল-কলে ইনপুট/আউটপুট রেকর্ড করুন (রিড্যাকশনসহ), ল্যাটেন্সি, রিট্রাই, এবং চূড়ান্ত স্ট্যাটাস। সহজ করে দিন উত্তর: “মডেল কী দেখল, কোন টুলগুলো চালানো হয়েছে, এবং আমরা কী স্টেট পারসিস্ট করলাম?”

বিল্ড চেকলিস্ট (সাধারণ স্টেট বাগ এড়াতে)

  • ব্যাকএন্ড সোর্স অফ ট্রুথ; ফ্রন্টএন্ড ক্যাশ স্পষ্টভাবে লেবেলকৃত ও ডিসপোজেবল।
  • প্রতিটি রাইট আইডেম্পোটেন্ট (রিট্রাই নিরাপদ) request_id (এবং/অথবা Idempotency-Key) ব্যবহার করে।
  • স্ট্যাটাস ট্রানজিশন স্পষ্ট ও ভ্যালিডেটেড (কোনো গোপন লাফ queued থেকে succeeded-এ নেই)।
  • স্ট্রিমিং আপডেট আইডি/সিকোয়েন্স অনুযায়ী মার্জ করা হয়, না যে “শেষ মেসেজ জিতে যায়” নীতিতে।
  • কনফ্লিক্টগুলো version/etag বা সার্ভার-সাইড মিশ্রণ নীতিমালা দিয়ে হ্যান্ডেল করা হয়।
  • PII ও সিক্রেট কখনই ক্লায়েন্ট স্টেটে নেই; লগ ডিফল্টে রিড্যাক্ট করা হয়েছে।
  • ডিবাগিংয়ের জন্য একটি ড্যাশবোর্ড আছে: রিকোয়েস্ট, টুল কল, জব স্ট্যাটাস, এবং এরর।

যখন আপনি দ্রুত বিল্ড সাইকেল (এআই-সহায়িত জেনারেশন সহ) গ্রহণ করবেন, এই চেকলিস্টের আইটেমগুলো স্বয়ংক্রিয়ভাবে প্রয়োগ করার গার্ডরেল যোগ করার চিন্তা করুন—স্কিমা ভ্যালিডেশন, আইডেম্পোটেন্সি, এবং ইভেন্টেড স্ট্রিমিং—তাহলে “দ্রুত চলা” স্টেট ড্রিফটে পরিণত হবে না। বাস্তবে, এটাই সেই জায়গা যেখানে Koder.ai-এর মতো একটি end-to-end প্ল্যাটফর্ম সহায়ক হতে পারে: এটি ডেলিভারিকে দ্রুত করে, আবার আপনি সোর্স কোড এক্সপোর্ট করে স্টেট-হ্যান্ডলিং প্যাটার্নগুলো ওয়েব, ব্যাকএন্ড, এবং মোবাইল জুড়ে ধারাবাহিক রাখতে পারবেন।

সাধারণ প্রশ্ন

একটি AI অ্যাপে স্টেট বলতে কী বোঝায়?

স্টেট হলো অ্যাপ যে তথ্য মনে রাখে, যাতে সেটি সঠিকভাবে সাড়া দিতে পারে। AI চ্যাটে এর মধ্যে থাকে বার্তা, সক্রিয় কথোপকথন, স্ট্রিমিংয়ের অগ্রগতি, সক্রিয় টুল এবং ত্রুটি।

কোন স্টেট ফ্রন্টএন্ডে রাখা উচিত?

অস্থায়ী ও ব্যবহারকারীর নিয়ন্ত্রণে থাকা তথ্য ফ্রন্টএন্ডে রাখুন, যেমন প্রম্পটের খসড়া, খোলা প্যানেল বা লোডিং সূচক। সংবেদনশীল, শেয়ার করা বা রিফ্রেশের পরেও দরকারি সবকিছু ব্যাকএন্ডে সংরক্ষণ করুন।

কোন স্টেট ব্যাকএন্ডে থাকা উচিত?

ব্যাকএন্ডে অনুমতি, বিলিং সীমা, কথোপকথনের ইতিহাস, কাজের অবস্থা এবং মডেল সেটিংস থাকা উচিত। এটি প্রতিটি পরিবর্তন যাচাই করতে পারে এবং বিভিন্ন ডিভাইসে একই রেকর্ড উপলব্ধ রাখে।

ফ্রন্টএন্ড ও ব্যাকএন্ডের স্টেট কীভাবে সমন্বয়ে থাকে?

ব্যাকএন্ডকে তথ্যের নির্ভরযোগ্য উৎস হিসেবে ব্যবহার করুন। গতি বাড়াতে ফ্রন্টএন্ড একটি কপি ক্যাশে রাখতে পারে, তারপর প্রতিটি লেখার পর সার্ভারের প্রতিক্রিয়া দিয়ে সেই কপি প্রতিস্থাপন বা মিলিয়ে নিতে পারে।

একটি অ্যাপের স্ট্রিমিং AI প্রতিক্রিয়া কীভাবে সামলানো উচিত?

একটি অপেক্ষমাণ সহকারী বার্তা তৈরি করুন এবং ইভেন্ট আসার সঙ্গে সঙ্গে তাতে নতুন লেখা যোগ করুন। সার্ভার চূড়ান্ত সমাপ্তির ইভেন্ট পাঠানোর পরেই সেটিকে সম্পূর্ণ হিসেবে চিহ্নিত করুন, যাতে অসম্পূর্ণ লেখা কখনও সম্পূর্ণ উত্তরের মতো না দেখায়।

AI অনুরোধের জন্য ID কেন দরকার?

প্রতিটি কথোপকথন, বার্তা ও অনুরোধকে আলাদা ID দিন। সার্ভার এই ID ব্যবহার করে ডুপ্লিকেট অনুরোধ প্রত্যাখ্যান করতে পারে, আর UI পুরোনো অনুরোধ থেকে দেরিতে আসা আপডেট উপেক্ষা করতে পারে।

কথোপকথনের মেমরি পরিচালনার একটি ব্যবহারিক উপায় কী?

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

AI অ্যাপের দীর্ঘস্থায়ী কাজ কীভাবে সামলানো উচিত?

কাজটি একটি ব্যাকগ্রাউন্ড কিউতে পাঠান এবং সঙ্গে সঙ্গে একটি জব ID ফেরত দিন। queued, running, succeeded, failed এবং canceled-এর মতো স্পষ্ট অবস্থা সংরক্ষণ করুন, যাতে ব্যবহারকারী নিরাপদে রিফ্রেশ বা আবার চেষ্টা করতে পারেন।

একটি AI অ্যাপে সংবেদনশীল স্টেট কীভাবে সুরক্ষিত রাখব?

ব্রাউজারের প্রতিটি মানকে অবিশ্বস্ত ধরে নিন। সংরক্ষিত স্টেট পড়া বা বদলানোর আগে ব্যাকএন্ডকে ব্যবহারকারী, রিসোর্সের মালিকানা, অনুমতি, পেলোডের ফিল্ড ও সীমা যাচাই করতে হবে।

দুটি ট্যাব একই কথোপকথন সম্পাদনা করলে কী হয়?

ক্লায়েন্ট যখন শেয়ার করা রেকর্ড আপডেট করে, তখন সংস্করণ নম্বর, টাইমস্ট্যাম্প বা ETag ব্যবহার করুন। জমা দেওয়া সংস্করণটি পুরোনো হলে সার্ভারের বর্তমান রেকর্ড ফেরত দিন এবং ক্লায়েন্টকে রিফ্রেশ করতে বা দ্বন্দ্ব সমাধান করতে বলুন।

Related posts