30초 답변
한국어 기업 RAG에서는 키워드 검색과 벡터 검색 중 하나만 고르기보다 두 검색을 병렬로 실행하고 순위 기반으로 합치는 편이 안전하다. BM25는 제품 코드, 오류 코드, 사규 조항, 고유명사처럼 정확히 일치해야 하는 표현에 강하고, 벡터 검색은 사용자가 문서와 다른 말로 질문해도 의미가 가까운 내용을 찾는 데 유리하다. 두 결과의 점수 범위는 서로 다르므로 원점수를 단순히 더하지 말고 RRF(Reciprocal Rank Fusion)로 순위를 융합한다. 그다음 리랭커가 실제 품질을 높이는지는 별도 평가셋에서 확인한다.
권장 기본 흐름은 다음과 같다.
질문 정규화 → BM25 + 벡터 병렬 검색 → 메타데이터·권한 필터 → RRF → 선택적 리랭킹 → 중복 제거 → 근거 구성 → 답변
이 글의 핵심
- 한국어라고 해서 벡터 검색만 사용하면 모델명, 약어, 숫자, 조항 번호를 놓칠 수 있다.
- BM25와 벡터 유사도 점수는 의미와 범위가 다르다. RRF는 점수 대신 각 결과의 순위를 사용해 합친다.
- 리랭킹은 후보에 정답 문서가 들어 있을 때만 도움을 준다. 검색 재현율이 낮다면 리랭커보다 앞단을 먼저 고쳐야 한다.
- 품질 평가는 키워드·바꿔 말하기·복합 조건·정답 없음 질문을 나눠 수행하고, 검색 지표와 답변 지표를 분리한다.
왜 한국어 기업 문서에는 두 검색 방식이 필요한가
사내 검색 질문에는 서로 다른 신호가 섞여 있다. “QX-4107 장애 코드의 조치 방법”은 QX-4107이 정확히 등장하는 문서가 중요하다. 반대로 “퇴직 후 회사 자료를 언제까지 보관해야 하나요?”는 문서에 “퇴직” 대신 “근로관계 종료”, “언제까지” 대신 “보존기간”이라고 적혀 있을 수 있다.
BM25 기반 전문 검색은 질의어가 문서에 얼마나 특징적으로 나타나는지와 문서 길이 등을 이용해 순위를 만든다. Azure AI Search도 전문 검색 결과에 BM25를 사용한다고 설명한다. 벡터 검색은 질문과 문서의 의미적 거리를 사용하기 때문에 표현이 달라도 가까운 내용을 찾을 수 있다. Azure의 하이브리드 검색 개요는 두 질의를 병렬 실행하고 결과를 RRF로 병합하는 구조를 제시한다.
실무에서는 질문을 다음처럼 나눠 샘플을 준비하면 검색 방식의 역할이 선명해진다.
| 질문 유형 | 예시 | 우선 기대 신호 |
|---|---|---|
| 식별자 | “E1042 원인”, “PRD-AX7 설치법” | BM25 |
| 고유명사·약어 | “ISMS-P 접근통제 항목” | BM25 + 벡터 |
| 자연어 바꿔 말하기 | “결재가 늦을 때 누구에게 문의하나요?” | 벡터 |
| 복합 조건 | “서울 지점의 2025년 이후 안전점검 절차” | 검색 + 메타데이터 필터 |
| 모호한 질문 | “그거 취소하려면?” | 대화 맥락 보완 또는 재질문 |
이 표는 검색 엔진 선택표가 아니라 평가셋 분류표다. 실제 서비스에서는 두 검색 결과를 함께 사용하되, 어떤 유형에서 어느 신호가 기여했는지 로그로 남겨야 한다.
권장 파이프라인: 후보를 넓게 찾고 단계적으로 줄인다
1. 색인 필드를 분리한다
문서 본문 하나만 색인하지 말고 최소한 제목, 본문, 문서 유형, 부서, 제품 코드, 시행일, 원문 URL, 문서·청크 ID를 구분한다. 제목과 코드 필드는 키워드 검색에서 별도 가중치를 줄 수 있고, 부서·시행일·권한은 필터에 사용한다. 벡터 필드와 사람이 읽을 수 있는 텍스트 필드를 함께 유지해야 검색 결과를 설명하고 리랭킹할 수 있다.
2. 동일한 질문으로 BM25와 벡터 검색을 병렬 실행한다
BM25 쪽에는 원 질문을 보존한다. 제품 코드에서 하이픈을 제거하거나 영문 대소문자를 바꾸는 정규화는 색인과 질의에 같은 규칙으로 적용하고, 원문 토큰도 남긴다. 벡터 쪽은 질문 임베딩을 사용한다. 자동 질의 재작성이나 동의어 확장은 원 질문과 재작성 질문을 모두 로그에 남겨야 실패를 재현할 수 있다.
3. RRF로 순위를 합친다
BM25 점수와 코사인 유사도는 같은 척도가 아니다. Azure 문서에서도 BM25, 벡터, RRF, 시맨틱 리랭커의 점수 범위가 서로 다르게 제시된다. RRF는 각 목록에서 문서가 몇 위인지에 따라 1 / (상수 + 순위) 형태의 값을 합산한다. 여러 목록에서 상위에 반복 등장한 문서가 유리하며, 한 검색 방식의 큰 원점수가 다른 방식을 압도하는 문제를 줄인다. 여기서 RRF 식의 상수와 벡터 검색의 top-k는 다른 개념이다. RRF 점수 설명을 구현 기준과 함께 확인해야 한다.
4. 권한과 업무 조건을 검색 단계에서 적용한다
사용자가 볼 수 없는 문서를 가져온 뒤 LLM 프롬프트에서 제외하는 방식은 안전하지 않다. 권한·테넌트·문서 상태 필터는 검색 후보가 만들어지는 단계에 결합한다. 필터 적용 시점과 검색 엔진의 동작 방식에 따라 후보 수가 크게 줄 수 있으므로, 허용 문서가 적은 사용자군도 따로 평가한다.
5. 필요할 때만 리랭킹한다
리랭커는 질문과 후보 텍스트를 함께 보고 관련도를 다시 판단한다. RRF 상위 후보 안에 정답이 있지만 순서가 낮을 때 효과가 있다. 반대로 정답 문서가 후보에 없다면 리랭커는 복구할 수 없다. Azure의 시맨틱 랭커도 BM25 또는 RRF 결과 뒤에서 재정렬하는 단계로 설명된다. 리랭킹 입력에는 제목, 섹션 경로, 본문을 포함하되 ACL이나 내부 분류값처럼 의미 판단에 불필요한 필드는 빼는 편이 낫다.
6. 문서 중복과 근거 다양성을 제어한다
같은 문서의 인접 청크가 상위를 모두 차지하면 답변에 필요한 다른 문서를 밀어낼 수 있다. 문서별 최대 청크 수, 인접 청크 병합, 중복 문장 제거 규칙을 둔다. 다만 규정의 본문과 예외 조항처럼 함께 읽어야 하는 청크를 기계적으로 하나만 남기지 않도록 문서 구조를 고려한다.
리랭킹은 반드시 A/B가 아니라 네 가지 기준선으로 평가한다
최소한 다음 구성을 같은 질의 집합으로 비교한다.
- BM25 단독
- 벡터 단독
- BM25 + 벡터 + RRF
- BM25 + 벡터 + RRF + 리랭커
검색 단계에서는 정답 문서 또는 정답 청크 라벨을 이용해 Recall@k, MRR, nDCG@k를 본다. Recall@k가 낮으면 후보 생성 문제이고, Recall@k는 유지되는데 nDCG가 오르면 순위 개선 효과다. Azure의 RAG 평가기 문서도 문서 검색 평가와 최종 응답의 groundedness·relevance 평가를 구분한다.
최종 답변에서는 정답성, 근거 충실성, 필수 항목 누락, 인용 출처 일치 여부를 확인한다. 검색 품질이 올라도 긴 후보 목록이 프롬프트를 오염시켜 답변이 나빠질 수 있기 때문이다. 품질과 함께 검색 시간, 리랭킹 시간, 전체 P95 응답시간, 질의당 처리 비용도 기록한다. 평균만 보면 일부 사용자가 겪는 긴 지연을 숨길 수 있다.
평가셋에는 실제 업무 분포를 반영하되 다음 묶음을 의도적으로 포함한다.
- 정확한 코드·버전·조항 번호 질문
- 문서 표현과 다른 구어체 질문
- 띄어쓰기, 영문 대소문자, 한영 혼용, 오탈자
- 두 문서의 정보를 함께 찾아야 하는 질문
- 권한 때문에 정답 문서를 볼 수 없는 질문
- 말뭉치에 답이 없는 질문
사용자 경험과 자주 발생하는 실패 시나리오
“문서에 코드가 있는데 검색이 안 됩니다”
벡터 모델이 짧은 식별자를 의미 신호로 잘 다루지 못했거나 분석기가 하이픈을 분리했을 가능성이 있다. 원문 코드 필드를 별도로 보존하고 BM25 결과가 RRF 후보에 들어오는지 확인한다. 답변 모델을 바꾸기 전에 검색 로그에서 각 경로의 순위를 본다.
“관련 문서는 찾았는데 첫 결과가 엉뚱합니다”
제목만 비슷한 일반 문서가 본문의 구체적 절차보다 높은 순위를 받은 경우다. 제목 가중치, 문서 상태, 최신 시행일을 무조건 올리기 전에 정답 라벨로 리랭킹 효과를 비교한다. 최신 문서라는 이유만으로 관련성이 없는 문서를 높이면 검색은 더 나빠진다.
“하이브리드로 바꿨더니 느려졌습니다”
병렬이어야 할 두 검색이 직렬로 실행되거나, 후보 수가 과도하거나, 모든 질의에 비싼 리랭커를 붙였을 수 있다. 코드 조회처럼 BM25 상위 결과가 매우 명확한 질문은 리랭킹을 생략하는 정책을 검토한다. 단, 생략 조건은 점수 하나가 아니라 평가된 규칙이어야 한다.
“같은 매뉴얼 내용만 반복해서 답합니다”
동일 문서의 겹치는 청크가 후보를 독점한 상황이다. 청크 중복 제거와 문서별 후보 제한을 적용하고, 원문 섹션 경로를 답변에 보여 사용자가 근거의 위치를 판단할 수 있게 한다.
실무 체크리스트
- 제품 코드, 약어, 조항 번호를 원형 그대로 검색할 필드가 있는가?
- 제목·본문·문서 유형·시행일·부서·권한·원문 URL이 분리되어 있는가?
- BM25와 벡터 결과의 문서 ID, 개별 순위, RRF 순위를 로그로 남기는가?
- 서로 다른 점수 체계를 원점수 합산으로 섞지 않는가?
- 권한과 테넌트 필터가 LLM 이전의 검색 단계에서 적용되는가?
- BM25, 벡터, RRF, RRF+리랭커 네 기준선을 같은 평가셋으로 비교했는가?
- 검색 Recall@k와 최종 답변 groundedness를 별도로 측정하는가?
- 한영 혼용·띄어쓰기·오탈자·식별자 질문이 평가셋에 있는가?
- 정답 없음과 권한 없음 질문에서 답변 보류가 작동하는가?
- 품질뿐 아니라 P95 지연, 후보 수, 리랭킹 비용을 함께 본다는 운영 기준이 있는가?
- 동일 문서의 중복 청크가 근거 목록을 독점하지 않는가?
자주 묻는 질문
Q1. 한국어 RAG는 무조건 하이브리드 검색을 써야 하나요?
아니다. 문서가 작고 질문이 식별자 조회로 거의 고정되어 있다면 BM25만으로 충분할 수 있다. 반대로 사용자가 다양한 자연어로 질문한다면 벡터 검색의 기여가 커진다. 결정은 기능 목록이 아니라 실제 질의 평가셋에서 BM25 단독 대비 하이브리드의 품질·지연·비용이 얼마나 달라지는지로 내려야 한다.
Q2. RRF를 쓰면 리랭커는 필요 없나요?
역할이 다르다. RRF는 여러 순위 목록을 안정적으로 합치고, 리랭커는 합쳐진 후보와 질문의 관련성을 더 정밀하게 판단한다. RRF만으로 목표 지표를 충족하면 리랭커를 생략할 수 있다. 후보에 정답이 없으면 리랭커를 추가해도 해결되지 않는다.
Q3. 후보 수와 최종 컨텍스트 수는 같아야 하나요?
같을 필요가 없다. 첫 검색은 정답을 놓치지 않도록 비교적 넓은 후보를 만들고, RRF·리랭킹·중복 제거 후 소수의 근거만 LLM에 전달할 수 있다. 단, 특정 숫자를 관행처럼 고정하지 말고 Recall@k, 답변 품질, 컨텍스트 길이, 지연을 함께 보며 정한다.
근거 자료
- Microsoft Learn, Azure AI Search의 하이브리드 검색 개요
- Microsoft Learn, RRF를 이용한 하이브리드 검색 점수 계산
- Microsoft Learn, 하이브리드 쿼리 작성 방법
- Microsoft Learn, Azure AI Search 시맨틱 랭킹 개요
- Microsoft Learn, 생성형 AI용 RAG 평가기