پرش به محتوای اصلی
پرش به محتوای مقاله

تولید تیک‌های سبز کاذب؛ دلیل شکست عامل‌های هوش مصنوعی محلی در کدنویسی

·۹ مهر ۱۴۰۵۵ دقیقه مطالعه
مدل زبانی محلی یک باگ را در طول شب برطرف کرد. «موفقیت»، خود آن باگ بود.
مدل زبانی محلی یک باگ را در طول شب برطرف کرد. «موفقیت»، خود آن باگ بود.
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

کشف مکانیزم «تیک‌های سبز کاذب» در مدل‌های محلی؛ جایی که مدل با تولید Diffهای فاسد، باعث عبور خط لوله از مرحله اعمال کد و رسیدن به تست‌های موفق (به دلیل عدم تغییر کد) می‌شود.

تصور کنید یک برنامه‌نویس هستید که برای رفع باگ‌های پیچیده، یک عامل کدنویسی محلی را به خدمت گرفته است و مدل با اطمینان کامل گزارش می‌دهد که مشکل حل شده، اما در واقع هیچ خط کدی تغییر نکرده است. این سناریوی واقعی برای توسعه‌دهنده‌ای رخ داد که از مدل Qwen3 27B روی یک کارت گرافیک دست‌دوم RTX 3090 و با استفاده از لاماسی‌پلاس‌پلاس (llama.cpp) استفاده می‌کرد و متوجه شد سامانه او در حال تولید «تیک‌های سبز» (گزارش موفقیت) از دل فایل‌های خالی است. این اتفاق که در جریان تلاش برای حل باگ‌های پولی در گیت‌هاب (GitHub Bounties) رخ داد، شکافی حیاتی را در نحوه اعتبارسنجی کارهای توسط عامل‌های هوش مصنوعی (AI Agents) — شبیه به کارآموزی که برای پنهان کردن اشتباهاتش، گزارش‌های جعلی از پیشرفت کار می‌نویسد — فاش کرد.

جزئیات پیاده‌سازی

طبق گزارش این توسعه‌دهنده، خط لوله (Pipeline) او برای پایداری حداکثری، عمداً به گونه‌ای طراحی شده بود که «خسته‌کننده» و پیش‌بینی‌پذیر باشد. یک اجراکننده پایتون تمام چرخه اصلاح باگ را از طریق توالی زیر مدیریت می‌کرد:

  • کلون کردن مخزن هدف.
  • نصب تمام وابستگی‌های لازم.
  • اجرای مجموعه تست‌های موجود برای تعیین یک خط مبنا (Baseline).
  • درخواست از مدل برای رفع مشکل در حداکثر ۶ دور تکرار.

در هر دور، یک حلقه سخت‌گیرانه اجرا می‌شد: تولید یک وصله (Patch)، اعمال آن، اجرای تست‌ها و بازگرداندن هرگونه شکست یا خطا به مدل. اگر تست‌ها پاس می‌شدند، وصله برای بررسی انسانی ذخیره می‌شد.

ساخت عامل‌های خودمختار معمولاً شامل همین حلقه است. در حالی که مدل‌های پیشرو (Frontier Models) معمولاً Diffهای درستی می‌نویسند، مدل‌های محلی کوچک‌تر — مانند مدل ۲۷ میلیارد پارامتری کوانتیده در این مورد — اغلب وصله‌هایی بدشکل تولید می‌کنند که اصلاً اعمال نمی‌شوند. مدیریت این شکافِ شکست، هسته اصلی چالش مهندسی در عامل‌های محلی است. این موضوع بازتاب‌دهنده همان کلنجار رفتن گسترده با موتورهای LLM محلی است، همان‌طور که پیش‌تر در مقایسه خود بین اولاما (Ollama)، vLLM و llama.cpp در رابطه با هم‌روندی (Concurrency) و عملکرد بررسی کردیم.

تحلیل «تیک سبز» جعلی

شکست مذکور به این دلیل رخ داد که عامل، یک Diff (تفاوت کد) با سرآیندهای (Hunk Headers) جعلی تولید کرد. نسخه ساده‌ی فرآیند اعمال کد از دستور subprocess.run(["git", "apply", "-"], input=diff, ...) استفاده می‌کرد. در این مورد، دستور git apply وصله‌ی فاسد را رد کرد، اما خط لوله بدون توقف و به اشتباه به سراغ اجرای مجموعه تست‌ها رفت.

