প্রোগ্রেসিভ ডিসক্লোজার — ধাপে ধাপে এক্সপ্লেনেশন
এই পাঠে যা শিখবেন
- কেন একটি এক্সপ্লেনেশন একবারে সম্পূর্ণ দেখানো প্রায়ই খারাপ ডিজাইন সিদ্ধান্ত
- কীভাবে একটি স্তর-ভিত্তিক এক্সপ্লেনেশন ডেটা স্ট্রাকচার ডিজাইন করা যায়
- একটি সত্যিকারের কোড উদাহরণ — ব্যবহারকারীর অনুরোধ (সংখ্যা বা নাম) অনুযায়ী সঠিক স্তর নির্বাচন করা
- প্রোগ্রেসিভ ডিসক্লোজারের বাস্তব UI প্যাটার্নসমূহ
১ · কেন একবারে সবকিছু দেখানো ক্ষতিকর
L14-এ দেখা গিয়েছিল একটি টেকনিক্যাল, দীর্ঘ ব্যাখ্যা একটি দ্রুত-প্রেক্ষাপটে UX ব্যর্থতা তৈরি করে। কিন্তু এর বিপরীত সমাধানও — শুধু একটি সংক্ষিপ্ত একলাইন ব্যাখ্যা সবসময় দেখানো — সমস্যাযুক্ত, কারণ কিছু ব্যবহারকারী (একজন অডিটর, একজন সন্দিহান ব্যবহারকারী, বা কেউ যিনি সিদ্ধান্তে আপত্তি জানাতে চান) এর চেয়ে অনেক বেশি বিস্তারিত তথ্য চান। একটি স্থির, একক-স্তরের ব্যাখ্যা কখনোই সব ধরনের ব্যবহারকারীর জন্য সঠিক দৈর্ঘ্য হতে পারে না। প্রোগ্রেসিভ ডিসক্লোজার এই দ্বন্দ্বের সমাধান করে: ডিফল্টভাবে ছোট, কিন্তু প্রয়োজনে গভীরে যাওয়ার পথ খোলা রাখা — যা কগনিটিভ লোড ব্যবস্থাপনার একটি মূল নীতি (M6-এ বিস্তারিত)।
২ · তিন স্তরের এক্সপ্লেনেশন ডেটা স্ট্রাকচার
নিচের কোডে একটি ঋণ-আবেদনের সিদ্ধান্তের জন্য তিনটি স্তরের এক্সপ্লেনেশন সংজ্ঞায়িত করা হয়েছে — লেভেল ১ (একলাইন সারাংশ), লেভেল ২ (প্রধান কারণসমূহ), লেভেল ৩ (সম্পূর্ণ সাংখ্যিক ব্রেকডাউন)। একটি ফাংশন ব্যবহারকারীর অনুরোধ করা লেভেল নিয়ে সঠিক স্তরটি ফেরত দেয় — এবং অনুরোধ পরিসীমার বাইরে গেলে তা নিরাপদে ক্ল্যাম্প করে।
explanation_levels = {
"loan_app_482": {
1: "আবেদনটি প্রত্যাখ্যাত হয়েছে, প্রধানত উচ্চ ক্রেডিট-ব্যবহারের হারের কারণে।",
2: "প্রধান কারণ (প্রভাবের ক্রম অনুযায়ী): credit_utilization (সবচেয়ে বড় নেতিবাচক প্রভাব), "
"late_payments, account_age। মোট স্কোর: -0.30 (থ্রেশহোল্ড 0.00)।",
3: "সম্পূর্ণ ব্রেকডাউন -- প্রতিটি ফিচারের অবদান = ওয়েট x (মান - বেসলাইন): income +0.040, "
"credit_utilization -0.200, late_payments -0.090, account_age -0.020। মডেল: রৈখিক স্কোরিং "
"ফাংশন। কন্ট্রাস্টিভ: credit_utilization ০.২০ বা তার কম হলে অনুমোদিত হতো (বর্তমান মান ০.৮০)।",
}
}
def get_explanation(decision_id, requested_level):
levels = explanation_levels[decision_id]
max_level = max(levels.keys())
clamped = max(1, min(requested_level, max_level))
return clamped, levels[clamped]
print("অনুরোধ করা লেভেল অনুযায়ী দেখানো এক্সপ্লেনেশন:\n")
for requested in [1, 2, 3, 5, 0]:
clamped, text = get_explanation("loan_app_482", requested)
print(f"অনুরোধ লেভেল {requested} -> দেখানো হচ্ছে লেভেল {clamped}:")
print(f" {text}\n")
৩ · ব্যবহারকারীর অনুরোধ অনুযায়ী স্তর নির্বাচন — নামভিত্তিক সংস্করণ
বাস্তব UI-তে ব্যবহারকারী প্রায়ই সংখ্যা নয়, বরং একটি নাম-ভিত্তিক বিকল্প বেছে নেন (যেমন "সংক্ষিপ্ত" বা
"বিস্তারিত" বাটন)। নিচের কোডে একই get_explanation লজিকের উপর একটি নামভিত্তিক স্তর তৈরি করা
হয়েছে, যা অজানা/ভুল নামের জন্যও একটি নিরাপদ ডিফল্টে পড়ে।
explanation_levels = {
"loan_app_482": {
1: "আবেদনটি প্রত্যাখ্যাত হয়েছে, প্রধানত উচ্চ ক্রেডিট-ব্যবহারের হারের কারণে।",
2: "প্রধান কারণ (প্রভাবের ক্রম অনুযায়ী): credit_utilization (সবচেয়ে বড় নেতিবাচক প্রভাব), "
"late_payments, account_age। মোট স্কোর: -0.30 (থ্রেশহোল্ড 0.00)।",
3: "সম্পূর্ণ ব্রেকডাউন -- প্রতিটি ফিচারের অবদান = ওয়েট x (মান - বেসলাইন): income +0.040, "
"credit_utilization -0.200, late_payments -0.090, account_age -0.020। মডেল: রৈখিক স্কোরিং "
"ফাংশন। কন্ট্রাস্টিভ: credit_utilization ০.২০ বা তার কম হলে অনুমোদিত হতো (বর্তমান মান ০.৮০)।",
}
}
def get_explanation(decision_id, requested_level):
levels = explanation_levels[decision_id]
max_level = max(levels.keys())
clamped = max(1, min(requested_level, max_level))
return clamped, levels[clamped]
depth_names = {"সংক্ষিপ্ত": 1, "স্ট্যান্ডার্ড": 2, "বিস্তারিত": 3}
def get_explanation_by_name(decision_id, depth_name):
level = depth_names.get(depth_name, 1) # অজানা নাম হলে ডিফল্ট লেভেল ১ (সবচেয়ে নিরাপদ, সবচেয়ে সংক্ষিপ্ত)
return get_explanation(decision_id, level)
print("নাম-ভিত্তিক অনুরোধ অনুযায়ী দেখানো এক্সপ্লেনেশন:\n")
for name in ["সংক্ষিপ্ত", "বিস্তারিত", "অজানা-নাম"]:
clamped, text = get_explanation_by_name("loan_app_482", name)
print(f"'{name}' অনুরোধ -> লেভেল {clamped} দেখানো হলো:")
print(f" {text}\n")
depth_names
ডিকশনারিতে নেই — .get(depth_name, 1)-এর কারণে নিরাপদে ডিফল্ট লেভেল ১-এ পড়ে, ক্র্যাশ না করে।
বাস্তব প্রোডাক্টে এই ধরনের "গ্রেসফুল ফলব্যাক" গুরুত্বপূর্ণ — একটি অপ্রত্যাশিত ইনপুট কখনোই ব্যবহারকারীকে একটি
ভাঙা বা খালি এক্সপ্লেনেশন দেখানো উচিত নয় (এরর ডিজাইনের বিস্তারিত M6-এ, L25)।
৪ · বাস্তব UI প্যাটার্ন
ডিফল্টভাবে লেভেল ১ দেখানো হয়, ব্যবহারকারী ক্লিক করলে লেভেল ২-৩ ধীরে ধীরে খুলে যায় — সবচেয়ে সাধারণ প্যাটার্ন।
একটি ছোট লিংক যা ব্যবহারকারীকে একটি সম্পূর্ণ, ডেডিকেটেড ব্যাখ্যা-পেজে নিয়ে যায় — বেশি জায়গা প্রয়োজন হলে উপযোগী।
হোভার/ট্যাপে একটি সংক্ষিপ্ত টুলটিপ, আরও ক্লিকে একটি সাইড-ড্রয়ার — মোবাইল ও ডেস্কটপ দুই জায়গাতেই কার্যকর।
ব্যবহারকারী একবার "সবসময় বিস্তারিত দেখাও" বেছে নিলে, সিস্টেম সেই পছন্দ মনে রাখে — বারবার একই ক্লিক করা এড়ায়।
প্রোগ্রেসিভ ডিসক্লোজার "কতটা তথ্য দেব" প্রশ্নটিকে একটি বাইনারি সিদ্ধান্ত (সব অথবা কিছুই না) থেকে একটি স্তরবিন্যস্ত সিদ্ধান্তে রূপান্তরিত করে। এটি বাস্তবায়নের জন্য কোনো জটিল প্রযুক্তি লাগে না — শুধু দরকার এক্সপ্লেনেশন ডেটাকে আগে থেকেই স্তরে সংগঠিত করা এবং একটি সহজ, নিরাপদ (ক্ল্যাম্পড/ডিফল্টেড) নির্বাচন লজিক।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ ডিফল্ট স্তর হিসেবে সবসময় লেভেল ১ (সবচেয়ে সংক্ষিপ্ত) বেছে নেওয়া হয়েছে, লেভেল ২ বা ৩ নয় কেন?
এটি একটি সচেতন ডিজাইন সিদ্ধান্ত: বেশিরভাগ ব্যবহারকারীর জন্য একলাইন সারাংশই যথেষ্ট, এবং কগনিটিভ লোডের দৃষ্টিকোণ থেকে অপ্রয়োজনীয় তথ্য দিয়ে শুরু করা খারাপ ডিফল্ট (M6-এ বিস্তারিত)। যাদের বেশি প্রয়োজন, তারা সক্রিয়ভাবে গভীরে যেতে পারেন — কিন্তু কাউকে জোর করে দীর্ঘ ব্যাখ্যা দিয়ে শুরু করানো ঠিক নয়। একই যুক্তিতে অজানা/ভুল ইনপুটের জন্যও সবচেয়ে নিরাপদ (সংক্ষিপ্ততম) বিকল্পে ফলব্যাক করা হয়েছে।
প্র ০২ প্রোগ্রেসিভ ডিসক্লোজার কীভাবে L16-এর কনফিডেন্স কমিউনিকেশনের সাথে একসাথে কাজ করতে পারে?
L16-এর কনফিডেন্স ব্যান্ড ("মাঝারি নিশ্চয়তা") লেভেল ১-এর অংশ হিসেবে দেখানো যায় — একটি সংক্ষিপ্ত, দ্রুত বোধগম্য সংকেত। raw সংখ্যাসূচক স্কোর (যেমন ০.৭২) ও এর পেছনের ক্যালিব্রেশন বিস্তারিত লেভেল ৩-এ রাখা যায় — এভাবে দুটো কৌশল একসাথে ব্যবহার করলে ডিফল্ট UI সহজ থাকে, অথচ প্রয়োজনে সম্পূর্ণ স্বচ্ছতাও পাওয়া যায়।
প্র ০৩ প্রোগ্রেসিভ ডিসক্লোজারের একটি সম্ভাব্য ঝুঁকি কী — অতিরিক্ত স্তর যোগ করলে কী ভুল হতে পারে?
যদি অনেকগুলো স্তর তৈরি করা হয় (যেমন ৭-৮টি), তাহলে ব্যবহারকারীকে বারবার ক্লিক করে গভীরে যেতে হয়, যা নিজেই একটি ঘর্ষণ (friction) তৈরি করে এবং ব্যবহারকারী মাঝপথে থেমে যেতে পারেন — গুরুত্বপূর্ণ তথ্য কখনো দেখাই হয় না। সাধারণত ২-৩টি স্তরই যথেষ্ট এবং কার্যকর; অতিরিক্ত জটিলতা প্রোগ্রেসিভ ডিসক্লোজারের মূল উদ্দেশ্যকেই ব্যর্থ করে দেয়।
অনুশীলন
-
চিন্তা করুন: প্রথম কোড সেলে
explanation_levels["loan_app_482"]-এ যদি একটি নতুন লেভেল4যোগ করা হয় (আরও বিস্তারিত টেক্সট দিয়ে), তাহলেget_explanation("loan_app_482", 10)কল করলে এখন কোন লেভেল ফেরত আসবে বলে আপনার ধারণা?যেহেতু
max_level = max(levels.keys())স্বয়ংক্রিয়ভাবে ডিকশনারির সর্বোচ্চ চাবি খুঁজে বের করে, লেভেল ৪ যোগ করলেmax_levelএখন ৪ হয়ে যাবে — তাইget_explanation("loan_app_482", 10)এখন লেভেল ৪-এ ক্ল্যাম্প হবে বলে অনুমান করা যায়, লেভেল ৩ নয়। -
পরীক্ষা করুন: প্রথম কোড সেলে
explanation_levels["loan_app_482"]ডিকশনারিতে4: "সম্পূর্ণ মডেল-অডিট লগ, সব ফিচারের ইতিহাসসহ।"যোগ করে, তারপরget_explanation("loan_app_482", 10)কল করে Run চেপে দেখুন।যাচাই করলে দেখা যায় অনুমানটি সঠিক —
get_explanation("loan_app_482", 10)এখন ক্ল্যাম্প লেভেল ৪ ও নতুন যোগ করা টেক্সট ফেরত দেয়, লেভেল ৩ নয়। এটি দেখায় ফাংশনটি সত্যিই ডাইনামিক — এটি কোথাও হার্ডকোড করা "সর্বোচ্চ ৩" ধরে নেয়নি, বরং প্রতিবারlevels.keys()থেকে প্রকৃত সর্বোচ্চ লেভেল হিসাব করে, যা একে ভবিষ্যতে নতুন স্তর যোগ করার জন্যও নির্ভরযোগ্য করে তোলে।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- ব্যবহারকারীদের সাথে এক্সপ্লেনেশনের গুণমান যাচাই পরবর্তী পাঠ একটি এক্সপ্লেনেশন সত্যিই "ভালো" কিনা তা কীভাবে পরিমাপ করবেন।
- কনফিডেন্স ও আনসার্টেইনটি কমিউনিকেশন ডিজাইন আগের পাঠ সংখ্যাসূচক স্কোরকে বোধগম্য ভাষায় রূপান্তর করা।
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ কগনিটিভ লোড ও ইন্টারঅ্যাকশন ডিজাইন প্যাটার্ন (M6) সহ কোর্সের বাকি অংশ।