4편에서는 FAQ 기반 문서 재설계를 통해 답변 품질을 극적으로 끌어올렸고, 5편에서는 메타데이터 필터링으로 검색의 정확도와 신뢰도를 높였습니다.
이제 마지막 퍼즐 한 조각이 남았습니다. 바로 '하이브리드 검색(Hybrid Search)'입니다. 이번 글에서는 RAG 시스템의 검색 품질을 극대화하기 위해 하이브리드 검색을 도입한 과정과, 그 테스트 결과에서 얻은 예상치 못한 교훈을 공유합니다.
1. 벡터(Vector) 검색의 2% 부족함
현재까지 구축한 챗봇은 벡터 검색만으로도 약 90%의 높은 정확도를 보여주고 있습니다. 벡터 검색은 문맥과 의미(Semantic)를 이해하는 데 탁월하기 때문입니다.
질문: "결제가 안 될 때 어떻게 하나요?"
벡터 검색 결과:
"결제 실패 처리 방법" 문서를 찾아냄 (성공 ✅)
"Error Handling Guide" 문서도 찾아냄 (성공 ✅)
하지만 벡터 검색에도 치명적인 약점이 있습니다. 바로 '정확한 키워드 매칭'입니다.
예를 들어, "ABC 서비스 API 키는 어디서 받나요?"라고 물었을 때, 벡터 검색은 의미적으로 비슷한 문서들을 가져옵니다.
- "API 키 발급 방법" (일반적인 가이드)
- "서비스 설정 가이드" (관련 있어 보임)
- "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 기반 업무 지식 챗봇 만들기]의 핵심 개발 과정이 마무리되었습니다.
- 기획: 막연한 아이디어에서 구체적 설계로
- 위기: 답변 품질의 한계 직면
- 도약: FAQ 문서 재설계 (Quality)
- 정교화: 메타데이터 필터링 (Precision)
- 완성: 하이브리드 검색 (Stability)
이번 프로젝트를 통해 단순히 랭체인(LangChain) 사용법을 익힌 것을 넘어, "AI 서비스를 만들 때 데이터를 어떻게 바라봐야 하는가"에 대한 귀중한 경험을 얻었습니다.
다음 글에서는 이 프로젝트의 최종 회고와, 앞으로의 고도화 계획을 정리하며 시리즈를 마무리하겠습니다.
'사이드프로젝트' 카테고리의 다른 글
| [사이드 프로젝트] #2. RAG 챗봇 개발기 (5) - '메타데이터'를 활용한 필터링 (1) | 2025.11.13 |
|---|---|
| [사이드 프로젝트] #2 RAG 챗봇 개발기 (4) - 문서를 FAQ로 바꿨더니 답변 품질이 10배 향상됐다 (1) | 2025.11.08 |
| [사이드 프로젝트] #2. RAG 기반 '업무 지식' AI 챗봇 개발기 (3) - RAG 구축 삽질기 (0) | 2025.10.29 |
| [사이드 프로젝트] #2. RAG 기반 '업무 지식' AI 챗봇 개발기 (2) - 챗봇 프로토타입 및 RAG 기본개념정리 (0) | 2025.10.24 |
| [사이드 프로젝트] #2. RAG 기반 '업무 지식' AI 챗봇 개발기 (1) (0) | 2025.10.22 |