تصور کنید یک عامل کدنویسی را در مخزن کدتان قرار میدهید که هر اشتباه شما را تایید میکند؛ این ارزانترین «بلهمن» تاریخ برنامهنویسی است. این مشاهده، هسته مرکزی یک چارچوب آموزشی جدید برای بوتکمپهای هوش مصنوعی است که توسط MonkeyCode منتشر شده است. در این آزمایشگاه، دانشجویان مجبورند ثابت کنند که یک خطای منطقی را شناسایی کردهاند، پیش از آنکه اجازه داشته باشند از یک مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن کتابها جواب میدهد — برای رفع آن استفاده کنند.
بسیاری از توسعهدهندگان وقتی با یک تست شکستخورده مواجه میشوند، صرفاً پرامپت را «تکرار» میکنند تا کد سبز شود. این رفتار، خواندنِ تنبلانه را پنهان کرده و به جای تشخیص دقیق، به امیدِ اتفاقی پاداش میدهد. یک تکرارِ روان میتواند یک خوانشِ تنبل را بپوشاند. اگر تنها تغییر بین دو اجرای کد، «امید» باشد، چیزی برای نمرهدهی وجود ندارد. طبق گزارش MonkeyCode، این رویکرد در محیطهای حرفهای منجر به ایجاد بدهی فنی (Technical Debt) میگردد؛ جایی که کد به دلایل اشتباه پاس میشود و سیستمهای شکنندهای ایجاد میشوند که با کوچکترین تغییر در مشخصات، فرو میپاشند.
برای شکستن این چرخه، این آزمایشگاه یک «دروازه تکرار» (Retry Gate) معرفی کرده است. این ابزار که یک بررسیکننده مبتنی بر پایتون است، هرگونه فراخوانی دوم مدل را مسدود میکند، مگر اینکه دانشجو ابتدا مخالفت خود با پیشنهاد اولیه هوش مصنوعی را در یک دفترچه یادداشت (Ledger) با فرمت markdown ثبت کرده باشد. هدف این است که «مخالفت» نمره بگیرد، نه صرفاً «وایب» (Vibe) یا حس و حالِ وصله نهایی. پیش از هر تکرار، باید یک ردیف در دفترچه وجود داشته باشد؛ نبود ردیف به معنای عدم امکان فراخوانی دوم است. آیا شما به تست سبزِ همکلاسی خود اعتماد میکردید اگر اجرای مجدد آن هیچ ردی از تحلیل بر جای نگذاشته بود؟
زمینه و ساختار آزمایشگاه
این محیط برای یک گروه آموزشی (Cohort) طراحی شده است. این متن در واقع پیشنهادی برای یک آزمایشگاه است، نه گزارش کلاسی که قبلاً نمرهدهی شده باشد. برای گروهی که پیش از این با pytest آشنا شدهاند، مدت زمان برنامهریزی شده برای این آزمایش حدود ۹۰ دقیقه است، هرچند این یک تخمین برای برنامهریزی است و نه زمان اندازهگیری شده در کلاس.
دانشجویان دستور میگیرند که مخزن اولیه (Starter Repository) را فورک کرده و از یک درخت تمیز با نام lab/disagree-retry شاخه بزنند. نکته حیاتی این است که آنها نباید کامنتهای گمراهکننده را «پاکسازی» کنند، زیرا این کامنتها در واقع تجهیزات و ابزار اصلی (Fixture) این آزمایش هستند. پیش از هرگونه فراخوانی مدل، دانشجویان باید تستهای عمومی را یک بار اجرا کرده و خروجی را در فایلی (مثلاً attempt-0.txt) ذخیره کنند. این رویکرد یادآور اهمیت ثبت خروجیهای مدل در قالب Snapshot است تا از خطاهای نامشخص در ارزیابیهای بعدی جلوگیری شود.
برای اینکه نمره دانشجو در صورت بسته شدن پنجره دسترسی به تامینکننده مدل (Vendor Window) از بین نرود، آزمایش بهگونهای طراحی شده که برای پاس شدن لزوماً نیازی به فراخوانی مدل نیست. یک اصلاح دستی (Hand-written patch) همراه با یک دفترچه مخالفت صادقانه، یک تسلیم کامل و معتبر محسوب میشود. MonkeyCode برای حذف محدودیتهای سختافزاری یا ضعف لپتاپ دانشجویان، دسترسی رایگان به مدل و یک گزینه سرور رایگان به عنوان محیط اجرای مشترک فراهم کرده است. این اقدام برای بهینهسازی منابع مشابه استراتژیهای جلوگیری از اتلاف بودجه در AI است که بر کاهش هزینههای غیرضروری فراخوانیهای API تاکید دارد.
گردش کار پیادهسازی
برای راهاندازی محیط، دانشجویان توالی دستورات زیر را اجرا میکنند تا خط پایه (Baseline) خود را تثبیت کنند:
git checkout -b lab/disagree-retrypython -m pytest tests/test_discount.py -q | tee attempt-0.txtmkdir -p lab_outprintf '# retry ledger\n' > retry_ledger.md
این توالی تضمین میکند که شکست اولیه در attempt-0.txt ثبت شود، پیش از آنکه هرگونه مداخلهای از سوی هوش مصنوعی صورت گیرد. استفاده از دستور tee به دانشجو اجازه میدهد تا همزمان با مشاهده شکست، آرتیفکت (Artifact) مورد نیاز برای معیارهای نمرهدهی (Rubric) را ایجاد کند.
کالبدشکافی تله
آزمایش روی تابعی به نام apply_discount تمرکز دارد که یک باگ ظریف دارد. این تابع باید تخفیف ۱۰ درصدی را فقط در صورتی اعمال کند که یک کد خاص استفاده شده باشد و تاریخ، برابر یا قبل از ۲۰۲۴-۱۲-۳۱ باشد. هر ورودی دیگری باید مقدار price_cents را بدون تغییر برگرداند.
اما در کد اولیه، یک کامنت گمراهکننده وجود دارد: «راهنما: باگ مربوط به تقسیم اعداد صحیح است. تقسیم را بعد از تبدیل نوع انجام دهید.»
این راهنما یک دروغ عمدی است. شکستهای واقعی ناشی از یک عملگر or است که بررسی تاریخ را نادیده میگیرد و یک شاخه سال (today.year < 2000) که کد اشتباهی را تخفیف میدهد. تقسیم اعداد صحیح برای سنتها (price_cents // 10) کاملاً پذیرفتنی و درست است. این تله طراحی شده تا ببیند یک عامل کدنویسی چقدر سریع با نزدیکترین جمله موافقت میکند، به جای اینکه به مشخصات واقعی (Specification) توجه کند. این چالش در واقع نقطه مقابل سازوکارهای Hint-Guided است که در آن از راهنماها برای اصلاح رفتار عاملها استفاده میشود، اما اینجا هدف، سنجش قدرت تفکر انتقادی انسان در برابر راهنمای غلط است. چرا یک مدل باید با راهنمایی که شبیه به یک دستورالعمل است، مخالفت کند؟
جزئیات فنی و مکانیزم دروازه
ساختار فایلها
برای پیادهسازی این آزمایش، ساختار فایلهای زیر ارائه میشود:
discount.py: تابعی که مورد آزمایش میگیرد.tests/test_discount.py: شامل سه ادعای تست (Assertion)، از جمله تاریخهای خاص.lab_out/retry_gate.py: اسکریپت بررسیکننده خودکار.retry_ledger.md: فایلی که توسط دانشجو ایجاد میشود و در ابتدا خالی است.
مجموعه تستها
سه تست منتشر شده بهگونهای طراحی شدهاند که خطاهای منطقی را افشا کنند:
test_expired_code_is_rejected: بررسی میکند کهapply_discount(1000, "SAVE10", date(2026, 10, 13))مقدار ۱۰۰۰ را برگرداند.test_active_code_still_discounts: بررسی میکند کهapply_discount(1000, "SAVE10", date(2024, 1, 1))مقدار ۹۰۰ را برگرداند.test_unrelated_code_never_discounts: بررسی میکند کهapply_discount(1000, "OTHER", date(1999, 1, 1))مقدار ۱۰۰۰ را برگرداند.
در کد اولیه، تست کد منقضیشده و تست کد نامرتبط شکست میخورند. اما تست کد فعال (Active) از قبل پاس میشود. این «پاس شدن» همان تله است؛ تابع به دلیل اشتباه، جواب درست میدهد، زیرا هر کد "SAVE10" بدون توجه به تاریخ انقضا، تخفیف میگیرد.
دفترچه مخالفت
پیش از آنکه دانشجو بتواند برای اصلاح کد از مدل درخواست کند، باید ردیفی به retry_ledger.md اضافه کند. پارسر این فایل بسیار سختگیر است: هر خط باید یک جفت کلید-مقدار باشد و بین ردیفها یک خط خالی قرار گیرد. فیلدهای الزامی عبارتند از:
attempt: شماره تکرار فعلی (مثلاً ۰).observed: توصیف شکست (مثلاً: "SAVE10 منقضی شده هنوز ۹۰۰ برمیگرداند؛ OTHER در سال ۱۹۹۹ نیز تخفیف میدهد").disagreed: یک مقدار باینری 'yes' یا 'no'.retry_reason: توضیح دقیق (مثلاً: "این یک تکرار نیست؛ راهنما تقسیم را مقصر میداند اما شکستها اینطور نیستند").
مکانیزم خودکار دروازه
آزمایش از یک اسکریپت پایتون ۳.۱۰+ استفاده میکند که به عنوان یک دروازه بدون نیاز به شبکه عمل میکند. این اسکریپت دفترچه markdown را با استفاده از عبارات منظم (Regular Expressions) میخواند و هیچ فراخوانی به مدل نمیکند. منطق اسکریپت به این صورت است:
- فراخوانی اول: اگر
next_attempt <= 1باشد، فراخوانی بهطور خودکار اجازه داده میشود، زیرا مدرس میخواهد یک انسان یادداشت اول را بخواند، نه یک regex. - بررسی دفترچه: اگر دفترچه خالی باشد، تکرار مسدود میشود.
- اعتبارسنجی فیلدها: وجود هر چهار کلید الزامی (
attempt,observed,disagreed,retry_reason) بررسی میشود. اگرdisagreedبرابر با 'yes' یا 'no' نباشد، تکرار مسدود میشود. - بررسی عمق: اگر
retry_reasonکمتر از ۲۰ کاراکتر باشد، به عنوان «بیش از حد کوتاه برای نمرهدهی» علامتگذاری میشود. - الزام رد کردن: اگر
disagreedبرابر با 'yes' نباشد، تکرار مسدود میشود زیرا راهنمای کاذب رد نشده است.
دانشجویان میتوانند دروازه را با دستوری مانند python lab_out/retry_gate.py 2 && echo "call the model now" تأیید کنند. این تضمین میکند که انسان پیش از واگذاری پیادهسازی به هوش مصنوعی، کار شناختیِ تشخیص را انجام داده است.
تستهای تأیید دروازه
برای اطمینان از اینکه خودِ دروازه بدون نیاز به شبکه درست کار میکند، مدرس میتواند از دو تست کوچک استفاده کند:
- تست مسدودسازی (Block Test): ردیفی که در آن
disagreedبرابر با "no" و دلیل آن "دوباره امتحان میکنم چون فراخوانی اول مبهم بود" باشد، باید منجر بهok is Falseشود. - تست اجازه (Allow Test): ردیفی که در آن
disagreedبرابر با "yes" و دلیل آن "راهنما با ادعای کد منقضیشده مطابقت ندارد" باشد، باید منجر بهokTrue با پیام "retry allowed" شود.
ارزیابی فراتر از تستهای سبز
معیارهای نمرهدهی (Rubric) این آزمایش، ارزش را از نتیجه نهایی به فرآیند منتقل میکند. از ۱۰ نمره کل، توزیع به این صورت است:
- ۲ نمره: ذخیره خروجی شکست (
attempt-0.txt) پیش از هر فراخوانی مدل. - ۳ نمره: دفترچه مخالفت، راهنمای کاذب را با کلمات خود دانشجو رد کرده و به هر دو مورد شکست اشاره کند.
- ۲ نمره: کد خروجی (Exit Code) دروازه با تصمیم منطقی مطابقت داشته باشد (حتی اگر تکراری صورت نگیرد، نمره کامل است).
- ۲ نمره: اصلاحیه (Patch) هر سه تست منتشر شده را پاس کند.
- ۱ نمره: یک همکلاسی بتواند نتایج را تنها از روی شاخه git و بدون نیاز به لاگ چت بازتولید کند.
اگر اصلاحیه اشتباه باشد اما مخالفت درست ثبت شده باشد، نمره جزئی داده میشود. هدف، پاداش دادن به امتناع از اطاعت از یک راهنمای غلط، برتر از یک اجرای سبزِ اتفاقی است.
ریسک «پاس شدن تصادفی»
دانشجویانی که فقط به دنبال حذف «خطوط قرمز» هستند، خطای منطقی در تست کد فعال را نخواهند دید. آزمایشگاه به کسانی پاداش میدهد که متوجه پاس شدن تصادفی شوند و آن را مستند کنند. جدولی که برای دانشجویان روی تخته قرار میگیرد، منطق زیر را پیشنهاد میکند:
- تستها شکست میخورند و راهنما با داستان شما مطابقت دارد: مخالفید؟ هنوز نه. تکرار؟ خیر. ممکن است در حال نمرهدهی به کامنت باشید، نه کد.
- یک تست در کد اولیه پاس میشود: مخالفید؟ بله. تکرار؟ شاید. پیش از فراخوانی مدل بگویید کدام پاس شدن تصادفی است.
- متن شکست با تلاش قبلی یکسان است: مخالفید؟ قبلاً بله شده است. تکرار؟ خیر. یک فراخوانی دیگر مشاهده جدیدی خلق نمیکند.
- تستها پاس میشوند اما دفترچه هرگز مخالفت نکرده است: نتیجه؟ همچنان شکست. شانس، ردیفی در معیار نمرهدهی نیست.
تسلیم نهایی و بازبینی
اصلاحیه نهایی «خستهکننده» باید صرفاً از یک عملگر and استفاده کند: if code == "SAVE10" and today <= date(2024, 12, 31):. تاریخ ۲۰۲۴-۱۲-۳۱ جادویی نیست؛ بلکه صراحتاً در تستها نام برده شده تا از نمرهدهی غیرمنصفانه جلوگیری شود.
در طول بازبینی، مدرسان تشویق میشوند که دفترچه را با صدای بلند بخوانند و خطوط کوتاه و مبهم را به چالش بکشند. اگر دانشجویی بنویسد «مدل گیج شده بود»، مدرس باید بپرسد: «گیج شده بود در مقایسه با کدام ادعای تست؟» اگر لاگ چت حذف شده باشد، شاخه git باید همچنان شامل attempt-0.txt ، retry_ledger.md ، اصلاحیه و attempt-final.txt باشد تا یک همکلاسی بتواند نتیجه را بازتولید کند.
اهداف توسعهای و محدودیتها
برای دانشجویانی که زودتر تمام میکنند، مدرس میتواند اهداف توسعهای (Stretch Goals) را تنها پس از تثبیت مسیر نمرهدهی معرفی کند:
- قرار دادن دومین راهنمای غلط در یک فایل README و الزام دفترچه به نام بردن آن فایل.
- محدود کردن سختگیرانه فراخوانیهای مدل به دو بار؛ بار سوم نیاز به یادداشت دستی TA دارد.
- تبادل اصلاحیهها با یک همکلاسی برای اطمینان از اینکه دروازه بر اساس دفترچه پاس میشود، نه بر اساس لحن نویسنده.
این آزمایشگاه برای همه نیست. اگر گروه آموزشی هنوز قادر به خواندن یک تابع ۱۵ خطی نیست، باید از آن صرفنظر کرد، زیرا تله or در مقابل and شبیه به یک شوخی (Prank) به نظر خواهد رسید. همچنین برای آموزشهای On-call (پشتیبانی عملیاتی) در نظر گرفته نشده است، زیرا کامنتهای کاذب ابزار کلاس درس هستند، نه مدلهای حادثه واقعی. علاوه بر این، دروازه یک کنترل امنیتی نیست؛ دانشجویان میتوانند markdown را ویرایش کنند، به همین دلیل است که معیار نمرهدهی همچنان به بازبینی انسانی یادداشتها نیاز دارد.
این رویکرد با هوش مصنوعی به عنوان ابزاری برای پیادهسازی برخورد میکند، نه منبع حقیقت. با اجبار به «بستن پنجره تامینکننده»، آزمایشگاه تضمین میکند که دانشجویان به در دسترس بودن مدل یا سهمیه توکنها وابسته نشوند. این تغییر در پداگوژی (روش تدریس) پیشنهاد میکند که نسل بعدی مهندسی با کمک هوش مصنوعی، نه با میزان مهارت ما در پرامپتنویسی، بلکه با میزان اثربخشی ما در مخالفت با ماشین اندازهگیری خواهد شد.
گام بعدی شما
- در پروژههای خود، هرگاه مدل پاسخی داد که با شهود شما در تضاد است، ابتدا دلیل مخالفت خود را مکتوب کنید و سپس پرامپت را تغییر دهید.
- سعی کنید در کدها کامنتهای راهنما را به عنوان «فرضیه» ببینید، نه «حقیقت»، و آنها را با تستهای واحد (Unit Tests) به چالش بکشید.
- اگر از عاملهای کدنویسی استفاده میکنید، بررسی کنید که آیا مدل در حال حل مسئله است یا صرفاً در حال تایید پیشفرضهای شماست.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو