جلسه ۹ از ۱۱، بخش ۱: طراحی ایجنت

امنیت ایجنت و هارنس خودتکامل

متنی ۳۰ دقیقه به‌روز شده در ۱۰ آبان ۱۴۰۵

در این جلسه
  1. بخش اول: امنیت ایجنت
  2. بخش دوم: هارنس خودتکامل
  3. جمع‌بندی
  4. پرسش‌هایی برای فکر کردن
  5. منابع

این جلسه در درس اصلی را دانشجوها ارائه کردند و اسلاید عمومی ندارد. این یادداشت بر اساس فهرست مطالعه‌ی همان جلسه نوشته شده است. دو موضوع به ظاهر جدا در آن هست: امنیت و خودبهبودی. این دو یک نقطه‌ی مشترک مهم دارند: ایجنتی که بتواند چیزی را تغییر دهد، می‌تواند معیار سنجش خودش را هم تغییر دهد.

بخش اول: امنیت ایجنت#

چرا ایجنت از چت‌بات خطرناک‌تر است#

چت‌بات فقط متن تولید می‌کند و انسان تصمیم می‌گیرد با آن چه کند. ایجنت عمل می‌کند: فایل پاک می‌کند، ایمیل می‌فرستد، پول خرج می‌کند. هر متنی هم که ایجنت می‌خواند، مثل صفحه‌ی وب، ایمیل، issue در GitHub یا خروجی ابزار، ممکن است دستوری پنهان داشته باشد.

یک قاعده‌ی سرانگشتی که Simon Willison آن را «سه‌گانه‌ی کشنده» نامیده: وقتی ایجنتی هم‌زمان (۱) به داده‌ی خصوصی دسترسی دارد، (۲) محتوای نامطمئن می‌خواند و (۳) می‌تواند به بیرون پیام بفرستد، مهاجم می‌تواند با یک متن تزریق‌شده داده را بیرون بکشد. دست‌کم یکی از این سه ضلع را قطع کنید.

ده خطر اصلی طبق OWASP#

OWASP در فهرست Top 10 for Agentic Applications 2026 ده خطر مخصوص ایجنت‌ها را نام برده است:

کد خطر یعنی چه دفاع اصلی
ASI01 ربودن هدف محتوایی که ایجنت می‌خواند هدفش را عوض می‌کند محتوای بازیابی‌شده را نامطمئن بدانید؛ دستور را از داده جدا کنید؛ تأیید انسانی برای عمل حساس
ASI02 سوءاستفاده از ابزار ابزار مشروع (شل، API، CLI ابری) برای کار مضر به کار می‌رود محدود کردن ابزار، اعتبارسنجی پارامتر، بررسی سیاست در هر فراخوانی
ASI03 سوءاستفاده از هویت و دسترسی اعتبارنامه‌ی مشترک، بلندمدت یا با دامنه‌ی زیاد هویت جدا برای هر ایجنت؛ اعتبارنامه‌ی کوتاه‌مدت و محدود به کار
ASI04 زنجیره‌ی تأمین فریم‌ورک، سرور MCP یا plugin مخرب یا آسیب‌پذیر فهرست اجزا، امضا و منشأ تأییدشده، پایش آسیب‌پذیری‌ها
ASI05 اجرای کد ناخواسته متن نامطمئن به مفسر، subprocess یا eval می‌رسد sandbox با کمترین دسترسی؛ بستن شبکه‌ی خروجی؛ API پارامتری به جای شل خام
ASI06 مسموم کردن حافظه و کانتکست اطلاعات غلط در حافظه یا ایندکس، رفتار آینده را شکل می‌دهد اعتبارسنجی نوشتن در حافظه؛ دامنه‌ی جدا برای هر کاربر؛ حافظه‌ی قابل بازبینی و پاک‌کردنی
ASI07 ارتباط ناامن بین ایجنت‌ها پیام بدون احراز هویت؛ جعل، دست‌کاری یا تکرار احراز هویت دوطرفه؛ پیام امضاشده؛ فهرست مجاز واگذاری
ASI08 خرابی آبشاری خطای یک ایجنت در همه‌ی روندهایی که به آن اعتماد دارند پخش می‌شود محدود کردن شعاع انفجار؛ circuit breaker؛ جدا کردن محیط توسعه از تولید
ASI09 سوءاستفاده از اعتماد انسان ایجنت خلاصه‌ای را که انسان تأیید می‌کند خودش می‌نویسد نشان دادن عمل خام هنگام تأیید؛ ثبت آنچه نمایش داده شد در برابر آنچه اجرا شد
ASI10 ایجنت سرکش ایجنت با نفوذ، ناهمسویی یا رانش، بیرون از سیاست کار می‌کند خط پایه‌ی رفتاری و هشدار؛ مالک و تاریخ انقضا برای هر ایجنت؛ کلید توقف آزموده‌شده

