
هر تیمی که روی جستوجوی یک فروشگاه اینترنتی کار میکند، دیر یا زود با این پرسش روبهرو میشود. از BM25 به جستوجوی برداری رفتهاید، یک مرحلهی رتبهبندی دوباره (reranker) اضافه کردهاید یا بازنویسی پرسش را فعال کردهاید. عددهای ارزیابی آفلاین هم کمی بالا رفتهاند. اما آیا این بهبود واقعی است، یا حاصل نویز، برچسبهای ناقص و یک داور یکطرفه؟
در این یادداشت روشی را توضیح میدهم که برای پاسخ دادن به همین پرسش به کار میبرم و آن را در یک ابزار متنباز پایتون به نام llm-search-eval پیاده کردهام (کد منبع در GitHub). تمرکز یادداشت روی ایدههاست، نه روی خود ابزار: این ایدهها در هر سامانهی ارزیابی جستوجو قابل پیادهسازیاند.
ارزیابی آفلاین جستوجو یعنی مجموعهای از پرسشها، فهرستی از محصولات و برچسبهایی که میگویند هر محصول برای هر پرسش چقدر مرتبط است. سامانهها روی همین پرسشها اجرا میشوند و نتیجهشان با معیارهای بازیابی اطلاعات سنجیده میشود. در عمل، این روش معمولاً در پنج جا میلنگد:
برچسبها تمام میشوند. مجموعهی طلایی (gold set) که فصل پیش برچسب خورده، محصولاتی را که بازیاب جدید امروز پیدا میکند پوشش نمیدهد. نتیجههای بدون برچسب بیصدا «نامرتبط» حساب میشوند و سامانهی جدید بدتر از واقعیت دیده میشود.
میانگینها نویز را پنهان میکنند. دو درصد بهبود nDCG روی پنجاه پرسش بهراحتی میتواند تصادفی باشد.
یک مدل، یک نظر است. یک داور مدل زبانی سوگیریهای خودش را دارد و معمولاً کسی بررسی نمیکند که چقدر با برچسبگذارهای انسانی همنظر است.
هزینه بیصدا بالا میرود. داوری هزاران جفت «پرسش ـ محصول» با یک مدل بزرگ گران است و معمولاً تا رسیدن صورتحساب کسی متوجه نمیشود.
کاتالوگهای چندزبانه نامرتباند. متن فارسی ترکیبی از حروف عربی و فارسی، چند نظام رقم و نیمفاصله است و تطبیق ساده را خراب میکند.
اولین تصمیم طراحی این است که برچسب انسانی همیشه بر داوری مدل اولویت دارد. داور مدل زبانی فقط جفتهایی را داوری میکند که در نتیجههای برتر یکی از سامانهها آمدهاند و برچسب طلایی ندارند. به این ترتیب مشکل «شکاف برچسب» حل میشود، بدون اینکه برچسبهای قابلاعتماد انسانی کنار گذاشته شوند.
نکتهی مهم دیگر این است که همهی سامانهها روی یک مخزن برچسب مشترک سنجیده شوند. اگر محصولی برای سامانهی B داوری شده، همان برچسب برای سامانهی A هم به کار میرود. در غیر این صورت مقایسه منصفانه نیست.
برچسبها درجهبندیشدهاند: از ۰ (نامرتبط) تا ۳ (کاملاً مرتبط). برای معیارهای دودویی، درجهی ۲ و بالاتر بهطور پیشفرض «مرتبط» حساب میشود.
بهجای یک مدل، میتوان چند مدل را بهعنوان «هیئت داوران» به کار برد و رأیها را با یکی از قاعدههای اکثریت، میانگین، میانه، کمینه یا بیشینه ترکیب کرد. اگر یکی از داوران خطا بدهد (مثلاً timeout)، جفت از دست نمیرود، به شرط اینکه حداقل تعداد رأی لازم جمع شده باشد.
اما هیئت داوران تنها وقتی ارزش دارد که توافق آنها اندازهگیری شود. آمارههایی که در این روش گزارش میشوند:
سهم اتفاق آرا: جفتهایی که همهی داوران درجهی یکسان دادهاند.
کاپای فلایس (Fleiss' kappa): توافق اصلاحشده برای شانس، برای هر تعداد داور.
آلفای کریپندورف (Krippendorff's alpha): با نسخههای اسمی، ترتیبی و فاصلهای. برای درجههای ۰ تا ۳، نسخهی ترتیبی آموزندهترین است و رأیهای گمشده را هم تحمل میکند.
کاپای کوهن دوبهدو: ساده و وزندار درجهدوم برای هر جفت داور.
بهعنوان یک قاعدهی سرانگشتی، کاپا یا آلفای بالای ۰٫۸ توافق قوی، بین ۰٫۶ و ۰٫۸ توافق قابلتوجه، و زیر ۰٫۴ نشانهی این است که دستورالعمل داوری یا مدلها نیاز به اصلاح دارند.
پرسش مهمتر این است که داور چقدر با انسان همنظر است. در حالت واسنجی (calibration)، جفتهایی که برچسب طلایی دارند هم به داور فرستاده میشوند. امتیازها همچنان با برچسب طلایی محاسبه میشوند و داوریهای اضافه فقط برای جدول توافق به کار میروند. این جدول شامل توافق دقیق، توافق با اختلاف حداکثر یک درجه، توافق دودویی در آستانهی ارتباط، کاپای کوهن و کاپای وزندار، سوگیری میانگین (مثبت یعنی داور از انسان سهلگیرتر است) و ماتریس درهمریختگی است. برای کنترل هزینه میتوان فقط یک نمونهی تصادفی تکرارپذیر از جفتها را واسنجی کرد.
معیارهای کلاسیک بازیابی اطلاعات پایهی کارند: nDCG@k با بهرهی نمایی (2^rel − 1) یا خطی، دقت@k، بازخوانی@k، MRR و MAP. اما گزارش میانگین بهتنهایی کافی نیست.
هر سامانه با سامانهی پایه با یک آزمون تصادفیسازی جفتی دوطرفه (sign-flip) روی مقدار هر پرسش از معیار اصلی مقایسه میشود. این آزمون فرض نرمال بودن ندارد و انتخاب رایج در ارزیابی بازیابی اطلاعات است. کنار آن، برای هر میانگین و هر اختلاف، فاصلهی اطمینان بوتاسترپ و شمار برد، تساوی و باخت پرسشها گزارش میشود.
یک جزئیات روششناختی مهم: پرسشی که در مخزن برچسب هیچ محصول مرتبطی ندارد، معیارهایش تعریفنشده است. چنین پرسشی بهجای اینکه صفر حساب شود از میانگین کنار گذاشته میشود و تعداد پرسشهای واقعاً شمردهشده (n) برای هر میانگین ثبت میشود.
وقتی دو سامانه از نظر nDCG نزدیکاند یا برچسبها کماند، داوری دوبهدو (pairwise) یک نظر دوم مفید است. در این روش داور برای هر پرسش، k نتیجهی برتر دو سامانه را کنار هم میبیند و میگوید خریدار کدام فهرست را ترجیح میدهد: A، B یا تساوی.
مدلهای زبانی سوگیری جایگاه دارند و گاهی گزینهی اول را ترجیح میدهند. برای خنثی کردن آن، هر پرسش دو بار داوری میشود: یک بار A اول و یک بار B اول. سامانه فقط وقتی پرسش را میبرد که هر دو ترتیب همنظر باشند؛ اگر دو ترتیب برندهی متضاد انتخاب کنند، پرسش «ناسازگار» ثبت میشود که خودش معیاری از پایداری داور است. نتیجه با نرخ برد، فاصلهی ویلسون و آزمون علامت گزارش میشود.
دو موضوع عملی اغلب نادیده گرفته میشوند:
هزینه. مصرف توکن برای هر مدل شمرده میشود، قیمت را کاربر تعیین میکند و میتوان برای هزینه، توکن یا تعداد داوری سقف گذاشت. پیش از اجرا هم میتوان تعداد فراخوانی، توکن و هزینه را تخمین زد. یک حافظهی نهان مبتنی بر محتوا باعث میشود اجرای دوباره هزینهی تکراری نداشته باشد.
منشأ (provenance). نتیجهی داور مدل زبانی به سه چیز بستگی دارد: مدل، ارائهدهنده و متن پرامپت. از نسخهی 0.4.0 هر پرامپت یک نسخهی دستی و یک هش دارد: ۱۲ نویسهی اول SHA-256 روی متن کامل پرامپت. این هش بخشی از کلید حافظهی نهان است، پس داوریای که با پرامپت دیگری انجام شده هرگز از حافظهی نهان برنمیگردد. در تغییرات منتشرنشدهی بعدی، نسخهی تاریخدار مدلی که ارائهدهنده واقعاً پاسخ داده هم ثبت میشود و اگر در یک اجرا چند نسخه از یک مدل دیده شود، گزارش هشدار میدهد که امتیازها مستقیماً قابل مقایسه نیستند. دلیلش این است که ارائهدهندهها گاهی مدل را بیصدا بهروز میکنند.
مشکلات خاص متن فارسی در جستوجو را پیشتر در یادداشت «ی عربی، نیمفاصله و PDF برعکس» شرح دادهام؛ اینجا فقط به اثر آنها بر ارزیابی میپردازم.
برای پرسشهای فارسی، پیش از تطبیق، «ي» و «ك» عربی به «ی» و «ک» فارسی تبدیل میشوند، ارقام فارسی و عربی یکسان میشوند، اعراب، کشیده و نویسههای جهت حذف میشوند و نیمفاصله مرز کلمه حساب میشود. زبان پرسش اگر مشخص نشده باشد از روی خط تشخیص داده میشود و گزارش، معیار اصلی را به تفکیک زبان نشان میدهد. پرامپت داور هم زبان پرسش را ذکر میکند و ترجمه یا نویسهگردانی میان فارسی و انگلیسی را تطابق حساب میکند؛ مثلاً پرسش «گوشی سامسونگ» با محصولی به نام Samsung Galaxy.
مخزن پروژه یک کاتالوگ کوچک دوزبانهی لوازم الکترونیکی با سه سامانه برای مقایسه دارد. با داور شبیهساز (mock)، که قطعی است و برای CI و اجرای آفلاین ساخته شده، میتوان بدون هیچ هزینهای اجرا کرد:
pip install llm-search-eval llm-search-eval run \ --queries examples/electronics/queries.jsonl \ --products examples/electronics/products.jsonl \ --qrels examples/electronics/qrels.csv \ --system bm25=examples/electronics/runs/bm25.jsonl \ --system semantic=examples/electronics/runs/semantic.csv \ --system hybrid=examples/electronics/runs/hybrid.trec \ --judge mock --output-dir reports/
در این دادهی نمونه، nDCG@10 برای bm25 برابر 0.5305، برای semantic برابر 0.9865 و برای hybrid برابر 0.9767 است. این عددها فقط برای نمایش کارکرد ابزار روی یک دادهی کوچک نمونهاند و نباید بهعنوان مقایسهی عمومی روشها خوانده شوند.
برای داور واقعی کافی است داور، قیمت و سقف بودجه را مشخص کنید:
llm-search-eval run ... --judge openai=gpt-4o-mini \ --cache .judge-cache.jsonl --price gpt-4o-mini=0.15,0.60 --max-cost 2
خروجی شامل گزارش Markdown و JSON، یک داشبورد HTML مستقل (بدون سرور و CDN)، گزارش هزینه و فایل همهی داوریهاست.
ارزیابی وقتی بیشترین ارزش را دارد که خودکار باشد. با فرمان gate یا GitHub Action پروژه میتوان قاعدههایی مثل «nDCG@10 نباید از فلان کف پایینتر برود» یا «نسبت به سامانهی فعلی نباید افت کند» تعریف کرد. اگر تغییری در رتبهبندی این قاعدهها را نقض کند، build شکست میخورد و نتیجه در یک کامنت بهروزشونده روی pull request نمایش داده میشود. اجراها را هم میتوان مستقیماً از Elasticsearch، OpenSearch، Algolia، Meilisearch، Typesense یا هر API جستوجوی HTTP/JSON گرفت.
داور مدل زبانی جایگزین برچسبگذار انسانی نیست؛ واسنجی فقط میزان همنظری را نشان میدهد و آن را تضمین نمیکند.
آزمون معناداری روی مجموعهای کوچک از پرسشها توان آماری کمی دارد. «معنادار نبودن» به معنای «برابر بودن» نیست.
داور شبیهساز فقط پوشش واژهها را میسنجد و برای آزمون خط لوله ساخته شده، نه برای قضاوت دربارهی کیفیت.
مقایسهی دوبهدو هیچ معیار نقطهای را تغییر نمیدهد و باید کنار آن خوانده شود.
برای اینکه بگوییم جستوجوی جدید واقعاً برای خریداران بهتر است، چهار چیز لازم است: پر کردن شکاف برچسبها با داوری که توافقش با انسان سنجیده شده، مقایسهی همهی سامانهها روی یک مخزن برچسب مشترک، یک آزمون معناداری جفتی برای هر اختلاف، و ثبت هزینه و منشأ هر داوری. هیچکدام از اینها پیچیده نیست، اما نبود هر کدام میتواند تصمیم اشتباهی را با عددهای قانعکننده توجیه کند.
کد منبع llm-search-eval: github.com/sadrmanesh/llm-search-eval
نسخهی نرمافزار در Zenodo، DOI: 10.5281/zenodo.23944666
مستندات: sadrmanesh.github.io/llm-search-eval
داشبورد نمونه: sadrmanesh.github.io/llm-search-eval/demo/report.html
نسخهی قابل اجرا در مرورگر (Hugging Face Space): huggingface.co/spaces/sadrmanesh/llm-search-eval-demo
دادهی نمونه: huggingface.co/datasets/sadrmanesh/llm-search-eval-electronics
کد و مستندات پروژه: github.com/sadrmanesh/llm-search-eval