RAG 시스템 청크 크기 최적화 실험

문제 상황

사내 기술 문서 검색 RAG 시스템을 운영 중인데, 사용자들이 검색 결과가 부정확하다는 피드백을 계속 받았다. 특히 긴 문서에서 맥락이 끊기는 문제가 자주 발생했다.

기존 설정은 청크 크기 256토큰, 오버랩 없음이었다. Claude 3.5 Sonnet을 임베딩과 생성 모델로 사용하고 있었다.

실험 설계

청크 크기와 오버랩 조합을 변경하며 테스트했다.

  • 청크 크기: 256, 512, 1024 토큰
  • 오버랩: 0, 25, 50, 100 토큰

평가 지표는 검색된 문서의 관련성 점수(MRR)와 최종 답변의 정확도를 수동으로 측정했다. 100개의 질문 세트를 준비해서 각 조합마다 테스트했다.

결과

512토큰에 50토큰 오버랩을 적용했을 때 가장 좋은 결과가 나왔다. MRR은 0.73에서 0.84로 향상됐고, 답변 정확도도 눈에 띄게 좋아졌다.

256토큰은 맥락이 너무 짧아서 문제였고, 1024토큰은 노이즈가 많아 오히려 정확도가 떨어졌다. 오버랩 100토큰은 중복이 너무 많아 검색 속도가 느려졌다.

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=50,
    length_function=len,
    separators=["\n\n", "\n", ". ", " ", ""]
)

chunks = splitter.split_documents(documents)

적용 결과

프로덕션에 배포 후 2주간 모니터링했다. 사용자 만족도 설문에서 검색 품질 점수가 3.2/5에서 4.1/5로 올랐다. 응답 시간은 평균 1.8초에서 2.1초로 소폭 증가했지만 허용 범위였다.

벡터 DB 저장 용량은 약 30% 증가했는데, 청크 수가 늘어났기 때문이다. 하지만 검색 품질 향상을 고려하면 충분히 가치 있는 트레이드오프였다.

교훈

청크 크기는 문서 특성에 따라 달라진다. 기술 문서처럼 구조화된 콘텐츠는 512토큰 정도가 적당했다. 오버랩은 문맥 연속성을 유지하는 데 필수적이었다.

RAG 시스템은 튜닝할 변수가 많다. 청크 크기 외에도 retrieval k값, 리랭킹 전략 등을 계속 실험할 예정이다.