1. Retrieve
Il Retriever è un'interfaccia incapsulata da LangChain, che restituisce documenti correlati basati su query non strutturate. Lo scopo del design del retriever è quello di facilitare l'interrogazione dei dati locali. Lo storage vettoriale può essere utilizzato come implementazione sottostante del retriever, e LangChain supporta più implementazioni sottostanti dell'interfaccia del retriever.
2. Inizia con il Retriever
2.1. Installazione
Per mostrare come ottenere un retriever, useremo il database vettoriale Qdrant come esempio.
%pip install --upgrade --quiet qdrant-client
2.2. Ottenere la Chiave API di OpenAI
Prima di utilizzare OpenAIEmbeddings
, è necessario ottenere la chiave API di OpenAI.
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass("Chiave API di OpenAI:")
2.3. Importare i Dati dei Documenti e Ottenere il Cliente Qdrant
Il seguente codice mostra come importare i dati dei documenti e ottenere il cliente Qdrant per creare un retriever:
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. Ottenere il Retriever
Il seguente codice mostra come ottenere un retriever da Qdrant:
retriever = qdrant.as_retriever()
retriever
Puoi interrogare i documenti correlati a una domanda in questo modo:
docs = retriever.get_relevant_documents("di cosa ha parlato ketanji brown jackson")
Puoi anche impostare la soglia di similarità per il retriever in questo modo:
retriever = db.as_retriever(
search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5}
)
Inoltre, puoi impostare il retriever per restituire i primi 'K' record più simili, ad esempio, per restituire i primi 2 record più simili:
retriever = db.as_retriever(search_kwargs={"k": 2})
2.5. Utilizzo del Retriever in LCEL
Poiché i retriever sono oggetti eseguibili, possiamo facilmente combinarli con altri oggetti eseguibili per orchestrare flussi di lavoro:
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 = """Rispondi alle domande basandoti solo sul seguente contesto:
{context}
Domanda: {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("Di cosa ha parlato il presidente riguardo alla tecnologia?")
Spiegazione del processo:
- Passaggio 1: L'obiettivo è generare un dizionario contenente due proprietà,
context
equestion
, per preparare i parametri per il template della prompt. Il parametrocontext
è generato dal retriever basato sul parametro passato al metodoinvoke
, che è "Di cosa ha parlato il presidente riguardo alla tecnologia?". Questo recupera documenti simili alla domanda, quindi formatta l'array di documenti utilizzando la funzioneformat_docs
e lo assegna alla proprietàcontext
. La funzioneRunnablePassthrough
copia il parametro (domanda dell'utente) della catena alla proprietàquestion
. - Passaggio 2: Passa il dizionario generato nel primo passaggio al template della prompt per la formattazione.
- Passaggio 3: Passa la prompt formattata dal template al modello.
- Passaggio 4: Passa il risultato della chiamata al modello all'output parser
StrOutputParser
.
3. Retriever Personalizzato
4.1. Introduzione all'Interfaccia del Retriever
L'interfaccia del retriever è molto semplice e possiamo facilmente scrivere retriever personalizzati.
4.2. Esempio di Recupero Personalizzato
Di seguito è riportato un esempio di un recupero personalizzato, che illustra come scrivere un recupero personalizzato e usarlo per recuperare documenti rilevanti:
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")
Attraverso lo studio delle sezioni precedenti, acquisirai una comprensione più approfondita del concetto, dei metodi di recupero e della personalizzazione dei recuperi.