مجموعه سؤال مرجع آماده است، اما هنوز مقایسه تغییرها دستی انجام میشود: چند سؤال را در چت میفرستیم، پاسخها را نگاه میکنیم و حس میکنیم نسخه تازه بهتر شده است. این روش برای پیدا کردن ایده مفید است، ولی برای تصمیم انتشار کافی نیست. ممکن است سؤالها، اسناد یا تنظیمات بین دو بار اجرا عوض شده باشند.
در بخش قبل، پوشش داده، منشأ و روبریک را مشخص کردیم. حالا یک ابزار اجرای کوچک میسازیم که ورودی ثابت را بخواند، پاسخ هر مورد را بگیرد و نتیجه قابل بررسی ذخیره کند. نمونه با Python و پاسخدهنده آزمایشی اجرا میشود؛ در این مقاله هیچ مدل واقعی فراخوانی و هیچ امتیاز کیفیت مدلی گزارش نمیشود.
ابزار اجرا را از داوری جدا کنیم
ابزار اجرا یا harness مسئول خواندن نمونه، فراخوانی پاسخدهنده، ثبت زمان و ذخیره نتیجه است. داور مشخص میکند پاسخ بر اساس چه معیاری پذیرفته میشود. اگر این دو را مخلوط کنیم، تغییر مدل یا روبریک میتواند ثبت نتیجه را هم بیدلیل عوض کند.
برای دستیار نمونه، پاسخ ساختاری شامل رفتار انتخابشده، متن و شناسه منابع است. رفتار میتواند پاسخ، سؤال تکمیلی یا خودداری باشد. در این مرحله فقط بخشی از قرارداد را خودکار بررسی میکنیم؛ درستبودن معنایی هر ادعا همچنان به داور مناسب و بازبینی نیاز دارد.
ورودی نسخهدار و شناسه پایدار لازم است
هر سؤال باید شناسه داشته باشد تا نتیجه دو اجرا را به همان نمونه وصل کنیم. علاوه بر فایل سؤال، نسخه اسناد و تنظیمات بازیابی را ثبت کنید. اگر مدل نام مستعار متغیر دارد، تا جایی که ارائهدهنده اجازه میدهد مشخصات نسخه و تنظیمات واقعی را هم نگه دارید.
هش فایل داده میتواند نشان دهد دو اجرا دقیقاً از یک فایل استفاده کردهاند، اما بهتنهایی منشأ یا کیفیت داده را ثابت نمیکند. اطلاعات گردآوری و محدودیتها از بخش قبل همچنان لازماند. شناسه اجرا و زمان شروع هم کمک میکنند خروجیها اشتباهی روی هم نوشته نشوند.
سه نتیجه متفاوت داشته باشیم
اگر پاسخ معتبر است ولی انتظار را برآورده نمیکند، شکست معیار داریم. اگر فراخوانی پاسخدهنده با خطای ارتباط یا اجرا متوقف شود، خطای اجرا داریم. نتیجه پذیرفتهشده نیز حالت سوم است. یکیکردن اینها باعث میشود معلوم نباشد افت نتیجه از کیفیت پاسخ آمده یا از خرابی مسیر.
| وضعیت | معنا در ابزار نمونه | نمونه |
|---|---|---|
pass | شرطهای محدود داور برقرارند | رفتار و منابع مطابق قرارداد |
fail | پاسخ دریافت شده ولی شرط برقرار نیست | منبع نامجاز یا قالب نامعتبر |
error | پاسخدهنده نتیجه نداده است | استثنای اجرایی یا قطع ارتباط |
عبارت pass در این نمونه به معنی «تمام پاسخ از نظر معنایی درست است» نیست. هر داور باید دقیق بگوید چه چیزی را بررسی کرده و چه چیزی را پوشش نمیدهد.
هسته کوچک ارزیابی
تابع زیر پاسخدهنده را بهعنوان ورودی میگیرد. میتوان برای آزمون ابزار، یک تابع ساختگی و بعداً برای اجرای واقعی، یک تطبیقدهنده مجاز مدل به آن داد. این جداسازی باعث میشود پیش از مصرف سرویس بیرونی، ثبت خطا و نتیجه را بررسی کنیم.
from time import perf_counter
def evaluate(case, answerer):
started = perf_counter()
try:
actual = answerer(case['question'])
except Exception as exc:
return {'id': case['id'], 'status': 'error',
'error_type': type(exc).__name__,
'latency_ms': (perf_counter() - started) * 1000}
valid = (isinstance(actual, dict)
and isinstance(actual.get('text'), str)
and isinstance(actual.get('sources'), list)
and all(isinstance(s, str) for s in actual['sources']))
passed = (valid
and actual.get('behavior') == case['expected_behavior']
and set(actual['sources']) <= set(case['allowed_sources'])
and set(case['required_sources']) <= set(actual['sources']))
return {'id': case['id'],
'status': 'pass' if passed else 'fail',
'latency_ms': (perf_counter() - started) * 1000}
این داور فقط شکل بخشهایی از پاسخ، رفتار انتخابشده و محدوده شناسه منابع را میسنجد. اگر مدل منبع درست را ذکر کند ولی جمله غلط بنویسد، ممکن است از این بررسی عبور کند. برای پوشش آن خطا، داور ادعا و شاهد لازم است؛ وجود لینک با پشتیبانی واقعی یکی نیست.
خطای ابزار را پیش از کیفیت مدل بررسی کنیم
با پاسخدهنده آزمایشی، چهار حالت بسازید: پاسخ مطابق قرارداد، رفتار اشتباه، منبع خارج از فهرست و استثنای اجرایی. قالب ناقص را هم بررسی کنید. اگر ابزار این حالتها را اشتباه دستهبندی کند، امتیاز هر مدل روی آن قابل اعتماد نخواهد بود.
نمونه این مقاله با همین حالتهای ساختگی اجرا شده است. این آزمون فقط منطق ابزار را میسنجد، نه توانایی یک مدل زبانی. زمان ثبتشده نیز زمان تابع آزمایشی محلی است و نباید بهعنوان تأخیر سرویس AI یا بنچمارک محصول معرفی شود.
نتیجه هر نمونه را جدا ذخیره کنیم
یک فایل JSONL که هر خطش نتیجه یک نمونه است، برای شروع کافی است. شناسه اجرا، شناسه سؤال، وضعیت، زمان و نسخه داور را نگه دارید. اگر ثبت متن پاسخ برای بازبینی لازم است، سیاست نگهداری و دسترسی آن را مشخص کنید و داده حساس را بیدلیل وارد لاگ نکنید.
در نمونه ساده، پیام کامل استثنا ذخیره نمیشود؛ فقط نوع آن ثبت میشود. در اجرای واقعی ممکن است برای تشخیص مشکل به کد خطا یا شناسه درخواست نیاز داشته باشید. این اطلاعات باید کنترلشده اضافه شوند، چون پیام خطا گاهی شامل داده ورودی یا نشانیهای داخلی است.
میانگین کل را کنار گروهها بخوانیم
پس از اجرا، نتیجه را برای سؤالهای مستقیم، مبهم و فاقد شاهد جدا گزارش کنید. اگر نسخه تازه در سؤالهای آسان بهتر و در خودداری بدتر شده، یک عدد کل ممکن است معامله را پنهان کند. تعداد نمونه هر گروه نیز باید کنار نتیجه باشد.
خطاهای اجرا را از گزارش حذف نکنید تا درصد نتیجه بهتر به نظر برسد. میتوان هم موفقیت کل مسیر و هم نتیجه مشروط به دریافت پاسخ معتبر را گزارش کرد، به شرط اینکه مخرج هر معیار روشن باشد. نام معیار باید معنایش را توضیح دهد و بهاشتباه «دقت» نامیده نشود.
تکرار را با ثابتبودن کامل اشتباه نگیریم
خروجی مدل ممکن است بین اجراها تغییر کند. تنظیم بعضی پارامترها میتواند پراکندگی را کم کند، ولی نباید بدون تضمین مشخص، نتیجه را کاملاً قطعی فرض کنیم. برای تغییرهای مهم، چند اجرای مستقل روی داده ثابت میتواند به فهم نوسان کمک کند.
در گزارش، تعداد اجرا و روش جمعبندی را بنویسید. انتخاب بهترین اجرای هر نسخه و کنارگذاشتن بقیه، مقایسه منصفانهای نیست. اگر اختلاف دو نسخه کوچکتر از نوسان معمول است، باید با احتیاط بیشتری نتیجه گرفت یا داده بیشتری جمع کرد.
هر بار فقط یک تغییر اصلی را مقایسه کنیم
اگر همزمان مدل، روش برش سند و پرامپت عوض شوند، فهم علت تغییر نتیجه دشوار میشود. برای آزمایش تشخیصی، یک عامل اصلی را تغییر دهید و بقیه شرایط را ثبت و تا جای ممکن ثابت نگه دارید. آزمایش ترکیبی هم میتواند لازم باشد، اما باید هدفش روشن باشد.
نمونههای شکست را با شناسه نگه دارید تا بازبین بتواند به آنها برگردد. یک دستهبندی ساده مثل بازیابی نامرتبط، ادعای فاقد شاهد و خطای قالب، از جمعکردن همه مشکلها در برچسب «پاسخ بد» کاربردیتر است.
قدم بعدی ابزار
برای تمرین، یک نمونه مبهم به داده اضافه کنید و انتظار رفتار پرسش تکمیلی را ثبت کنید. سپس پاسخدهنده آزمایشی را طوری تغییر دهید که بهاشتباه جواب قطعی بدهد؛ نتیجه باید fail شود. یک استثنا هم بسازید و مطمئن شوید در گروه error باقی میماند.
در بخش بعد، پاسخ ساختاری را تا مرز اعتبارسنجی دنبال میکنیم: Schema، خروجی ناقص و رفتار جایگزین. آن بخش داور ساده این مقاله را کاملتر میکند، بدون اینکه بررسی قالب را با تضمین درستی معنایی یکی بداند.
منابع فنی
- مستندات perf_counter در Python برای اندازهگیری فاصله زمانی.
- مستندات JSON در Python 3.13 برای ذخیره و خواندن نتیجه ساختاری.
- راهنمای ارزیابی Anthropic برای تفکیک آزمون، اجرا و داوری.