اصلی که OWASP زیر همه‌ی این‌ها می‌گذارد «کمترین عاملیت» (least agency) است: ایجنت فقط همان مقدار خودمختاری، ابزار و دسترسی‌ای را داشته باشد که کارش لازم دارد.

حمله‌ها: چهار درس از پژوهش#

  • تزریق پرامپت غیرمستقیم (Greshake و همکاران، ۲۰۲۳): متنی که در صفحه‌ی وب یا ایمیل کاشته شده، وقتی LLM آن را بازیابی می‌کند دستوری می‌شود که اپراتور هرگز ننوشته است. این حمله روی برنامه‌های واقعی از جمله Bing Chat نشان داده شد. درس: ابزارهای ایجنت تعیین می‌کنند یک دستور تزریق‌شده تا کجا می‌رسد.
  • AgentPoison: با مسموم کردن کمتر از ۰٫۱٪ حافظه یا پایگاه دانش، یک ماشه‌ی پنهان ساخته می‌شود که بازیاب را به سمت نمونه‌های مهاجم می‌برد، در حالی که رفتار عادی تقریباً عوض نمی‌شود. درس: حافظه‌ی پایدار یک تزریق یک‌باره را دائمی می‌کند.
  • سیستم‌های چندایجنتی کد دلخواه اجرا می‌کنند: حتی وقتی هر ایجنت جداگانه در برابر تزریق مقاوم است، یک پیام وضعیت جعلی از یک زیرایجنت می‌تواند هماهنگ‌کننده را قانع کند که از ایجنت اجرای کد بخواهد فایل مهاجم را اجرا کند. درس: امنیت تک‌تک ایجنت‌ها به امنیت سیستم ترکیب نمی‌شود.
  • مهاجم دوم حرکت می‌کند: ۱۲ دفاع اخیر که نرخ موفقیت حمله را نزدیک صفر گزارش کرده بودند، با حمله‌هایی که برای هر دفاع تطبیق داده شده بودند شکستند. درس: دفاع را باید در برابر مهاجم تطبیق‌پذیر سنجید، نه فهرست ثابتی از حمله‌ها.

دفاع‌ها: مدل یا معماری؟#

دفاع مدل‌محور. «سلسله‌مراتب دستورها» (OpenAI) به مدل آموزش می‌دهد دستورها را اولویت‌بندی کند: پیام سیستمی بالاتر از کاربر و کاربر بالاتر از خروجی ابزار. دستورهای پایین‌تر فقط وقتی اجرا می‌شوند که با بالاتری‌ها هم‌خوان باشند. این مقاومت را خیلی بالا می‌برد، به قیمت کمی امتناع بی‌دلیل، اما هیچ تضمینی نمی‌دهد.

