تصور کنید سیستمی ساختهاید که قرار است بدون دخالت شما، مقاله بنویسد و آنها را مدیریت کند، اما ناگهان متوجه میشوید که مدلهای پیشرفتهترین هوش مصنوعی در برابر سادهترین خطاهای کدنویسی، کاملاً فلج میشوند. این دقیقاً همان اتفاقی است که در پروژه AiOps Community رخ داد؛ نشریهای خودکار که در آن عاملهای هوش مصنوعی (AI Agents) — شبیه دستیارهای دیجیتالی که میتوانند بهجای شما ابزارها را اجرا کنند — مسئولیت تولید و نظارت بر محتوا را بر عهده دارند.
به نقل از گزارش توسعهدهنده این پروژه، پس از ۶ هفته کار روی این سامانه — جایی که عاملها مقالات را مینویسند و یک ناظر خودکار تاییدیه آنها را صادر میکند — شکافی بنیادین در طراحی APIها آشکار شد. این پروژه چهار باگ بحرانی را شناسایی کرد که تنها به این دلیل رخ دادند که ماشینها مستندات را با چنان دقتِ خشک و تحتاللفظیای دنبال میکنند که انسانها بهطور طبیعی از آن چشمپوشی میکنند.
بیشتر برنامهنویسان هنگام اتصال به یک API، «قصد» سازنده را حدس میزنند. برای مثال، اگر یک انسان با خطای «سرویس در دسترس نیست» مواجه شود، احتمالاً کمی صبر میکند یا روش دیگری را امتحان میکند. اما عاملهای هوش مصنوعی، قرارداد API را مانند یک قانون مطلق میبینند. همین ویژگی، آنها را به ابزاری بیرحم اما بسیار کارآمد برای تست کدهای محیط عملیاتی تبدیل میکند.
همانطور که در تحلیلهای قبلی ما دربارهی امنیت مدلهای بازمتن اشاره کردیم، تکیه بر رفتارهای پیشفرض مدلها بدون در نظر گرفتن لایههای سختافزاری و نرمافزاری، میتواند منجر به نتایج غیرمنتظره شود.
تلهی تحتاللفظی بودن
اولین شکست مربوط به اعتبارسنجی URLهای منبع بود. یک عامل، مقالهای را با لینکی ارسال کرد که به صفحهی آخرین نسخهی یک پروژه در گیتهاب اشاره داشت (مانند github.com/owner/repo/releases/latest). این لینک بهطور خودکار کاربر را به صفحهی نهایی یک نسخه تگشده منتقل میکند (302-redirect). برای سختسازی سیستم در برابر حملات SSRF، اعتبارسنج سیستم طوری طراحی شده بود که هرگونه انتقال خودکار (Redirect) را رد کند.
طبق مستندات پروژه، سیستم در این حالت خطای ۵۰۳ (Service Unavailable) برمیگرداند. در استانداردهای HTTP، خطای ۵۰۳ یعنی «سرویس موقتاً در دسترس نیست، بعداً امتحان کن». در حالی که یک انسان این خطا را نادیده میگرفت و از آن میگذشت، عامل هوش مصنوعی آن را یک اختلال موقت دانست و ۴ بار پشتسرهم تلاش کرد. هر تلاش، یک درخواست نظارتی را مصرف کرد اما نتیجه تغییری نکرد چون شکست دائمی بود.
توسعهدهنده اشاره کرد که اگر تلاش مجدد نمیتواند مشکل را حل کند، خطا باید از نوع 4xx باشد. راهکار این بود که پاسخ سیستم به خطای ۴۲۲ (Unprocessable Entity) تغییر یابد و یک کد دلیل خاص یعنی source_url_redirects ارسال شود. این کار به عامل میفهماند که بهجای چرخش ابدی در حلقه تکرار، باید لینک مقصد نهایی را ذکر کند.
فساد وضعیت و نشت امنیتی
دو باگ دیگر، خطرات شکستهای خاموش در گردشکارهای عاملمحور (Agentic) را نشان دادند:
- رقابت وضعیت (State Race): یک تداخل در خواندن-تغییر-نوشتن (read-modify-write) باعث شد عامل در ۷ اجرای متوالی، وضعیت خود را از دست بدهد. عامل مقالات را با موفقیت منتشر میکرد اما هرگز در بحثها شرکت نمیکرد. دلیلش این بود که یک تابع بیرونی، وضعیت را در ابتدا بارگذاری میکرد، در حالی که یک تابع داخلی به نام
publish()عملیات بارگذاری و ذخیرهسازی خود را بهطور مجزا انجام میداد. در نهایت، فراخوانیsave_state(state)در تابع بیرونی، تمام بهروزرسانیهای تابع داخلی را بهطور خاموش پاک میکرد. چون فایل وجود داشت و درست به نظر میرسید، تنها نشانه یک لاگ مبهم بود که میگفت: «هیچ حقیقت ذخیرهشدهای یافت نشد — نادیده گرفته شد». راهکار، حذف کامل ذخیرهسازی در تابع بیرونی بود. - نشت کلید امنیتی: یک تولیدکنندهی کد، اسکریپتی را برای عاملهای جدید میساخت. برای اینکه اسکریپت بلافاصله اجرا شود، از کد
os.environ.get("AIOPS_COMMUNITY_KEY", "aac_live_13480b83d624...")استفاده شده بود. این مقدار پیشفرض، در واقع یک کلید API واقعی و فعال بود. در نتیجه، وقتی کاربری این کد تولیدشده را در یک مخزن عمومی گیتهاب منتشر کرد، این راز امنیتی در معرض دید کل اینترنت قرار گرفت. اکنون توسعهدهنده الزام کرده است که ازos.environ[]بدون هیچ مقدار جایگزینی استفاده شود تا بهجای یک شکست امنیتی خاموش، یک خطای پیکربندی بلند و صریح رخ دهد. این نوع آسیبپذیریها اهمیت پیادهسازی لایههای کنترلی را دوچندان میکند؛ همانطور که در بررسی مکانیزمهای GuardRail برای جلوگیری از دسترسیهای غیرمجاز عاملها به دادههای عملیاتی به این موضوع پرداختیم.
رشتههای نامرئی
آخرین شکست به دلیل کاراکترهای خاص HTML (HTML entities) در نام دستهبندیها رخ داد. محتوایی که از وردپرس وارد شده بود، دستهبندیهایی مثل «Tools & Platforms» را با کاراکترهای کدگذاریشده ذخیره کرده بود. رابط کاربری مدیریت (Admin UI) این را درست نمایش میداد چون مرورگرها این کدها را رمزگشایی میکنند و برای انسان همه چیز درست به نظر میرسید.
اما API عملیات تطبیق دقیق رشتهها (Exact String Matching) را انجام میداد. وقتی عامل عبارت «Tools & Platforms» را ارسال میکرد، با رشتهی خام ذخیرهشده در دیتابیس تطبیق نمییافت. این منجر به رد شدن تمام ارسالها به آن دستهبندی با خطای no_matching_category شد. این شکست در رابط کاربری نامرئی بود اما برای API مرگبار. درس آموخته شده این بود که دادهها باید در مرز ورود به سیستم نرمالسازی شوند: مقادیر رمزگشاییشده ذخیره شوند و کدگذاری تنها در مرحلهی نمایش (Render) انجام شود.
تغییر ترافیک از انسان به ماشین، استانداردهای طراحی API را تغییر میدهد. ابهامات کوچکی که برای برنامهنویسان مزاحم بودند، اکنون برای سامانههای خودکار به سدهای مرگبار تبدیل میشوند. وقتی مشتری شما یک ماشین است، یک کد وضعیت اشتباه، یک پیشنهاد نیست؛ بلکه دستوری است برای اینکه تا ابد در یک حلقه تکرار بماند.
برای جلوگیری از این شکستها، توسعهدهندگان باید دادهها را در مرز سیستم نرمالسازی کنند و کلیدهای پیشفرض را با خطاهای فوری و صریح جایگزین کنند. هدف این است که از APIهایی که «برای انسان خوانا» هستند به سمت APIهایی حرکت کنیم که «برای ماشین دقیق» باشند.
گام بعدی شما
- اگر گردشکارهای عاملمحور میسازید، تمام هندلرهای خطای ۴xx و ۵xx خود را بازبینی کنید تا مطمئن شوید هر کد دقیقاً نشان دهد که آیا تلاش مجدد (Retry) منطقی است یا خیر.
- دادههای ورودی را در مرز API نرمالسازی کنید تا تفاوتهای ظاهری در رشتهها (مانند HTML entities) باعث شکست عملیات نشود.
- هرگونه مقدار پیشفرض (Fallback) برای کلیدهای امنیتی را حذف کنید تا خطاهای پیکربندی بهجای نشت داده، بهصورت صریح و سریع ظاهر شوند.
- برای کسانی که به جزئیات فنی علاقهمند هستند، قرارداد API، قوانین نظارتی و محدودیتهای نرخ درخواست (Rate Limits) برای AiOps Community در مسیر
/agents.mdبهصورت عمومی در دسترس است.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو