eval

ارزیابی ایجنت‌ها — چطور بفهمیم بهتر شده است

چرا «بهتر به نظر می‌رسد» نتیجه نیست: ساختن یک مجموعه‌ی eval کوچک و واقعی، انواع grader، خطاهای LLM-as-judge، جداسازی holdout و پیگیری regression.

· ۹ دقیقه مطالعه

یک نفر prompt سیستمی ایجنت را عوض می‌کند، پنج تا سؤال می‌پرسد، جواب‌ها را می‌خواند و می‌گوید «بهتر شد». تغییر می‌رود روی production. دو هفته بعد کاربری گزارش می‌دهد که کاری که قبلاً درست کار می‌کرد حالا خراب است. هیچ‌کس نمی‌داند کدام تغییر آن را شکسته، چون هیچ‌وقت اندازه‌ای در کار نبوده.

«بهتر به نظر می‌رسد» یک نتیجه نیست. ارزیابی — یا همان eval — کاری است که این جمله را به عددی تبدیل می‌کند که می‌شود دنبالش کرد. این مقاله می‌گوید چطور یک مجموعه‌ی ارزیابی کوچک و صادقانه بسازید، چه نوع grader ی برای چه کاری مناسب است، و چطور جلوی فریب دادن خودتان را بگیرید.

چرا خواندن چند خروجی کافی نیست

سه دلیل مشخص:

نمونه‌ی کوچک و انتخابی. پنج سؤالی که خودتان می‌پرسید همان‌هایی هستند که موقع ساختن سیستم در ذهنتان بوده. حالت‌های سختی که کاربر واقعی می‌سازد در آن پنج تا نیستند.

تصادفی بودن خروجی. مدل زبانی قطعی نیست. همان ورودی می‌تواند دو خروجی متفاوت بدهد. یک بار اجرا کردن، بین «بهتر شد» و «شانس آوردید» تفاوتی نمی‌گذارد.

سوگیری تأیید. وقتی خودتان تغییر را نوشته‌اید، خروجی را با انتظار مثبت می‌خوانید. این را نمی‌شود با تلاش بیشتر خنثی کرد؛ باید معیار بیرونی گذاشت.

اضافه کنید که ایجنت‌ها چندمرحله‌ای‌اند: یک ایجنت که ابزار صدا می‌زند می‌تواند در انتخاب ابزار، در ساختن آرگومان‌ها، یا در تفسیر خروجی ابزار خطا کند. خروجی نهایی این سه را با هم قاطی می‌کند و خواندن متن پایانی نمی‌گوید کدام‌شان شکسته است.

مجموعه‌ی ارزیابی کوچک و صادقانه

یک eval خوب لازم نیست بزرگ باشد. لازم است واقعی و پایدار باشد.

از کجا نمونه بیاورید:

  • گزارش‌های واقعی خطا و شکایت کاربران — گران‌ترین و باارزش‌ترین منبع.
  • log واقعی درخواست‌ها. حالت‌های پرتکرار و حالت‌های عجیب را جدا کنید.
  • مواردی که در آن‌ها می‌دانید سیستم قبلاً شکست خورده است.

هر نمونه باید سه چیز داشته باشد: ورودی، معیار درستی مشخص، و — اگر مهم است — زمینه‌ای که با آن اجرا می‌شود. برای ایجنت، معیار درستی همیشه متن نیست؛ می‌تواند «این ابزار با این پارامتر صدا زده شد» یا «این رکورد در پایگاه داده تغییر کرد» باشد.

سه توصیه که بیشترین اثر را دارند:

  1. موارد شکست را نگه دارید. هر باگی که در production پیدا می‌شود باید قبل از رفع شدن، به eval اضافه شود. این کار مجموعه را خودبه‌خود روی نقاط ضعف واقعی متمرکز می‌کند.
  2. حالت‌های منفی بگذارید. ورودی‌هایی که پاسخ درستشان «نمی‌دانم» یا «این خارج از حوزه‌ی من است» است. سیستمی که فقط با سؤال‌های خوب سنجیده شود، در برابر سؤال بد اعتماد به نفس کاذب نشان می‌دهد.
  3. پاسخ مرجع را انسان تأیید کند. پاسخ درستی که خود مدل تولید کرده باشد، ارزیابی را بی‌معنا می‌کند.

چند ده نمونه‌ی خوب از هزار نمونه‌ی سرهم‌بندی‌شده مفیدتر است. اگر دامنه‌تان فارسی است، متن مرجع را قبل از مقایسه نرمال کنید وگرنه اختلاف در «ی» یا نیم‌فاصله را به‌عنوان خطای مدل خواهید شمرد.

grader ها؛ چه کسی نمره می‌دهد

grader تابعی است که خروجی را با معیار درستی مقایسه می‌کند و نمره می‌دهد. سه دسته دارد و هرکدام جای خودش را دارد.

نوعمناسب برایضعف
تطبیق دقیق / برنامه‌ایخروجی ساختاریافته، کد، عدد، فراخوانی ابزاربرای متن آزاد بی‌استفاده است
rubric انسانیکیفیت، لحن، درستی محتواییکند و گران، به‌درد CI نمی‌خورد
LLM-as-judgeمتن آزاد در مقیاس بزرگخودش خطا دارد و باید کالیبره شود

تطبیق دقیق و بررسی برنامه‌ای را دست‌کم نگیرید. بخش بزرگی از رفتار یک ایجنت قابل بررسی قطعی است: آیا JSON معتبر برگشت؟ آیا ابزار درست انتخاب شد؟ آیا پارامتر اجباری پر شد؟ آیا وقتی داده‌ای نبود، ادعای بی‌پشتوانه نکرد؟ این بررسی‌ها ارزان، سریع و قابل اتکا هستند. هر چیزی که می‌شود این‌طور سنجید، نباید به grader پرهزینه سپرده شود.

rubric یعنی معیار نمره‌دهی مکتوب — مثلاً «صفر اگر ادعای بی‌منبع دارد، یک اگر درست ولی ناقص است، دو اگر کامل و مستند است». نوشتن rubric ارزش دارد حتی وقتی خودتان نمره می‌دهید، چون معیار را از حافظه‌ی لحظه‌ای بیرون می‌آورد و بین دو نفر قابل مقایسه‌اش می‌کند.

LLM-as-judge و جاهایی که خراب می‌شود

استفاده از یک مدل زبانی برای نمره‌دهی به خروجی مدل دیگر عملی و پرکاربرد است، ولی الگوهای خطای شناخته‌شده‌ای دارد که باید حسابشان را بکنید:

  • سوگیری طول. قضاوت‌کننده معمولاً پاسخ بلندتر را کامل‌تر می‌بیند، حتی وقتی نیست.
  • سوگیری موقعیت. وقتی دو پاسخ را برای مقایسه می‌دهید، ترتیبشان روی نتیجه اثر می‌گذارد. راه‌حل ساده: هر جفت را دو بار با ترتیب معکوس بسنجید.
  • سوگیری خودی. مدل به سبک خودش نمره‌ی بهتری می‌دهد. اگر همان مدلی که پاسخ را ساخته قضاوتش هم بکند، نتیجه خوش‌بینانه است.
  • تساهل. بدون rubric صریح، مدل‌ها بیش از حد سخاوتمندند و بیشتر چیزها را «خوب» می‌بینند.
  • ناتوانی در تشخیص خطای واقعیت. اگر پاسخ مرجع را به قضاوت‌کننده ندهید، نمی‌تواند بفهمد یک عدد یا نام غلط است.

