تصور کنید یک سرویس Node.js در ساعت ۲ بامداد ۸ اوت ۲۰۲۶ بهطور ناگهانی کرش میکند. این اتفاق ثابت کرد که درخواست از یک هوش مصنوعی برای «پیدا کردن باگ» تنها بر اساس کد منبع، دستورالعملی برای تلف کردن وقت است.
بر اساس گزارش توسعهدهنده، Claude Code میتواند الگوهای مشکوک را شناسایی کند، اما بدون شواهد عینی نمیتواند تفاوت بین یک «الگوی بد» و یک «شکست واقعی در زماناجرا» را تشخیص دهد. این چالش شکاف بزرگی را در نحوه استفاده مهندسان از عاملهای هوش مصنوعی برای دیباگینگ نشان میدهد.
همانطور که در تحلیل قبلی ما دربارهی تبدیل فلگهای هوش مصنوعی به قوانین دائمی اشاره کردیم، جهش بعدی در بهرهوری، نه در پرامپتنویسی بهتر، بلکه در ادغام بهتر دادههاست. برای اکثر برنامهنویسان، غریزه این است که با یک مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن کتابها جواب میدهد — مانند یک معمار ارشد رفتار کنند که با خواندن نقشهها نقص را میبیند؛ اما در واقعیت، این عامل در نقش یک تحلیلگر جنایی که صحنه جرم را بررسی میکند، بسیار موفقتر است. برای جلوگیری از فراموشی این الگوهای تحلیل در جلسات طولانی، استفاده از فایلهای حافظه محلی برای توقف بازنشانی زمینه میتواند تداوم استدلال عامل را تضمین کند.
شکست استدلال استاتیک
این حادثه با یک نشت حافظه (Memory Leak) کلاسیک شروع شد: مصرف حافظه بهطور مداوم بالا میرفت بدون اینکه به ثبات برسد یا توسط جمعآوریکننده زباله (Garbage Collection) بازیابی شود. طبق مستندات فنی این مورد، نشت حافظه به مدت ۶ ساعت پایدار بود تا اینکه در ساعت ۲ بامداد منجر به خطای OOM (کمبود حافظه) و چرخه کرش شد. پیچیدگی سرویس که طی دو سال توسط دهها نفر توسعه یافته بود، بازتولید محلی این باگ را دشوار میکرد.
توسعهدهنده ابتدا از Claude Code خواست تا کد را برای یافتن نشت تحلیل کند. عامل سه گزینه را شناسایی کرد:
- یک شنونده رویداد (Event Listener) بدون روتین پاکسازی.
- یک حافظه پنهان (Cache) بدون سیاست حذف داده.
- یک کلوژر (Closure) که شیئی بزرگ را در بر گرفته است.
هیچکدام علت اصلی نبودند. توسعهدهنده نزدیک به یک ساعت را صرف تعقیب گزینه کلوژر کرد چون «جالبترین» به نظر میرسید. او کد را اصلاح و در محیط Staging مستقر کرد، اما مصرف حافظه همچنان با همان نرخ بالا میرفت. این تلهای بحرانی است: عاملی که در خواندن کد مهارت دارد، همیشه چیزی پیدا میکند که «شبیه» نشت حافظه باشد، حتی اگر علت کرش نباشد.
گردشکار مبتنی بر شواهد
برای حل مشکل، توسعهدهنده از «حس و حال» به سمت «داده» رفت. راهکار، پرامپت هوشمندانهتر نبود، بلکه دادن دادههای واقعی زماناجرا به عامل بود. این فرآیند یک حلقه جنایی چهار مرحلهای را دنبال کرد:
مرحله ۱: ثبت شواهد
دو اسنپشات حافظه با فاصله ۲۰ دقیقه با استفاده از node --inspect=9229 server.js گرفته شد. یک اسنپشات تنها نشان میدهد چه چیزهایی زنده هستند؛ اما تفاوت (Diff) بین دو اسنپشات تحت فشار است که رشد واقعی را فاش میکند.
مرحله ۲: تغذیه تفاوتها
توسعهدهنده تفاوتهای اندازه اشیاء را به صورت JSON استخراج کرد و به Claude Code داد:
- Array: ۳۴۰+ مگابایت (۱.۲ میلیون شیء)
- RequestContext: ۱۸۰+ مگابایت (۴۰ هزار شیء)
- Closure: ۹۰+ مگابایت
این دادهها گفتگو را تغییر داد. عامل متوجه شد رشد ۴۰ هزار شیء در RequestContext دقیقاً با حجم درخواستها همخوانی دارد و نشان میدهد چیزی ارجاع را پس از پایان چرخه پاسخ نگه داشته است.
مرحله ۳: ردیابی نگهدارندهها
عامل بهجای حدس زدن مسیرهای کد، از نام کلاس RequestContext به عنوان لنگر استفاده کرد تا تمام نقاط ساخت و ذخیرهسازی را در کد جستوجو کند. این کار باعث حذف فرآیند خستهکننده جستوجو و تطبیق دستی شد.
مرحله ۴: تایید با کاناری
پس از اصلاح، کد در محیط کاناری مستقر شد و اسنپشات سوم گرفته شد. مقایسه با خط پایه نشان داد که منحنی رشد تخت شده است و باگ واقعاً رفع شده است.
علت ریشهای: داربستهای دیباگینگ
باگ واقعی یک لاگر (Logger) بود که برای «بازپخش دیباگ» در یک آرایه سطح ماژول ذخیره میشد. این ابزار موقتی به دلیل یک نقص در پاکسازی، تبدیل به یک نشت دائمی شده بود. هر درخواستی که به شاخه بازگشت زودهنگام (Early-return) میرسید — حدود ۱۵٪ ترافیک — مقدار RequestContext خود را برای همیشه نشت میکرد.
Claude Code نیاز به یک بلوک finally را شناسایی کرد تا پاکسازی بدون توجه به مسیر خروج اجرا شود. صرفهجویی در زمان ناشی از «شهود» هوش مصنوعی نبود، بلکه توانایی آن در انجام کارهای تکراری تطبیق دادههای حافظه با کد منبع بود. برای بهینهسازی این فرآیند و جلوگیری از تکرار اشتباهات در تحلیلهای مشابه، میتوان از روش Run-Log-Distill برای حذف خطاهای تکراری استفاده کرد تا عاملها در حلقههای شکست تکراری گیر نکنند.
تحلیل: تغییر پارادایم دیباگینگ
این چرخش از استدلال استاتیک به شواهد زماناجرا، معیار دیباگینگ با هوش مصنوعی را تغییر میدهد. ارزشمندترین عاملها آنهایی نخواهند بود که بزرگترین پنجره متنی (Context Window) — مثل میز کاری که جا برای چند ورق دارد، نه برای کل کتابخانه — را دارند، بلکه آنهایی هستند که بهترین ادغام را با ابزارهای مشاهدهپذیری (Observability) دارند.
برای توسعهدهنده، نقش «انسان در حلقه» در حال تغییر است. شما دیگر کسی نیستید که باگ را جستوجو میکند؛ بلکه کسی هستید که تصمیم میگیرد چه دادهای ثبت شود و تایید میکند که اصلاحیه ایمن است. قضاوت انسانی باقی میماند، اما نیروی کار جنایی خودکار شده است.
خطر پاسخهای پذیرفتنی
خطرناکترین لحظه، ساعت اول بود. اولین حدس عامل به قدری معقول و مفصل بود که تایید شده به نظر میرسید. این یک تله روانشناختی است که توسعهدهنده را متقاعد میکند چون توضیح هوش مصنوعی «درست به نظر میرسد»، دیگر نیازی به داده نیست.
برای جلوگیری از این اتفاق، این جریان تبدیل به یک چکلیست تیمی شد. هدف این است که «آیا تفاوت اسنپشاتها را چک کردیم؟» به یک گیت سخت تبدیل شود تا هیچ اصلاحی بدون داده به محیط Production نرود.
گام بعدی شما
- در مواجهه با باگهای حافظه، بهجای تحلیل کد، ابتدا دو اسنپشات با فاصله زمانی بگیرید و Diff آنها را به عامل بدهید.
- ابزارهای دیباگ موقتی را با تاریخ انقضا یا در بلوکهای
finallyپیادهسازی کنید. - از عاملها برای تطبیق سریع دادههای Runtime با خطوط کد استفاده کنید، نه برای حدس زدن علت باگ.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو