Retrieval-Augmented Generation (RAG)

فراتر از کلمات کلیدی: پیاده‌سازی جستجوی معنایی در پایپ‌لاین‌های RAG مدرن

برای سال‌ها، رویکرد استاندارد بازیابی داده مبتنی بر تطبیق کلمات کلیدی بود. اگر کاربر «یادگیری ماشین» را جستجو می‌کرد، سیستم به دنبال آن کلمات دقیق در نمایه می‌گشت. اگرچه این روش برای پرس‌وجوهای ساختاریافته کارآمد است، اما هنگام کار با زبان طبیعی، مترادف‌ها یا نیت‌های پیچیده، این روش به شدت ناکارآمد عمل می‌کند. با تبدیل شدن معماری‌های تولید تقویت‌شده با بازیابی (RAG) به ستون فقرات برنامه‌های هوش مصنوعی سازمانی، نیاز به جستجوی معنایی به یک ضرورت غیرقابل‌تصرف تبدیل شده است. این مطلب بررسی می‌کند که چگونه می‌توان جستجوی معنایی را پیاده‌سازی کرد تا مدل‌های زبانی بزرگ (LLMs) مرتبط‌ترین زمینه را بازیابی کنند و بدین ترتیب توهم‌سازی (Hallucination) را کاهش داده و کیفیت پاسخ‌ها را بهبود بخشند.

چرا جستجوی کلمات کلیدی در RAG شکست می‌خورد

موتورهای جستجوی سنتی به الگوریتم‌های TF-IDF (فرکانس اصطلاح-فرکانس معکوس سند) یا BM25 متکی هستند. این روش‌ها بر این فرض عمل می‌کنند که همپوشانی کلمات برابر با مرتبط بودن است. با این حال، سناریوی زیر را در نظر بگیرید: کاربر می‌پرسد، «چگونه شیر چکه‌ای را تعمیر کنم؟» یک جستجوی کلمات کلیدی ممکن است اسنادی حاوی «تعمیر شیرآلات» یا «مشکلات لوله‌کشی» را بازگرداند، اما یک راهنما با عنوان «عیب‌یابی سینک‌های چکه‌زن» را از قلم بیندازد، صرفاً به این دلیل که کلمه دقیق «شیر» (Tap) در آن وجود ندارد. در یک پایپ‌لاین RAG، بازیابی سند اشتباه به معنای تغذیه زمینه نامربوط به LLM است که منجر به پاسخ‌های غیرمنطقی یا نادرست از نظر واقعی می‌شود.

جستجوی معنایی این مشکل را با درک معنای پشت کلمات حل می‌کند، نه صرفاً خود کلمات. این روش متن را به یک فضای برداری با ابعاد بالا نگاشت می‌کند که در آن مفاهیم از نظر معنایی مشابه، فارغ از همپوشانی واژگانی، در نزدیکی یکدیگر قرار می‌گیرند.

مکانیک‌های اصلی: امبدینگ‌ها و پایگاه‌های داده برداری

در قلب جستجوی معنایی، امبدینگ (Embedding) قرار دارد. یک مدل امبدینگ (مانند text-embedding-ada-002 شرکت OpenAI یا مدل‌های متن‌باز مانند BGE) متن را به یک لیست از اعداد تبدیل می‌کند—یک بردار. برای مثال، جملات «گربه روی تشک نشسته است» و «گربه روی فرش استراحت می‌کند» بردارهایی با شباهت کسینوسی بالا خواهند داشت.

برای اینکه بازیابی در مقیاس بزرگ سریع و کارآمد باشد، این بردارها در یک پایگاه داده برداری (مانند Pinecone، Weaviate یا Milvus) ذخیره می‌شوند. وقتی یک پرس‌وجو وارد می‌شود، امبدینگ شده و سپس برای یافتن بردارهای همسایه نزدیک در پایگاه داده استفاده می‌شود. این فرآیند که به عنوان جستجوی همسایه نزدیک تقریبی (ANN) شناخته می‌شود، امکان بازیابی با تأخیر در حد میلی‌ثانیه را حتی در میان میلیون‌ها سند فراهم می‌کند.

مثال پیاده‌سازی با پایتون و LangChain

پیاده‌سازی جستجوی معنایی با بهره‌گیری از کتابخانه‌های مدرن مانند LangChain ساده است. در زیر یک مثال عملی از نحوه ایجاد یک جزء ساده RAG با استفاده از یک مدل امبدینگ و یک انبار برداری آورده شده است.

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import TextLoader

# 1. بارگذاری و تقسیم اسناد
loader = TextLoader('data/my_document.txt')
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

# 2. ایجاد امبدینگ‌ها
embeddings = OpenAIEmbeddings()

# 3. ذخیره در پایگاه داده برداری
db = Chroma.from_documents(docs, embeddings)

# 4. انجام جستجوی معنایی
query = "What are the main conclusions of this study?"
similar_docs = db.similarity_search(query, k=3)

# 5. بررسی زمینه بازیابی شده
for doc in similar_docs:
    print(doc.page_content[:100] + "...")

در این قطعه کد، روش similarity_search به طور خودکار پرس‌وجو را به یک بردار تبدیل کرده و ۳ سند با بیشترین شباهت معنایی را برمی‌گرداند. توجه کنید که ما هیچ کلمه کلیدی‌ای را پاس نمی‌دهیم؛ بلکه سوال زبان طبیعی را مستقیماً ارسال می‌کنیم.

بهترین شیوه‌ها برای جستجوی سطح تولید

اگرچه بازیابی مبتنی بر امبدینگ پایه قدرتمند است، اما سیستم‌های تولیدی به تنظیمات اضافی نیاز دارند:

  • استراتژی تکه‌تکه کردن (Chunking): نحوه تقسیم اسناد تأثیر شدیدی بر بازیابی دارد. اطمینان حاصل کنید که تکه‌ها از نظر معنایی کامل هستند (مثلاً پاراگراف‌های کامل یا بخش‌ها) تا اینکه صرفاً شمارش کاراکتری تصادفی باشند.
  • جستجوی سلسله‌مراتبی: برای مجموعه‌های داده عظیم، رویکرد «کوچک به بزرگ» را در نظر بگیرید. ابتدا یک مجموعه کوچک از خلاصه‌های سند را جستجو کنید تا بخش‌های مرتبط را شناسایی نمایید، سپس متن کامل آن بخش‌ها را بازیابی کنید.
  • مرتب‌سازی مجدد (Re-ranking): جستجوی برداری اولیه سریع است اما همیشه دقیق نیست. پیاده‌سازی یک مرتب‌ساز مجدد مبتنی بر کراس-اینکودر (Cross-encoder) به عنوان گام دوم می‌تواند با تحلیل دقیق جفت پرس‌وجو-سند، مرتبط بودن را به طور قابل توجهی بهبود بخشد.

نتیجه‌گیری

جستجوی معنایی پل ارتباطی بین زبان انسان و درک ماشین است. با یکپارچه‌سازی امبدینگ‌ها و پایگاه‌های داده برداری در معماری RAG خود، شما از تطبیق شکننده کلمات کلیدی فراتر رفته و به سیستمی می‌رسید که واقعاً نیت را درک می‌کند. با بالغ‌تر شدن برنامه‌های هوش مصنوعی، تفاوت بین تجربه خوب و عالی LLM اغلب به کیفیت لایه بازیابی بستگی خواهد داشت. سرمایه‌گذاری در استراتژی‌های جستجوی معنایی قوی دیگر اختیاری نیست—این یک ضرورت است.

Share: