تصور کنید کدی را به یک عامل هوش مصنوعی میسپارید و او با یک تیک سبز و لاگی بینقص، موفقیت تستها را اعلام میکند؛ اما در واقعیت، هیچ تستی اجرا نشده است. شما با یک «روایت» طرف هستید، نه یک «نتیجه»، و این دقیقاً همان جایی است که خطای فاجعهبار در محیط تولید رخ میدهد. وقتی یک عامل کدنویس ادعا میکند که مجموعه تستها پاس شدهاند، ممکن است صرفاً در حال تولید توکنهایی باشد که شبیه به لاگهای pytest هستند، به جای اینکه واقعاً یک فرآیند سیستمعامل با یک شناسه فرآیند (PID) را استارت زده باشد.
این تفاوت میان روایت و اجرا، ریشه در ماهیت هوش مصنوعی زاینده (Generative AI) — شبیه به نویسندهای که میداند یک گزارش فنی باید چه شکلی باشد اما لزوماً آن را تجربه نکرده است — دارد. یک عامل کدنویس ممکن است توکنهایی تولید کند که دقیقاً شبیه لاگهای pytest باشند، بدون اینکه واقعاً یک فرآیند سیستمعامل با یک شناسه فرآیند (PID) را استارت زده باشد. همانطور که در بحثهای گذشتهی ما دربارهی توهمات مدلهای زبانی اشاره کردیم، مدلها تمایل دارند شکافهای اطلاعاتی را با الگوهای آماری پر کنند. این تمایز حیاتی است زیرا عاملها مرز بین روایت و اجرا را میبلورند. یک وظیفه، تولید توکنهایی است که شبیه لاگ هستند؛ وظیفه دیگر، شروع یک فرآیند واقعی با یک PID است. در یک روز خوب، این دو وظیفه با هم همسو میشوند، اما میتوانند بدون هیچ هشدار قرمزی از هم فاصله بگیرند. یک مدل میتواند یک لاگ TAP بینقص را از حافظه آموزشی خود بیرون بکشد بدون اینکه هرگز با یک شل (Shell) تماس گرفته باشد. این امر شکاف خطرناکی ایجاد میکند که در آن توسعهدهندگان کدها را بر اساس «تئاتر» ادغام میکنند؛ یعنی مدرکی بصری که درست به نظر میرسد اما هیچ رکورد اجرایی متناظری روی یک سرور یا لپتاپ ندارد.
طبق راهنمای فنی منتشر شده در dev.to در ۱۳ سپتامبر ۲۰۲۶، تنها راه عبور از این تله، برخورد با هر متن چت به عنوان «نثر» است، مگر اینکه یک «رسید» (Receipt) ماشینخوان ارائه شود. رسید در اینجا مجموعهای از فیلدهای خستهکننده و تولید شده توسط ماشین است که ثابت میکند یک فرآیند روی یک قطعه سختافزار مشخص وجود داشته است. افشای رابطه: این مقاله به عنوان بخشی از فعالیتهای ترویجی محصول MonkeyCode تهیه شده است و نویسنده گاهی اوقات رسیدها را روی دسترسی رایگان مدل MonkeyCode و گزینه سرور رایگان آن اجرا میکند. این موضوع یادآور چالشهای زیرساختی است که در بررسی باورهای غلط درباره نقاط اتصال رایگان مدلها به آنها پرداختیم.
تلهی روایت
بسیاری از توسعهدهندگان فریب «خروجیهای بصری» را میخورند. وقتی نقاط (dots) و کد خروجی صفر را در چت میبینند، گمان میکنند تستها اجرا شدهاند. ادعای تکراری در چتهای عاملها این است: «من نقاط را دیدم، پس مجموعه تستها اجرا شدند.» اما بافر چت توکنها را نگه میدارد، نه PIDها را.
اگر یک عامل نتواند فیلدهای مشخصی مثل نام میزبان (hostname)، دایرکتوری کاری (cwd) و مسیر دقیق فایل اجرایی را از یک میزبان برگرداند، شما با یک روایت طرف هستید. روایت برای پیشنویس کردن وصلهها (Patches) مفید است، اما مدرکی برای یک Pull Request نیست. یک فرآیند، یک شیء سیستمعامل است، نه یک پاراگراف.
برای شناسایی روایت، میتوانید این اسکریپت را روی میزبانی که گمان میکنید تستها در آن اجرا شدهاند، اجرا کنید:
import os, socket, sys
print("hostname=", socket.gethostname())
print("cwd=", os.getcwd())
print("pid=", os.getpid())
print("executable=", sys.executable)
print("argv=", sys.argv)
اگر PID-ی از آن میزبان وجود ندارد، هیچکس در آنجا pytest را اجرا نکرده است. با فیلدهای مفقود شده بحث نکنید.
توهم کد خروجی
یک باور غلط رایج این است که عدد صفر در پنل چت، همان نتیجه CI است. اما صفرِ درون یک جمله با صفرِ یک Runner نامگذاری شده متفاوت است. سیستمهای CI شناسه شغل (Job ID)، برچسب Runner و آرتیفکتها را ذخیره میکنند. سیستمهای چت فقط یک رقم را کنار نثر قرار میدهند. این دو سیستم هیچ پایگاه داده مشترکی ندارند.
کپی کردن یک «۰» از یک متن چت به داخل یک PR، صرفاً یک نمایش تئاترگونه است. بازبینها نمیتوانند تئاتر را روی کامیت ادغام (Merge Commit) بازپخش کنند. یک کد خروجی در چت باید به عنوان غیرقابل اعتماد تلقی شود تا زمانی که یک رسید در کنار آن قرار بگیرد که شامل نام میزبان و یک Nonce انتخابی کاربر باشد. برای جلوگیری از چنین شکستهایی در هنگام تغییر مدلها، میتوان از رویکرد تستهای مبتنی بر قرارداد استفاده کرد تا ثبات خروجیها تضمین شود.
تأیید میزبان و خطای انتقال
اشتباه دیگر، فرض «تلپورت» است. عامل ممکن است npm install را اجرا کند و شما فکر کنید درخت وابستگیها روی لپتاپ شما آماده است. اما کدام دیسک واقعاً آماده است؟ یک سرور رایگان سیستمفایل خودش را دارد و لپتاپ شما سیستمفایلی جداگانه. پنل چت اصلاً هیچ سیستمفایلی ندارد.
درختهای پکیج تلپورت نمیشوند چون یک مدل نام یک وابستگی را برده است. اگر میزبان یک جعبه موقت (Scratch box) است، لپتاپ شما همچنان به نصب مستقل نیاز دارد. اگر CI باید نصب را انجام دهد، شما باید فایل lockfile را از کلون خود کامیت کنید؛ node_modules را از یک سرور یکبار مصرف ارسال نکنید، زیرا آن tarball یک اثر جانبی روی یک دیسک است، نه یک محصول نهایی برای ارسال.
برای تأیید محیط، از عامل بخواهید این بلوک را اجرا کند:
echo "host=$(hostname)"
echo "node=$(command -v node || echo missing)"
echo "python=$(command -v python3 || echo missing)"
echo "npm_root=$(npm root 2>/dev/null || echo missing)"
ls -ld node_modules 2>/dev/null || echo "node_modules=absent"
ls -ld .venv 2>/dev/null || echo "venv=absent"
خط host= را با نام میزبان لپتاپ خود مقایسه کنید. عدم تطابق به این معنی است که شما در دو دنیای متفاوت هستید.
توهم ساعت
توسعهدهندگان اغلب به لاگی که میگوید «۱۴:۰۲» اعتماد میکنند و فرض میکنند همین الان اجرا شده است. اما مدلها اغلب ساعتها را از روی الگوهای آموزشی ابداع میکنند. سرورها و لپتاپها ساعتهایی دارند که به روشهای مختلفی دچار انحراف (Drift) میشوند یا خطا میکنند.
تنها زمانی به برچسب زمانی اعتماد کنید که شامل منطقه زمانی، نام میزبان و Nonce شما باشد. UTC کمتر از یک عبارت غیررسمی مثل «اکنون» مبهم است. از این اسکریپت برای تأیید استفاده کنید:
from datetime import datetime, timezone
import time, socket
print("utc=", datetime.now(timezone.utc).isoformat())
print("unix=", time.time())
print("tz=", time.tzname)
print("host=", socket.gethostname())
اگر عامل یک زمان زیبا بدون Nonce برگرداند، آن را نادیده بگیرید. یک ساعت زیبا، مدرکی برای اجرا نیست.
مکانیزم رسید اجرا (Run-Receipt)
برای تبدیل اعتماد به تأیید، این راهنما یک گردشکار چهار مرحلهای برای تولید یک رسید قابل تأیید پیشنهاد میکند:
- تولید Nonce: کاربر یک رشته تصادفی (nonce) را روی ماشین خود میسازد. اجازه ندهید عامل آن را ابداع کند. از این دستور استفاده کنید:
NONCE="$(python3 -c 'import secrets; print(secrets.token_hex(8))')". این کار از توهم مدل در ساخت رسید جلوگیری میکند. - درخواست فیلدهای ثابت: داستانسراییهای اضافی را رد کنید. عامل باید دقیقاً هشت فیلد را برگرداند:
nonce,hostname,cwd,pid,executable,utc,argv, وexit. - اجرای اسکریپت کمکی: فایلی به نام
receipt.pyرا روی میزبان ذخیره کنید. این اسکریپت اشیاء سطح سیستمعامل را ثبت میکند:
#!/usr/bin/env python3
import json, os, socket, sys
from datetime import datetime, timezone
nonce = sys.argv[1] if len(sys.argv) > 1 else "MISSING_NONCE"
doc = {
"nonce": nonce,
"hostname": socket.gethostname(),
"cwd": os.getcwd(),
"pid": os.getpid(),
"executable": sys.executable,
"utc": datetime.now(timezone.utc).isoformat(),
"argv": sys.argv,
}
print(json.dumps(doc, indent=2))
آن را با این دستور اجرا کنید: python3 receipt.py "$NONCE" && echo "exit=$?".
- تأیید تطبیق: عدم تطبیق Nonce به معنای عدم اجرای تست است. تطبیق Nonce به این معنی است که آن میزبان خاص، آن
argvخاص را اجرا کرده است.
تفکیک محیطها
همه رسیدها یکسان نیستند. این راهنما نام میزبانها را به اهداف خاصی متصل میکند تا از خطاهای ادغام جلوگیری شود:
- میزبان لپتاپ: برای کارهای پیشنویس خوب است، اما مدرک ادغام نیست.
- میزبان سرور رایگان: برای یک دستور آزمایشی (Canary) مناسب است، اما همچنان CI نیست.
- میزبان CI Runner: تنها دروازه ادغامی است که باید پذیرفته شود.
این میزبانها را در ذهن خود به هم زنجیر نکنید. هر بار نام میزبان را بلند بخوانید. برای مثال، یک لاگ جعلی ممکن است شبیه این باشد: ======================= 47 passed in 3.14s ========================. چون این خط هیچ nonce، pid یا host ندارد، به عنوان داستان (Fiction) تلقی میشود.
محدودیتهای تأیید
یک رسید ثابت میکند که یک فرآیند روی یک میزبان شروع شده است. این ثابت نمیکند که تستها درست هستند، مجموعه تست کامل است یا یک سرور رایگان با محیط تولید مطابقت دارد. همچنین ثابت نمیکند که مدل دلیل شکست را درک کرده است. تستهای ناپایدار (Flaky) همچنان ناپایدار میمانند، متغیرهای محیطی مفقود شده همچنان باعث شکست میشوند و یک cwd اشتباه همچنان میتواند نیمی از مجموعه تستها را نادیده بگیرد.
این روش عمداً یک دقیقه اصطکاک به گردشکار اضافه میکند. این اصطکاک یک ویژگی (Feature) است که برای متوقف کردن عادت کپی کردن متن چت در PRها به عنوان مدرک موفقیت طراحی شده است. بازبینها فقط اسکرینشاتی از نثر را در دست دارند؛ آنها نمیتوانند آن نثر را در صورت نیاز دوباره اجرا کنند. مدرک یک PR باید یک شغل قابل بازپخش باشد، مانند یک URL از CI یا یک آرتیفکت receipt.json.
چه کسانی باید از این روش صرفنظر کنند
این رویکرد برای همه نیست. در موارد زیر آن را نادیده بگیرید:
- اگر از قبل یک مسیر CI کاملاً بسته و کنترل شده دارید.
- اگر نمیتوانید هیچ دستوری را روی میزبان اجرا کنید (جلسات مدل-محور نمیتوانند PID تولید کنند).
- اگر در حال استقرار در محیط تولید (Production Deploy) هستید (یک سرور رایگان هدف اشتباهی است).
- اگر به گواهی رسمی (Formal Attestation) نیاز دارید (این یک ابزار عیبیابی است، نه اثبات امضاشده از منشأ ساخت).
در نهایت، توجه داشته باشید که این روش به سهمیههای سختافزاری یا ماندگاری فایلها در سرورهای رایگان نمیپردازد. متن چت یک داستان است؛ یک فرآیند یک شیء سیستمعامل است. یک Nonce داستان را به آن شیء پیوند میدهد. تنها CI مدرک ادغام است.
گام بعدی شما
- از این به بعد هر لاگ موفقی را که عامل ارائه میدهد، با درخواست
hostnameوpidبه چالش بکشید. - یک اسکریپت ساده برای تولید Nonce روی ماشین خود داشته باشید تا مدل نتواند رسیدها را جعل کند.
- در بررسی PRها، هرگونه اسکرینشات از چت را به عنوان مدرک اجرا رد کنید و تنها لینک CI را بپذیرید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو