본문 바로가기

ML&DL and LLM

LangChain - 2.6 Retrievers

참조 : https://python.langchain.com/docs/modules/data_connection/retrievers/

 

Retrievers | 🦜️🔗 Langchain

A retriever is an interface that returns documents given an unstructured query. It is more general than a vector store.

python.langchain.com

 

Retrievers

구조화 되지 않은 쿼리가 제공되면 문서를 반환하는 Interface로 문서 저장 없이 반환하기만 함

 

Name Index Type Uses an LLM When to use Description
Vectorstore Vectorstore No 쉽게 사용 가능 가장 간단한 방법. 각 Text 조각에 대한 임베딩을 만드는 작업이 포함됨
ParentDocument Vectorstore + Document
Store
No 페이지에 인덱싱이 잘된 더 작은 조작의 정보가 많은 경우 각 문서에 대한 여러 chunk 인덱싱 작업 후 가장 유사한 Chunk를 찾아서 전체 상위 문서를 검색하여 반환
Multi Vector Sometimes 
during 
indexing
텍스트 자체보다 인덱스와 관련이 있다고 생각하는 문서로부터 정보를 추출하는 경우 각 문서에 대한 여러 벡터를 다양한 방법으로 생성
Self Query Vectorestore Yes 텍스트를 유사성 검색 보다는 메타데이터 기반으로 문서를 가져와서 더 나은 답변을 제공하는 질문을 하는 경우 LLM을 사용하여 의미론적으로 String을 찾고 그에 따른 메타데이터 필러를 가져오는 것으로 컨텐츠 자체가 아닌 메타데이터에 관한 질문인 경우에 유용
Contextual
Compression
Any Sometimes 검색된 문서에 관련없는 정보가 너무 많이 포함된 경우 다른 검색기 뒤에 배치하여 가장 관련성이 높은 정보만 추출함. embedding이나 LLM 사용하여 수행 가능
Time-Weighted 
Vectorstore
Vectorstore No 문서에 timestamp가 존재하고 가장 최근 데이터를 가져와야하는 경우 Semantic similarity를 timestamp를 이용하요 가장 최근 데이터로 가져옴
Multi-Query
Retriever
Any Yes 복잡하고 응답하기 위해 여러가지 고유한 정보가 필요한 정보를 질문하는 경우 LLM을 이용하여 원본 쿼리에서 여러 쿼리를 생성 후 각 쿼리에 대한 문서를 가져옴
Ensemble Any No 여러 Retriever를 가지고 함께 사용하고자 하는 경우 여러 Retriever를 묶어서 사용
Long-Context
Reorder
Any No Long-context 모델로 작업중이며 문서 중간에 있는 정보에 주의를 기울이지 않는 경우 기본 검색기에서 문서를 가져와서 가장 유사한 문서가 시작과 끝 근처에 위치하도록 순서변경

 

 

Using Retrivers in 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 = """Answer the question based only on the following context:

{context}

Question: {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("What did the president say about technology?")

 

 

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

 

 


참조 : https://python.langchain.com/docs/modules/data_connection/retrievers/vectorstore

 

Vector store-backed retriever | 🦜️🔗 Langchain

A vector store retriever is a retriever that uses a vector store to

python.langchain.com

 

Vector store-backed retriever

문서를 가져오기 위해서 Vector store를 사용하는 retreiver

from datetime import datetime

from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_community.embeddings.sentence_transformer import (
    SentenceTransformerEmbeddings,
) 

DB_PATH_OPENAI = "./ChromadbOpenAI"
DB_PATH_STF    = "./ChromadbStf"

stf_embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

chroma_openai = Chroma(persist_directory=DB_PATH_OPENAI, embedding_function = OpenAIEmbeddings())
chroma_stf    = Chroma(persist_directory=DB_PATH_STF   , embedding_function = stf_embeddings    )

query = "How to check AP Server?"
print("Query = ", query)

print('Similarity search ----------------------------------------------------------------------')
retriever_openai = chroma_openai.as_retriever(search_kwargs={"k": 1})
retriever_stf    = chroma_stf   .as_retriever(search_kwargs={"k": 1})

docs_openai = retriever_openai.get_relevant_documents(query)
docs_stf    = retriever_stf   .get_relevant_documents(query)

print('\n', docs_openai[0].page_content[:500])
print('\n', docs_stf[0].page_content[:500])
a = input()

print('mmr ----------------------------------------------------------------------')
retriever_openai = chroma_openai.as_retriever(search_type='mmr', search_kwargs={"k": 1})
retriever_stf    = chroma_stf   .as_retriever(search_type='mmr', search_kwargs={"k": 1})

docs_openai = retriever_openai.get_relevant_documents(query)
docs_stf    = retriever_stf   .get_relevant_documents(query)

print('\n', docs_openai[0].page_content[:500])
print('\n', docs_stf[0].page_content[:500])
a = input()


print('similarity score threshold ----------------------------------------------------------------------')
retriever_openai = chroma_openai.as_retriever(search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5, 'k':1})
retriever_stf    = chroma_stf   .as_retriever(search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5, 'k':1})

docs_openai = retriever_openai.get_relevant_documents(query)
docs_stf    = retriever_stf   .get_relevant_documents(query)

print('\n', docs_openai[0].page_content[:500])
print('\n', docs_stf[0].page_content[:500])
  • 기본으로는 similarity search로 수행되며 다른 방식으로 쿼리를 하려면 search_type에 지정하면 됨
  • search_kwargs={'k':1}은 top-n을 가져오기 위함으로 여기서는 1건만 가져오게 됨
  • similarity scroe threshold인 경우 해당 threshold에 해당하는 건을 가져오지 못할 수도 있음

 

Contextual compression

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
from langchain_openai import OpenAI

llm = OpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor, base_retriever=retriever
)

compressed_docs = compression_retriever.get_relevant_documents(
    "What did the president say about Ketanji Jackson Brown"
)
pretty_print_docs(compressed_docs)

# ------------------------------

from langchain.retrievers.document_compressors import LLMChainFilter

_filter = LLMChainFilter.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
    base_compressor=_filter, base_retriever=retriever
)

compressed_docs = compression_retriever.get_relevant_documents(
    "What did the president say about Ketanji Jackson Brown"
)
pretty_print_docs(compressed_docs)

# ------------------------------

from langchain.retrievers.document_compressors import EmbeddingsFilter
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings()
embeddings_filter = EmbeddingsFilter(embeddings=embeddings, similarity_threshold=0.76)
compression_retriever = ContextualCompressionRetriever(
    base_compressor=embeddings_filter, base_retriever=retriever
)

compressed_docs = compression_retriever.get_relevant_documents(
    "What did the president say about Ketanji Jackson Brown"
)
pretty_print_docs(compressed_docs)

'ML&DL and LLM' 카테고리의 다른 글

(Docker) ollama + chroma로 RAG 구성  (0) 2024.08.14
LangChain - 2.5 Vector stores GetStarted  (0) 2024.04.02
LangChain - 2.3 Text Splitter  (0) 2024.04.02
LangChain - 2.2 Document loaders  (0) 2024.04.01
LangChain - 2.1 Retrieval concept  (1) 2024.03.29