محدودیتهای نظارت
سیستمهای agent معمولاً با نظارت بر آنها اداره میشوند. traceها منتشر میشوند، داشبوردها ساخته میشوند، آستانهها تعیین میشوند و چرخهٔ on-call برقرار میشود. این مفید است، اما ویژگیای متفاوت از کنترل است. یک داشبورد کنشی انجامشده را مشاهده میکند. تا زمانی که یک پنل قرمز شود، tool call پیشتر اجرا شده، نوشتن پیشتر انجام شده و عارضهٔ جانبی خارجی پیشتر رخ داده است. بهترین کاری که یک پشتهٔ پایش میتواند بکند کوتاهکردن فاصلهٔ میان آسیب و کشف آن است.
نظارت همچنین به کاملبودن telemetry وابسته است. اگر یک tool wrapper انتشار یک رویداد را فراموش کند، اگر یک مسیر retry کلاینت ابزارگذاریشده را دور بزند، یا اگر یک یکپارچهسازی جدید بدون decorator ردیابی عرضه شود، داشبورد دقیقاً برای کنشهایی ساکت میماند که کمترین درک را از آنها داریم. شکافهای پوشش در telemetry بهطور یکنواخت توزیع نمیشوند؛ آنها پیرامون جدیدترین و کمبازبینیشدهترین مسیرهای کد خوشه میبندند، همانجایی که رخدادها تمرکز مییابند.
یک agent پایششده با مجوزهای گسترده همچنان یک agent با مجوزهای گسترده است. رصدپذیری مجموعهٔ حالتهای قابلدسترس را کاهش نمیدهد. دوربینی به اتاقی اضافه میکند که همچنان قفلنشده باقی میماند. مدل مجوز چیزی است که ممکنبودن را تعیین میکند؛ داشبورد تنها تعیین میکند چه چیزی متوجه میشود.
آستانههای هشدار یک اعوجاج دیگر وارد میکنند. آستانهها برای کاهش نویز تنظیم میشوند، یعنی برای تحمل نرخ مشخصی از ناهنجاریهای سطح پایین تنظیم میشوند. این یک سازش عملیاتی معقول برای تشخیص است، اما ابزار نادرست برای پیشگیری است. سیاستی که وقتی یک عملیات حساس بیش از تعداد پیکربندیشدهای بار در هر بازه رخ دهد فعال میشود، سیاستی است که چندین رخداد نخست را مجاز میداند. پیشگیری نیازمند تصمیمی پیش از نخستین رخداد است، نه یک rate limit پس از آن.
پیامد عملی این است که حاکمیتی که تنها بهصورت پایش بیان میشود به همان حالت شکست همگرا میشود: سیستم در سطح کلان بهخوبی درک میشود و در سطح خاص بیقید میماند. نمای کلان واقعاً برای تحلیل ظرفیت، هزینه و کیفیت ارزشمند است. اما یک سطح کنترل نیست.
کدگذاری ناورداها
جایگزین این است که سیاست را بهصورت پیششرطهایی بیان کنیم که در مرزی بررسی میشوند که در آن قصد agent به کنش تبدیل میشود: tool call. هر قابلیتی که agent دارد از طریق برخی رابط ابزار قابلدسترس است، و آن رابط باریکترین نقطهای است که در آن میتوان تصمیمی را اجرا کرد. اگر بررسی همانجا انجام شود، برای هر فراخوانندهای انجام میشود، از جمله آنهایی که پس از نوشتن سیاست اضافه شدهاند.

