1. بازیابی‌کننده‌ها

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

2. شروع کار با بازیابی‌کننده

2.1. نصب

برای نمایش این که چگونه می‌توان بازیابی‌کننده را دریافت کرد، ما از پایگاه داده بردار Qdrant به عنوان مثال استفاده خواهیم کرد.

%pip install --upgrade --quiet qdrant-client

2.2. دریافت کلید API OpenAI

قبل از استفاده از OpenAIEmbeddings، نیاز داریم که کلید API OpenAI را دریافت کنیم.

import getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass("کلید API OpenAI:")

2.3. وارد کردن داده اسناد و دریافت کلاینت Qdrant

کد زیر نشان می‌دهد چگونه می‌توان داده اسناد را وارد کرد و کلاینت Qdrant را برای ایجاد یک بازیابی‌کننده دریافت کرد:

from langchain_community.document_loaders import TextLoader
from langchain_community.vectorstores import Qdrant
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter

loader = TextLoader("../../modules/state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()

qdrant = Qdrant.from_documents(
    docs,
    embeddings,
    path="/tmp/local_qdrant",
    collection_name="my_documents",
)

2.4. دریافت بازیابی‌کننده

کد زیر نشان می‌دهد چگونه می‌توان یک بازیابی‌کننده از Qdrant دریافت کرد:

retriever = qdrant.as_retriever()
retriever

می‌توانید اسناد مرتبط با یک سوال را به این شکل پرس و جو کنید:

docs = retriever.get_relevant_documents("چه چیزهایی درباره کتانجی براون جکسون گفته است")

همچنین، می‌توانید آستانه شباهت برای بازیابی‌کننده تنظیم کنید به این شکل:

retriever = db.as_retriever(
    search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5}
)

علاوه بر این، می‌توانید بازیابی‌کننده را تنظیم کنید تا برترین 'K' سابقه مشابه را بازگرداند، برای مثال برای بازگرداندن دو سابقه برترین مشابه:

retriever = db.as_retriever(search_kwargs={"k": 2})

2.5. استفاده از بازیابی‌کننده در LCEL

چون بازیابی‌کننده‌ها اشیاء قابل اجرا هستند، ما می‌توانیم آسان‌تر آنها را با سایر اشیاء قابل اجرا ترکیب کنیم تا الگوهای کاری را سازماندهی کنیم:

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

template = """پاسخ‌ها را فقط براساس متن زیر بدهید:

{context}

سوال: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()

def format_docs(docs):
    return "\n\n".join([d.page_content for d in docs])

chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

chain.invoke("رییس‌جمهور درباره تکنولوژی چه گفت؟")

توضیح فرایند:

  • مرحله ۱: هدف ایجاد یک دیکشنری حاوی دو خصوصیت context و question برای آماده‌سازی پارامترهای قالب پرسش است. پارامتر context توسط بازیابی‌کننده براساس پارامتری که به متود invoke منتقل می‌شود (که "رییس‌جمهور درباره تکنولوژی چه گفت؟" است) آماده شده و سپس آرایه اسناد مشابه سوال را می‌گیرد، سپس آرایه اسناد را با استفاده از تابع format_docs قالب بندی کرده و آن را به خصوصیت context اختصاص می‌دهد. تابع RunnablePassthrough پارامتر (سوال ورودی کاربر) زنجیره را به خصوصیت question کپی می‌کند.
  • مرحله ۲: دیکشنری تولید شده در مرحله اول را به قالب پرسش برای قالب بندی انتقال می‌دهد.
  • مرحله ۳: قالب فرمت‌شده از قالب پرسش را به مدل ارسال می‌کند.
  • مرحله ۴: نتیجه فراخوانی مدل را به تجزیه‌گر خروجی StrOutputParser ارسال می‌کند.

3. بازیابی‌کننده سفارشی

3.1. معرفی به رابط بازیابی‌کننده

رابط بازیابی‌کننده بسیار ساده است و ما به راحتی می‌توانیم بازیابی‌کننده‌های سفارشی بنویسیم.

4.2. مثال بازیابی سفارشی

در زیر مثالی از یک بازیابی سفارشی آمده است که نشان می‌دهد چگونه می‌توان یک بازیابی سفارشی را نوشته و از آن برای بازیابی اسناد مرتبط استفاده کرد:

from langchain_core.retrievers import BaseRetriever
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from typing import List

class CustomRetriever(BaseRetriever):
  
    def _get_relevant_documents(
        self, query: str, *, run_manager: CallbackManagerForRetrieverRun
    ) -> List[Document]:
        return [Document(page_content=query]

retriever = CustomRetriever()

retriever.get_relevant_documents("bar")

از طریق مطالعه بخش‌های فوق، شما یک درک عمیق‌تر از مفهوم، روش‌های بازیابی و سفارشی‌سازی بازیابی‌کننده‌ها خواهید یافت.