تصور کنید یک خط لوله تولیدی (Production Pipeline) تنها به دلیل یک فاصله (Space) اشتباه یا جابهجایی یک کلید در فایل JSON از کار میافتد؛ اینها دقیقاً همان رگرسیونهایی هستند که در بازنویسیهای «تمیز» دستیارهای کدنویسی AI پنهان میشوند. برای مقابله با این فروپاشی، یک راهنمای فنی مفصل در وبسایت dev.to که در ۳ سپتامبر ۲۰۲۶ منتشر شد، پروتکلی سختگیرانه را بر پایه تست Golden-Master معرفی کرده است. ادعای اصلی این است: شما باید رفتار فعلی و حتی «نامرتب» یک اسکریپت را منجمد کنید، پیش از آنکه بخواهید آن را پاکسازی کنید.
کدهای قدیمی اغلب از منطقهای «درهمتنیده» رنج میبرند؛ جایی که محاسبات، ورودی/خروجی و قالببندی بهطور جداییناپذیری با هم مخلوط شدهاند. در این محیطها، توسعهدهندگان برای بازسازی کد (Refactor) به دستیارهای AI تکیه میکنند. اگرچه تغییرات پیشنهادی AI تمیز به نظر میرسند، اما رفتار مشاهدهپذیر — مانند کدهای خروج (Exit Codes) یا مسیر فایلها — اغلب تغییر میکند. این تغییرات را تستهای واحد (Unit Tests) معمولی که معمولاً هر فراخوانی را شبیهسازی (Mock) میکنند، نمیتوان شناسایی کرد. در واقع، AI هزینه ویرایشهای محلی را ارزان و متداول میکند، اما هزینه تأیید رفتار مشاهدهپذیر را کاهش نمیدهد. این چالش دقیقاً همان نقطهای است که بررسی متنیِ وصلههای هوش مصنوعی به تنهایی ناکافی است و نیاز به ثبت وضعیتهای رفتاری (Behavior Snapshots) را ضروری میکند.
برای حل این مشکل، این پروتکل مفهوم «اوراکل رفتار» (Behavior Oracle) را معرفی میکند. برخلاف یک مستندات طراحی که میگوید کد «باید» چگونه کار کند، اوراکل سندی است از اینکه کد امروز «در واقع» چگونه کار میکند. این رویکرد، خروجی فعلی را به عنوان قرارداد میپذیرد، فارغ از اینکه این خروجی از نظر فنی «درست» باشد یا «زشت».
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، اعتماد کورکورانه به خروجیهای مدلهای زبانی بدون داشتن یک لایه تأیید مستقل، ریسکهای عملیاتی بزرگی ایجاد میکند.
زمینه: حالتهای شکست
اسکریپتهای نامرتب معمولاً الگوهای خاصی دارند که منجر به شکست در بازنویسیهای AI میشود:
- توابع کمکی یک دیکشنری تغییرپذیر (Mutable) را در شاخههای مختلف به اشتراک میگذارند.
- کدهای خروج اغلب به ترتیب خاص دستورات print وابسته هستند.
- مخازن کد نامرتب، اثرات جانبی را در چاپها، فایلها و متغیرهای سراسری پنهان میکنند.
- دستیاران AI اغلب کل فایل را بازنویسی میکنند و تغییراتی ایجاد میکنند که در ظاهر تمیز است اما باعث شکست در مراحل بعدی به دلیل تغییر در فاصلهها، مسیرها یا کدهای خروج میشود.
گام اول: فهرستبرداری از درهمتنیدگی
بر اساس مستندات این راهنما، پیش از ویرایش حتی یک خط کد، توسعهدهنده باید نقطه ورود (Entrypoint) را فهرست کند. باید روی هر بار یک نقطه ورود کار کنید و پاکسازی را از داخل توابع کمکی شروع نکنید. این کار شامل ثبت چهار حقیقت است:
- دستورات دقیقی که امروز اجرا میشوند.
- هر فایلی که فرآیند میخواند یا مینویسد.
- خروجیهای دقیق stdout، stderr و کدهای خروج عددی.
- متغیرهای محیطی (Environment Variables) که جریان برنامه را کنترل میکنند.
این حقایق در یک فایل متنی در کنار تستهای توصیفی ذخیره و در مخزن کد (Check-in) ثبت میشوند. راهنما هشدار میدهد که به حافظه یک دستیار AI برای این فهرستبرداری اعتماد نکنید. برای اسکریپتی مانند score_jobs.py:
- نقطه ورود:
python3 score_jobs.py jobs.csv - خواندنیها:
jobs.csv - نوشتنیها:
summary.txtوfailures.jsonدر مسیر$SCORE_OUT - خروجی استاندارد: یک خط وضعیت برای هر شغل
- خروجی خطا: خالی در حالت موفقیت (Happy Path)
- خروج: ۰ اگر شغلی امتیاز گرفت، ۲ اگر هیچکدام نگرفتند
- محیط:
SCORE_STRICT=1(وضعیتهای ناشناخته را شکست تلقی میکند) وSCORE_OUT(دایرکتوری خروجی را انتخاب میکند)
گام دوم: جداسازی دادههای آزمایشی زشت
سپس، توسعهدهنده یک مجموعه داده ورودی (Fixture) کوچک میسازد. نکته حیاتی این است که این دادهها باید «عمداً زشت» باشند. دادههای واقعی تولید را کپی نکنید. با گنجاندن وزنهای صفر یا وضعیتهای ناشناخته، مطمئن میشوید که شاخههای پیچیده و نامرتب منطق کد واقعاً اجرا میشوند.
برای مثال، یک فایل jobs.csv آزمایشی میتواند شامل ردیفهای زیر باشد:
a1,done,2b2,UNKNOWN,1c3,done,0d4,failed,4
ردیفهای زشت، قرارداد شما هستند، نه نویز. دادههای نمونهی تمیز خطرناکاند چون لبههای تیز کد — مانند وزنهای صفر — را که احتمالاً در حین پاکسازی میشکنند، پنهان میکنند. در واقع، برای ارزیابی دقیق مدلهای عاملمحور، داشتن مجموعهدادههای طلایی پایدار بسیار حیاتیتر از تکیه بر نظرات گذرا یا دادههای ایدهآل است.
گام سوم: ثبت طلاییها
به جای نوشتن سریعِ تأییدیه (Assertion)، توسعهدهنده یک «ثبتکننده» (Recorder) مینویسد. این ابزار باید نقطه ورود واقعی را اجرا کرده و تمام خروجیها — شامل stdout، stderr، کدهای خروج و فایلها — را در فایلهای «طلایی» (Golden Files) بریزد.
ابزارهایی مانند record_score_jobs_oracle.py این کار را خودکار میکنند؛ آنها یک دایرکتوری موقت .oracle-tmp میسازند، اسکریپت را با متغیرهای محیطی خاص (مثلاً حالتهای default و strict) اجرا کرده و نتایج را در tests/golden/score_jobs ذخیره میکنند.
این فایلهای طلایی به عنوان قرارداد رفتار در مخزن کد ثبت میشوند. پروتکل بهشدت از ثبت مجدد این فایلها پس از یک تغییر AI منع میکند؛ زیرا این کار رگرسیونها را پنهان کرده و اوراکل را با رفتار جدید (و احتمالاً خراب) هماهنگ میکند. بهروزرسانی طلاییها فقط باید پس از یک تصمیم محصولی صریح باشد.
گام چهارم: تأیید کثیفیها
با وجود طلاییها، یک محیط تست (Test Harness) ساخته میشود تا خروجی فعلی را بایتبهبایت با فایلهای طلایی مقایسه کند. این تست نباید بر اساس «حس کلی» باشد، بلکه باید روی یک فاصله (Space) تنها هم شکست بخورد. تست از همان ساختار اجرایی ثبتکننده استفاده میکند.
با استفاده از ابزاری مانند pytest، سیستم خروجیها، کدهای خروج و محتوای فایلها (مانند summary.txt و failures.json) را مقایسه میکند. محیط تست باید پیش از دست زدن به کد منبع اجرا شود؛ اگر تست قرمز شد، یعنی ثبتکننده و تست با هم اختلاف دارند و این باید پیش از هر بازنویسی اصلاح شود.
گام پنجم: طبقهبندی و اعمال ویرایشها
هر تغییر مورد نظر باید در برابر اوراکل طبقهبندی شود. برنامه بازنویسی را به صورت متن ساده نپذیرید؛ از یک جدول طبقهبندی استفاده کنید:
- تغییر نام متغیر محلی: آیا اوراکل را تغییر میدهد؟ خیر. اولین کامیت؟ بله.
- استخراج تابع کمکی خالص: آیا اوراکل را تغییر میدهد؟ خیر (اگر چاپها باقی بمانند). اولین کامیت؟ بله.
- تغییر ترتیب خطوط خروجی: آیا اوراکل را تغییر میدهد؟ بله. اولین کامیت؟ خیر (رد شود یا با تایید محصول تغییر کند).
- تغییر فاصله یا ترتیب کلیدها در JSON: آیا اوراکل را تغییر میدهد؟ بله. اولین کامیت؟ خیر (باید
json.dumpsرا همانطور که هست منجمد کنید). - حذف شاخه وضعیت ناشناخته: آیا اوراکل را تغییر میدهد؟ بله. اولین کامیت؟ خیر (نیاز به تست مشخصات صریح دارد).
- افزودن Type Hintها: آیا اوراکل را تغییر میدهد؟ خیر. اولین کامیت؟ بله.
گام ششم: قانون تکخطی
برای حفظ پایداری، راهنما توصیه میکند «کوچکترین تغییر امن» اعمال شود. در مثال اسکریپت score_jobs.py که ترکیبی از csv.DictReader و متغیرهای محیطی و نوشتن دستی فایلها است، اولین حرکت امن، استخراج محاسبات ریاضی است.
به جای بازنویسی کامل، توسعهدهنده عبارت s = weight * 10 را به یک تابع کمکی منتقل میکند: def score_done(weight: int) -> int: return weight * 10.
پس از این جایگزینی تکخطی، تستهای طلایی اجرا میشوند. اگر خروجی دقیقاً مطابقت داشت، کامیت انجام میشود. توسعهدهنده هشدار داده است که برای «زیبایی»، کلاسهای جدید اضافه نکنید، تابع main را در همان کامیت استخراج نکنید یا JSON را مرتب نکنید، زیرا اینها ریسکهای رفتاری هستند که باید در جدول طبقهبندی ثبت شوند.
ادغام دستیارهای AI
مدلهای AI میتوانند برای پیشنویس ثبتکننده از روی فایل فهرست یا پیشنهاد استخراج تکخطی استفاده شوند، اما نباید مالک اوراکل یا جدول باشند. ابزارهایی مانند MonkeyCode میتوانند محیط تست را بسازند، به شرطی که این قوانین رعایت شود:
- ابتدا تستها تولید شوند.
- پاسخهایی که فقط بازنویسی کلی هستند رد شوند.
- محیط تست روی ماشین محلی اجرا شود.
- فایلهای طلایی مقایسه شوند، نه متون مدل.
- در هر کامیت فقط یک ریسک رفتاری پذیرفته شود.
- اگر مدل فایلهای طلایی را برای مطابقت با یک Diff جدید ویرایش کرد، جلسه (Session) را متوقف کنید.
این متد پذیرفته است که Golden Masterها باگها را هم مانند ویژگیها تثبیت میکنند. این یک روش است، نه نقص. این کار صحت عملکردی را ثابت نمیکند، بلکه فقط پایداری لبههای فعلی را تضمین میکند.
محدودیتها و موارد خاص
- خروجیهای غیرقطعی: طلاییها در برابر برچسبهای زمانی (Timestamp)، شناسههای تصادفی و مجموعههای بدون ترتیب شکست میخورند.
- فایلهای باینری: خروجیهای باینری بزرگ نباید در گیت باشند؛ به جای آن از هش sha256 استفاده کنید.
- فراخوانیهای شبکه: تماسهای زنده شبکه باید با دادههای ثبتشده (Fixture) جایگزین شوند؛ هرگز در این تستها به شبکه زنده متصل نشوید.
- محیط: پایان خطوط (Line Endings) و Locale در سیستمعاملهای مختلف میتواند مقایسهها را خراب کند. در ثبتکننده خطوط را نرمالسازی کنید اگر تیم از سیستمعاملهای مختلف استفاده میکند، اما فاصلههایی که اپراتورها به آنها وابسته هستند را حذف نکنید.
چه زمانی این پروتکل را نادیده بگیریم؟
- کدهای جدید (Greenfield) که مستندات طراحی مکتوب دارند.
- رفتارهای فعلی که ناامن یا مخرب هستند.
- اسنپشاتهایی که حاوی اطلاعات حساس (Secrets) هستند.
از مدل AI برای رفع خطاهای طلایی استفاده نکنید، زیرا این کار رگرسیونی را که باید میدیدید، پنهان میکند. پس از اولین کامیت سبز، آن را به عنوان خط پایه (Baseline) توصیفی علامت بزنید. هر استخراج بعدی از همان طلاییها شروع میشود. اگر در مراحل بعدی لازم است خروجی استاندارد تغییر کند، ابتدا یک تست مشخصات (Spec Test) اضافه کنید و سپس طلاییها را در یک کامیت مجزا بهروزرسانی کنید. هرگز تغییرات قالب (Format) را با تغییرات منطقی (Logic) مخلوط نکنید.
این تغییر در رویکرد، توسعهدهنده را از ذهنیت «اعتماد به تمیزی AI» به ذهنیت «تأیید لبههای مشاهدهپذیر» منتقل میکند. با تثبیت لبههای یک مخزن نامرتب، ریسک بازنویسی به مجموعهای از گامهای کنترلشده و قابل تأیید تبدیل میشود.
گام بعدی شما
- در اولین بازنویسی کد قدیمی با AI، به جای اعتماد به «تمیزی» کد، یک فایل خروجی طلایی از وضعیت فعلی تهیه کنید.
- یک جدول طبقهبندی برای تغییرات بسازید تا متوجه شوید کدام ویرایشها روی خروجی نهایی اثر میگذارند.
- ابزارهای ثبت خروجی بایتبهبایت را جایگزین تستهای واحد (Unit Test) در لایههای بیرونی اسکریپتها کنید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو