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 ได้อย่างอ้อมอกอัน