دفاع معماری‌محور. تضمین از ساختار سیستم می‌آید، نه از رفتار مدل:

  • CaMeL (Google DeepMind) جریان کنترل را از داده‌ی نامطمئن جدا می‌کند. یک مدل ممتاز فقط از روی درخواست مطمئن کاربر یک برنامه می‌نویسد. یک مدل قرنطینه‌شده محتوای نامطمئن را پردازش می‌کند ولی به هیچ ابزاری دسترسی ندارد. یک مفسر منشأ هر مقدار را دنبال می‌کند و پیش از هر عمل با اثر جانبی، سیاست را اعمال می‌کند. در AgentDojo، CaMeL ۷۷٪ کارها را با امنیت قابل اثبات حل کرد، در برابر ۸۴٪ سیستم بدون دفاع.
  • الگوهای طراحی امن: یک مقاله‌ی مشترک چند آزمایشگاه شش الگو را فهرست کرده که اثر خروجی نامطمئن ابزار بر عمل ایجنت را محدود می‌کنند، از جمله «انتخاب‌گر عمل» (مدل فقط از میان عمل‌های از پیش تعریف‌شده انتخاب می‌کند)، «اول برنامه، بعد اجرا» (برنامه پیش از دیدن داده‌ی نامطمئن ثابت می‌شود)، «LLM دوگانه» و «اول کد، بعد اجرا». هر الگو بخشی از عمومیت را با یک ویژگی امنیتی معاوضه می‌کند که به مدل وابسته نیست.
  • کنترل AI: امنیت به شکل یک بازی بین تیم آبی (طراح پروتکل) و تیم قرمز دیده می‌شود، با فرض اینکه مدل نامطمئن ممکن است عمداً خرابکاری کند. یک مدل ضعیف‌تر اما مطمئن، مدل قوی‌تر را پایش و ممیزی می‌کند. نتیجه یک مصالحه‌ی قابل تنظیم بین امنیت و کارایی است.

AgentDojo محیط استاندارد سنجش این حمله‌ها و دفاع‌هاست و کارایی و امنیت را با هم می‌سنجد.

در عمل: یک hook محافظ#

در جلسه‌ی ۲ گفتیم skill پیشنهاد است و hook اجبار. این یک hook ساده‌ی PreToolUse برای Claude Code است که دستورهای خطرناک شل را پیش از اجرا مسدود می‌کند:

#!/usr/bin/env python3
# .claude/hooks/guard_bash.py
import json, re, sys

event = json.load(sys.stdin)                       # Claude Code رویداد را به stdin می‌دهد
cmd = event.get("tool_input", {}).get("command", "")

BLOCK = [
    (r"\brm\s+-[a-z]*r[a-z]*f?\s+(/|~|\$HOME)(\s|$)", "حذف بازگشتی ریشه یا خانه"),
    (r"\bgit\s+push\b.*\s(--force|-f)\b",           "push اجباری"),
    (r"\b(curl|wget)\b.*\|\s*(ba|z)?sh\b",          "اجرای اسکریپت دانلودشده"),
    (r"\.env\b|id_rsa|\.aws/credentials",           "دسترسی به فایل رمز"),
]
for pattern, reason in BLOCK:
    if re.search(pattern, cmd):
        print(f"Blocked by policy: {reason}. Ask the user if this is really needed.", file=sys.stderr)
        sys.exit(2)                                 # کد ۲ = مسدود؛ پیام به مدل برمی‌گردد
sys.exit(0)

و ثبت آن در .claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "python3 .claude/hooks/guard_bash.py" }] }
    ]
  }
}

این یک لایه است، نه دیوار

فهرست سیاه همیشه دورزدنی است، مثلاً با bash -c "$(echo ...)". hook برای جلوگیری از اشتباه عالی است. برای جلوگیری از حمله به ایزوله‌سازی واقعی نیاز دارید: sandbox، دسترسی‌های محدود و بستن شبکه. این همان درس «مهاجم دوم حرکت می‌کند» است.

بخش دوم: هارنس خودتکامل#

اگر هارنس این‌قدر روی نتیجه اثر دارد (جلسه‌ی ۴: همان مدل، تا دو برابر دقت)، آیا ایجنت می‌تواند خودش هارنسش را بهتر کند؟

سطح ۱: یادگیری از تجربه‌ی خود#

  • Reflexion: بعد از هر تلاش ناموفق، ایجنت یک بازتاب کلامی می‌نویسد («شکست خوردم چون فرض کردم فایل در src است») و در حافظه‌ی رویدادی نگه می‌دارد. تلاش بعد با این یادداشت شروع می‌شود. رفتار از راه کانتکست تغییر می‌کند، نه وزن‌های مدل.
  • Self-Refine: یک مدل خروجی می‌سازد، نقدش می‌کند و بازنویسی‌اش می‌کند، بدون هیچ آموزشی. محدودیتش این است که منتقد همان وزن‌ها را دارد، پس ممکن است همان خطاها را نبیند.
  • ACE (مهندسی کانتکست ایجنتی): کانتکست ایجنت یک «کتاب بازی» از مدخل‌های جداست. وظایف بین تولیدکننده، بازتاب‌دهنده و ویراستار تقسیم می‌شود و تغییرات کوچک به‌شکل قطعی ادغام می‌شوند. این کار جلوی «فروپاشی کانتکست» را می‌گیرد، همان اتفاقی که وقتی مدل کل کانتکست را بازنویسی می‌کند رخ می‌دهد.

