Skip to main content

재순위화 (Reranking)

재순위화는 1차 검색(retrieval)으로 가져온 문서들의 순서를 질문과의 관련성에 따라 다시 정렬하는 과정입니다. 1차 검색은 속도를 위해 근사적 유사도를 사용하지만, 재순위화는 더 정밀한 모델로 관련성을 재평가합니다.

왜 재순위화가 필요한가?

단계모델속도정밀도
1차 검색 (Bi-encoder)쿼리/문서 독립 임베딩빠름 (ms)보통
재순위화 (Cross-encoder)쿼리+문서 동시 입력느림 (100ms~)높음

전략 비교 종합

재순위화 방법정밀도속도비용다국어적합한 경우
Cross-encoder (BGE)매우 높음느림무료 (로컬)O한국어 프로덕션
Cohere Rerank매우 높음보통유료 APIO빠른 통합, 관리형
ColBERT높음빠름무료 (로컬)제한적대규모 문서, 속도 중시
FlashRank보통매우 빠름무료 (로컬)제한적프로토타이핑, 경량 환경

재순위화 파이프라인 패턴

# 전체 파이프라인: 검색 → 재순위화 → 생성
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_community.cross_encoders import HuggingFaceCrossEncoder
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain.retrievers import ContextualCompressionRetriever

# 1차 검색: 넓게 가져오기 (top-20)
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma(collection_name="docs", embedding_function=embeddings)
base_retriever = vectorstore.as_retriever(search_kwargs={"k": 20})

# 재순위화: 정밀하게 좁히기 (top-4)
model = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3")
compressor = CrossEncoderReranker(model=model, top_n=4)

retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=base_retriever,
)

# 사용
results = retriever.invoke("질문")
# → 20개 후보에서 가장 관련성 높은 4개만 반환
한국어 RAG에서는 BAAI/bge-reranker-v2-m3를 기본으로 추천합니다. 다국어 성능이 뛰어나고 한국어에서도 높은 정밀도를 보입니다. API 호출 방식을 선호한다면 Cohere Rerank v3.5를 사용하세요.

세부 전략 가이드