مدلهای تصمیم جدید در واقع چه کاری انجام میدهند
مدل تصمیم یک طبقهبند کوچک و سریع است که میان شاخهها انتخاب میکند. در سیستمهای عاملی، به پرسشهایی پاسخ میدهد مانند: کدام ابزار باید این درخواست را مدیریت کند، آیا برنامهریز باید ادامه دهد یا ارجاع دهد، کدام زیرعامل باید وظیفه را دریافت کند. مدل اعتبارنامه، بودجه یا حالت پایدار نگه نمیدارد. یک برچسب یا یک انتخاب ساختاریافته صادر میکند. سپس آن انتخاب توسط فراخوانی که آن چیزها را در اختیار دارد، اجرا میشود.
بودجههای تأخیر مدل را مجبور میکنند نمای فشردهای از اجرا ببیند. برای بازگرداندن یک تصمیم در زمان زیر یک ثانیه، روتر یک خلاصه دریافت میکند: نوبتهای اخیر، توصیف وظیفه، شاید فهرستی از ابزارهای موجود. کل رد اجرا، هزینه انباشته، اختیارات کاربر یا اثرات جانبی پاییندستی شاخههای قبلی را نمیبیند. تصمیماتش بهطور ساختاری دارای اتلاف هستند. این یک نقص نیست؛ این همان بدهبستان طراحی است که روتر را بهقدر کافی ارزان میکند تا مکرراً فراخوانی شود. اما به این معناست که روتر نمیتواند مؤلفهای باشد که یک محدودیت را تضمین میکند.
بنچمارکهای منتشرشده برای این مدلها دقت مسیریابی را روی مجموعههای وظیفه نگهداشتهشده اندازه میگیرند. آنها مهار را اندازه نمیگیرند: اینکه آیا یک شاخه اشتباه میتواند باعث یک اقدام غیرمجاز شود، از بودجه فراتر رود یا داده را افشا کند. دقت و مهار ویژگیهای متفاوتی هستند. یک روتر میتواند بسیار دقیق باشد و همچنان یک نقطه اعمال ناامن باشد اگر فراخوان خروجی آن را معتبر بداند.
خطای مقولهای: مسیریابی در برابر اعمال
اعمال نیازمند مؤلفهای است که بتواند رد کند. روتر توصیه میکند؛ اعمالکننده رد میکند. اگر روتر مشورتی باشد، فراخوان تصمیم میگیرد که آیا توصیه را دنبال کند. اگر روتر معتبر باشد، به یک رد حسابرسی، راهی برای احراز هویت ورودیهایش و یک حالت خرابی که هنگام اشتباه مدل ایمن باشد نیاز دارد. بیشتر مدلهای تصمیم هیچکدام از اینها را فراهم نمیکنند. آنها نقاط تصمیم سیاست به معنای XACML نیستند، که یک درخواست را در برابر یک سیاست ارزیابی میکنند و یک تصمیم اجازه یا رد با تعهدات بازمیگردانند. یک مدل تصمیم یک برچسب شاخه بازمیگرداند. تفاوت معنایی نیست؛ معماری است.

