본문 바로가기
Artificial Intelligence/60. Python

[PYTHON] RAG 시스템 성능 저하 해결을 위한 Re-ranking 도입 방법과 7가지 구현 전략

by Papa Martino V 2026. 4. 25.
728x90

RAG(Retrieval-Augmented Generation)
RAG (Retrieval-Augmented Generation)

최근 LLM(Large Language Model)의 할루시네이션(Hallucination)을 억제하기 위한 해법으로 RAG(Retrieval-Augmented Generation)가 각광받고 있습니다. 하지만 단순히 벡터 DB에서 유사도 기반으로 문서를 검색하는 것만으로는 충분하지 않습니다. 검색된 문서 중 정답과 관련 없는 '노이즈'가 섞여 있을 경우, LLM은 잘못된 정보를 바탕으로 답변을 생성하기 때문입니다. 본 포스팅에서는 RAG의 품질을 결정짓는 핵심 단계인 Re-ranking(재정렬)의 필요성을 살펴보고, 파이썬을 이용해 이를 실무에 바로 적용하는 7가지 해결 전략을 심도 있게 다룹니다.


1. 왜 Re-ranking이 필요한가? 검색 품질의 한계 해결

표준적인 RAG 시스템은 임베딩 모델을 이용한 Bi-Encoder 구조를 사용합니다. 이는 수만 개의 문서 중 유사한 것을 빠르게 찾는 데는 효율적이지만, 쿼리와 문서 간의 정교한 의미적 상관관계를 파악하는 데는 한계가 있습니다. Re-ranking 단계는 검색된 상위 K개의 문서를 Cross-Encoder 모델을 통해 다시 한번 정밀하게 평가하여, 실제 정답에 가까운 문서를 최상단으로 끌어올리는 역할을 합니다.

2. 단순 검색(Retrieval)과 재정렬(Re-ranking)의 차이 분석

시스템 구축 시 두 단계의 역할을 명확히 구분하는 것이 리소스 관리의 핵심입니다.

비교 항목 1단계: Retrieval (Dense/Sparse) 2단계: Re-ranking (Cross-Encoder)
처리 속도 매우 빠름 (밀리초 단위) 상대적으로 느림 (모델 연산 필요)
대상 범위 전체 문서 저장소 (수백만 개 가능) 검색된 상위 K개 (보통 10~50개)
연산 방식 벡터 유사도 (Cosine Similarity 등) 쿼리-문서 쌍 간의 딥러닝 어텐션 연산
정확도 낮음 (의미적 맥락 파악 부족) 매우 높음 (정밀한 랭킹 부여)
주요 역할 후보군 추출 LLM 전달 정보의 순위 최적화

3. 실무 RAG 성능 극대화를 위한 7가지 Re-ranking 구현 예제

파이썬 생태계에서 가장 널리 쓰이는 도구들을 활용하여 실제 프로덕션 수준의 Re-ranking 시스템을 구축하는 방법을 제시합니다.

Example 1: Cross-Encoder를 이용한 기본 Re-ranker 구현

Hugging Face의 sentence-transformers를 활용하여 쿼리와 문서의 점수를 직접 계산합니다.

from sentence_transformers import CrossEncoder

# 1. 모델 로드 (BGE-Reranker 등 SOTA 모델 권장)
model = CrossEncoder('BAAI/bge-reranker-base')

query = "RAG 시스템에서 Re-ranking의 비용 효율성은?"
documents = [
    "Re-ranking은 LLM의 연산 비용을 최적화하는 데 기여합니다.",
    "RAG는 외부 지식을 검색하여 답변을 생성하는 기법입니다.",
    "파이썬은 데이터 과학에 널리 쓰이는 언어입니다."
]

# 2. 쿼리-문서 쌍 생성 및 스코어 계산
pairs = [[query, doc] for doc in documents]
scores = model.predict(pairs)

# 3. 결과 정렬
reranked_results = sorted(zip(documents, scores), key=lambda x: x[1], reverse=True)
print(reranked_results)
        

Example 2: Cohere Rerank API를 활용한 서버리스 구현

직접 GPU 서버를 운영하기 어려운 경우, 외부 API를 통해 고성능 Re-ranking을 해결할 수 있습니다.

import cohere

co = cohere.Client('YOUR_API_KEY')

