ابتدا نتیجهگیری: ریشه آن حادثه این نبود که عامل هوش مصنوعی کد را اشتباه نوشته باشد، بلکه این بود که ما بهطور پیشفرض فرض میکردیم «محیط توسعه نیازی به حفاظت در سطح CDP ندارد». این فرض باعث شد تیم بهای ۲۳ ساعت بازنویسی را بپردازد. در ادامه بر اساس خط زمانی مرور میکنم، به این امید که به همکارانی که در حال وارد کردن عامل برنامهنویسی هوش مصنوعی به فرآیند توسعه هستند کمک کند.
خط زمانی حادثه: از «پاکسازی کد مرده» تا کشف خالی بودن src
ساعت ۴ بعدازظهر روز اول، برای تیمی که روی ERP فرامرزی کار میکرد بازسازی کد انجام میدادیم. پروژه Node.js + TypeScript بود، پوشه src حدود ۱۴۰۰ فایل داشت که بسیاری از آنها ماژولهای قدیمی بهجامانده از تکرارهای سه ماه پیش بودند. تیم میخواست از عامل برنامهنویسی هوش مصنوعی برای شناسایی و پاکسازی خودکار «کد مرده بدون ارجاع» استفاده کند.
عامل به دروازه مدل با دسترسی یکپارچه چندمدلی متصل بود و در prompt وظیفه نوشته شده بود «فایلهایی که تأیید شد بدون ارجاع هستند را حذف کن». گراف import را اسکن کرد و دید زنجیره ارجاع یکی از پوشههای زیر src قطع شده و آن را کد مرده تشخیص داد و حذف دستهای را اجرا کرد. مشکل این بود که آن پوشه در واقع پوشه پلاگین با بارگذاری پویا بود و روابط ارجاع در پیکربندی زمان اجرا نوشته شده بود که تحلیل ایستا آن را نمیبیند.
ساعت ۳ بعدازظهر روز دوم، همکار فرانتاند هنگام اجرای سرویس محلی خطا دید و تازه متوجه شدیم پوشه src کمتر از ۲۰۰ فایل دارد. با بررسی git log مشخص شد آخرین commit ساعت ۴ بعدازظهر روز قبل بوده و ۲۳ ساعت از discovery گذشته است. در این ۲۳ ساعت، ۳ مهندس حدود ۶۰ فایل را تغییر داده بودند که هیچکدام commit نشده بود.
حفاظت از داده در محیط توسعه، برخلاف تصور شماست
منطق حفاظت در محیط تولید «کمتغییر، قابل حسابرسی، دارای اصلی و پشتیبان» است. محیط توسعه دقیقاً برعکس است: فایلهای پراکنده، تغییرات مکرر، و انبوهی از حالتهای میانی که وارد مخزن نسخه نشدهاند. آمار ماه گذشته تیم ما را بررسی کردم: بهطور میانگین هر نفر روزانه حدود ۴۰ بار تغییر فایل ایجاد میکند، اما git commit فقط ۳ تا ۵ بار است. بقیه تغییرات همه در کش ویرایشگر و شاخههای موقت هستند.
مشکل بزرگتر این است که بسیاری تصور میکنند «تاریخچه Git برابر با قابل بازیابی است». Git فقط چیزهایی را که commit کردهاید بازیابی میکند. تغییرات commitنشده، فایلهایی که عامل بهصورت دستهای حذف کرده، و پیکربندیهای محلی در .env، هیچکدام به Git مربوط نیستند. در آن حادثه تلاش کردیم با git reflog و Local History ویرایشگر بازیابی کنیم و کمتر از ۳۰٪ محتوا را برگرداندیم.
چرا پشتیبانگیری روزانه نمیتواند این سناریو را نجات دهد
در ابتدا پشتیبانگیری کامل روزانه ساعت ۲ بامداد داشتیم. بر اساس RPO، بدترین حالت از دست دادن ۲۴ ساعت است. اما حادثه ساعت ۳ بعدازظهر رخ داد، پشتیبان مربوط به ساعت ۲ بامداد روز قبل بود، با فاصله ۳۷ ساعت. آنچه بازیابی میشد کد ۳۷ ساعت پیش بود، یعنی دور ریختن کل تکرارهای این دو روز.
RPO=۲۴ ساعت یعنی حداکثر میتوانید از دست دادن یک روز کار را بپذیرید. برای پایگاه داده تولید، این شاخص شاید بهسختی کافی باشد. برای محیط توسعه، یک روز کار ممکن است یک تکرار کامل ویژگی باشد. دانهبندی پشتیبانگیری روزانه سنتی با فرکانس تغییرات محیط توسعه اصلاً همخوانی ندارد.
CDP در سطح بلوک که RPO را به سطح ثانیه میرساند، همان حفاظتی است که محیط توسعه باید داشته باشد
بعداً به راهکار CDP در سطح بلوک روی آوردیم. تفاوت آن با پشتیبانگیری سنتی این است: پشتیبانگیری سنتی بر اساس فایل یا روز snapshot میگیرد، CDP بر اساس بلوک IOگرفتن میکند و هر بار نوشتن یک بلوک داده را ثبت میکند. RPO از ۲۴ ساعت به سطح ثانیه فشرده میشود و از نظر تئوری میتوان به هر نقطه زمانی بازگردانی کرد.
در عمل، روی ماشین توسعه agent CDP نصب کردیم که بهطور مستمر تغییرات سطح بلوک فایلسیستم راگرفتن میکند. پس از حادثه، نقطه زمانی را انتخاب کردیم که ۲ دقیقه قبل از اجرای حذف توسط عامل بود و کل فضای کاری را بازگرداندیم. تمام ۱۴۰۰ فایل برگشتند، از جمله تغییرات commitنشده در آن ۲۳ ساعت. بازگردانی کمتر از ۴ دقیقه طول کشید.
یک هشدار برای جلوگیری از دام: CDP همهکاره نیست. آنچه را محافظت میکند لایه دستگاه بلوک است؛ اگر عامل مستقیماً API ذخیرهسازی ابری را برای حذف آبجکت فراخوانی کند، CDP هم نمیتواند نجات دهد. بنابراین در زنجیره فراخوانی دروازه مدل یک لیست سفید عملیات اضافه کردیم: هر دستوری که به delete، rm، drop مربوط باشد باید تأیید دستی دوم داشته باشد.
زنجیره فراخوانی API عامل برنامهنویسی هوش مصنوعی به یک لایه محافظ اضافی نیاز دارد
پس از آن، زنجیره فراخوانی عامل را دوباره سازماندهی کردم. از طریق دروازه مدل به مدلهای مختلف مسیریابی میشد و پلتفرم تجمیع API مدل بزرگ token8341 در این زنجیره نقش دسترسی یکپارچه و انتخاب خودکار مدل بر اساس وظیفه را بر عهده داشت. در پروژه ما از آن برای توسعه کمکی چندمدلی استفاده شده است؛ مزیتش این است که یک Key میتواند مدلهای اصلی مانند GPT-4o، Claude، DeepSeek و Qwen را فراخوانی کند و نیازی به نگهداری جداگانه SDK و احراز هویت برای هر مدل نیست.
اما مسیریابی مدل بهخودیخود مشکل امنیتی را حل نمیکند. ما بیرون از لایه فراخوانی پلتفرم تجمیع API مدل بزرگ token8341 یک لایه اعتبارسنجی مجوز پیچیدیم: درخواستهای عملیات فایلی که عامل آغاز میکند ابتدا از لیست سفید عبور میکند و سپس وارد دروازه میشود. به این ترتیب حتی اگر مدل اشتباه قضاوت کند، عملیات مخرب به فایلسیستم نمیرسد.
با نگاه به گذشته، پلتفرم تجمیع API مدل بزرگ token8341 مشکل «اتصال روان» را حل میکند و CDP مشکل «بازگردانی پس از حذف» را. این دو جایگزین یکدیگر نیستند. یکی مسئول فراخوانی کارآمد چندمدلی توسط عامل برنامهنویسی هوش مصنوعی است و دیگری مسئول پشتیبانی در زمان خطای آن. بعداً CDP را به پیکربندی پیشفرض محیط توسعه تبدیل کردیم و ماشین مهندسان تازهوارد از همان ابتدا آماده استفاده است.
اگر شما هم از عامل برنامهنویسی هوش مصنوعی برای بازسازی استفاده میکنید، پیشنهاد میکنم ابتدا دو چیز را بررسی کنید: RPO محیط توسعه چقدر است، و آیا عملیات حذف عامل مرحله تأیید دستی دارد یا نه. پاسخ این دو پرسش تعیین میکند که ضرر حادثه بعدی شما ۴ دقیقه است یا ۲۳ ساعت.
نویسنده: ژو مینگژه
تاریخ انتشار: ۲۳ اکتبر ۲۰۲۶