AI 챗봇의 거짓말(환각)을 막는 기술, 리랭킹(Re-ranking)
AI 챗봇에게 중요한 질문을 던졌는데, 그럴듯하지만 사실과 전혀 다른 답변을 받아 당황한 경험이 있으신가요? 이는 LLM(거대 언어 모델)이 마치 사실인 것처럼 거짓 정보를 만들어내는 '환각(Hallucination)' 현상 때문입니다. RAG(검색 증강 생성)는 AI가 외부 문서를 참조하게 함으로써 이러한 환각을 줄이는 강력한 기술이지만, 때로는 이 RAG 시스템마저도 엉뚱한 문서를 참고하여 잘못된 답변을 내놓기도 합니다.
왜 이런 일이 발생할까요? 기본적인 RAG의 검색기는 속도를 위해 키워드나 표면적인 의미가 비슷한 문서를 우선적으로 가져오는 경향이 있습니다. 하지만 문맥까지 깊이 이해하지는 못하기 때문에, 정작 질문의 핵심과는 거리가 먼 문서를 '정답'이라고 착각하고 LLM에게 전달하는 실수를 저지르곤 합니다.
오늘은 이 문제를 해결하고 AI 답변의 신뢰도를 극적으로 끌어올리는 고급 RAG 기법, '리랭킹(Re-ranking)'에 대해 알아보겠습니다. 『LLM과 RAG로 구현하는 AI 애플리케이션』 7장의 핵심 내용을 바탕으로, 리랭킹의 원리와 실제 구현 코드를 초보자도 이해하기 쉽게 설명해 드립니다.
리랭킹의 작동 원리: 빠르고! 정확하게!
리랭킹은 이름 그대로 '순위를 다시 매기는' 기술입니다. 한 번의 검색으로 끝내는 것이 아니라, 두 단계에 걸쳐 더 정교하게 정답을 찾아내는 방식이죠. 책에서는 이 과정을 '이중 필터링'에 비유하며, 서로 다른 두 가지 검색 모델의 장점만을 결합한 영리한 접근법이라고 설명합니다.
1단계: 빠른 초기 검색 (Bi-Encoder 방식)
역할: 넓은 그물로 물고기를 잡듯, 질문과 조금이라도 관련 있어 보이는 문서들을 최대한 빠르게 많이 찾아냅니다.
작동 방식: 우리가 흔히 사용하는 RAG 검색 방식으로, 질문과 문서를 각각 독립적인 숫자 벡터로 변환한 뒤, 벡터 값이 가장 유사한 문서들을 후보로 올립니다. 속도가 매우 빠르다는 장점이 있습니다.
한계: 속도를 위해 문맥을 깊이 파악하지 않아, 관련성이 떨어지는 문서가 상위 순위에 포함될 수 있습니다.
2단계: 정밀한 재평가 (Cross-Encoder 방식)
역할: 그물로 건져 올린 물고기 중, 우리가 진짜 찾던 물고기만 꼼꼼히 골라내는 작업입니다.
작동 방식: 1단계에서 추려진 소수의 후보 문서들을 가져와, '질문 + 문서'를 한 쌍으로 묶어 문맥적 관련성을 매우 정밀하게 재평가합니다. "이 문서가 정말 이 질문에 대한 정답이 맞는가?"를 심층적으로 판단하는 것이죠.
장점: 정확도가 매우 높습니다.
단점: 모든 문서를 일일이 대조해야 하므로 처리 속도가 매우 느립니다.
리랭킹은 이 두 가지 방식을 결합하여, 빠른 속도(Bi-Encoder)와 높은 정확도(Cross-Encoder)라는 두 마리 토끼를 모두 잡는 것입니다.
실전! 크로스 인코더로 RAG 챗봇 성능 업그레이드하기
이제 『LLM과 RAG로 구현하는 AI 애플리케이션』 7.3.1절의 예제를 따라, 리랭킹을 적용했을 때 RAG 시스템의 답변 품질이 얼마나 달라지는지 직접 확인해 보겠습니다.
1단계: 환경 설정 및 데이터 준비
먼저 실습에 필요한 라이브러리를 설치하고, 분석할 대상인 '2023 북한인권보고서' PDF 파일을 준비합니다.
Bash
pip install llama-index==0.12 sentence-transformers==4.1.0 openai==1.79.0
Python
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader,
Settings
from llama_index.llms.openai import OpenAI
from llama_index.embeddings.openai import OpenAIEmbedding
from llama_index.core.postprocessor import SentenceTransformerRerank
# LLM, 임베딩 모델, 청킹 방식 등 전역 설정
Settings.llm = OpenAI(model="gpt-4.1", temperature=0.2)
Settings.embed_model = OpenAIEmbedding(model="text-embedding-3-large")
Settings.chunk_size = 300
Settings.chunk_overlap = 100
# PDF 문서 로드 및 인덱스 생성
documents = SimpleDirectoryReader(input_files=["2023_북한인권보고서.pdf"]).load_data()
index = VectorStoreIndex.from_documents(documents)
2단계: 두 종류의 검색 엔진 준비하기
리랭킹의 효과를 비교하기 위해, 리랭킹을 적용하지 않은 기본 검색 엔진과 리랭킹을 적용한 리랭크 검색 엔진 두 가지를 모두 만들어 보겠습니다.
Python
# 1. 리랭킹 없는 기본 검색 엔진 (1단계 검색만 수행)
basic_query_engine = index.as_query_engine(
similarity_top_k=4 # 유사도가 높은 상위 4개 문서를 검색
)
# 2. 리랭킹 모델(크로스 인코더) 설정
# 책에서는 'BAAI/bge-reranker-v2-m3' 모델을 사용합니다.
reranker = SentenceTransformerRerank(
model="BAAI/bge-reranker-v2-m3",
top_n=2 # 1차 검색된 4개 중 가장 관련성 높은 2개만 최종 선택
)
# 3. 리랭킹을 적용한 검색 엔진
rerank_query_engine = index.as_query_engine(
similarity_top_k=4,
node_postprocessors=[reranker] # 검색 후 리랭커를 적용
)
basic_query_engine은 1단계 검색만으로 4개의 문서를 찾아 답변을 생성합니다.
rerank_query_engine은 똑같이 4개의 문서를 찾은 뒤, reranker를 이용해 이 4개 문서의 순위를 다시 매기고 가장 정확한 2개만 골라내어 답변을 생성합니다.
성능 비교: 리랭킹의 놀라운 효과
이제 동일한 질문을 두 엔진에 각각 던져보고, 그 차이를 확인해 보겠습니다. 질문은 보고서의 아주 구체적인 내용을 묻는 것입니다.
질문: "19년 말 평양시 소재 기업소에서 달마다 배급받은 음식"
[Before] 리랭킹 없는 기본 검색 결과
Python
basic_response = basic_query_engine.query(query)
print(f"답변: {basic_response.response}")
print("\n[참고한 문서들]:")
for i, node in enumerate(basic_response.source_nodes):
print(f"--- 문서 {i+1} ---")
print(node.node.get_content())
실행 결과:
답변: 2019년에 평양시의 기업소에서는 매월 쌀, 설탕, 기름, 야채, 돼지고기 등을 배급받았다는 증언이 있었습니다... (중략)
[참고한 문서들]:
- 문서 1: ...2019년 평양의 외화벌이 사업소에서는 보수 50달러를 현금으로 지급... (질문과 다른 내용) - 문서 2: ...배급량의 80%는 강냉이로 쌀은 명절에만 배급... (일반적인 배급 상황) - 문서 3: ...2019년 중앙당 산하의 기업소에서 매월 쌀 6㎏, 기름 5ℓ, 설탕 2㎏, 돼지고기 2㎏... 받았다는 증언이 있었다. (정답이 포함된 문서)
- 문서 4: ...기관·기업소의 상황에 따라 식량배급량에 차이가... (일반적인 상황)
기본 검색 엔진은 정답이 포함된 문서 3을 찾아내긴 했지만, 관련성이 떨어지는 다른 문서들과 섞어서 LLM에게 전달했습니다. 이 때문에 답변이 다소 포괄적으로 생성되었습니다.
[After] 리랭킹을 적용한 검색 결과
Python
rerank_response = rerank_query_engine.query(query)
print(f"답변: {rerank_response.response}")
print("\n[참고한 문서들]:")
for i, node in enumerate(rerank_response.source_nodes):
print(f"--- 문서 {i+1} ---")
print(node.node.get_content())
실행 결과:
답변: 2019년 말 평양시의 기업소 배급 상황은 두 가지 증언이 있습니다. 한 기업소 운전원은 매월 쌀, 설탕, 기름, 야채, 돼지고기 등을 배급받았다고 증언했습니다. 중앙당 산하 기업소의 경우 매월 쌀 6kg, 기름 5L, 설탕 2kg, 맛내기 2봉지, 돼지고기 2kg, 닭고기 1마리 정도를 배급받았다는 증언이 있었습니다.
[참고한 문서들]:
- 문서 1: ...2019년 중앙당 산하의 기업소에서 매월 쌀 6㎏, 기름 5ℓ, 설탕 2㎏, 돼지고기 2㎏... 받았다는
증언이 있었다. (정답 문서가 1순위로!)
- 문서 2: ...배급량의 80%는 강냉이로 쌀은 명절에만 배급...
결과가 놀랍도록 달라졌습니다. 리랭커는 4개의 후보 문서 중에서 질문의 의도("19년 말", "평양시", "배급받은 음식")와 가장 정확하게 일치하는 문서를 1순위로 끌어올렸습니다. 그리고 관련성이 떨어지는 문서들은 과감히 필터링했습니다. 그 결과, LLM은 더 정확하고 구체적인 정보를 바탕으로 훨씬 신뢰도 높은 답변을 생성할 수 있었습니다.
결론: AI의 환각을 잠재우는 신뢰의 계층
리랭킹은 RAG 시스템에 '정밀 검수'라는 신뢰의 계층을 추가하는 것과 같습니다. 빠른 1차 검색으로 시간을 절약하고, 강력한 2차 평가로 정확도를 보장하는 이 방식은 AI 챗봇이 더 이상 '거짓말'을 하지 않고, 우리가 제공한 데이터를 기반으로 정확한 답변만을 하도록 만드는 핵심 기술입니다.
오늘 실습한 크로스 인코더 기반 리랭킹은 『LLM과 RAG로 구현하는 AI 애플리케이션』 7장의 핵심 내용 중 하나입니다. 책에서는 이 외에도 LLM을 직접 리랭커로 사용하는 방법, 그리고 'Hyde'와 같이 검색 성능을 높이는 또 다른 창의적인 기법까지, AI 챗봇의 신뢰도를 한 단계 끌어올릴 수 있는 다양한 고급 RAG 전략을 상세히 다룹니다.
더 똑똑하고 신뢰할 수 있는 AI를 만들고 싶으신가요? 이 책과 함께 여러분의 RAG 시스템을 한 단계 업그레이드해 보세요.
https://wikibook.co.kr/llm-rag/
이 책은 빠르게 진화하는 AI 기술 트렌드를 단순히 따라가는 데 그치지 않고 실제 구현과 통합에 필요한 핵심 통찰과 실용적인 해법을 제시하는 완성도 높은 실무 가이드입니다. 생성형 AI 기술의 주요 흐름을 실무 관점에서 체계적으로 다뤄 개발자와 기획자 모두가 RAG 시스템을 손쉽게 구축할 수 있도록 구성했습니다.