পাঠ ৫৩ · ৫৭-এর মধ্যে · মডিউল ১২
Home / Courses / Human-Computer Interaction / ডিজাইন এথিক্স

HCI-তে ডিজাইন এথিক্স ও ডার্ক প্যাটার্ন

Design ethics & dark patterns in HCI
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ডার্ক প্যাটার্নের সংজ্ঞা এবং কেন এটি ব্যবহারকারীর স্বায়ত্তশাসনের জন্য ক্ষতিকর
  • সাতটি সুপরিচিত ডার্ক-প্যাটার্ন ক্যাটাগরি এবং প্রতিটির বাস্তব উদাহরণ
  • একটি সত্যিকারের কীওয়ার্ড/স্ট্রাকচার-ভিত্তিক ডিটেক্টর কোড দিয়ে বাস্তব UI কপি স্ক্যান করা
  • "প্ররোচনামূলক ডিজাইন" ও "ম্যানিপুলেশন"-এর মধ্যে সীমারেখা কোথায় অস্পষ্ট হয়ে যায়

১ · ডার্ক প্যাটার্ন কী, এবং কেন এটি একটি প্রকৃত সমস্যা

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

তবে এর মানে এই নয় যে প্রতিটি প্ররোচনামূলক ডিজাইন ম্যানিপুলেটিভ — একটি "লিমিটেড এডিশন" ব্যাজ যা সত্যিকারের সীমিত স্টক দেখায়, বা একটি "বাকি ২টি জিনিস কার্টে" বার্তা যা সত্যিকারের ইনভেন্টরি থেকে আসে, প্ররোচনামূলক হলেও প্রতারণামূলক নয় — কারণ তথ্যটি সত্য। ধারা ৪-এ এই ধূসর অঞ্চল নিয়ে আরও আলোচনা আছে।

২ · সাতটি সুপরিচিত ডার্ক-প্যাটার্ন ক্যাটাগরি

রোচ মোটেল (roach motel)
সাইন-আপ করা সহজ, কিন্তু ক্যানসেল করা কঠিন — যেমন অনলাইনে এক ক্লিকে সাবস্ক্রাইব, কিন্তু ক্যানসেল করতে ফোন করে "রিটেনশন এজেন্ট"-এর সাথে কথা বলতে হয়।
ফোর্সড কন্টিনিউইটি (forced continuity)
ফ্রি ট্রায়াল শেষে কোনো স্পষ্ট রিমাইন্ডার ছাড়াই স্বয়ংক্রিয়ভাবে পেইড সাবস্ক্রিপশনে রূপান্তরিত হয়ে যাওয়া।
স্নিক-ইনটু-বাস্কেট (sneak into basket)
চেকআউটের সময় ব্যবহারকারীর অজান্তে অতিরিক্ত আইটেম (যেমন "শিপিং প্রোটেকশন") কার্টে যোগ করে দেওয়া।
প্রাইভেসি-জাকারিং (privacy zuckering)
জটিল, দ্বৈত-নেগেটিভ ভাষায় প্রাইভেসি সেটিংস লেখা, যাতে ব্যবহারকারী বুঝতেই না পারেন তিনি আসলে কী শেয়ার করছেন।
কনফার্ম-শেমিং (confirm-shaming)
প্রত্যাখ্যান-বাটনকে লজ্জাজনক ভাষায় লেখা — "না ধন্যবাদ, আমি টাকা বাঁচাতে চাই না।"
মিথ্যা জরুরিতা (false urgency)
কৃত্রিম কাউন্টডাউন টাইমার বা "মাত্র ২টি বাকি" বার্তা, যেখানে প্রকৃত সীমাবদ্ধতা নেই।
বেইট-অ্যান্ড-সুইচ (bait-and-switch)
একটি জিনিসের প্রতিশ্রুতি দিয়ে ব্যবহারকারীকে একটি অ্যাকশনে প্ররোচিত করা, তারপর ভিন্ন কিছু ডেলিভার করা।

৩ · একটি সত্যিকারের কীওয়ার্ড/স্ট্রাকচার-ভিত্তিক ডিটেক্টর

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

Python
def detect_roach_motel(text):
    text_l = text.lower()
    has_cancel_mention = "cancel" in text_l
    friction_phrases = [
        "call our support line",
        "speak to a retention agent",
        "must call",
        "during business hours",
    ]
    has_friction = any(p in text_l for p in friction_phrases)
    return has_cancel_mention and has_friction

