본문으로 건너뛰기
채택됨실전RAG

사내 문서 RAG에서 최신 문서가 검색에 안 잡히고 옛날 버전이 상위로 뜨는데 어떻게 최신성을 반영하나요?

사내 위키·정책 문서를 pgvector에 임베딩해서 RAG를 돌리고 있습니다. 문제는 방금 갱신한 v3 매뉴얼을 물어봐도 검색 상위에 예전 v1 문서가 뜨고, 최신 문서는 top-5 밖으로 밀려납니다. 임베딩 모델(bge-m3)이나 청크 크기(500토큰)를 바꿔봐도 큰 차이가 없었고, 코사인 유사도 상위 5개를 그대로 컨텍스트로 넣는 구조입니다. 검색 단계에서 문서 최신성을 어떻게 반영해야 하나요?

답변 1

  • 채택된 답변

    증상만 보면 임베딩 탓 같지만, 대개 검색 로직이 시간축을 안 보는 게 원인입니다. 순수 코사인은 갱신 시점을 모르고, v3와 v1 매뉴얼은 임베딩이 거의 같아 오래된 청크가 top-k를 잠식합니다. 업서트 때 구버전 청크를 안 지우면 유령 청크도 계속 쌓입니다.

    먼저 진단을 나누세요. 정답 문서가 top-50엔 있는데 top-5에 없으면 랭킹 문제, top-50에도 없으면 청크·임베딩 문제입니다. 원인마다 처방이 다릅니다.

    대응

    1. 최신성 소프트 부스팅

    하드 날짜 필터(최근 6개월만)는 오래돼도 유효한 정책 문서를 놓쳐 위험합니다. 점수에 감쇠항을 더하는 게 안전합니다.

    def rerank(hits, half_life=180, w=0.15):
        now = time.time()
        for h in hits:
            age = (now - h["updated_at"]) / 86400
            h["score"] = h["cosine"] + w * (0.5 ** (age / half_life))
        return sorted(hits, key=lambda x: -x["score"])
    

    w는 0.1~0.2에서 골드셋으로 튜닝하고, 크면 최신 잡문서가 상위로 올라옵니다.

    1. 크로스 인코더 리랭커

    bge-reranker-v2-m3로 top-50을 top-5로 좁힙니다. 코사인 단독보다 정밀해, 밀려나 있던 최신 문서가 상위로 복원되는 경우가 많습니다.

    1. 중복 제거

    업서트 시 doc_id 기준으로 구버전 청크를 먼저 delete한 뒤 새 청크를 insert합니다. 소프트 삭제 방식이면 삭제 플래그를 검색 필터에서 반드시 제외하세요. 내용이 거의 같은 near-dup은 MMR로 누릅니다.

    검증

    최근 문서 대상 질문 골드셋으로 recall@5를 날짜 구간별로 봅니다. "최근 30일 문서 recall@5"가 안 오르면 부스팅이 아니라 청크·인덱싱을 의심하세요.