سیستمی که بتواند باگهای خود را در لحظه و بهطور خودکار تعمیر کند، دیگر یک رویای تئوری نیست. MailKite در حال پیادهسازی الگوی معماری خاصی است که شکستهای واقعی نرمافزاری را از طریق عاملهای (Agents) هوش مصنوعی به اصلاحات دائمی و خودکار تبدیل میکند. این رویکرد یادآور تلاشهای گستردهتر در صنعت برای کاهش خطاهای مدلهاست، مشابه آنچه در معماری خودترمیمی مایگزور برای کاهش توهمات عاملهای هوشمند مشاهده شده است. این تغییر رویکرد، گلوگاه صنعت را جابهجا میکند؛ حالا مسئله دیگر «نوشتن اصلاحیه» نیست، بلکه «طراحی گیتهای ایمنی» است که اجازه میدهد این اصلاحات بدون نظارت انسانی مستقر شوند. در عصر عاملمحور، یک عامل توانمند میتواند کد اصلاحی را بنویسد؛ اما چالش اصلی این است که اطمینان یابیم این اصلاح، ایمن، خودکار و تجمعی است.
اکثر نرمافزارهای فعلی از یک چرخه تعمیر کند و انسانمحور پیروی میکنند. در این چرخه سنتی، یک باگ به محیط عملیاتی (Production) میرسد، سرانجام کسی آن را گزارش میکند، یک انسان تلاش میکند آن را بازتولید کند، یک وصله (Patch) مینویسد و هفتهها بعد نسخه جدید منتشر میشود. اگرچه در نهایت تمام نصبها از این اصلاح بهرهمند میشوند، اما فرآیند با هفتهها تأخیر همراه است و برای هر تکتک اصلاحات، حضور یک انسان بهعنوان دروازهبان لازم است. هدف فعلی این است که هر بار «اشتباه بودن دنیا» (یعنی مواجهه با دادههای غیرمنتظره) به یک اتفاق یکباره تبدیل شود و بخش «میانی و خستهکننده» مسیر تعمیر کاملاً خودکار گردد.
برای دستیابی به این هدف، کتابخانه mail-parse — یک تجزیهکننده متنباز MIME — بهعنوان نقشهراه و الگوی اولیه برای یک الگوی پنجمرحلهای خودبهبودی عمل میکند. استاندارد MIME نمونهای بسیار واضح است زیرا ورودیهای ایمیل بهطرز عجیبی ناقص و بههمریخته هستند؛ و دادههای نامنظم دقیقاً همان جایی هستند که نرمافزارها معمولاً در آنجا شکست میخورند و از کار میافتند. این چالش مدیریت ایمیلهای پیچیده، همان نقطهای است که شرکتهایی مانند Xero با استفاده از سیستمهای عاملمحور توانستهاند بخش بزرگی از پردازش ایمیلهای ورودی خود را خودکار کنند. با این حال، این معماری برای تقریباً هر سیستمی که دادههای خصمانه و واقعی را مصرف میکند، کاربرد دارد. این مقاله بخش اول از یک سری دو بخشی است: بخش اول بر معماری و قابلیتهای فعلی تمرکز دارد و بخش دوم، روند استقرار کامل چرخه خودبهبود مستقل را دنبال خواهد کرد.
معماری تابآوری
اول، سیستم هرگز نباید کرش کند. پایه و اساس یک سیستم خودبهبود این است که شکست، یک خروجی ساختارمند و درجهیک باشد، نه یک استثنا (Exception) که باعث بازگشت پشته (Stack Unwind) و توقف برنامه شود. اگر نرمافزار در مواجهه با یک ورودی بد بمیرد، چیزی برای بهبودی باقی نمیماند؛ و اگر ورودی را بهطور بیصدا تخریب کند، چیزی برای شناسایی وجود نخواهد داشت. انضباط معماری در اینجا این است که همیشه «بهترین نتیجه ممکن» را همراه با یک رکورد ماشینخوان از مواردی که مجبور به «پوشاندن یا نادیده گرفتن» شدهاند، تولید کند.
در پیادهسازی mail-parse (که هماکنون عرضه شده است)، هسته سیستم هرگز خطا نمیدهد (Never Throws). برای مثال، اگر یک مجموعه نویسهها (Charset) رمزگشایی نشود، سیستم به حالت پیشفرض بازگشته و کد UNKNOWN_CHARSET را صادر میکند. اگر یک مرز MIME باز بماند و بسته نشود، سیستم کانتکست یتیم را خارج کرده و کد BOUNDARY_NOT_CLOSED را منتشر میکند. این تشخیصها صرفاً برای لاگگیری نیستند؛ بلکه مواد خام و دادههای ورودی برای هر چرخه پردازش پاییندستی هستند.
دوم، اصلاحات باید تجمعی باشند نه جراحیگونه. اگر هر اصلاح نیاز به ویرایش مستقیم هسته کد داشته باشد، اصلاحات ریسکپذیر شده و با یکدیگر تداخل میکنند. این معماری از یک «درز پلاگین» (Plugin Seam) استفاده میکند؛ یک دفتر ثبت (Registry) که در آن هر رفتار جدید، یک واحد مستقل با دامنه اثر بسیار محدود است. چون این واحدها ایزوله هستند، نمیتوانند کل سیستم را از کار بیندازند و دقیقاً مشخص است که کدام بخش از داده را لمس میکنند.
در تجزیهکننده (نسخه عرضه شده)، اصلاحات به صورت میانافزارهایی در یک دفتر ثبت به سبک PostCSS عمل میکنند. هر میانافزار یک «فاز»، یک «شرط تطبیق» (Match Predicate) و یک «مدیریتکننده» (Handler) تعریف میکند. اگر یک میانافزار دچار خطا شود، این خطا به یک تشخیص ایزوله تحت عنوان MIDDLEWARE_ERROR تبدیل میشود در حالی که بقیه زنجیره پردازش به مسیر خود ادامه میدهد. یک نقص جدید در فرمت دادهها نه با تغییر در هسته، بلکه با افزودن یک میانافزار جدید با شرط تطبیق محدود مدیریت میشود.
سوم، شکستها با استفاده از امضاهای قطعی و بدون دادههای شناسایی شخصی (PII) شناسایی میشوند. برای اصلاح یک دسته از خرابیها، باید بتوانید آن را در تمام نسخههای نصبشده بهصورت یکسان نامگذاری کنید، بدون اینکه دادههای خصوصی کاربران را جمعآوری کنید. این امضای شکست، یک هش (Hash) قطعی است که فقط بر روی ساختار داده محاسبه میشود. این روش اجازه میدهد هزاران مورد شکست که باگ یکسانی دارند، در یک سیگنال اولویتبندی شده ادغام شوند و به چرخه تعمیر یک هدف دقیق بدهند.
در mail-parse (نسخه عرضه شده)، امضا یک هش FNV-1a روی ویژگیهای بدون PII است که شامل موارد زیر میشود:
- کدهای تشخیص (Diagnostic codes)
- نوع محتوا (Content-type) و کدگذاری انتقال (Transfer-encoding)
- اثرانگشت شکلبایتی (Byte-shape fingerprint)
- خانواده ایمیلفرست (Mailer family)
- مسیر ساختاری (Structure path)
نکته حیاتی این است که این امضا هرگز شامل بایتهای خام، آدرسهای ایمیل یا موضوعات پیام نمیشود. دو نصب در دو نقطه مختلف جهان که هر دو با یک نقص خاص در Outlook-TNEF مواجه شوند، دقیقاً یک هش یکسان را محاسبه خواهند کرد. برای جلوگیری از تغییر رفتار در نسخههای مختلف، این امضاها در پورتهای TypeScript، Python و Go از طریق یک «مجموعه طلایی» (Golden Corpus) تست شده و پین شدهاند تا از هرگونه انحراف جلوگیری شود.

