Retriever로 관련 문서 검색하기

gclee·2026년 1월 21일

LangChain-RAG

목록 보기
12/13

Retriever는 벡터 스토어에서 질문과 관련된 문서를 검색하는 인터페이스입니다. 본 포스트에서는 다양한 Retriever 옵션과 고급 검색 기법을 정리합니다.


준비 사항

  • Python 3.9 이상
  • Chroma DB 또는 FAISS 벡터 스토어 구축 완료
  • OpenAI API 키 설정 (.env 파일) - MultiQueryRetriever 사용 시

라이브러리 설치

Retriever를 사용하기 위해 필요한 패키지를 설치합니다.

pip install langchain langchain-chroma langchain-huggingface langchain-openai python-dotenv
패키지설명
langchainMultiQueryRetriever 등 고급 Retriever
langchain-chromaChroma 벡터 스토어
langchain-huggingfaceHuggingFace 임베딩 모델
langchain-openaiMultiQueryRetriever에서 LLM 사용 시
python-dotenv.env 파일에서 환경 변수 로드

기본 Retriever

as_retriever()

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 옵션

search_kwargs 로 검색 동작을 세밀하게 조정할 수 있습니다.

  • k: 반환할 문서 개수
retriever = db.as_retriever(
    search_kwargs={"k": 5}  # 상위 5개 문서 반환
)

검색할 문서 개수를 지정합니다.

search_type 옵션

search_type 으로 검색 알고리즘을 선택할 수 있습니다.

타입설명
similarity기본 유사도 검색
similarity_score_threshold점수 임계값 기반 검색
mmr다양성을 고려한 검색
# 기본 유사도 검색
retriever = db.as_retriever(search_type="similarity")

similarity_score_threshold

유사도 점수가 특정 임계값 이상인 문서만 반환합니다.

retriever = db.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={
        "score_threshold": 0.7  # 70% 이상 유사한 문서만
    }
)

docs = retriever.invoke("인공지능 기술")
print(f"검색된 문서: {len(docs)}개")

임계값을 높이면 더 관련성 높은 문서만 반환되고, 낮추면 더 많은 문서가 반환됩니다.


MMR (Maximal Marginal Relevance)

MMR은 검색 결과의 다양성을 고려합니다. 단순히 유사한 문서만 반환하는 것이 아니라, 서로 다른 내용의 문서를 포함하여 정보의 다양성을 확보합니다.

retriever = db.as_retriever(
    search_type="mmr",
    search_kwargs={
        "k": 4,
        "fetch_k": 10,
        "lambda_mult": 0.5
    }
)

docs = retriever.invoke("인공지능의 활용 분야")

MMR 파라미터

파라미터설명
k최종 반환할 문서 개수
fetch_k초기에 가져올 후보 문서 개수
lambda_mult다양성 조절 (0: 최대 다양성, 1: 최대 유사도)

lambda_mult 동작

  • 1에 가까울수록: 유사도 우선 (비슷한 내용의 문서)
  • 0에 가까울수록: 다양성 우선 (서로 다른 내용의 문서)

MultiQueryRetriever

사용자 질문을 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)}개")

동작 원리

  1. 사용자 질문: "여행 계획 세우기"
  2. LLM이 3가지 버전으로 확장:
    • "여행 일정을 어떻게 짜면 좋을까요?"
    • "여행을 준비하는 데 필요한 팁은?"
    • "효과적인 여행 코스 구성 방법은?"
  3. 각 질문으로 검색 후 결과 병합

디버그 모드

내부 동작을 확인하려면 디버그 모드를 활성화합니다.

import langchain
langchain.debug = True

docs = retriever.invoke("여행 계획 세우기")

Retriever 비교 정리

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]}...")

0개의 댓글