یک مکانیزم مشخص را در نظر بگیرید. فرض کنید یک روتر بین ابزار read_file و ابزار write_file انتخاب میکند. روتر یک نمای فشرده میبیند: کاربر خواسته است «پیکربندی را بهروزرسانی کن». write_file را انتخاب میکند. اگر فراخوان آن را بهعنوان مجوز تلقی کند، نوشتن انجام میشود. روتر هرگز بررسی نکرده که آیا کاربر دسترسی نوشتن دارد، آیا فایل محافظتشده است یا آیا تغییر از بودجه فراتر میرود. آن بررسیها متعلق به یک اعمالکننده پاییندستی است. اگر اعمالکننده غایب باشد، حالت خرابی حذف نمیشود؛ از دقت روتر به اعتماد فراخوان منتقل میشود.
بدهبستان صادقانه این است که اعمال تأخیر و پیچیدگی اضافه میکند. یک اعمالکننده پاییندستی باید سیاست را ارزیابی کند، که ممکن است نیازمند جستجوی حالت، بررسیهای رمزنگاری یا فراخوانیهای خارجی باشد. این هزینه دلیلی است که تیمها وسوسه میشوند اعمال را در روتر ادغام کنند. اما یک طبقهبند سریع نمیتواند وزن یک موتور سیاست را بدون تبدیل شدن به آن حمل کند، و در آن نقطه دیگر یک روتر ۲B نیست.
یک قاعده جایگذاری: داخل حلقه برنامهریز، هرگز روی مسیر خروجی
مدلهای تصمیم را داخل حلقه برنامهریز قرار دهید، جایی که میتوانند طرح را قبل از وقوع هر اثر جانبی شکل دهند. هرگز آنها را روی مسیر خروجی قرار ندهید، جایی که خروجیشان مستقیماً یک اقدام خارجی را فعال میکند. حلقه برنامهریز میتواند یک شاخه اشتباه را تحمل کند زیرا طرح همچنان در معرض بازبینی، شبیهسازی یا یک اعمالکننده پاییندستی است. مسیر خروجی نمیتواند.
هر روتر را با یک اعمالکننده پاییندستی که بسته شکست میخورد جفت کنید. اعمالکننده باید مؤلفهای جداگانه با سیاست خودش، اعتبارنامه خودش و گزارش حسابرسی خودش باشد. باید بتواند یک اقدام را رد کند حتی اگر روتر آن را توصیه کرده باشد. اعمالکننده باید بسته شکست بخورد: اگر نتواند سیاست را ارزیابی کند، رد میکند. این نقطه مقابل حالت خرابی روتر است، که حدس زدن است.
عکس فوری ورودی روتر را ثبت کنید، نه فقط برچسب خروجی آن را. عکس فوری ورودی همان نمای فشردهای است که مدل واقعاً دیده است. بدون آن، یک شاخه اشتباه غیرقابل توضیح است. با آن، میتوانید بازسازی کنید که چرا روتر آنگونه انتخاب کرده و آ

پیامدهای ارزیابی
ارزیابیهای روتر به ورودیهای خصمانه نیاز دارند، نه مجموعههای وظیفه نگهداشتهشده. یک مجموعه نگهداشتهشده اندازه میگیرد که روتر چند وقت یکبار با یک برچسب موافق است. یک مجموعه خصمانه اندازه میگیرد که وقتی روتر اشتباه میکند چه اتفاقی میافتد: آیا شاخه اشتباه باعث آسیب میشود، یا اعمالکننده آن را میگیرد؟ پرسش دوم همان است که برای ایمنی اهمیت دارد.
هزینه یک شاخه اشتباه را اندازه بگیرید، نه دقت شاخه را. برای هر مسیریابی اشتباه ممکن، بدترین نتیجه را تخمین بزنید: یک نوشتن غیرمجاز، یک فراتر رفتن از بودجه، یک نشت داده، یک حلقه گیرکرده. اگر هزینه توسط یک اعمالکننده پاییندستی محدود شود، دقت روتر یک معیار عملکرد است. اگر هزینه نامحدود باشد، روتر یک نقطه اعمال در لباس مبدل است، و این یک نقص طراحی است.
این هدف ارزیابی را بازقالببندی میکند. بهجای پرسیدن «روتر چند وقت یکبار ابزار درست را انتخاب میکند؟»، بپرسید «شعاع انفجار وقتی ابزار اشتباه را انتخاب میکند چقدر است؟» پاسخ تعیین میکند که آیا روتر میتواند ارزان و دارای اتلاف باشد یا آیا باید با یک نقطه تصمیم سیاست جایگزین شود.
این برای معماریهای عاملی چه معنایی دارد
مدلهای تصمیم مانند Strands Decider آمازون و Clef کلادفلر ابتداییهای مسیریابی مفیدی هستند. هزینه شاخهبندی را کاهش میدهند و حلقههای عامل را پاسخگوتر میکنند. اما آنها سطوح کنترل نیستند. برخورد با آنها بهعنوان چنین چیزی، حالت خرابی را جابهجا میکند نه اینکه آن را حذف کند. الگوی درست یک الگوی لایهای است: یک روتر سریع و دارای اتلاف داخل حلقه برنامهریز، یک اعمالکننده پاییندستی که بسته شکست میخورد، و یک رد حسابرسی که عکس فوری ورودی روتر را ثبت میکند. این الگو محدودیتهای روتر را میپذیرد و بار اعمال را جایی میگذارد که به آن تعلق دارد.
بدهبستان صریح است: شما برای اعمال با تأخیر و پیچیدگی پرداخت میکنید، و مهار به دست میآورید. نمیتوانید مهار را از یک طبقهبندی به دست آورید که هرگز حالت کامل را نمیبیند و نمیتواند رد کند. کار مهندسی این است که روتر را جایی قرار دهید که تصمیمات دارای اتلافش ایمن باشند، و اعمالکنندهای بسازید که بقیه را بگیرد.
