
Retriever는 벡터 스토어에서 질문과 관련된 문서를 검색하는 인터페이스입니다. 본 포스트에서는 다양한 Retriever 옵션과 고급 검색 기법을 정리합니다.
Retriever를 사용하기 위해 필요한 패키지를 설치합니다.
pip install langchain langchain-chroma langchain-huggingface langchain-openai python-dotenv
| 패키지 | 설명 |
|---|---|
langchain | MultiQueryRetriever 등 고급 Retriever |
langchain-chroma | Chroma 벡터 스토어 |
langchain-huggingface | HuggingFace 임베딩 모델 |
langchain-openai | MultiQueryRetriever에서 LLM 사용 시 |
python-dotenv | .env 파일에서 환경 변수 로드 |
as_retriever() 는 벡터 스토어를 Retriever 객체로 변환합니다.
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-m3")
db = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
# Retriever로 변환
retriever = db.as_retriever()
# 검색 실행
docs = retriever.invoke("인공지능이란?")
print(f"검색된 문서: {len(docs)}개")
기본적으로 유사도가 높은 상위 4개 문서를 반환합니다.
search_kwargs 로 검색 동작을 세밀하게 조정할 수 있습니다.
retriever = db.as_retriever(
search_kwargs={"k": 5} # 상위 5개 문서 반환
)
검색할 문서 개수를 지정합니다.
search_type 으로 검색 알고리즘을 선택할 수 있습니다.
| 타입 | 설명 |
|---|---|
similarity | 기본 유사도 검색 |
similarity_score_threshold | 점수 임계값 기반 검색 |
mmr | 다양성을 고려한 검색 |
# 기본 유사도 검색
retriever = db.as_retriever(search_type="similarity")
유사도 점수가 특정 임계값 이상인 문서만 반환합니다.
retriever = db.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={
"score_threshold": 0.7 # 70% 이상 유사한 문서만
}
)
docs = retriever.invoke("인공지능 기술")
print(f"검색된 문서: {len(docs)}개")
임계값을 높이면 더 관련성 높은 문서만 반환되고, 낮추면 더 많은 문서가 반환됩니다.
MMR은 검색 결과의 다양성을 고려합니다. 단순히 유사한 문서만 반환하는 것이 아니라, 서로 다른 내용의 문서를 포함하여 정보의 다양성을 확보합니다.
retriever = db.as_retriever(
search_type="mmr",
search_kwargs={
"k": 4,
"fetch_k": 10,
"lambda_mult": 0.5
}
)
docs = retriever.invoke("인공지능의 활용 분야")
| 파라미터 | 설명 |
|---|---|
k | 최종 반환할 문서 개수 |
fetch_k | 초기에 가져올 후보 문서 개수 |
lambda_mult | 다양성 조절 (0: 최대 다양성, 1: 최대 유사도) |
사용자 질문을 LLM을 통해 여러 버전으로 확장하여 검색합니다. 같은 의미의 다양한 표현을 검색에 활용합니다.
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain_openai import ChatOpenAI
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from dotenv import load_dotenv
load_dotenv()
# 벡터 스토어 준비
embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-m3")
db = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
# LLM 준비
llm = ChatOpenAI(model="gpt-4o-mini")
# MultiQueryRetriever 생성
retriever = MultiQueryRetriever.from_llm(
retriever=db.as_retriever(),
llm=llm
)
# 검색 실행
docs = retriever.invoke("여행 계획 세우기")
print(f"검색된 문서: {len(docs)}개")
내부 동작을 확인하려면 디버그 모드를 활성화합니다.
import langchain
langchain.debug = True
docs = retriever.invoke("여행 계획 세우기")
| Retriever | 특징 | 사용 시점 |
|---|---|---|
| 기본 Retriever | 단순 유사도 검색 | 일반적인 검색 |
| score_threshold | 임계값 기반 필터링 | 품질 보장 필요 시 |
| MMR | 다양성 고려 | 다양한 정보 필요 시 |
| MultiQuery | 질문 확장 검색 | 검색 품질 향상 필요 시 |
from langchain_chroma import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain.retrievers.multi_query import MultiQueryRetriever
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
load_dotenv()
# 1. 벡터 스토어 준비
embeddings = HuggingFaceEmbeddings(model_name="BAAI/bge-m3")
db = Chroma(persist_directory="./chroma_db", embedding_function=embeddings)
# 2. 기본 Retriever
basic_retriever = db.as_retriever(search_kwargs={"k": 3})
# 3. 임계값 기반 Retriever
threshold_retriever = db.as_retriever(
search_type="similarity_score_threshold",
search_kwargs={"score_threshold": 0.7}
)
# 4. MMR Retriever
mmr_retriever = db.as_retriever(
search_type="mmr",
search_kwargs={"k": 3, "fetch_k": 10, "lambda_mult": 0.5}
)
# 5. MultiQuery Retriever
llm = ChatOpenAI(model="gpt-4o-mini")
multiquery_retriever = MultiQueryRetriever.from_llm(
retriever=db.as_retriever(),
llm=llm
)
# 6. 검색 비교
query = "인공지능의 미래"
print("=== 기본 검색 ===")
for doc in basic_retriever.invoke(query):
print(f"- {doc.page_content[:50]}...")
print("\n=== MMR 검색 ===")
for doc in mmr_retriever.invoke(query):
print(f"- {doc.page_content[:50]}...")
print("\n=== MultiQuery 검색 ===")
for doc in multiquery_retriever.invoke(query):
print(f"- {doc.page_content[:50]}...")