1. ตัวกรอง (Retrievers)

ตัวกรอง (Retriever) เป็นอินเทอร์เฟซที่ถูกครุภัณฑ์โดย LangChain ซึ่งสามารถคืนเอกสารที่เกี่ยวข้องโดยใช้คำค้นที่ไม่มีโครงสร้าง วัตถุประสงค์ของการออกแบบตัวกรองคือเพื่อเป็นที่ช่วยในการคิวรี่ข้อมูลท้องถิ่น การเก็บเวกเตอร์ (Vector storage) สามารถนำมาใช้เป็นการสร้างฐานข้อมูลรุ่นหลักของตัวกรอง และ 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("OpenAI API Key:")

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' รายการที่เกี่ยวข้องที่สุด, ตัวอย่างเช่น, รายการที่เกี่ยวข้องที่สุด 2 อันดับ:

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

2.5. การใช้ตัวกรองใน LCEL

เนื่องจากตัวกรองเป็นวัตถุ Runnable ทำให้เราสามารถรวมพวกเขาไปกับวัตถุ Runnable อื่นๆ ง่ายๆ เพื่อต่อเติมการทำงาน:

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("ประธานมีประกาศเกี่ยวกับเทคโนโลยีอะไรบ้าง?")

อธิบายขั้นตอนการทำงาน:

  • ขั้นตอนที่ 1: การกำหนดเป้าหมายคือการสร้างดิกชันนารี่ที่มีสองคุณสมบัติคือ context และ question, สำหรับการเตรียมพารามิเตอร์สำหรับแม่แบบโปรมท์ พารามิเตอร์ context ถูกสร้างโดยตัวกรอง (retriever) อิงจากพารามิเตอร์ที่ส่งผ่านมาหรือ "ประธานมีประกาศเกี่ยวกับเทคโนโลยีอะไรบ้าง?" ดีเรกเอ้าก์เอาเอกสารที่เกี่ยวข้องกับคำถามนั้นๆมาจากนั้นจัดรูปเรียงเอกสารสตริงให้กับฟังก์ชัน format_docs และ กำหนดค่าให้กับ context พารามิเตอร์ ฟังก์ชัน RunnablePassthrough กํบผลลัพธ์ ทำให้ค่าของหัวข้อถามของผู้ใช้ถูกคัดลอกไปยังคุณสมบัติ question ของลูกโซ่
  • ขั้นตอนที่ 2: ส่งดิกชันนารี่ที่สร้างขึ้นมาในขั้นตอนแรกไปยังแม่แบบโปรมท์เพื่อทำการจัดรูป
  • ขั้นตอนที่ 3: ส่งการจัดรูปโปรมท์ที่จัดรูปแล้วไปยังโมเดล
  • ขั้นตอนที่ 4: ส่งผลการเรียกร้องจากโมเดลไปยังตัวแยกข้อความ StrOutputParser

4.2. ตัวอย่างการสร้าง Retriever ที่กำหนดเอง

นี่คือตัวอย่างของ Retriever ที่กำหนดเอง ที่สาธิตวิธีการเขียน Retriever และใช้งานเพื่อดึงเอกสารที่เกี่ยวข้อง:

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")

ผ่านการศึกษาส่วนข้างต้น คุณจะได้เข้าใจอย่างลึกซึ้งเกี่ยวกับแนวคิด วิธีการดึงเอกสาร และการกำหนดเองของ Retriever ได้อย่างอ้อมอกอัน