از آنجا که کد اصلی یا از قبل کار می‌کرد و یا تست‌ها نتوانستند باگ خاص را شناسایی کنند، تست‌ها با کد خروجی ۰ (موفق) به پایان رسیدند. سیستم سپس این موفقیت را به وصله‌ای نسبت داد که در واقع صفر بایت بود. توسعه‌دهنده عملاً ماشینی ساخته بود که از هیچ، تیک‌های سبز تولید می‌کرد.

لایه‌های حفاظتی و فنی

برای جلوگیری از این وضعیت، بر اساس مستندات این پروژه، چندین حفاظ (Guardrails) — شبیه به نرده‌های ایمنی در لبه یک پل که مانع سقوط کاربر می‌شود — پیاده‌سازی شد تا اطمینان حاصل شود مدل درباره پیشرفت خود دروغ نمی‌گوید:

  • اعتبارسنجی سیستم‌فایل: توسعه‌دهنده دو خط کد «پارانوئید» اضافه کرد: changed = subprocess.run(["git", "status", "--porcelain"], cwd=repo, capture_output=True, text=True).stdout.strip(). اگر متغیر changed خالی باشد، خط لوله به دور بعدی می‌رود؛ زیرا پاس شدن تست‌ها روی یک درخت کاری دست‌نخورده (Pristine Working Tree) هیچ معنایی ندارد.
  • سقف اندازه وصله: برای باگ‌های متمرکز، هر وصله‌ای با بیش از ۶۰ خط تغییر رد می‌شود. این کار مانع از «رانش پژواکی» (Echo Drift) می‌شود؛ وضعیتی که مدل کل فایل را بازنویسی کرده و باگ‌های جدیدی ایجاد می‌کند. برای مثال، در یک مورد، مدل یک فایل ۵۸ کیلوبایتی React Context را برای رفع یک باگ تک‌خطی در صفحه‌بندی بازنویسی کرد. اگرچه کد از نظر TypeScript تایید شد، اما این Diff با ۱۳۷۹ خط، باعث حذف توکن‌های Refresh در localStorage و جایگزینی اشتباه یک Endpoint از نوع PATCH با POST شد.
  • آگاهی از وضعیت ایندکس: یک باگ ظریف در git apply --3way کشف شد که ادغام‌ها را در ایندکس Stage می‌کرد. یک git diff معمولی فقط تغییرات Stage نشده را نشان می‌دهد، که منجر به یک Diff خالی می‌شد حتی زمانی که وصله با موفقیت اعمال شده بود. راهکار این بود که برای استخراج وصله نهایی از git diff HEAD استفاده شود.

بهینه‌سازی خروجی مدل

علاوه بر اعتبارسنجی، این تجربه نشان داد که درخواست Diffهای استاندارد (Unified Diffs) از مدل‌های کوچک، نبردی شکست‌خورده است. مدل «شاید هرگز» نتوانست Diffهای یکپارچه و معتبر تولید کند. برای حل این مشکل، دو استراتژی جدید جایگزین شد:

۱. بلاک‌های SEARCH/REPLACE: مدل به جای Diff، بلوک‌هایی را ارائه می‌دهد که شامل خطوطی است که باید دقیقاً کاراکتر به کاراکتر کپی شوند. اجراکننده پایتون ابتدا تایید می‌کند که متن SEARCH دقیقاً در فایل وجود دارد و در غیر این صورت، دور فعلی با خطای شدید متوقف می‌شود.
۲. ارائه بستر کامل (Full Context): محدود کردن بستر فایل به ۲۰ هزار کاراکتر متوقف شد. وقتی یک فایل ۵۸ کیلوبایتی قطع می‌شد، مدل نیمه دوم فایل را بر اساس «حس و حال» (Vibes) ابداع می‌کرد. در حالی که این ابداعات کامپایل می‌شدند، اما از نظر عملکردی غلط بودند. قطع کردن متن باعث می‌شود مدل‌های کوچک به جای دقت، با اعتمادبه‌نفس اشتباه کنند.

این رویکرد در نهایت نتایج واقعی داد. خط لوله توانست یک باگ در وضعیت صفحه‌بندی (Pagination) را که در آن hasMoreBounties از یک مقدار Closure قدیمی محاسبه می‌شد، و همچنین یک آسیب‌پذیری DoS در نقطه پایانی کد QR را برطرف کند (جایی که پارامتر size بدون هیچ حد بالایی مستقیماً وارد تخصیص بافر PNG می‌شد). هر دو وصله موفق زیر ۲۵ خط بودند و ثابت کردند که مدل‌های کوچک اگر مسیر اعتبارسنجی آن‌ها «پارانوئید» و سخت‌گیرانه باشد، می‌توانند موثر باشند.

برای توسعه‌دهندگان، این یعنی «پرامپت» ساده‌ترین بخش طراحی عامل است. کار واقعی در لایه اعتبارسنجی نهفته است. اگر یک مدل محلی را به یک سامانه خودمختار متصل می‌کنید، باید فرض کنید مدل اشتباه می‌کند تا زمانی که سیستم‌فایل خلاف آن را ثابت کند.

در نهایت، انسان آخرین حفاظ است. بررسی تک‌تک وصله‌ها پیش از انتشار، تنها راه شکار باگ‌هایی است که حفاظ‌های خودکار برای پیش‌بینی آن‌ها برنامه‌ریزی نشده‌اند. داشتن یک گفتگو با نگهدارنده پروژه (Maintainer) بر سر یک وصله خوب، بسیار بهتر از ارائه یک وصله ساختگی است.

گام بعدی شما

  • اگر از عامل‌های کدنویسی استفاده می‌کنید، اعتبارسنجی را از سطح «خروجی مدل» به سطح «تغییرات واقعی فایل» منتقل کنید.
  • به جای درخواست Diff، از مدل بخواهید بلوک‌های جایگزینی (Search/Replace) تولید کند تا احتمال خطای ساختاری کاهش یابد.
  • هرگز اجازه ندهید مدل‌های کوچک فایل‌های حجیم را بازنویسی کنند؛ سقف تعداد خطوط تغییر را محدود کنید.

اما داستان سخت‌افزاری این تحول حتی شگفت‌انگیزتر است — به تحلیل ما درباره‌ی تراشه‌های Blackwell مراجعه کنید.

چرا این موضوع مهم است؟

این یافته بر اساس تجربه عملی نشان می‌دهد که تکیه بر گزارش‌های داخلی مدل‌های محلی برای تایید موفقیت، ریسک امنیتی و فنی بالایی دارد. برای استقرار ایمن عامل‌های هوش مصنوعی، باید از متدهای اعتبارسنجی مبتنی بر وضعیت واقعی سیستم (Ground Truth) استفاده کرد.

تأثیر برای ایران

برای توسعه‌دهندگان ایرانی که به دلیل محدودیت‌های API و هزینه، به مدل‌های محلی و وزن‌های باز روی سخت‌افزارهای محدود تکیه می‌کنند، پیاده‌سازی این حفاظ‌های سیستم‌فایلی تنها راه دستیابی به پایداری در ابزارهای خودکارسازی است.

·نگاه ما
تحریریه دات‌هوش

اعتماد بیش از حد به خروجی‌های مدل‌های زبانی کوچک در وظایف Agentic، منجر به ایجاد توهمات ساختاری می‌شود که در تست‌های نرم‌افزاری به راحتی شناسایی نمی‌شوند. این تجربه ثابت می‌کند که در سیستم‌های خودمختار، لایه «اعتبارسنجی بیرونی» (External Verification) بسیار حیاتی‌تر از «بهینه‌سازی پرامپت» است. در واقع، هرچه مدل کوچک‌تر باشد، نیاز به لایه‌های نظارتی سخت‌گیرانه‌تر در سطح سیستم‌عامل افزایش می‌یابد.

منابع

این گزارش با خط‌لولهٔ خودکار دات‌هوش از منابع معتبر جهانی تدوین و زیر نظر تحریریه منتشر شده است. روش کار ما

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

اخبار روزانه، معرفی ابزارها و مدل‌ها، و آموزشِ کار با هوش مصنوعی؛ همیشه با این پرسش که از ایران چه چیزی کار می‌کند و چه چیزی نه.