def detect_sneak_into_basket(text):
    text_l = text.lower()
    added_phrases = ["we've added", "has been added to your cart", "automatically added"]
    extra_item_words = ["protection", "insurance", "warranty", "priority shipping"]
    has_added = any(p in text_l for p in added_phrases)
    has_extra = any(w in text_l for w in extra_item_words)
    return has_added and has_extra

def detect_privacy_zuckering(text):
    text_l = text.lower()
    negation_markers = ["not", "don't", "uncheck", "opt out"]
    negation_count = sum(text_l.count(m) for m in negation_markers)
    return negation_count >= 3   # একাধিক নেগেশন একসাথে থাকলে ভাষা সন্দেহজনকভাবে জটিল

def detect_forced_continuity(text):
    text_l = text.lower()
    free_offer_phrases = ["get a free", "free trial", "free premium"]
    auto_convert_phrases = ["converts to", "automatically charged", "will be billed"]
    has_free_offer = any(p in text_l for p in free_offer_phrases)
    has_auto_convert = any(p in text_l for p in auto_convert_phrases)
    return has_free_offer and has_auto_convert

def scan(text):
    return {
        "roach_motel": detect_roach_motel(text),
        "sneak_into_basket": detect_sneak_into_basket(text),
        "privacy_zuckering": detect_privacy_zuckering(text),
        "forced_continuity": detect_forced_continuity(text),
    }

samples = [
    "Sign up in 10 seconds! To cancel, you must call our support line and speak to a retention agent.",
    "Your cart total is $49.99. We've added Priority Shipping Protection ($4.99) to help protect your order.",
    "Uncheck this box if you do not want to opt out of not sharing your data with our partners.",
    "Get a FREE premium subscription! *Terms: the free trial automatically converts to a $19.99/month plan unless cancelled before the trial ends.",
    "You can review your order summary before it ships, and cancel anytime from your account page.",
    "Get a FREE trial today! To cancel your subscription, you must call our support line and speak to a retention agent before your free trial converts to $29.99/month.",
]

for i, text in enumerate(samples, start=1):
    result = scan(text)
    flags = [name for name, hit in result.items() if hit]
    verdict = ", ".join(flags) if flags else "no pattern detected (clean)"
    print(f"Sample {i}: {text}")
    print(f"  -> {verdict}")

total_flagged = sum(1 for text in samples if any(scan(text).values()))
print()
print(f"{total_flagged} out of {len(samples)} samples flagged with at least one dark-pattern signal.")

    
আউটপুট দেখায়: স্যাম্পল ১-এ শুধু roach_motel ধরা পড়ে ("cancel" + "call our support line" একসাথে থাকায়)। স্যাম্পল ২-এ শুধু sneak_into_basket ধরা পড়ে ("we've added" + "priority shipping"/"protection" একসাথে থাকায়)। স্যাম্পল ৩-এ শুধু privacy_zuckering ধরা পড়ে (নেগেশন শব্দের সংখ্যা ৪, থ্রেশহোল্ড ৩-এর বেশি)। স্যাম্পল ৪-এ শুধু forced_continuity ধরা পড়ে ("get a free"/"free trial" + "converts to" একসাথে থাকায়)। স্যাম্পল ৫ — একটি সৎ, স্বাভাবিক ক্যানসেলেশন নীতি — কোনো প্যাটার্ন ছাড়াই "clean" থাকে, কারণ শুধু "cancel" শব্দ থাকলেই ফ্ল্যাগ হয় না, সাথে ঘর্ষণ-নির্দেশক বাক্যাংশও লাগে। স্যাম্পল ৬-এ, যেখানে দুটি কৌশল একসাথে ব্যবহার করা হয়েছে, ডিটেক্টর একসাথে দুটি সিগন্যাল (roach_motel ও forced_continuity) ধরে ফেলে। মোট ৬টি স্যাম্পলের মধ্যে ৫টিতে অন্তত একটি সিগন্যাল পাওয়া যায়।

৪ · সীমাবদ্ধতা এবং "প্ররোচনা বনাম ম্যানিপুলেশন"-এর অস্পষ্ট সীমারেখা