قاعده‌های عملی برای اینکه قضاوت‌کننده قابل استفاده شود:

  1. rubric کوتاه و مشخص بدهید، نه دستور مبهم «کیفیت را ارزیابی کن».
  2. پاسخ مرجع را در اختیارش بگذارید.
  3. خروجی ساختاریافته بخواهید — نمره به‌علاوه‌ی دلیل — تا بشود موارد اختلافی را بازبینی کرد.
  4. خود قضاوت‌کننده را ارزیابی کنید. چند ده نمونه را انسان نمره بدهد و ببینید قضاوت‌کننده چقدر با انسان می‌خواند. اگر همخوانی ضعیف است، عددهایش بی‌معناست.
  5. برای قضاوت از مدل قوی‌تر و دما‌ی پایین استفاده کنید. قضاوت‌کننده جایی نیست که هزینه را کم کنید.

جداسازی مجموعه‌ی تنظیم از مجموعه‌ی آزمون

این نقطه‌ای است که بیشتر تیم‌ها ناخواسته خودشان را فریب می‌دهند. اگر همان مجموعه‌ای را که برای بهبود prompt استفاده می‌کنید مبنای گزارش پیشرفت هم بگذارید، عملاً روی آزمون خودتان تنظیم کرده‌اید. عدد بالا می‌رود و رفتار واقعی سیستم بهتر نمی‌شود.

راه درست: مجموعه را از اول به دو بخش تقسیم کنید.

  • مجموعه‌ی توسعه: هرچقدر خواستید رویش تکرار و آزمون‌وخطا کنید.
  • مجموعه‌ی نگه‌داشته (holdout): به‌ندرت اجرا شود — پیش از انتشار نسخه، نه در هر تغییر.

اگر دیدید نمره‌ی مجموعه‌ی توسعه بالا می‌رود و نمره‌ی holdout ثابت مانده، تنظیمات شما دارد به همان نمونه‌ها می‌چسبد، نه به مسئله. وقتی holdout آن‌قدر اجرا شد که تصمیم‌هایتان از رویش گرفته شد، دیگر holdout نیست؛ نمونه‌ی تازه اضافه کنید.

پیگیری regression در طول زمان

ارزیابی یک کار یک‌باره نیست. چیزی که امروز درست است می‌تواند فردا با تغییر prompt، تغییر ابزار، به‌روزرسانی داده یا عوض شدن مدل بشکند.

چیزی که باید بسازید ساده است:

  1. eval را با یک دستور اجرا کنید و خروجی‌اش را ذخیره کنید.
  2. برای هر اجرا، نسخه‌ی prompt، شناسه‌ی مدل، پارامترها و تاریخ را ثبت کنید. بدون این‌ها نمی‌شود فهمید چه چیزی عوض شد.
  3. نمره‌ی کلی و نمره‌ی هر نمونه را نگه دارید. نمره‌ی کلی ثابت می‌تواند دو تغییر متضاد را پنهان کند — چیزی درست شده و چیز دیگری شکسته.
  4. برای مقابله با تصادفی بودن خروجی، نمونه‌های کلیدی را چند بار اجرا کنید و پراکندگی را ببینید.
  5. اجرای eval را به بخشی از فرایند انتشار تبدیل کنید، نه کاری که وقتی یادتان افتاد انجام می‌دهید.

اگر نمی‌توانید بگویید نسخه‌ی امروز نسبت به نسخه‌ی ماه پیش چند نمونه را بهتر و چند نمونه را بدتر حل می‌کند، ایجنت‌تان را نمی‌سنجید — فقط تماشایش می‌کنید.

جمع‌بندی: با بیست نمونه‌ی واقعی شروع کنید، هر باگ را به مجموعه اضافه کنید، هرچه قابل بررسی برنامه‌ای است را برنامه‌ای بسنجید، LLM-as-judge را قبل از اعتماد کالیبره کنید، holdout را دست‌نخورده نگه دارید، و نتیجه‌ی هر اجرا را با نسخه‌ی prompt و مدل ثبت کنید. این کاری است که ما هم در ساخت رونا ایجنت با آن درگیریم و کوتاه آمدن در آن همیشه بعداً گران‌تر تمام می‌شود.