본문 바로가기
사이드프로젝트

[사이드 프로젝트] #2. RAG 챗봇 개발기 (6) - 하이브리드 검색과 '의외의' 결과

by Jaejin Sim 2025. 11. 21.
반응형

4편에서는 FAQ 기반 문서 재설계를 통해 답변 품질을 극적으로 끌어올렸고, 5편에서는 메타데이터 필터링으로 검색의 정확도와 신뢰도를 높였습니다.

이제 마지막 퍼즐 한 조각이 남았습니다. 바로 '하이브리드 검색(Hybrid Search)'입니다. 이번 글에서는 RAG 시스템의 검색 품질을 극대화하기 위해 하이브리드 검색을 도입한 과정과, 그 테스트 결과에서 얻은 예상치 못한 교훈을 공유합니다.

1. 벡터(Vector) 검색의 2% 부족함

현재까지 구축한 챗봇은 벡터 검색만으로도 약 90%의 높은 정확도를 보여주고 있습니다. 벡터 검색은 문맥과 의미(Semantic)를 이해하는 데 탁월하기 때문입니다.

질문: "결제가 안 될 때 어떻게 하나요?"

벡터 검색 결과:
"결제 실패 처리 방법" 문서를 찾아냄 (성공 ✅)
"Error Handling Guide" 문서도 찾아냄 (성공 ✅)

 

하지만 벡터 검색에도 치명적인 약점이 있습니다. 바로 '정확한 키워드 매칭'입니다.

예를 들어, "ABC 서비스 API 키는 어디서 받나요?"라고 물었을 때, 벡터 검색은 의미적으로 비슷한 문서들을 가져옵니다.

  1. "API 키 발급 방법" (일반적인 가이드)
  2. "서비스 설정 가이드" (관련 있어 보임)
  3. "ABC 서비스 API 키 발급" (우리가 찾는 정답!)

의미적으로는 1번과 2번도 매우 가깝기 때문에, 정작 고유명사('ABC')가 포함된 3번 문서가 뒤로 밀리거나 검색되지 않을 수 있습니다.

2. 해결책: 하이브리드 검색 (Vector + Keyword)

이 문제를 해결하기 위해 도입한 것이 하이브리드 검색입니다.

  • 벡터 검색 (Dense): 문맥과 의미를 파악 (60% 비중)
  • BM25 검색 (Sparse): 정확한 단어/키워드 매칭을 파악 (40% 비중)

이 두 가지 검색 결과를 **앙상블(Ensemble)**하여, 의미도 통하고 핵심 키워드도 포함된 최적의 문서를 찾아내는 방식입니다.

💡 잠깐, BM25가 뭔가요?

단순한 SQL의 LIKE %검색어%와는 다릅니다. BM25는 '똑똑한 키워드 검색' 알고리즘입니다.

단순히 단어가 포함되었는지만 보는 것이 아니라, "이 문서에서 해당 단어가 얼마나 자주 등장하는가?"(빈도)"이 단어가 전체 문서군에서 얼마나 희귀한가?"(희귀도)를 따져 점수를 매깁니다.

3. 구현: LangChain으로 앙상블 구성하기

구현은 생각보다 간단합니다. LangChain의 EnsembleRetriever를 사용하면 됩니다.

from langchain.retrievers import BM25Retriever, EnsembleRetriever

# 1. 벡터 검색기 (의미 기반)
vector_retriever = vector_store.as_retriever(
    search_kwargs={"k": 5}
)

# 2. BM25 검색기 (키워드 기반)
# 가지고 있는 모든 FAQ 문서(documents)를 기반으로 생성
bm25_retriever = BM25Retriever.from_documents(
    documents,
    k=5
)

# 3. 앙상블 (하이브리드 조합)
ensemble_retriever = EnsembleRetriever(
    retrievers=[vector_retriever, bm25_retriever],
    weights=[0.6, 0.4]  # 벡터 60%, BM25 40% 가중치 부여
)