এই ডিটেক্টরের একটি স্পষ্ট সীমাবদ্ধতা আছে: এটি শুধু তালিকাভুক্ত নির্দিষ্ট বাক্যাংশ খুঁজে পায়। "Nah, I'll pass on saving money" — যা একইভাবে কনফার্ম-শেমিং, কিন্তু ভিন্ন শব্দে লেখা — এই ডিটেক্টর ধরতে ব্যর্থ হবে, কারণ এটি কোনো তালিকাভুক্ত বাক্যাংশের সাথে মেলে না। বাস্তব প্রোডাক্ট রিভিউতে তাই কীওয়ার্ড- ভিত্তিক স্ক্যান শুধু একটি প্রাথমিক ছাঁকনি হিসেবে ব্যবহার করা উচিত, মানুষের চূড়ান্ত পর্যালোচনার বিকল্প হিসেবে নয়।

আরও গুরুত্বপূর্ণভাবে — যদিও "ম্যানিপুলেটিভ ডিজাইন ক্ষতিকর" এই কোর্সের স্পষ্ট অবস্থান, সততার সাথে বলা দরকার যে প্রতিটি ক্ষেত্রে সীমারেখা টানা সহজ নয়। একটি "৩ দিনের ফ্রি ট্রায়াল শেষে $৯.৯৯/মাস চার্জ হবে" — যদি এটি সাইন-আপের সময় স্পষ্টভাবে, বড় হরফে দেখানো হয় এবং ইমেইল রিমাইন্ডার পাঠানো হয় — এটি ফোর্সড কন্টিনিউইটি নয়, একটি সৎ ব্যবসায়িক মডেল। কিন্তু একই তথ্য যদি ছোট, ধূসর হরফে, পৃষ্ঠার নিচে লুকিয়ে রাখা হয় এবং কোনো রিমাইন্ডার না পাঠানো হয় — তখন এটি ফোর্সড কন্টিনিউইটিতে পরিণত হয়। কাজটি একই, কিন্তু স্বচ্ছতা-র মাত্রা ভিন্ন — এবং সেই মাত্রা প্রায়ই একটি ধারাবাহিক স্কেল, বাইনারি সিদ্ধান্ত নয়। এই ধূসর অঞ্চল স্বীকার করা মানে ডার্ক-প্যাটার্ন সমালোচনাকে দুর্বল করা নয় — বরং এটি একটি নির্ভরযোগ্য মূল্যায়নের জন্য প্রয়োজনীয়, যাতে প্রতিটি প্ররোচনামূলক ডিজাইনকে ঢালাওভাবে "ম্যানিপুলেটিভ" বলে দাগিয়ে না দেওয়া হয়।

মূল কথা · Key takeaway

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

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ detect_privacy_zuckering ফাংশনে একটি একক নেগেশন শব্দ নয়, বরং তিনটি বা বেশি নেগেশন শব্দের উপস্থিতি চেক করা হয়েছে কেন?

একটি বা দুটি নেগেশন শব্দ (যেমন "don't share") স্বাভাবিক, স্পষ্ট ভাষায়ও থাকতে পারে। কিন্তু একাধিক নেগেশন একসাথে স্তুপীকৃত হলে (যেমন "uncheck ... if you do not want to opt out of not sharing") বাক্যটি বোঝা কঠিন হয়ে যায় — এটি প্রাইভেসি-জাকারিং-এর একটি কাঠামোগত লক্ষণ, কারণ জটিলতা নিজেই এখানে একটি ম্যানিপুলেশন কৌশল (ব্যবহারকারী ক্লান্ত হয়ে যেকোনো ডিফল্ট মেনে নেন)।

প্র ০২ একটি ই-কমার্স সাইট যদি সত্যিই মাত্র ২টি জিনিস স্টকে রেখে "মাত্র ২টি বাকি!" দেখায় (মিথ্যা নয়, সত্যিকারের ইনভেন্টরি ডেটা), এটি কি তবুও একটি ডার্ক প্যাটার্ন?

