1. Pencari
Pencari adalah sebuah antarmuka yang dienkapsulasi oleh LangChain, yang dapat mengembalikan dokumen-dokumen relevan berdasarkan kueri-kueri yang tidak terstruktur. Tujuan dari desain pencari adalah untuk memudahkan pengaksesan data lokal. Penyimpanan vektor dapat digunakan sebagai implementasi dasar dari pencari, dan LangChain mendukung beberapa implementasi dasar dari antarmuka pencari.
2. Memulai dengan Pencari
2.1. Instalasi
Untuk menunjukkan bagaimana cara mendapatkan pencari, kita akan menggunakan basis data vektor Qdrant sebagai contoh.
%pip install --upgrade --quiet qdrant-client
2.2. Mendapatkan Kunci API OpenAI
Sebelum menggunakan OpenAIEmbeddings
, kita perlu mendapatkan kunci API OpenAI.
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass("Kunci API OpenAI:")
2.3. Mengimpor Data Dokumen dan Mendapatkan Klien Qdrant
Kode berikut menunjukkan bagaimana cara mengimpor data dokumen dan mendapatkan klien Qdrant untuk membuat pencari:
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. Mendapatkan Pencari
Kode berikut menunjukkan bagaimana cara mendapatkan pencari dari Qdrant:
retriever = qdrant.as_retriever()
retriever
Anda dapat menanyakan dokumen-dokumen yang terkait dengan sebuah pertanyaan seperti ini:
docs = retriever.get_relevant_documents("apa yang dikatakan tentang ketanji brown jackson")
Anda juga dapat mengatur ambang kesamaan untuk pencari seperti ini:
retriever = db.as_retriever(
search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5}
)
Selain itu, Anda dapat mengatur pencari untuk mengembalikan 'K' rekaman yang paling mirip, misalnya, untuk mengembalikan 2 rekaman yang paling mirip:
retriever = db.as_retriever(search_kwargs={"k": 2})
2.5. Menggunakan Pencari dalam LCEL
Karena pencari adalah objek Runnable
, kita dapat dengan mudah menggabungkannya dengan objek Runnable
lain untuk mengatur alur kerja:
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 = """Jawab pertanyaan berdasarkan konteks berikut:
{context}
Pertanyaan: {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("Apa yang dikatakan presiden tentang teknologi?")
Penjelasan dari proses ini:
- Langkah 1: Tujuannya adalah untuk menghasilkan sebuah kamus yang berisi dua properti,
context
danquestion
, untuk menyiapkan parameter untuk template prompt. Parametercontext
dihasilkan oleh pencari berdasarkan parameter yang dilewatkan ke metodeinvoke
, yaitu "Apa yang dikatakan presiden tentang teknologi?". Hal ini mengambil dokumen-dokumen yang mirip dengan pertanyaan, kemudian memformat array dokumen menggunakan fungsiformat_docs
dan menetapkannya ke properticontext
. FungsiRunnablePassthrough
menyalin parameter (pertanyaan pengguna) rantai ke propertiquestion
. - Langkah 2: Meneruskan kamus yang dihasilkan pada langkah pertama ke template prompt untuk diformat.
- Langkah 3: Meneruskan prompt yang diformat dari template prompt ke model.
- Langkah 4: Meneruskan hasil dari panggilan model ke parser output
StrOutputParser
.
3. Pencari Kustom
4.1. Pengantar ke Antarmuka Pencari
Antarmuka pencari sangat sederhana, dan kita dapat dengan mudah menulis pencari kustom.
4.2. Contoh Pencari Kustom
Berikut adalah contoh pencari kustom, yang menunjukkan bagaimana menulis pencari kustom dan menggunakannya untuk mendapatkan dokumen yang relevan:
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")
Dengan mempelajari bagian di atas, Anda akan mendapatkan pemahaman yang lebih mendalam tentang konsep, metode pencarian, dan penyesuaian pencari.