# 검색 실행
results = ensemble_retriever.invoke(query)

이렇게 하면 벡터 검색 결과와 BM25 검색 결과를 가중치에 따라 합산(Weighted Sum)하고, 최종 순위(Rank)를 다시 매겨 상위 문서를 반환합니다.

4. 테스트 결과: 어라? 차이가 없네? 😮

구현을 마치고 부푼 기대를 안고 테스트를 진행했습니다. 실제 질문 30개를 던져 정확도를 측정했습니다.

검색 방식  정확도  비고
벡터 검색 27/30 (90%) 의미 기반
하이브리드 27/30 (90%) 벡터 + BM25

놀랍게도 결과에 차이가 없었습니다. 하이브리드 검색을 도입하면 정확도가 비약적으로 상승할 줄 알았는데, 왜 그대로였을까요?

5. 원인 분석 및 교훈: 기술보다 중요한 것

실망감을 뒤로하고 원인을 분석해 보니, 오히려 매우 긍정적인 신호를 발견할 수 있었습니다.

1) 문서의 구조가 너무 좋았다 (Perfect Structure)

가장 큰 이유는 4편에서 진행한 'FAQ 문서 재설계' 덕분이었습니다.

이미 문서가 "1 질문 = 1 답변" 형태로 완벽하게 쪼개져 있고, 질문 의도가 명확히 반영되어 있다 보니, 벡터 검색만으로도 이미 정답을 100% 가까이 찾아내고 있었던 것입니다.

2) 데이터셋의 크기 (Small Data)

현재 FAQ 문서는 약 33개입니다. 데이터가 적고 문서 품질이 높으면 벡터 검색만으로도 충분합니다. 하이브리드 검색은 문서가 수백, 수천 개로 늘어나서 벡터 간의 의미가 겹칠 때 진가를 발휘합니다.

3) 핵심 교훈

이번 결과에서 저는 RAG 개발의 가장 중요한 본질을 깨달았습니다.

"좋은 임베딩 모델이나 복잡한 검색 알고리즘보다, 잘 설계된 문서 구조(Data Quality)가 훨씬 중요하다."
  • 4편(FAQ 문서화): 정확도 20% → 90% (대도약 🚀)
  • 6편(하이브리드): 정확도 90% → 90% (유지)

결국 가장 큰 성능 향상은 코드가 아니라 데이터를 다루는 방식에서 나왔습니다.

6. 마치며: '보험'으로서의 하이브리드

비록 당장의 수치 변화는 없었지만, 하이브리드 검색 코드는 그대로 유지하기로 했습니다. 그 이유는 '확장성''안정성' 때문입니다.

  • 확장성: 향후 문서가 500개, 1000개로 늘어나면 벡터 검색만으로는 한계가 옵니다. 그때 하이브리드 검색이 진가를 발휘할 것입니다.
  • 안정성: 사용자의 오타나, 매우 특이한 고유명사 검색 등 벡터가 놓칠 수 있는 예외 케이스를 BM25가 방어해 주는 '보험' 역할을 합니다.

이로써 약 한 달간 진행된 [RAG 기반 업무 지식 챗봇 만들기]의 핵심 개발 과정이 마무리되었습니다.

  1. 기획: 막연한 아이디어에서 구체적 설계로
  2. 위기: 답변 품질의 한계 직면
  3. 도약: FAQ 문서 재설계 (Quality)
  4. 정교화: 메타데이터 필터링 (Precision)
  5. 완성: 하이브리드 검색 (Stability)

이번 프로젝트를 통해 단순히 랭체인(LangChain) 사용법을 익힌 것을 넘어, "AI 서비스를 만들 때 데이터를 어떻게 바라봐야 하는가"에 대한 귀중한 경험을 얻었습니다.

다음 글에서는 이 프로젝트의 최종 회고와, 앞으로의 고도화 계획을 정리하며 시리즈를 마무리하겠습니다.

반응형