না — যদি তথ্যটি সত্য হয় এবং প্রকৃত ইনভেন্টরি থেকে সরাসরি আসে, এটি প্ররোচনামূলক হলেও প্রতারণামূলক নয়, কারণ ব্যবহারকারী সঠিক তথ্যের ভিত্তিতে সিদ্ধান্ত নিচ্ছেন। এটি "মিথ্যা জরুরিতা" ক্যাটাগরিতে পড়ে তখনই, যখন সংখ্যাটি বানোয়াট বা কৃত্রিমভাবে কমিয়ে দেখানো হয়। এই পার্থক্যটাই ধারা ৪-এ আলোচিত ধূসর অঞ্চলের একটি সরাসরি উদাহরণ।

প্র ০৩ ডার্ক প্যাটার্ন এড়ানো কেন শুধু "নৈতিকভাবে সঠিক কাজ" নয়, বরং দীর্ঘমেয়াদে একটি ব্যবসায়িক কৌশলও হতে পারে?

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

অনুশীলন

  1. চিন্তা করুন: নতুন একটি স্যাম্পল টেক্সট — "This subscription renews automatically. You will be billed $14.99/month starting after your 7-day free trial, and we'll email you a reminder 2 days before." — উপরের ডিটেক্টরগুলোর কোনোটি দিয়ে স্ক্যান করলে কী ফলাফল আসবে বলে আপনার ধারণা, এবং এটি কি সত্যিকারের ফোর্সড কন্টিনিউইটি হওয়া উচিত?

    যান্ত্রিকভাবে, detect_forced_continuity এখানে True রিটার্ন করবে, কারণ "free trial" এবং "will be billed" দুটোই টেক্সটে আছে — কিন্তু ধারা ৪-এর আলোচনা অনুযায়ী এটি প্রকৃতপক্ষে ফোর্সড কন্টিনিউইটি নয়, কারণ মূল্য, সময়সীমা ও রিমাইন্ডার সবকিছু স্পষ্টভাবে জানানো হয়েছে। এটি প্রমাণ করে কীওয়ার্ড-ভিত্তিক ডিটেক্টরের একটি সীমাবদ্ধতা — এটি স্বচ্ছতার মাত্রা বুঝতে পারে না, শুধু কাঠামোগত মিল খুঁজে পায় (একটি সম্ভাব্য false positive)।

  2. পরীক্ষা করুন: উপরের কোড সেলে samples তালিকায় উপরের বাক্যটি যোগ করে Run চেপে আপনার অনুমান যাচাই করুন — তারপর ভাবুন, ডিটেক্টরে কী পরিবর্তন আনলে এই false positive কমানো যেত (ইঙ্গিত: "reminder" বা "we'll email you" জাতীয় স্বচ্ছতা-নির্দেশক শব্দের উপস্থিতি একটি নেগেটিভ সিগন্যাল হিসেবে যোগ করা যেতে পারে)।

    যোগ করার পর ফলাফল আসে: forced_continuity — ঠিক অনুমান অনুযায়ী, যদিও বাক্যটি প্রকৃতপক্ষে স্বচ্ছ। একটি উন্নতি হতে পারে has_auto_convert and not has_transparency_cue যোগ করা, যেখানে has_transparency_cue "we'll email you a reminder" বা "starting after" -এর মতো স্পষ্টতা-নির্দেশক বাক্যাংশ চেক করে — এটি দেখায় বাস্তব ডিটেক্টর ডিজাইনে false positive কমানো একটি চলমান, পুনরাবৃত্তিমূলক প্রক্রিয়া, একবারে সম্পূর্ণ নয়।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ কগনিটিভ সাইকোলজি, ইন্টারঅ্যাকশন ডিজাইন, ইউজেবিলিটি হিউরিস্টিক্স, ইউজার রিসার্চ, প্রোটোটাইপিং, ইভালুয়েশন মেথড, ভিজ্যুয়াল ডিজাইন, অ্যাক্সেসিবিলিটি ও ক্যাপস্টোন।
  • Human-Centered AI কোর্স সহোদর কোর্স AI-নির্দিষ্ট ইন্টারঅ্যাকশন ডিজাইন — ট্রাস্ট ক্যালিব্রেশন, এক্সপ্লেইনেবিলিটি — এই কোর্সের সাধারণ ভিত্তির উপর দাঁড়িয়ে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, Machine Learning, Deep Learning, System Design, Cybersecurity, Cloud Computing & DevOps, এবং আরও অনেক কোর্স — সব এক জায়গায়।
আগের পাঠ
গেমস ও এন্টারটেইনমেন্টে HCI