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

چه چیزی را اندازه بگیریم
تزریق خطا بدون اندازهگیری، حکایت تولید میکند. اندازهگیریهایی که اهمیت دارند همانهایی هستند که به شما میگویند آیا مسیر بازیابی یک رفتار طراحیشده است یا یک تصادف.
- زمان بازیابی. ایجنت چقدر طول میکشد، بر حسب زمان واقعی یا نوبتهای مدل، تا پس از خطا به وضعیت پایدار برسد. بازیابیای که بیش از مهلت خود وظیفه طول بکشد، بازیابی نیست.
- گامهای مصرفشده برای بازیابی. چند فراخوانی ابزار و چرخه برنامهریزی صرف خطا میشود. ایجنتی که بازیابی میکند اما کل بودجه گامش را میسوزاند، ظرفیتی برای وظیفه باقی نگذاشته است.
- وضعیت پایانی. آیا اجرا در وضعیت ایمن پایان مییابد. ایمن یعنی اثرات جانبی یا بهدرستی تعهد شدهاند یا اصلاً تعهد نشدهاند، و به کاربر گفته میشود کدام. اجرایی که با یک نوشتن ناقص و یک پیام موفقیت پایان مییابد، شکست است صرفنظر از اینکه چقدر زیبا بازیابی کرده باشد.
- واگرایی مسیر. پس از هر خطای تزریقشده، مسیر برنامهریزیشده را با مسیر اجراشده مقایسه کنید. واگرایی بهطور خودکار بد نیست، اما واگرایی اندازهگیرینشده بد است. اگر ایجنت بیصدا برنامه را تغییر دهد، توانایی استدلال درباره رفتارش را از دست دادهاید.
این اندازهگیریها یک امتیاز واحد نیستند. یک پروفایل هستند. اجرایی که سریع بازیابی میکند اما ناایمن پایان مییابد، بدتر از اجرایی است که بیشتر طول میکشد و تمیز پایان مییابد. پروفایل به شما اجازه میدهد این بدهبستان را صریح انجام دهید.
یک مکانیزم مشخص: هارنس تزریق خطا
مکانیزمی که این را تکرارپذیر میکند، هارنسی است که بین ایجنت و ابزارهایش قرار میگیرد. این یک mock نیست. یک پروکسی است که میتواند یک مجموعه خطا را روی پاسخهای زنده یا ضبطشده ابزار اعمال کند.
class FaultInjector:
def __init__(self, faults, seed):
self.faults = faults
self.rng = random.Random(seed)
def wrap(self, tool):
def call(*args, **kwargs):
fault = self._select(tool.name)
if fault == "timeout":
raise ToolTimeout(tool.name)
if fault == "schema_drift":
return self._mutate_schema(tool(*args, **kwargs))
if fault == "partial":
return self._truncate(tool(*args, **kwargs))

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