728x90
Ensemble Retriever란?
- 앙상블 검색기는 Retriever의 list를 받아서 각각의 Retriever로
get_relevant_documents
방법으로 검색한 결과를 종합한 뒤 Reciprocal Rank Fusion 알고리즘으로 결과를 rerank한다. - Similarity search 만으로 성능이 잘 나오지 않을 때 사용하기 좋은 방법론이다.
- 가장 흔히 사용하는 방식은 sparse retriever(BM25 같이 키워드 기반)와 dense retriever(embedding similarity)를 함께 사용하는 것이다.
- Hybrid Search 라고도 알려져있고 sparse retriever는 keyword 기반으로 문서를 찾는데 특화되어 있고 dense retriever는 의미론적 유사도 기반으로 문서를 찾는데 특화되어 있으므로 두 종류를 합쳐서 사용하면 효과가 좋다.관련 문서 링크
- Reciprocal Rank Fusion에 대한 자세한 설명은 👉여기
- Ensemble Retriever 관련 Langchain 문서 👉여기
- BM25 Retriever 관련 Langchain 문서 👉여기
Dependency 설치
pip install --upgrade --quiet rank_bm25 > /dev/null
pip install rank_bm25
pip install faiss-cpu
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
실습
Retriever 정의
문자열이 저장된 리스트 2개를 선언한다. 이후 bm25_retriever와 faiss_retriever를 정의한다.
metadatas에 source를 정해주고 가져올 문서의 개수는 k로 설정한다.
이후 ensemble_retriever를 구성하고 weights로 어떤 retriever의 결과를 더 반영할 지 정한다.
doc_list_1 = [
"I like apples",
"I like oranges",
"Apples and oranges are fruits",
]
# initialize the bm25 retriever and faiss retriever
bm25_retriever = BM25Retriever.from_texts(
doc_list_1, metadatas=[{"source": 1}] * len(doc_list_1)
)
bm25_retriever.k = 2
doc_list_2 = [
"You like apples",
"You like oranges",
]
embedding = OpenAIEmbeddings()
faiss_vectorstore = FAISS.from_texts(
doc_list_2, embedding, metadatas=[{"source": 2}] * len(doc_list_2)
)
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k": 2})
# initialize the ensemble retriever
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
이제 결과를 살펴보자
docs = ensemble_retriever.invoke("apples")
docs
결과
[Document(page_content='You like apples', metadata={'source': 2}),
Document(page_content='I like apples', metadata={'source': 1}),
Document(page_content='You like oranges', metadata={'source': 2}),
Document(page_content='Apples and oranges are fruits', metadata={'source': 1})]
Runtime Configuration
개발자는 runtime에 retriever들을 구성할 수 있다. 이를 위해서는 우선 field들을 configurable 할 수 있게 표시해야한다.
from langchain_core.runnables import ConfigurableField
아래 과정을 통해서 개발자는 runtime에 faiss_retriever가 몇개의 문서를 반환할 지 결정할 수 있다.
faiss_retriever = faiss_vectorstore.as_retriever(
search_kwargs={"k": 2}
).configurable_fields(
search_kwargs=ConfigurableField(
id="search_kwargs_faiss",
name="Search Kwargs",
description="The search kwargs to use",
)
)
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, faiss_retriever], weights=[0.5, 0.5]
)
config = {"configurable": {"search_kwargs_faiss": {"k": 1}}}
docs = ensemble_retriever.invoke("apples", config=config)
docs
'인공지능 > RAG' 카테고리의 다른 글
LangChain (10) Gemini로 RAG 구현 (0) | 2024.06.04 |
---|---|
What is Elastic Search? (0) | 2024.06.03 |
Langchain - Hybrid Search 구현 (0) | 2024.05.31 |
MongoDB와 Gemma를 사용한 RAG 실습(LangChain X) (0) | 2024.05.28 |
Langchain - MessagesPlaceholder (0) | 2024.05.24 |