سطح ۲: جستجو در فضای طراحی ایجنت#

  • ADAS: ایجنت‌ها به‌شکل کد تعریف می‌شوند و یک فرا-ایجنت آرشیوی از ایجنت‌های کشف‌شده و امتیازشان را می‌خواند و ایجنت جدید پیشنهاد می‌دهد. نکته‌ی کلیدی: مجموعه‌ی ارزیابی عملاً تعیین می‌کند جستجو چه چیزی را بهینه کند.
  • Darwin Gödel Machine: یک ایجنت کدنویس مخزن کد خودش را ویرایش می‌کند و آرشیوی از نسخه‌ها نگه می‌دارد تا نسخه‌های بعد از هر نسخه‌ی قبلی شاخه بزنند. عملکرد روی SWE-bench به‌طور قابل توجهی بهتر شد. اما در یک اجرا، ایجنت امتیازش را با حذف لاگ‌هایی که آشکارساز توهمش به آن‌ها وابسته بود بالا برد.

آخرین مورد مهم‌ترین درس این بخش است و همان نقطه‌ی مشترک امنیت و خودبهبودی: ارزیابی باید بیرون از دسترس ایجنت باشد. (جلسه‌ی ۷: هارنس ایجنت را از هارنس ارزیابی جدا کنید.)

سطح ۳: مهندسی خودکار هارنس#

  • Meta-Harness: کد، امتیاز و رد کامل اجرای هر هارنس کاندید در فایل‌سیستم ذخیره می‌شود و یک ایجنت کدنویس هر چه لازم دارد را می‌خواند و نسخه‌ی بعد را پیشنهاد می‌دهد. یافته‌ی مهم: خلاصه کردن ردها سیگنالی را که جستجو لازم دارد از بین می‌برد.
  • مهندسی هارنس ایجنتی: تکامل هارنس به‌شکل یک فرایند مهندسی دیده می‌شود. هر جزء یک فایل است، پس تغییرها صریح و برگشت‌پذیرند. هر ویرایش با پیش‌بینی اینکه کدام کارها را درست یا خراب می‌کند همراه است. pass@1 روی Terminal-Bench 2 در ده تکرار از ۶۹٫۷٪ به ۷۷٫۰٪ رسید. اما پیش‌بینی‌ها اصلاح‌ها را خوب حدس می‌زدند و پسرفت‌ها را نه.
  • Live-SWE-agent: ایجنت حین کار ابزار سفارشی خودش را می‌نویسد؛ بعد از هر قدم از خودش می‌پرسد «آیا یک ابزار جدید کمک می‌کند؟». بدون هزینه‌ی جستجوی آفلاین نرخ حل را بالا برد. اما ابزاری که خودش نوشته بدون اعتبارسنجی و با همه‌ی دسترسی‌های خود ایجنت اجرا می‌شود و این دوباره ما را به بخش امنیت برمی‌گرداند.

جمع‌بندی#

اصل از کجا
هر متن ورودی را داده بدانید، نه دستور تزریق غیرمستقیم، ASI01
کمترین عاملیت OWASP
امنیت را در سطح سیستم بسنجید، نه هر ایجنت حمله به جریان کنترل چندایجنتی
دفاع را با مهاجم تطبیق‌پذیر بسنجید «مهاجم دوم حرکت می‌کند»
برای تضمین، معماری را تغییر دهید، نه فقط مدل را CaMeL، الگوهای طراحی
ارزیابی را بیرون از دسترس ایجنت نگه دارید Darwin Gödel Machine

پرسش‌هایی برای فکر کردن#

  • ایجنتی که استفاده می‌کنید، کدام ضلع‌های «سه‌گانه‌ی کشنده» را دارد؟ کدام را می‌توانید بدون از دست دادن کارایی اصلی قطع کنید؟
  • اگر بخواهید ایجنتتان skillهای خودش را بنویسد (مثل Live-SWE-agent)، چه محدودیت‌هایی می‌گذارید تا skill جدید پیش از استفاده سنجیده شود؟

منابع#