results = co.rerank(
    query=query,
    documents=documents,
    top_n=3,
    model='rerank-multilingual-v2.0'
)

for res in results:
    print(f"Document: {res.document['text']}, Score: {res.relevance_score}")
        

Example 3: FlashRank를 이용한 경량형 CPU Re-ranking

성능 손실을 최소화하면서도 CPU 환경에서 매우 빠르게 작동하는 Light-weight 전략입니다.

from flashrank import Ranker, RerankRequest

# 초경량 모델 로드
ranker = Ranker(model_name="ms-marco-TinyBERT-L-2-v2", cache_dir="/opt")

rerank_request = RerankRequest(query=query, passages=[{"text": d} for d in documents])
results = ranker.rerank(rerank_request)

# 결과 출력 (Fast & Efficient)
print(results)
        

Example 4: 앙상블 검색(Hybrid Search)과 Reciprocal Rank Fusion(RRF)

BM25(키워드)와 벡터 검색 결과를 수학적으로 결합한 뒤 Re-ranking을 수행하여 검색 누락을 해결합니다.

def rrf_score(ranks, k=60):
    score = 0
    for rank in ranks:
        score += 1 / (rank + k)
    return score

# 각 검색 엔진의 순위를 입력받아 통합 점수 산출
# 이후 상위 결과를 Cross-Encoder로 전달하는 파이프라인 구성
        

Example 5: LangChain의 Contextual Compression Retriever 연동

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CohereRerank
from langchain_community.vectorstores import FAISS

# 리트리버와 리랭커 결합
compressor = CohereRerank()
compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=retriever # 기존 벡터 DB 리트리버
)

compressed_docs = compression_retriever.get_relevant_documents("LLM 성능 개선 방법")
        

Example 6: 비대칭 시맨틱 검색(Asymmetric Search) 최적화

질문은 짧고 문서는 긴 실제 상황을 고려하여, 문서의 핵심 문장(Summary)을 기준으로 Re-ranking을 수행합니다.

# 팁: 문서 전체를 모델에 넣기보다, 검색된 청크(Chunk) 주변 문맥을 포함하여 
# Cross-Encoder에 전달하면 정확도가 15% 이상 향상됩니다.
        

Example 7: 정답 신뢰도 임계값(Threshold) 필터링

def filter_by_score(reranked_results, threshold=0.7):
    # Re-ranking 점수가 낮은 문서는 LLM 컨텍스트에서 제외하여 환각 증세 차단
    return [doc for doc, score in reranked_results if score > threshold]
        

4. Re-ranking 도입 시 주의할 점 및 문제 해결(FAQ)

  • 지연 시간(Latency): Re-ranking은 모델 추론이 동반되므로 상위 K(Top-K) 값을 너무 크게 설정하지 마세요 (현업에서는 보통 20-30개 적당).
  • Lost in the Middle 현상: LLM은 컨텍스트 중간에 있는 정보를 잘 인식하지 못합니다. Re-ranking을 통해 가장 중요한 정보를 반드시 '첫 번째'나 '마지막'에 배치하십시오.
  • 데이터 보안: 외부 API 사용 시 민감 정보가 포함된 문서가 외부로 전송될 수 있으므로, 보안이 중요하다면 오픈소스 로컬 모델(BGE-Reranker) 사용을 권장합니다.

5. 결론: 더 스마트한 RAG를 향하여

단순한 Retrieval만으로 구성된 RAG는 프로덕션 환경에서 사용자들의 질문을 견디기 어렵습니다. Re-ranking은 시스템에 약간의 지연 시간을 추가하지만, 그 대가로 LLM 답변의 일관성정확도를 획기적으로 보장해 줍니다. 오늘 소개한 7가지 전략을 통해 여러분의 파이썬 기반 RAG 프로젝트의 완성도를 한 단계 끌어올려 보시기 바랍니다.


참고 문헌 및 내용 출처

  • Gao, Y., et al. (2024). "Retrieval-Augmented Generation for Large Language Models: A Survey." arXiv.
  • Hugging Face: "Sentence Transformers: Cross-Encoders Documentation."
  • Cohere AI Blog: "Rerank: A Powerful Way to Boost Search Relevance."
  • Pinecone Learning Center: "Rag-stack: Re-ranking for Search."
728x90