문맥을 이해하는 검색 시스템을 만들기 위해 시맨틱 청킹과 Re-ranking 모델을 적용한 과정을 정리한 성장 기록이에요.
[테스트게시물이니 내용은 참고하지마세요]단순한 키워드 매칭을 넘어, 문맥을 이해하는 검색 시스템을 구축하는 과정은 생각보다 험난했어요. 이 글에서는 RAG(Retrieval-Augmented Generation) 파이프라인 성능을 높이기 위해 도입한 시맨틱 청킹(Semantic Chunking)과 Re-ranking 모델 적용 경험을 다뤄요.
초기 시스템은 고정된 길이(Fixed-size)로 문서를 분할해 벡터 스토어에 저장했어요. 구현이 빠르다는 장점이 있었지만, 문장의 문맥이 잘리거나 불필요한 노이즈가 함께 검색되는 문제가 자주 발생했어요. 특히 전문적인 도메인 지식을 다룰 때는 이런 현상이 답변의 신뢰도를 크게 떨어뜨렸어요.
1. 시맨틱 청킹으로의 전환
문맥의 연속성을 보장하기 위해 토큰 수를 기준으로 나누는 대신 의미 단위 청킹(Semantic Chunking) 알고리즘을 도입했어요. 문장 간 코사인 유사도를 측정하고, 유사도가 급격히 떨어지는 지점을 분할 지점으로 지정하는 방식이에요.
“문서의 논리적 흐름이 끊기지 않는 청크 크기를 유지했을 때, LLM의 환각(Hallucination) 발생률이 35% 이상 감소했어요.”
2. Re-ranker 도입 효과
1차 벡터 검색 결과에서 상위 20개 문서를 추출한 뒤, 크로스 인코더(Cross-encoder) 기반의 Re-ranker 모델을 거쳐 최종 5개 문서를 LLM 컨텍스트로 전달하는 2단계 파이프라인을 구축했어요.
# Re-ranking 파이프라인 예시 코드
def retrieve_and_rerank(query, top_k=5):
initial_docs = vector_store.similarity_search(query, k=20)
scores = reranker_model.predict([(query, d.page_content) for d in initial_docs])
reranked_docs = [doc for _, doc in sorted(zip(scores, initial_docs), reverse=True)]
return reranked_docs[:top_k]
3. 성능 비교 요약
| 청킹 방식 | 검색 정확도 (Hit@5) | 평균 응답 속도 |
|---|---|---|
| 고정 크기 분할 (500 tokens) | 62.4% | 120ms |
| 시맨틱 청킹 | 78.1% | 145ms |
| 시맨틱 청킹 + Re-ranker | 91.3% | 210ms |
원본 상세 페이지 샘플을 바탕으로 옮긴 기록이에요. 수치와 사례는 샘플 콘텐츠의 값을 그대로 보존했어요.
forum 토론 및 피드백 0
아직 작성된 피드백이 없습니다. 첫 번째 생각을 남겨보세요!