تصور کنید در ساعت ۳ صبح با شکست یک سرویس حیاتی در محیط عملیاتی مواجه میشوید؛ جایی که یک عامل (Agent) — شبیه دستیاری که سعی میکند همه کارها را خودش مدیریت کند — بهجای کمک، به یک نقطه ضعف تبدیل میشود. این سناریو در مورد شکست یک Prometheus exporter رخ داد؛ مرزی بحرانی در اتوماسیون هوش مصنوعی که در آن یک مدل زبانی بهجای ابزار، به یک بدهی (Liability) تبدیل میشود. مشکل زمانی شروع شد که یک liveness probe در Kubernetes در طول پیکهای بار شبانه دچار تایم-اوت میشد و باعث ریاستارتهای غیرضروری میگشت. از آنجایی که این exporter به سرویس دیگری وابسته بود که در طول کارهای شبانه کند میشد، تایم-اوت کوتاه probe باعث شد Kubernetes تصمیم بگیرد که exporter مرده است و آن را ریاستارت کند.
این اتفاق در حالی رخ میدهد که توسعهدهندگان بهشدت در تلاشاند کدهای رابط (Glue Code) سنتی را با عاملهای خودمختار جایگزین کنند. در حالی که مدلهای تخصصی مانند Falcon-Emirati-7B مرزهای درک گویشهای خاص را جابهجا کردهاند، چالش واقعی در محیط عملیاتی اغلب ظرافتهای زبانی نیست، بلکه قابلیت اطمینان عملیاتی است. برای حل این مشکل، راهکار خستهکننده و سادهای وجود داشت: افزایش زمان تایم-اوت probe، تنظیم تایم-اوت مانیتورینگ و استقرار تغییرات. با این حال، دشواری اصلی در «تأیید» این اصلاحیه بود؛ چون این تغییر فقط در ساعت ۳ صبح و در طول بار شبانه اهمیت داشت.
اصطکاک استقرار یک عامل هوش مصنوعی کامل را تصور کنید، فقط برای اینکه بررسی کند آیا یک سرویس در حال اجرا است یا خیر. در این حالت شما دیگر فقط یک پرامپت نمینویسید، بلکه در حال ساخت یک محیط امنیتی دور یک موتور غیرقطعی (Non-deterministic) هستید.
فاز بررسی و تحلیل
به نقل از گزارش نویسنده، یک مدل زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن جواب میدهد — در مرحله اول عیبیابی بسیار مؤثر بود. برای درک عمیقتر از اینکه این مدلها چگونه دادهها را پردازش میکنند، کالبدشکافی سازوکار مدلهای زبانی بزرگ دیدگاه فنی مفیدی را برای مدیریت این ابزارها ارائه میدهد. این مدل توانست به مهندس کمک کند تا ریاستارتها را با بار شبانه مرتبط کند، متریکها و لاگها را بررسی نماید و تیکتها و درخواستهای ادغام (Merge Requests) را آماده کند.
این مدل یک تلهی ظریف را شناسایی کرد: نموداری که حداکثر زمان استخراج داده (Scrape Time) را ۹ ثانیه نشان میداد، گمراهکننده بود. نویسنده متوجه شد که این حداکثر مدتزمان ظاهری، تنها بر اساس استخراجهای «موفق» محاسبه شده بود. وقتی یک استخراج از حد تایم-اوت میگذشت، بهجای گزارش یک مدتزمان بالا، کلاً شکست میخورد. بنابراین، نموداری که ۹ ثانیه را نشان میداد به این معنا نبود که exporter هرگز بیشتر از این زمان طول نکشیده است؛ بلکه به این معنا بود که ۹ ثانیه بلندترین استخراج «موفق» بوده است. در واقع، استخراجهای شکستخورده مشکل اصلی بودند.
تلهی زیرساختی
وقتی نوبت به تأیید اصلاحیه رسید، نویسنده به این فکر کرد که یک عامل هوش مصنوعی را به کار بگیرد تا هر صبح برای چند روز اجرا شود و بپرسد که آیا اصلاحیه کار کرده است یا خیر. این عامل باید از Prometheus پرسوجو میکرد، استقرار (Deployment) را چک میکرد و یک پیام میفرستاد. اما زیرساخت مورد نیاز برای یک عامل بدون نظارت (Unattended Agent) تکاندهنده بود:
- هویت و دسترسی: نیاز به یک کاربر غیر-root اختصاصی و احراز هویت مجزا برای ارائهدهنده مدل.
- مجوزها: دسترسی Read-only به سیستم مانیتورینگ و اعتبارنامههای خاص K8S برای دسترسی به دادهها.
- کنترل: مجموعهای محدود از ابزارها، یک تایم-اوت سختگیرانه و راهکاری مطمئن برای متوقف کردن فرآیند.
- مشاهدهپذیری: لاگهای جامع و مجموعهای از تستها برای کل گردشکار عاملمحور.
تمام اینها حجم عظیمی از سربار (Overhead) برای پاسخی بود که در نهایت به چهار پرسوجوی PromQL و چهار مقایسه ساده خلاصه میشد: آیا سرویس ریاستارت شد؟ آیا در کل دوره مشاهده فعال بود؟ حداکثر زمان استخراج موفق چقدر بود؟ آیا هشدار (Alert) فعال شد؟
راهکار «خستهکننده» اما مطمئن
بهجای عامل هوش مصنوعی، نویسنده یک اسکریپت شل (Shell Script) ۸۰ خطی نوشت. بخش اعظم کد صرف مدیریت خطا و اعلانها شد و هستهی بررسی بسیار کوچک بود. این اسکریپت با استفاده از curl با محدودیت --max-time 25 برای فراخوانی API پرومتیوس و jq برای تجزیه نتایج نوشته شد.
برای تضمین قابلیت اطمینان، اسکریپت سه وضعیت خروجی متمایز را پیادهسازی کرد:
- تأییدشده (CONFIRMED): همه چیز در محدوده مورد انتظار بود. در طول دوره مشاهده هیچ اعلانی ارسال نشد و تنها یک پیام تأیید کوتاه در روز آخر فرستاده شد.
- پسرفت (REGRESSED): مشکلی رخ داد. اسکریپت پیامی حاوی نتیجه مربوطه و دستورالعمل دقیق بازگشت (Rollback) را ارسال کرد.
- نامشخص (INCONCLUSIVE): پرسوجوی مانیتورینگ شکست خورد، دادهای بازگردانده نشد یا هدف دیگر وجود نداشت. در اینجا پیام ارسال میشد چون سکوت باید به معنای «بررسی شد و سالم است» باشد، نه «بررسیکننده شکست خورده است».
برای جلوگیری از مثبت کاذب (False Positives)، اسکریپت بهجای پرسش کلی درباره «exporter»، شناسه استقرار (Deployment Identifier) خاص مرتبط با workload جدید را تأیید میکرد. این کار تضمین میکرد که اگر کسی در حین انتظار برای تأیید، نسخه را بازگرداند یا نسخه جدیدی مستقر کرد، اسکریپت بهجای تأیید تصادفی نسخه غلط، وضعیت را «نامشخص» گزارش کند.
یکپارچگی با Systemd
نویسنده بهجای استفاده از cron، از systemd برای مدیریت تمیزتر استفاده کرد. سرویس به صورت Type=oneshot تنظیم شد و از یک تایمر با تاریخهای خاص OnCalendar و گزینه Persistent=true استفاده کرد تا مطمئن شود بررسیها دقیقاً در شبهای مورد نظر اجرا میشوند.
این تنظیمات شامل چندین ویژگی امنیتی و عملیاتی بود:
- مدیریت اسرار: استفاده از
LoadCredential=notifier.env:/path/to/notifier.envبرای فراهم کردن اعتبارنامههای اعلان بدون کپی کردن آنها در محیط اسکریپت. - کلید قطع (Kill Switch): استفاده از
ConditionPathExists=!/etc/example/PAUSEکه به نویسنده اجازه میداد تنها با ایجاد یک فایل، سرویس را متوقف کند. - سختافزاری کردن (Hardening): سرویس از
ProtectSystem=strict،ProtectHome=yes،PrivateTmp=yesوNoNewPrivileges=yesبرای محدود کردن سطح حمله استفاده کرد. - محدودیت اجرا: نویسنده ابتدا
RuntimeMaxSec=300را امتحان کرد، اما متوجه شد این تنظیم برای سرویسهایType=oneshotمناسب نیست. گزینه صحیحTimeoutStartSec=300بود؛ جزئیاتی که از طریق اجرایsystemd-analyze verifyکشف شد.
درس محیط اجرا
حتی مرحله پاکسازی هم درسی در مورد اتوماسیون داشت. پس از سه شب بررسی موفق، نویسنده سعی کرد تایمر، سرویس، اسکریپت و کاربر موقت را حذف کند. دستور پاکسازی در ظاهر با موفقیت اجرا شد اما فایلها حذف نشدند.
دلیل این اتفاق پیکربندی شل بود: شل تعاملی دارای یک Alias برای rm -i بود. محیط غیرتعاملی این Alias را به ارث برد، اما بدون داشتن ترمینالی برای پاسخ به درخواست تأیید، دستور rm -i عملاً هیچ کاری انجام نداد. این یادآور آن است که اتوماسیون در خلاء اجرا نمیشود و پیکربندی شل بخشی از محیط است. برای رفع این مشکل، نویسنده پیشنهاد میکند Aliasها را به شلهای تعاملی محدود کنید، مثلاً با بررسی: if [[ $- == *i* && -z ${AGENT_SHELL:-} ]]; then alias rm='rm -i' fi.
قانون جدید انگشتشست
در نهایت، یک قاعده ساده برای پشتههای مدرن هوش مصنوعی تعریف شد: اگر شرط موفقیت/شکست را بتوان به صورت یک «مقایسه» نوشت، از اسکریپت استفاده کنید. اگر هنوز در حال کشف این هستید که چه چیزی باید مقایسه شود، از LLM استفاده کنید.
مدل زبانی برای قضاوت و ابهام است — همبستگی سیگنالها، پیشنهاد موارد بررسی، به چالش کشیدن مفروضات و نوشتن مستندات. اسکریپت برای قابلیت اطمینان و تکرار است. استفاده از یک عامل برای یک حلقه سادهی «پرسوجو-مقایسه-اعلان»، استفاده از ماشینآلات بیش از حد برای یک کار ساده است. اسکریپت شل برای درک، ایمنسازی و عیبیابی راحتتر بود و به مراتب ارزانتر تمام شد.
این تغییر در رویکرد نشان میدهد که کارآمدترین گردشکارهای هوش مصنوعی آنهایی نیستند که اسکریپتها را جایگزین میکنند، بلکه آنهایی هستند که از هوش مصنوعی برای فهمیدن «چه چیزی باید بررسی شود» استفاده میکنند و سپس از ابزارهای خستهکننده و سنتی برای «انجام واقعی بررسی» بهره میبرند. در واقع، برای مدیریت خطاهای پیچیدهتر در محیط عملیاتی، میتوان از گامهای سیستماتیک رفع خطاهای پرامپت بهره برد تا تعادلی میان انعطافپذیری LLM و دقت اسکریپتها ایجاد شود.
گام بعدی شما
- بررسی کنید کدام بخشهای مانیتورینگ شما در حال حاضر توسط عاملهای هوش مصنوعی مدیریت میشوند و آیا میتوان آنها را به اسکریپتهای قطعی تبدیل کرد؟
- برای کارهای تکراری در لینوکس، بهجای cron از systemd timers استفاده کنید تا کنترل و امنیت بیشتری داشته باشید.
- در اسکریپتهای اتوماسیون، همیشه وضعیت «نامشخص» (Inconclusive) را تعریف کنید تا سکوت سیستم با موفقیت اشتباه گرفته نشود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو