تولید تقویتشده با بازیابی (RAG) با اتصال مدلهای زبانی بزرگ (LLM) به دانش خارجی، نحوه تعامل ما با آنها را متحول کرده است. با این حال، کیفیت خروجی به شدت به کیفیت بافت بازیابیشده وابسته است. اگرچه جستجوی شباهت برداری برای یافتن مستندات به طور کلی مرتبط مؤثر است، اما اغلب در همراستایی معنایی دقیق مشکل دارد و منجر به «مثبتهای کاذب» میشود که میتوانند LLM را گیج کنند. اینجاست که مرتبسازی مجدد (Re-ranking) وارد صحنه میشود.
چرا مرتبسازی مجدد ضروری است
الگوریتمهای جستجوی برداری استاندارد معمولاً از دوانکودرها (bi-encoders) استفاده میکنند که کوئری و سند را به صورت مستقل کدگذاری میکنند. اگرچه این روش سریع و مقیاسپذیر است، اما توانایی تعامل بین توکنهای کوئری و سند برای درک روابط ظریف را ندارد. مرتبسازی مجدد یک فرآیند محاسباتی گرانتر، معمولاً شامل کراسانکودرها (cross-encoders)، را بر K کاندیدای برتر برگشتی از جستجوی اولیه اعمال میکند. با تحلیل تعامل بین کوئری و هر سند، مرتبساز یک امتیاز مرتبطی جدید و دقیقتر را تخصیص میدهد و قطعات (chunks) مرتبطتر را به بالای لیست ارتقا میدهد.
کراسانکودرها در مقابل دوانکودرها
درک تفاوت بین این دو حیاتی است. یک دوانکودر امبیدهای (embeddings) جداگانهای برای کوئری و سند ایجاد میکند و شباهت کسینوس بین آنها را محاسبه میکند. از سوی دیگر، یک کراسانکودر کوئری و سند را به عنوان یک ورودی ترکیبی واحد دریافت کرده و آن را به طور همزمان از طریق مدل ترنسفورمر پردازش میکند. این امر به مدل اجازه میدهد وابستگیهای زمینهای را که در کدگذاری مستقل از دست میروند، درک کند. اگرچه کراسانکودرها کندتر هستند، اما به طور قابل توجهی دقیقترند و آنها را برای مرحله مرتبسازی مجدد ایدهآل میسازد، جایی که فقط نیاز به پردازش یک زیرمجموعه کوچک از مستندات دارید (مثلاً ۲۰ مورد برتر از ۱۰۰۰).
پیادهسازی مرتبسازی مجدد در پایتون
یکپارچهسازی یک مرتبساز در پایپلاین RAG شما با استفاده از فریمورکهای مدرن هوش مصنوعی ساده است. در زیر یک مثال با استفاده از کتابخانه `sentence-transformers` و یک مدل کراسانکودر ارائه شده است، که انتخاب محبوبی به دلیل تعادل بین عملکرد و آسانی استفاده است.
from sentence_transformers import CrossEncoder
from typing import List, Tuple
class ReRanker:
def __init__(self, model_name: str = "cross-encoder/ms-marco-MiniLM-L-6-v2"):
self.model = CrossEncoder(model_name)
def rerank(self, query: str, documents: List[str], top_k: int = 5) -> List[Tuple[int, float]]:
"""
Re-ranks a list of documents based on their relevance to the query.
Args:
query: The search query string.
documents: A list of document strings to re-rank.
top_k: Number of top results to return.
Returns:
A list of tuples containing (document_index, score).
"""
# Prepare input pairs (query, doc)
inputs = [(query, doc) for doc in documents]
# Score the pairs
scores = self.model.predict(inputs)
# Get indices of top K scores
top_indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:top_k]
# Return original indices and scores
return [(idx, scores[idx]) for idx in top_indices]
# Example Usage
query = "What are the health benefits of ginger?"
documents = [
"Ginger has anti-inflammatory properties and can help with nausea.",
"The weather is sunny today in London.",
"Ginger tea is a popular remedy for colds and digestion issues.",
"Python is a popular programming language.",
"Gingerbread cookies are made with spices including ginger."
]
reranker = ReRanker()
results = reranker.rerank(query, documents, top_k=3)
for idx, score in results:
print(f"Score: {score:.4f} | Doc: {documents[idx]}")
بهترین روشها و ملاحظات
- تعادل تأخیر (Latency): همیشه تعداد کاندیداها را که به مرتبساز منتقل میشوند محدود کنید. مرتبسازی مجدد ۱۰۰۰ سند تأخیر را به طور قابل توجهی افزایش میدهد. مرتبسازی مجدد ۲۰ تا ۵۰ نتیجه برتر از جستجوی برداری نقطه بهینه است.
- انتخاب مدل: یک مرتبساز را انتخاب کنید که روی دادههای مشابه حوزه کاری شما آموزش دیده باشد. مدلهای عمومی مانند
ms-marco-MiniLMبرای دانش عمومی خوب کار میکنند، اما مدلهای خاص حوزه (مثلاً برای متون حقوقی یا پزشکی) ممکن است نتایج بهتری ارائه دهند. - یکپارچهسازی: از امتیازهای مرتبسازی مجدد شده برای تنظیم پویای تعداد قطعات (chunks) ارسالی به LLM استفاده کنید. اگر امتیاز برتر بسیار پایین است، در نظر بگیرید که به یک جستجوی گستردهتر یا اصلاً بدون بازیابی بازگردید.
نتیجهگیری
مرتبسازی مجدد یک جزء حیاتی در ساخت سیستمهای RAG با کیفیت بالا است. با افزودن این لایه از پالایش، میتوانید توهمسازی (hallucinations) را به طور قابل توجهی کاهش دهید و دقت واقعی خروجیهای LLM خود را بهبود بخشید. با ادامه بهبود مدلهای کراسانکودر در سرعت و کارایی، شکاف بین جستجوی تقریبی سریع و امتیازدهی مرتبطی دقیق باریکتر خواهد شد و مرتبسازی مجدد به ابزاری رو به دسترسپذیری و ضروری در جعبه ابزار مهندس هوش مصنوعی تبدیل خواهد شد.