مدیریت چرخههای تعمیر
MailKite برای ایجاد تعادل بین پایداری جهانی و نیازهای فوری، از دو سرعت تعمیر مختلف استفاده میکند:
چرخه سرد: اصلاحات جهانی
این چرخه کتابخانه را برای تمام کاربران اصلاح میکند و هماکنون فعال است. وقتی تجزیهکننده دچار افت کیفیت میشود، یک FailureReport صادر میکند. ارسال گزارشها اختیاری (Opt-in) است و هیچ سیستم «گزارش خودکار به خانه» (Phone-home) بهصورت پیشفرض وجود ندارد. وقتی گزارشها به مخزن اصلی کد اشاره کنند، سیستم دقیقاً یک ایشوی (Issue) بدون تکرار در گیتهاب برای هر امضا ثبت میکند. برای این کار از یک مارکر پنهان parse-signature: استفاده میکند تا عملیات idempotent باشد (یعنی N نصب $ \rightarrow $ ۱ ایشو). این ایشو حاوی امضای ساختاری است اما هیچ محتوایی از پیام را ندارد.
سپس یک پاسخدهنده — که میتواند یک انسان یا یک روتین کدنویسی هوش مصنوعی باشد — باگ را از روی امضای پاکسازیشده بازتولید کرده و هسته را اصلاح میکند. یک PR باز میشود، اما سیستم CI آن را ادغام نخواهد کرد مگر اینکه هر دو مجموعه «کورپوس طلایی» و «مجموعه رگرسیون ورودیهای سالم» سبز بمانند. سپس این اصلاح برای تمام نصبها در هر زبان پشتیبانیشده ارسال میشود.
چرخه گرم: وصلههای لبهای
این چرخه که در حال طراحی است، یک لبه (Edge) خاص را فوراً وصله میکند. انتشار نسخههای کتابخانه زمانبر است و برخی نقصها فقط در سیستمهای خاص یک مشتری راسته (Tenant) متمرکز هستند. در این چرخه، یک عامل (Agent) نمونه شکستخورده و مهروموم شده را دریافت کرده و یک میانافزار با دامنه محدود به همراه یک تست طلایی برای تثبیت رفتار آن مینویسد. این یک راهکار موقت (Stopgap) است که لبه را فوراً بهبود میبخشد، در حالی که چرخه سرد روی علت ریشهای و دائمی کار میکند.
محور امنیت: اعتماد به گیتها، نه مدلها
اجرای کد تولیدشده توسط هوش مصنوعی در محیط عملیاتی — بهویژه در چرخه گرم — بهطور ذاتی خطرناک است. ایمنی در اینجا نه با اعتماد به مدل، بلکه با ساخت معماریای حاصل میشود که در آن یک اصلاح اشتباه یا نفوذیافته نتواند آسیبی بزند. تمام طراحی چرخه گرم بر روی این «پوش ایمنی» متمرکز است.
اجرای ایزولهشده (Sandboxed Execution)
اصلاحات تولیدشده در قالب Wasm (Extism) با قابلیتهای «پیشفرض رد شده» (Deny-by-default) و یک بودجه سختگیرانه برای CPU و سوخت (Fuel) اجرا میشوند. این کدها دارای ویژگیهای زیر هستند:
- هیچ دسترسی به شبکه ندارند
- هیچ دسترسی به سیستم فایل ندارند
- هیچ قدرت محیطی (Ambient Authority) ندارند
یک اصلاح بد میتواند ورودی خود را تغییر دهد یا تمام بودجه پردازشیاش را بسوزاند و متوقف شود، اما نمیتواند به هیچ چیز دیگری دسترسی یابد. فرآیند تولید کد و CI نیز در یک سندباکس مجزا، ایزوله از محیط عملیاتی اجرا میشوند.
گیتهای خصمانه (Adversarial Gates)
مدل هوش مصنوعی آزمونهایی را که باید از آنها عبور کند، نمینویسد. یک اصلاح تنها زمانی پذیرفته میشود که از آزمونهای تحت مالکیت سیستم عبور کند:
- آزمون صفر-آتش (Zero-Fire Test): اصلاحیه باید در برابر مجموعهای از ورودیهای سالم و خوشساخت، صفر بار فعال شود تا اطمینان حاصل شود که هیچ آسیب جانبی به دادههای درست وارد نمیشود.
- آزمون طلایی (The Golden Test): باید بتواند مورد شکستخوردهی خاصی را که از روی داده واقعی تولید شده، حل کند تا ثابت شود واقعاً مشکل را رفع کرده است.
- کف تخصصی (Specificity Floor): شرط تطبیق (Predicate) باید محدود باشد و نباید بهطور کلی (Catch-all) عمل کند.
استقرار و کنترل
پس از پذیرش، اصلاحیه از یک روند استقرار کاناری (Canary Rollout) پیروی میکند: ۵٪ $ \rightarrow $ ۲۵٪ $ \rightarrow $ ۱۰۰٪. این نسخه با یک معیار «توافق ساختاری» رصد میشود تا اصلاحات بد در حجم اندکی از ترافیک شناسایی شوند. در نهایت، هر واحد تولیدشده یک کلید قطعکننده (Kill Switch) اختصاصی دارد. این ویژگی اجازه میدهد بازگشت (Rollback) فوری و برگشتپذیر از طریق پیکربندی، بدون نیاز به استقرار مجدد کد، انجام شود.
این فلسفه طراحی — یعنی محدود کردن آنچه یک مدل فریبخورده اجازه انجامش را دارد — همان تز پشت «اینباکس عامل» (Agent Inbox) در MailKite برای جلوگیری از تزریق پرامپت (Prompt Injection) است. با انتقال اعتماد از مدل به معماری، خودمختاری (Autonomy) قابل دفاع میشود.
کاربردهای دیگر این الگو
این پنج حرکت — هسته تحملپذیر، درز پلاگین، امضای شکست ناشناس، چرخههای سرد/گرم و سندباکس حفاظتی — بهطور دقیق روی سایر مرزهای ورودی خصمانه قابل پیادهسازی است:
- دریافت فرمتهای نامنظم: وارد کردن فایلهای CSV، صورتحسابهای بانکی، استخراج PDF/OCR، استخراج داده از HTML و نرمالسازی آدرسها. به جای کرش یا تخریب بیصدا، این سیستمها میتوانند امضای شکست را تولید کنند و اجازه دهند یک عامل یک نرمالساز محدود (Scoped Normalizer) اضافه کند.
- آداپتورهای API شخص ثالث و وبهوکها: وقتی ساختار دادههای ارسالی از سمت ارائهدهنده تغییر میکند (Drift) یا نامعتبر میشود، آداپتور میتواند یک امضای «تغییر طرحواره» (Schema-drift Signature) صادر کند. سپس یک عامل میتواند یک لایه سازگارساز (Shim) محدود برای نقص آن ارائهدهنده بنویسد.
- خطلولههای داده / تغییر طرحواره ETL: وقتی یک ستون در منبع تغییر نام میدهد یا نوع داده تغییر میکند، خط لوله به جای مسموم کردن انبار داده (Data Warehouse)، یک امضا صادر میکند. یک عامل نقشهبرداری (Mapping) جدید پیشنهاد میدهد که باید روی دادههای تاریخی سبز بماند.
- قوانین سوءاستفاده، اسپم و تقلب: هر الگوی جدید برای دور زدن سیستم، یک امضای شکست جدید است. یک عامل قانونی تولید میکند که باید پیش از استقرار کاناری، در برابر مجموعهای از دادههای شناختهشدهی سالم، صفر بار فعال شود.
- سازگاری کلاینت و دستگاه: مواجهه با مرورگرهای عجیب، سفتافزارهای IoT یا ترمینالهای POS قدیمی. هر کلاینت غیرمنطبق به جای اینکه باعث پیچیدگی کد هسته با شرطهای متعدد
if (userAgent...)شود، به یک پلاگین مخصوص تبدیل میشود.
جدول وضعیت قابلیتها
| قابلیت | وضعیت |
|---|---|
| هسته تحملپذیر (بدون خطا، تشخیصهای تایپشده) | ✅ فعال |
| درز پلاگین تجمعی (دفتر ثبت، اصلاحات ایزوله) | ✅ فعال |
| امضاهای شکست بدون PII (قطعی، حذف تکرار) | ✅ فعال |
| برابری بین زبانها (مجموعه طلایی + پین کردن امضا) | ✅ فعال |
| بستگاه سایه (فقط مشاهده و مقایسه ساختاری) | ✅ فعال |
| چرخه سرد (اختیاری، ناشناس، ایشوهای گیتهاب) | ✅ فعال |
| چرخه گرم (اصلاحات تولیدشده توسط AI) | 🔧 در طراحی، گام بعدی |
| سندباکس Wasm + محدودیتهای دسترسی | 🔧 در طراحی، گام بعدی |
| گیتهای خصمانه، استقرار کاناری، کلید قطعکننده | 🔧 در طراحی، گام بعدی |
برای توسعهدهندگان، این یعنی بخشهای گرانقیمت انسانی — یعنی شناسایی، بازتولید و محدود کردن باگ — خودکار میشوند. نرمافزار همیشه با روشهای جدیدی از «اشتباه بودن دنیا» مواجه خواهد شد؛ عصر عاملمحور فرصتی است تا هر روش جدید را به یک اتفاق یکباره تبدیل کنیم، به جای اینکه آن را به یک زخم دائمی در کد تبدیل کنیم.
کتابخانه mail-parse نمونه متنباز این الگو در زبانهای TypeScript، Python و Go است. برای کسانی که ترجیح میدهند بدون اجرای کتابخانهها، پیامهای تجزیهشده را دریافت کنند، میتوانند یک دامنه را به MailKite متصل کنند. بخش دوم این گزارش پس از استقرار کامل چرخه خودکار و بهبود ورودیهای واقعی در محیط عملیاتی، با استفاده از سیگنالهای ناشناس، ساختاری و بدون PII که در اینجا توصیف شد، منتشر خواهد شد.




گفتگو