تصور کنید یک برنامهنویس ابزاری را به عامل هوش مصنوعی اضافه میکند که فقط باید نسخه یک نرمافزار را بخواند، اما به دلیل یک اشتباه در کد، مدل میتواند هر دستوری را در ترمینال سیستم اجرا کند. این دقیقاً همان نقطهای است که بسیاری از تیمهای توسعه در مسیر ساخت سیستمهای عاملمحور (Agentic AI) دچار لغزش میشوند. عبارت «تحلیلگر را ادغام کن، اما مجوز را نگه دار» (Merge the parser, but hold the grant)، انضباط لازم برای درخواستهای تغییر کد (PR) در ابزارهای عاملهای هوش مصنوعی است. دلیل این سختگیری آن است که موفقیت در تستهای طرحواره (Schema)، دلیلی بر درست بودن تحلیل (Parsing) است، اما دلیلی بر رعایت اصل «حداقل دسترسی» (Least Privilege) نیست. وقتی توسعهدهندگان طرحواره JSON یک ابزار و هندلر اجرای زنده آن را در یک Diff واحد ادغام میکنند، ناخواسته به عامل هوش مصنوعی این قدرت را میدهند که صرفاً چون مدل یک JSON معتبر تولید کرده است، اقدامات حساس را انجام دهد.
این شکاف امنیتی زمانی رخ میدهد که تیمها برای استقرار جریانهای کاری Agentic AI که با شلها، کلاینتهای HTTP و سیستمهای فایل تعامل دارند، عجله میکنند. در بسیاری از چرخههای توسعه فعلی، یک PR که ابزاری را اضافه میکند، به عنوان یک واحد تغییر واحد در نظر گرفته میشود. با این حال، طبق یک راهنمای فنی که در ۱۱ اکتبر ۲۰۲۶ در dev.to منتشر شد، این رویکرد سه تغییر متمایز را با هم خلط میکند: یک طرحواره (Schema)، یک سیاست (Policy) و یک اثر جانبی (Side effect). بررسیهای طرحواره میتوانند مانند هر قرارداد دیگری پذیرفته شوند، اما متن سیاست و یک هندلر زنده نباید صرفاً به این دلیل که مدل یک JSON معتبر تولید کرده است، همراه با آن ادغام شوند.
تصور کنید یک برنامهنویس ابزاری را به یک رجیستری اضافه میکند. PR اغلب کوچک به نظر میرسد: رجیستری یک ابزار میگیرد، یک تست بررسی میکند که یک نمونه Payload معتبر است و هندلر کوتاه است — معمولاً فقط برای اینکه تسک بتواند «تمام شود» اضافه شده است. این ساختار، ریسک اصلی است. اعتبارسنجی فقط پاسخ میدهد که «آیا یک شیء با طرحواره مطابقت دارد یا خیر»؛ اما اجرا پاسخ میدهد که «آیا یک فرآیند واقعاً مجاز به انجام آن اقدام است یا خیر». این دو سؤال به طور مستقل شکست میخورند. یک تست موفق در مسیر خوشبینانه (Happy-path)، کل بسته را ایمن نمیکند.
نشانههای خطر در درخواستهای تغییر کد
بازبینهای کد باید به دنبال سیگنالهای خاصی باشند که نشان میدهد یک «مجوز» (Grant) در لباس یک بهروزرسانی «تحلیلگر» (Parser) پنهان شده است. سیگنالهای پرخطر عبارتند از:
- افعال مبهم: نام ابزارهایی مانند
run_taskیاapply_fixکه فاقد جزئیات دقیق هستند. - قضاوتهای به تعویق افتاده: توصیفاتی که به مدل میگویند «هر چه لازم است انجام بده» به جای تعریف یک مرز سختگیرانه.
- ورودیهای بدون محدودیت: پارامترهایی که به عنوان رشتههای عمومی (Generic Strings) تایپ شدهاند و میتوانند برای تزریق دستور (Command Injection) استفاده شوند.
- هندلرهای خطرناک: کدهایی که بدون هیچ دروازه کنترلی به شل، کلاینت HTTP یا سیستم فایل دسترسی پیدا میکنند.
- تنظیمات فعال بهصورت پیشفرض: تنظیماتی که ابزار را به جای محیط تست، به طور پیشفرض در محیط عملیاتی (Production) فعال میکنند.
تحلیل یک نمونه ساختگی (Synthetic Review Fixture)
برای روشن شدن این ریسک، یک نمونه بازبینی ساختگی (که کد عملیاتی نیست) را در ماژولی مانند synth/agent_tools.py در نظر بگیرید. در این مثال، یک dataclass به نام Tool تعریف شده که شامل نام، توصیف، پارامترها و یک هندلر است. ابزاری پیشنهادی به نام run_task تعریف شده که توصیف آن «اجرای هر آنچه برای اتمام تسک کاربر لازم است» است و پارامترهای آن اجازه استفاده از یک رشته command بدون محدودیت را میدهد. هندلر آن یک lambda ساده است: lambda args: args["command"].
برگرداندن رشته در این نمونه ساختگی عمدی است. سؤال حیاتی بازبینی این نیست که اجراکننده چگونه فراخوانی شود، بلکه این است که آیا این شکل خاص از کد میتواند به یک اجراکننده تبدیل شود یا خیر. این یک مثال ساختگی برای آموزش بازبینی است؛ این نمونه هیچ ادعایی درباره میزان تأخیر (Latency)، هزینه یا نرخ موفقیت ندارد و دستورات آن محلی هستند.
چه چیزهایی میتوانند در کنار تحلیلگر پذیرفته شوند؟
بازبینها فقط باید به تکههای کدی (Hunks) اعتماد کنند که بتوان آنها را بدون نیاز به مدل و بدون شبکه مجدداً اجرا کرد. موارد قابل پذیرش عبارتند از:
- سند طرحواره (Schema)، به شرطی که یک تست، نام ابزار، کلیدهای ضروری و انواع داده را تثبیت (Pin) کرده باشد.
- توابع خالص (Pure Functions) که یک شیء آرگومان را قبل از اجرای هر هندلری، میپذیرند یا رد میکنند.
- نتایج اجرای آزمایشی (Dry-run) که اقدام مورد نظر را ثبت میکنند اما هیچ عملیاتی را انجام نمیدهند.
- بهبودهای ساختاری مانند تغییر نامها، افزودن کامنتها یا دقیقتر کردن انواع داده، به شرطی که تستهای مذکور وجود داشته باشند.
مواردی که باید از PR جدا شوند
هر تکه کدی که اقدامات زیر را انجام میدهد باید جدا شده یا حذف شود:
- فعال کردن ابزار جدید از طریق یک سازنده پیشفرض، کانفیگ عملیاتی یا یک fixture مشترک.
- ارسال مستقیم یک رشته تأمین شده توسط مدل به یک شل، یک API پرسوجو یا یک درخواست URL.
- استفاده از رشته توصیفی (Description) به عنوان تنها محدودکننده دسترسی.
- اضافه کردن یک ابزار «همه-منه» (Catch-all) در کنار یک ابزار محدود، به بهانه «انعطافپذیری».
- کپی کردن آرگومانهای خام در لاگها، برچسبهای متریک یا خطاهای خروجی.
- تأیید بر اساس متن تولید شده توسط دستیار (Assistant Prose) به جای مقدار بازگشتی دروازه کنترلی.
مکانیزم «دروازه» (Gate)
برای رفع این مشکل، راهنما یک معماری جایگزین پیشنهاد میکند که در آن مجوز به سه اثر مجزا تقسیم میشود: یک لیست سفید (Allowlist) که به صورت داده بیان شده است، یک دروازه (Gate) که اقدامات ناشناخته را قبل از رسیدن به هندلر رد میکند، و تستهایی که فقط یک اجراکننده جعلی (Fake Runner) را فراخوانی میکنند.
به جای هندلری که کورکورانه یک رشته تأمین شده توسط مدل را اجرا میکند، سیستم باید از یک دروازه استفاده کند. برای مثال، در synth/grants.py یک دیکشنری به نام ALLOWED اقدامات را به جفت-آرگومانهای ثابت متصل میکند. ابزاری به نام show_version باید به ("ruff", "--version") متصل شود. اگر مدل سعی کند یک فلگ اضافی مانند --unsafe را اضافه کند، دروازه باید یک استثنای GrantRejected ایجاد کند. این امر تضمین میکند که آرگومانهای اضافی باعث گسترش مجوز نشوند.
تست کردن مجوزها
تستها (مثلاً در tests/test_tool_grant.py) باید چهار رفتار کلیدی را با استفاده از pytest تأیید کنند:
۱. اقدامات شناختهشده باید یک argv ثابت برگردانند (مثلاً gate("show_version") == ("ruff", "--version")).
۲. اجراهای آزمایشی (Dry-runs) نباید اجرا شوند (پرچم executed باید False باشد).
۳. اقدامات ناشناخته (مانند bash ،curl یا run_task) باید با استثنای GrantRejected رد شوند.
۴. آرگومانهای اضافی نباید باعث گسترش مجوز دسترسی شوند.
رویه بازبینی سختگیرانه
برای تغییرات متوسط در عاملها، راهنما یک ترتیب بازبینی خاص را پیشنهاد میکند تا مجوزها در میان نویزهای فرمتبندی گم نشوند. بازبینها باید این مراحل را دنبال کنند:
۱. لیست فایلهای تغییر یافته: جداسازی طرحواره، کانفیگ، هندلر و تستها.
۲. ابتدا خواندن کانفیگ و سازندهها: یک فلگ فعال بهصورت پیشفرض، حتی اگر طرحواره محدود به نظر برسد، یک ریسک استقرار است.
۳. جستوجو در هندلر: به دنبال فراخوانیهای process ،network و filesystem بگردید. در صورت یافتن، در همان جایگزینی، یک مسیر Dry-run مطالبه کنید.
۴. تأیید تستها: اطمینان حاصل کنید که تستها دروازه (Gate) را ایمپورت میکنند، نه یک کلاینت میزبانیشده.
بازبینها باید از یک قالب کامنت ساختاریافته استفاده کنند: نام تکه کد را ذکر کنند (مثلاً synth/agent_tools.py, tool run_task)، به ردیف جدول ارجاع دهند (مثلاً unconstrained command string / grant) و تصمیم را اعلام کنند (split out). جایگزین باید شامل یک ورودی لیست سفید، یک تست رد دروازه و یک پرچم Dry-run باشد. متن دستیار یا یک فراخوانی موفق به یک هاست مشترک به عنوان مدرک پذیرفته نمیشود.
جدول تصمیمگیری برای سیگنالهای Diff
| سیگنال تغییر | دستهبندی | اقدام برای ادغام |
|---|---|---|
| طرحواره JSON (تثبیت شده با تست) | تحلیلگر | پذیرش پس از اجرای تست محلی |
| توصیف محدود شده به یک فعل/مفعول | متن سیاست | حفظ به عنوان مستندات تنها |
| رشته دستور یا URL بدون محدودیت | مجوز | جداسازی از PR |
| ایمپورت کمکی شل، HTTP یا فایل | اثر جانبی | الزام به Dry-run قبل از هر فراخوانی |
| فعالسازی ابزار در کانفیگ پیشفرض | سطح استقرار | حذف مقدار پیشفرض |
| تست وابسته به مدل زنده یا هاست خارجی | اوراکل | جایگزینی با اجراکننده جعلی |
| دادههای لیست سفید + تستهای رد | مدرک | ادغام مجدد مجوز به تنهایی |
نقش بازپخشهای میزبانیشده (Hosted Replays)
در حالی که تستهای محلی استاندارد طلایی هستند، راهنما اشاره میکند که دسترسی رایگان به مدل و گزینههای سرور میتواند برای پیشنویس کردن استفاده شود. یک توسعهدهنده ممکن است از یک سرور رایگان برای بازپخش یک ردپای (Trace) ثبت شده از فراخوانی ابزار روی ورودیهای آزمایشی استفاده کند تا موارد ردشدهی فراموش شده را بیابد. با این حال، این بازپخش یک ابزار پیشنهادی است، نه یک مکانیزم تأیید. هرگز نباید یک وابستگی CI یا مبنای تصمیم برای ادغام باشد. اگر از بازپخش استفاده شد، بازبین باید تاریخی که مستندات بررسی شدهاند را یادداشت کرده و تصریح کند که تصمیم ادغام بر اساس tests/test_tool_grant.py است، نه متن بازپخش.
محدودیتها و اجرا
این چارچوب اذعان میکند که لیستهای سفید تنها به اندازه باینریهایی که نام میبرند امن هستند. این مدل ابزارهایی که پس از استارتآپ بارگذاری میشوند یا عاملهایی که طرحوارهها را در زمان اجرا (Runtime) میسازند را پوشش نمیدهد. نکته حیاتی این است که راهنما تأکید میکند اجرا (Enforcement) باید در «دروازه» باشد، نه در «پرامپت». درخواست از مدل برای ایمن بودن، جایگزینی برای رد سختافزاری اقدامات غیرمجاز نیست.
برای تیمهایی که متعهد به ضمائم سختگیرانه پردازش داده، بندهای قراردادی زمان فعال بودن (Uptime) یا ممنوعیت استنتاج شخص ثالث هستند، راهنما هشدار میدهد که به طور کلی از ارسال ردپاها به سرورهای رایگان خودداری کنند. در این محیطها، دروازه محلی و لیست سفید تنها استانداردهای پذیرفته شده برای امنیت هستند. کاربران باید زمانی که مخزن (Repository) نمیتواند یک پردازشگر خارجی را بپذیرد، حتی برای یک ردپای آزمایشی، از بازپخش میزبانیشده صرفنظر کنند.
این تغییر در عمل، صنعت را از اعتماد به تستهای «مسیر خوشبینانه» دور میکند. با treating کردن تحلیلگر و مجوز به عنوان موجودیتهای مجزا، توسعهدهندگان میتوانند قابلیتهای ابزار را بدون باز کردن تصادفی یک درِ پشتی به زیرساختهای عملیاتی خود، توسعه دهند.
گام بعدی شما
- تمام PRهای مربوط به ابزارهای AI را بررسی کنید و هر جا که کد اجرا (Handler) و طرحواره (Schema) با هم ادغام شدهاند، آنها را تفکیک کنید.
- یک لایه
Gateیا لیست سفید برای تمام دستورات سیستمی ایجاد کنید تا ورودیهای مدل هرگز مستقیماً به شل نرسند. - تستهای
pytestخود را بهگونهای بهروز کنید که تلاش مدل برای اضافه کردن آرگومانهای غیرمجاز را صریحاً رد کنند.
اما امنیت در سطح پرامپت تنها لایه اول است؛ برای درک اینکه چگونه حملات تزریق پرامپت میتوانند این دروازهها را دور بزنند، به تحلیل ما دربارهی Prompt Injection مراجعه کنید.




گفتگو