본문으로 건너뛰기
AIPida
채택됨중급AI 코딩

RAG가 문서에 분명히 있는 내용도 못 찾습니다 (한국어, pgvector)

사내 문서 약 2천 페이지로 RAG 챗봇 만드는 중입니다. LangChain + 임베딩 + pgvector 구성이에요. 분명히 문서에 있는 내용을 질문해도 "관련 정보를 찾을 수 없습니다"가 나오거나 엉뚱한 청크를 가져옵니다.

  • 청킹: RecursiveCharacterTextSplitter, chunk_size 1000, overlap 0
  • 임베딩: OpenAI text-embedding-3-small
  • top_k 4

한국어 문서라 그런지 검색 품질이 영 별로입니다. 어디부터 손봐야 할까요?

답변 3

  • 채택된 답변에디터 검증

    증상이 전형적인 retrieval 단계 문제입니다. 생성 모델 건드리기 전에 검색부터 잡으세요. 제 경험상 ROI 순서대로 가면:

    overlap 0이 범인일 확률이 높습니다. 이게 1순위. chunk_size 1000에 overlap 0이면 경계에서 문장 통째로 잘리고, 그 정보가 어느 청크에도 온전히 안 담깁니다. overlap 100~200(10~20%)만 줘도 확 나아져요. 한국어는 의미 단위가 길어서 경계 손실이 영어보다 더 치명적입니다. 일단 이것부터 주고 다시 테스트해보세요.

    청킹을 의미 단위로. 글자 수로만 자르면 표/목록/제목이 본문에서 떨어져 나갑니다. MarkdownHeaderTextSplitter로 헤더 기준 먼저 쪼개고 그 안에서 길이 분할 하면 청크 하나의 주제 일관성이 올라가서 검색이 잘 잡혀요.

    하이브리드 검색. 순수 벡터만으로는 고유명사/코드/약어 정확일치에 약합니다. pgvector면 같은 DB에 tsvector 풀텍스트 인덱스 추가해서 키워드 검색 붙이고 결과 합치면 됩니다. 한국어 정확 매칭 확 좋아져요.

    top_k 4는 너무 적습니다. 20~30개 넓게 뽑은 다음 cross-encoder 리랭커(bge-reranker 계열)로 상위 4~5개만 추려서 LLM에 넣으세요. 1차 검색이 살짝 틀려도 리랭커가 건져줍니다.

    근데 제일 중요한 건 이거 한 번에 다 바꾸지 마세요. 질문-정답청크 쌍 30개라도 만들어서 평가셋 깔고, hit rate 보면서 하나씩 바꿔야 뭐가 효과 있었는지 압니다. 안 그러면 네 개 다 바꿔놓고 "뭐 때문에 좋아졌지" 모르게 돼요. 저는 overlap → 하이브리드 → 리랭커 순으로 붙였습니다.

  • 위 답변에 임베딩 모델 얘기만 추가. text-embedding-3-small이 한국어 못 하는 건 아닌데, 한국어/다국어 벤치에서 BGE-M3 같은 다국어 오픈 모델 써보면 같은 청킹에서도 hit rate가 올라가는 경우 많습니다. BGE-M3는 dense/sparse/multi-vector를 한 모델로 뽑아줘서 하이브리드 구성하기도 편하고요.

    근데 모델부터 갈아엎지는 마세요. 윗분 말대로 overlap·청킹 같은 파이프라인 문제 먼저 잡는 게 ROI 훨씬 큽니다. 임베딩 바꾸는 건 재인덱싱 비용도 있으니 파이프라인 정리 끝나고 A/B로 비교하는 게 순서예요.

  • 디버깅 순서 하나만. "못 찾는다"가 retrieval 실패인지 generation 실패인지부터 가르세요. LLM 넣기 직전에 검색된 청크 4개를 그냥 로그로 찍어보면 됩니다.

    • 정답 청크가 top_k 안에 들어왔는데 LLM이 "정보 없음"이라고 함 → 프롬프트/생성 문제 (컨텍스트 무시하거나 과보수적). 이건 39번 질문 쪽 해결책
    • 정답 청크가 아예 안 들어옴 → retrieval 문제. 윗분들 말한 overlap/하이브리드 쪽

    둘은 해결책이 완전 달라서 먼저 안 가르면 엉뚱한 데 시간 쏟습니다. 질문자분 케이스는 "엉뚱한 청크를 가져온다"고 하셨으니 retrieval 쪽이 맞는 듯한데, 그래도 로그 한 번 찍어서 확인하고 들어가세요.