یک پیششرط یک محمول بر فراخوانی پیشنهادی و زمینهٔ پیرامون آن است. میتواند به آرگومانها، هویت agent درخواستکننده، نشست، منبعی که لمس میشود و وضعیت محیط ارجاع دهد. نمونههایی از شکل، نه محتوای مشخص، شامل اینهاست: منبع هدف باید درون یک namespace مجاز باشد؛ عملیات باید خواندن باشد وقتی نشست ارتقا نیافته است؛ payload نباید فیلدی داشته باشد که بهعنوان محدود علامتگذاری شده است؛ فراخوانی باید همراه با یک approval token معتبر صادرشده توسط یک workflow جداگانه باشد.
اسکیمای نوعدار این را قابلاجرا میکند نه آرمانی. اگر ورودی ابزار با اسکیمایی توصیف شود که فیلدهای الزامی، مقادیر شمارششده و انواع کراندار دارد، آنگاه یک فراخوانی بدشکل در زمان parse شکست میخورد، پیش از آنکه هر handlerی اجرا شود. رفتار fail-closed از اسکیما ناشی میشود نه از کد دفاعی درون handler. agentی که آرگومانی بهظاهر معقول اما خارج از سیاست تولید میکند به عارضهٔ جانبی نمیرسد؛ یک رد ساختاریافته دریافت میکند و باید تصمیم بگیرد چه کند.
یک سازوکار مشخص چنین است. runtime agent مستقیماً ابزارها را فراخوانی نمیکند. یک policy gateway را با درخواستی ساختاریافته فراخوانی میکند:
{
"agent": "research-worker-3",
"session": "s-8841",
"tool": "documents.write",
"arguments": {"collection": "contracts", "document_id": "c-2210", "body": "..."},
"context": {"approval": null, "elevated": false}
}
gateway یک policy bundle را ارزیابی میکند، که مجموعهای نسخهدار از قواعد با یک evaluator قطعی است. ارزیابی یک تصمیم، یک reason code و نسخهٔ سیاست را برمیگرداند. gateway تنها در صورت allow ابزار زیربنایی را فراخوانی میکند. ردها بهعنوان نتایج عادی ابزار به agent بازگردانده میشوند، تا agent بتواند سازگار شود بدون آنکه runtime نیاز به مدیریت خطای خاص داشته باشد.
دو ویژگی اینجا اهمیت دارد. نخست، موتور سیاست بیرون از context مدل قرار دارد. نه یک prompt است، نه یک system message، و نه سندی که agent بتواند بازیابی کند. نمیتوان با آن بحث کرد، آن را با خلاصهسازی کنار گذاشت، یا با دستور بعدی جایگزینش کرد. تنها تأثیر مدل بر تصمیم محتوای درخواستی است که ارسال میکند. دوم، تصمیم با توجه به درخواست و نسخهٔ سیاست قطعی است. همان فراخوانی که دو بار در برابر همان bundle ارزیابی شود نتیجهٔ یکسانی تولید میکند، و همین است که تصمیم را پس از وقوع قابلتوضیح میکند.
سازش صادقانه این است که این کار پیچیدگی را جابهجا میکند نه حذف. هر قابلیت جدید نیازمند یک ورودی سیاست است، و هر تغییر سیاست تغییری در رفتار production است که نیاز به بازبینی دارد. یک gateway در مسیر درخواست تأخیر و یک حالت شکست جدید اضافه میکند: اگر gateway در دسترس نباشد، پیشفرض درست ردکردن است، یعنی قطعی در لایهٔ سیاست به قطعی در قابلیتهای agent تبدیل میشود. تیمهایی که این الگو را میپذیرند عموماً این هزینه را میپذیرند چون جایگزین آن قطعیای است که خاموش و بیکران است. معامله، دسترسپذیری قابلیت در برابر کرانداری قابلیت است.
سازش دومی هم هست که ارزش نامبردن دارد. اسکیماهای سختگیرانه و allowlistهای باریک فضای کنشهایی را که agent میتواند انجام دهد کاهش میدهند، که میتواند سودمندی آن را در وظایفی که پیشبینی نشدهاند کاهش دهد. کاهش این اثر نه شلکردن مرز است بلکه سریع و قابلبازبینیکردن تغییرات سیاست است، تا مرز بتواند عامدانه جابهجا شود نه اینکه بهطور پنهانی گسترش یابد.

کنترلی که نتوان برایش شاهد آورد کنترلی است که زیر سؤال خواهد رفت. هر تصمیم سیاست، چه allow و چه deny، باید رکوردی منتشر کند که برای بازسازی استدلال بدون دسترسی به سیستم زنده کافی باشد. آن رکورد شامل درخواست، تصمیم، reason code، نسخهٔ سیاست و امضایی بر سریالسازی متعارف تصمیم است.
امضا به دلیلی مشخص اهمیت دارد: رکورد را دستکاریآشکار و قابلانتساب به نقطهٔ اجرا میکند نه به خط لولهٔ logging. یک خط log را میتوان ویرایش، حذف یا بازچینش کرد. یک رکورد تصمیم امضاشده را میتوان مستقلاً تأیید کرد، و شکاف در توالی قابلتشخیص است.
نگهداشتن نسخهٔ سیاست در کنار تصمیم چیزی است که رفتار گذشته را دوباره قابلتوضیح میکند. سیاستها تغییر میکنند. تصمیمی که تحت یک bundle درست بود ممکن است تحت bundle بعدی نادرست باشد. بدون نسخه، یک بازرس که کنشی تاریخی را بررسی میکند باید حدس بزند کدام قواعد در جریان بودهاند. با نسخه، همان evaluator میتواند در برابر درخواست ثبتشده بازپخش شود و تصمیم را دقیقاً بازتولید کند. این یک بازرسی را از یک مصاحبه به یک تأیید تبدیل میکند.
ردها همان نگهداری allowها را شایستهاند. یک رد شاهدی است بر اینکه مرز کار کرد. همچنین سیگنال اصلی برای تنظیم سیاست است: ردی که پیوسته در برابر کار مشروع فعال میشود نشاندهندهٔ قاعدهای است که بیش از حد گسترده است، و ردی که هرگز در دستهای از نشستها فعال نمیشود ممکن است نشاندهندهٔ قاعدهای دستنیافتنی باشد. نگهداشتن هر دو سو سطح سیاست را رصدپذیر میکند بدون آنکه آن را مشورتی کند.
قطعهٔ پایانی آزمودن تغییرات سیاست در برابر traceهای ثبتشده پیش از استقرار است. اگر تصمیمها همراه با درخواستهایشان ثبت شوند، آنگاه یک policy bundle نامزد میتواند بهصورت آفلاین در برابر مجموعهای از فراخوانیهای واقعی تاریخی ارزیابی شود. خروجی یک diff است: کدام فراخوانیهای پیشتر مجاز اکنون رد میشوند، و کدام فراخوانیهای پیشتر ردشده اکنون مجاز میشوند. آن diff توسط همان افرادی که سیاست را بازبینی میکنند قابلبازبینی است، و یک تغییر سیاست را از یک عمل قضاوت به یک عمل اندازهگیری تبدیل میکند. همچنین مواردی را که هیچکس پیشبینی نکرده بود آشکار میکند، که معمولاً همانجایی است که رگرسیونهای سیاست زندگی میکنند.
این تفاوت عملی میان رصدپذیری و حاکمیت است. رصدپذیری رکوردی از آنچه رخ داد تولید میکند. حاکمیت مرزی تولید میکند که آنچه میتواند رخ دهد را مقید میکند، بههمراه رکوردی از تصمیمهای مرز که میتواند مستقلاً تأیید شود. اولی برای بهرهبرداری از یک سیستم ضروری است. دومی برای تفویض اختیار به آن ضروری است.
این چه پیامدی برای طراحی سیستم دارد
مرز ابزار را بهعنوان control plane در نظر بگیرید. evaluator سیاست را بیرون از دسترس مدل قرار دهید. اسکیما را خط اول دفاع کنید و بگذارید فراخوانیهای بدشکل fail-closed شوند. تصمیمهای امضاشده برای هر دو نتیجه منتشر کنید و نسخهٔ سیاست را پیوست نگه دارید. سیاستهای نامزد را پیش از رسیدن به production در برابر ترافیک ثبتشده بازپخش کنید.
هیچیک از اینها جایگزین رصدپذیری نمیشود. traceها، metricها و داشبوردها همچنان روش درک و بهبود یک سیستم باقی میمانند. آنچه تغییر میکند ترتیب است: مرز تصمیم میگیرد، رکورد اثبات میکند، و داشبورد توضیح میدهد. سیستمی که به این شکل اداره شود به درستانتخابکردن مدل وابسته نیست. به ناتوانی مدل در انتخاب جز آن وابسته است.
