Skip to content

하이브리드 검색과 리랭킹 ​

이 장에서 얻는 것

  • dense(embedding) 검색과 sparse(BM25) 검색이 각각 무엇을 놓치는지, 그리고 하이브리드가 왜 상호 보완적인지에 대한 구조적 이해
  • RRF(Reciprocal Rank Fusion)와 가중 선형 결합(weighted linear combination)의 차이와 선택 기준
  • cross-encoder 리랭킹의 구조적 원리(bi-encoder와의 차이)와 2단계 파이프라인에서의 비용/지연 계산법
  • recall@20 실패율 > 3% 임계치에서 시작하는 순차 적용 결정 표(contextual retrieval → Contextual BM25 하이브리드 → 리랭커)
  • OpenSearch(normalization processor, score-ranker processor)와 Bedrock Knowledge Bases(HYBRID search type, Rerank API)의 실제 지원 범위

왜 문제가 되는가 ​

dense 검색만으로 구축한 RAG 파이프라인은 특정 부류의 쿼리에서 체계적으로 실패한다. embedding 모델은 학습 분포 안의 의미(semantics)를 압축하는 장치이므로, 다음과 같은 토큰은 벡터 공간에서 변별력을 잃는다.

  • 제품 코드·에러 코드·티켓 ID: TS-999, 0x80070005, INC-20240817 같은 식별자는 embedding 모델에게 거의 의미가 없는 문자열이다. Anthropic의 Contextual Retrieval 문서도 "Error code TS-999" 같은 쿼리를 embedding이 놓치고 BM25가 잡아내는 대표 사례로 든다.
  • 신조어·사내 용어: 모델 학습 컷오프 이후 등장한 용어, 조직 내부에서만 쓰는 약어는 임의의 벡터로 매핑된다.
  • 정확한 키워드 일치가 요구되는 쿼리: 법령 조항 번호, API 파라미터 이름, 설정 키 등.

반대로 sparse(BM25)만 쓰면 동의어와 의미 유사성을 놓친다. "인스턴스가 느려요"라는 쿼리는 "EC2 성능 저하 트러블슈팅" 문서와 겹치는 토큰이 없으면 매칭되지 않는다. BM25는 TF-IDF를 확장한 어휘 일치(lexical match) 함수일 뿐 의미를 모른다.

에이전트 플랫폼에서 이 문제가 증폭되는 이유는 두 가지다. 첫째, 에이전트는 사람과 달리 검색 실패를 스스로 인지하고 쿼리를 바꿔 재시도하는 능력이 불완전하므로, 첫 검색의 recall이 곧 태스크 성공률의 상한이 된다. 둘째, 멀티스텝 파이프라인에서는 검색 실패율이 단계 수만큼 복리로 누적된다. 이 책의 전환 임계치 표는 검색 recall@20 실패율 > 3% 를 조치 개시 신호로 잡고, 조치 순서를 contextual retrieval → Contextual BM25 하이브리드 → 리랭커로 규정한다. 이 장의 결정 표는 그 순서를 그대로 뼈대로 삼는다.

핵심 개념 ​

dense와 sparse의 상호 보완 ​

축dense (embedding + ANN)sparse (BM25)
매칭 원리벡터 공간의 근접성 (의미)토큰 일치 + TF/IDF 가중 (어휘)
강점동의어, 패러프레이즈, 다국어 의미 유사정확한 키워드, ID, 코드, 희귀 토큰
약점식별자·신조어·정확 일치, out-of-domain 어휘동의어, 어순·표현 변형, 의미 질의
점수 스케일코사인 유사도 등 유계(bounded)무계(unbounded), 코퍼스 통계 의존
인덱스HNSW 등 ANN 인덱스 (ANN 인덱스 장 참고)inverted index

두 검색기의 실패 집합이 거의 겹치지 않는다는 점이 하이브리드의 근거다. 하나가 놓친 문서를 다른 하나가 상위에 올려주면, 융합(fusion) 단계에서 회수할 수 있다.

결합 방법 1: RRF (Reciprocal Rank Fusion) ​

RRF는 각 검색기가 매긴 순위(rank)의 역수를 합산한다.

RRFscore(d) = Σ_r  1 / (k + rank_r(d))

Cormack, Clarke, Büttcher의 SIGIR 2009 원 논문이 출처이며, 논문은 k = 60을 사용했다("k = 60 was chosen during a pilot investigation"). 이 값은 사실상 업계 표준 기본값이 되어, OpenSearch score-ranker processor의 rank_constant 기본값도 60이다.

RRF의 결정적 장점은 점수 스케일 문제를 우회한다는 것이다. BM25 점수(무계)와 코사인 유사도(유계)는 직접 비교할 수 없지만, 순위는 언제나 비교 가능하다. 정규화 파이프라인도, 코퍼스별 재튜닝도 필요 없다. 대가는 정보 손실이다 — 1위와 2위의 점수 차가 압도적이든 미미하든 RRF에게는 똑같은 "1위와 2위"다.

결합 방법 2: 가중 선형 결합 (weighted linear combination) ​

각 검색기의 점수 자체를 정규화한 뒤 가중 평균한다.

score(d) = w_dense · norm(s_dense) + w_sparse · norm(s_sparse)

점수 간 스케일을 맞추는 정규화가 전제 조건이다. OpenSearch의 normalization processor는 min_max, l2, z_score 정규화와 arithmetic_mean/geometric_mean/harmonic_mean 결합 기법, 서브쿼리별 weights 파라미터를 제공한다.

가중 결합은 점수의 절대적 확신도를 보존하고 도메인별로 가중치를 튜닝할 여지를 주지만, 그만큼 튜닝 부채를 진다. 가중치는 코퍼스와 쿼리 분포에 민감해서, 평가셋(검색 평가 장 참고) 없이 정한 가중치는 근거 없는 상수일 뿐이다. min-max 정규화는 결과 집합의 최고/최저 점수에 의존하므로 쿼리마다 스케일이 흔들리는 점도 주의해야 한다.

미정착 영역

RRF와 가중 선형 결합 중 무엇이 일반적으로 우월한지는 정착된 결론이 없다. 벤더 간 입장도 갈린다 — OpenSearch는 RRF 도입 블로그에서 두 방식을 병행 제공하는 이유를 설명하고, Anthropic의 Contextual Retrieval 구현은 rank 기반 융합을 사용한다. 실무 지침은 "평가셋이 없으면 RRF, 평가셋과 튜닝 여력이 있으면 가중 결합 실험"이 안전하다.

리랭킹: cross-encoder의 구조적 차이 ​

1단계 검색(dense/sparse/하이브리드)은 모두 bi-encoder 구조다 — 쿼리와 문서를 각각 독립적으로 인코딩해 두 벡터의 유사도를 계산한다. 문서 벡터를 미리 계산해 인덱싱할 수 있어 수백만 문서에서도 빠르지만, 쿼리와 문서가 서로를 보지 못한 채 인코딩되므로 정밀도에 상한이 있다.

cross-encoder는 쿼리와 문서를 하나의 입력으로 이어붙여 함께 트랜스포머에 통과시키고 관련도 점수를 직접 출력한다. 쿼리의 각 토큰이 문서의 각 토큰과 attention을 주고받으므로 훨씬 정밀하다. Sentence-Transformers 공식 문서가 이 구조 차이와 트레이드오프의 표준 레퍼런스다: cross-encoder는 bi-encoder보다 높은 정확도를 내지만, 쿼리·문서 쌍마다 전체 모델 forward pass가 필요해 사전 계산이 불가능하고 대규모 코퍼스 전수 스코어링은 비현실적이다.

그래서 실전 구조는 언제나 2단계 파이프라인이다:

  1. 1단계 (recall 지향): 하이브리드 검색으로 후보 top-N(예: 100~150)을 싸고 빠르게 회수한다.
  2. 2단계 (precision 지향): cross-encoder 리랭커가 후보 N개만 재채점하여 top-K(예: 5~20)를 최종 선택한다.

리랭킹 비용은 후보 수 N에 선형 비례하므로, N이 리랭킹의 지연·비용 다이얼이다. Anthropic의 Contextual Retrieval 문서도 top-150 후보를 리랭킹해 top-20을 선택하는 구성을 예시로 들면서, 리랭킹이 추가하는 지연과 "소수 문서 리랭킹의 추가 비용 대비 응답성" 트레이드오프를 명시한다.

AWS에서의 리랭킹: Bedrock Rerank API ​

Amazon Bedrock은 관리형 리랭커를 제공한다. 공식 지원 모델 문서 기준:

모델Model ID지원 리전 (단일 리전)
Cohere Rerank 3.5cohere.rerank-v3-5:0ap-northeast-1, ca-central-1, eu-central-1, us-east-1, us-west-2
Amazon Rerank 1.0amazon.rerank-v1:0ap-northeast-1, ca-central-1, eu-central-1, us-west-2

Amazon Rerank 1.0은 us-east-1을 지원하지 않는다(해당 리전은 Cohere Rerank 3.5만 가능). 서울(ap-northeast-2)은 두 모델 모두 미지원이므로, 국내 리전 중심 아키텍처라면 리랭킹 호출만 도쿄(ap-northeast-1)로 크로스 리전 호출할지, 오픈소스 cross-encoder를 자체 호스팅할지 결정해야 한다. 과금은 쿼리 단위이며 구체 단가는 Bedrock 요금 페이지에서 리전별로 확인한다.

Bedrock Knowledge Bases를 쓴다면 Retrieve/RetrieveAndGenerate의 Reranking 설정으로 위 리랭커를 검색 결과에 바로 연결할 수 있다.

AWS에서의 하이브리드 검색 ​

Bedrock Knowledge Bases: retrievalConfiguration.vectorSearchConfiguration.overrideSearchType에 HYBRID 또는 SEMANTIC을 지정한다. 공식 문서 기준 제약이 중요하다 — 하이브리드 검색은 Amazon OpenSearch Serverless, Amazon RDS(Aurora), MongoDB 벡터 스토어에서, filterable text field가 있을 때만 지원되며, 그 외 구성에서는 지정과 무관하게 semantic search로 폴백한다. 값을 지정하지 않으면 Bedrock이 스토어 구성에 맞는 전략을 자동 선택한다. 벡터 스토어 선택 자체는 AWS 벡터 스토어 장에서 다룬다.

OpenSearch (자체 관리 시): hybrid query에 search pipeline을 붙여 융합 방식을 선택한다.

  • normalization processor — 점수 기반 융합(가중 선형 결합 계열). 정규화·결합 기법·서브쿼리 가중치를 세밀하게 제어.
  • score-ranker processor — 순위 기반 융합(RRF). rank_constant 기본값 60.

즉 앞의 "RRF vs 가중 결합" 결정이 OpenSearch에서는 그대로 "어느 프로세서를 파이프라인에 넣는가"로 번역된다.

Contextual Retrieval과의 관계 ​

하이브리드 + 리랭킹 스택의 상한을 보여주는 정량 결과는 Anthropic의 Contextual Retrieval이다: contextual embedding + contextual BM25 하이브리드에 리랭킹까지 결합하면 top-20 검색 실패율이 5.7% → 1.9%로 67% 감소한다. 청크에 문맥을 주입하는 contextual retrieval 기법 자체(비용 구조, 프롬프트, 캐싱 포함)는 청킹 전략 장이 정본으로 다루므로 여기서는 반복하지 않는다. 이 장의 관점에서 중요한 것은 순서다 — 하이브리드와 리랭커는 contextual retrieval 위에 얹었을 때 각각 추가 이득을 냈다.

결정 표 ​

전환 임계치 표의 순차 적용 원칙(recall@20 실패율 > 3% → contextual retrieval → Contextual BM25 하이브리드 → 리랭커)을 뼈대로 한다. 각 단계는 이전 단계를 대체하는 것이 아니라 그 위에 누적된다.

상황선택이유트레이드오프
recall@20 실패율 ≤ 3%현 구성 유지, 계측 지속임계치 미만에서의 스택 추가는 비용·지연만 늘린다개선 여지를 남겨둠
실패율 > 3%, dense 단독 구성1순위: contextual retrieval (청킹 전략 장)인덱싱 시점 1회 비용으로 쿼리 경로에 지연을 추가하지 않음재인덱싱 필요, 문서 토큰당 전처리 비용
contextual retrieval 후에도 실패율 > 3%2순위: Contextual BM25 하이브리드 추가ID·코드·신조어 실패 집합을 sparse가 회수인덱스 2개 운영, 융합 로직 유지보수
하이브리드 후에도 실패율 > 3%3순위: 리랭커 추가 (top-N 후보만)precision 상한을 cross-encoder로 끌어올림쿼리당 추가 지연·비용 (N에 선형)
융합 방식: 평가셋 없음 / 빠른 출시RRF (k=60 기본)정규화·튜닝 불필요, 스케일 문제 없음점수 확신도 정보 손실
융합 방식: 평가셋 보유, 도메인 특성 뚜렷가중 선형 결합 + 정규화서브쿼리 가중치로 도메인 튜닝 가능가중치가 코퍼스에 과적합될 위험, 재튜닝 부채
리랭커: us-east-1 / 관리형 선호Cohere Rerank 3.5 on Bedrock (cohere.rerank-v3-5:0)us-east-1 포함 5개 리전 지원쿼리당 과금, 지원 리전 제약
리랭커: ap-northeast-2 필수 + 크로스 리전 불가오픈소스 cross-encoder 자체 호스팅Bedrock 리랭커는 서울 미지원모델 서빙 인프라 운영 부담
Bedrock KB 사용 + OpenSearch Serverless/Aurora/MongoDBoverrideSearchType: HYBRID관리형으로 하이브리드 활성화, 코드 변경 최소융합 방식·가중치 제어 불가
융합 로직을 직접 제어해야 함자체 OpenSearch + search pipelinenormalization/score-ranker processor 선택·튜닝 가능클러스터 운영 책임

실패 모드 ​

증상근본 원인확인 방법해결
ID·에러코드 쿼리만 체계적으로 실패dense 단독 검색 — 식별자가 벡터 공간에서 변별력 없음실패 쿼리를 유형별로 분류, ID성 쿼리의 recall 별도 측정BM25 하이브리드 추가
하이브리드 전환 후 오히려 품질 하락점수 정규화 없이 BM25(무계)와 코사인(유계)을 선형 결합융합 전 두 점수 분포를 로깅해 스케일 확인정규화 프로세서 적용 또는 RRF로 전환
가중치 튜닝 후 특정 쿼리 유형 회귀가중치가 평가셋의 다수 유형에 과적합쿼리 유형별(의미형/키워드형) recall을 분리 계측유형별 평가 슬라이스 유지, RRF 베이스라인과 상시 비교
리랭커 도입 후 p95 지연 급증후보 N이 과대 (전수에 가깝게 리랭킹)리랭킹 단계 지연을 N별로 프로파일링N 축소(예: 150→50), 후보 수를 SLO에서 역산
리랭커 도입 후에도 최종 품질 정체1단계 recall 자체가 낮음 — 정답이 후보 N에 없음recall@N(리랭킹 전)과 recall@K(리랭킹 후)를 분리 측정리랭커가 아니라 1단계(contextual retrieval·하이브리드)를 먼저 보강
Bedrock KB에서 HYBRID 지정했는데 효과 없음벡터 스토어가 하이브리드 미지원 구성 → semantic 폴백스토어 종류·filterable text field 유무를 공식 문서 기준으로 점검지원 스토어(OpenSearch Serverless/RDS/MongoDB)로 구성
리랭킹 호출이 리전 오류로 실패미지원 리전 호출 (예: 서울, us-east-1의 Amazon Rerank 1.0)지원 리전 표 대조지원 리전으로 크로스 리전 호출 또는 모델 변경
인덱스 갱신 후 하이브리드 품질 저하dense/sparse 인덱스 갱신 시점 불일치로 한쪽만 신선두 인덱스의 문서 수·최신 문서 포함 여부 대조동일 파이프라인에서 동기 갱신 (인덱스 신선도 장)

안티패턴 ​

  • ❌ recall 계측 없이 "요즘은 하이브리드가 표준"이라며 스택부터 쌓는다 → ✅ recall@20 실패율을 먼저 계측하고, > 3%일 때만 순차 적용을 시작한다.
  • ❌ 1단계 recall이 낮은데 리랭커부터 도입한다 → ✅ 리랭커는 후보 안의 순서만 바꾼다. 정답이 후보에 없으면 무력하다 — contextual retrieval과 하이브리드가 먼저다.
  • ❌ BM25 점수와 코사인 유사도를 정규화 없이 0.5 : 0.5로 더한다 → ✅ 스케일이 다른 점수의 선형 결합은 정규화가 전제다. 정규화를 피하고 싶다면 RRF를 쓴다.
  • ❌ 검색된 문서 전체를 리랭커에 넣는다 → ✅ 리랭킹 비용은 후보 수에 선형이다. 지연 SLO에서 감당 가능한 N을 역산해 top-N만 리랭킹한다.
  • ❌ RRF의 k나 융합 가중치를 감으로 바꾸고 배포한다 → ✅ 모든 융합 파라미터 변경은 평가셋 회귀 테스트를 통과해야 배포한다 (검색 평가 장).
  • ❌ 리랭커를 넣었으니 청킹·contextual retrieval은 건너뛴다 → ✅ Contextual Retrieval 결과가 보여주듯 각 계층의 이득은 누적적이다. 하위 계층을 리랭커로 대체할 수 없다.

계측 (SLI) ​

이 장의 조치는 전부 계측이 선행되어야 한다. 최소 SLI 세트:

  • recall@20 실패율: 정답 문서가 top-20에 없는 쿼리 비율. 전환 임계치 표의 기준 신호 (> 3% 시 조치). Anthropic의 Contextual Retrieval도 동일한 지표(top-20-chunk retrieval failure rate)로 개선을 보고했으므로 벤치마크 비교가 직접 가능하다.
  • recall@N (리랭킹 전) vs recall@K (리랭킹 후): 두 값을 분리하면 "1단계가 문제인가, 리랭커가 문제인가"를 즉시 판별할 수 있다.
  • 쿼리 유형별 recall 슬라이스: 최소한 의미형 쿼리와 키워드/ID형 쿼리를 분리한다. 하이브리드의 효과와 회귀는 유형별로만 보인다.
  • 검색 단계별 지연 p50/p95: dense, sparse, 융합, 리랭킹을 각각 계측한다. 리랭킹 지연은 후보 수 N과 함께 기록해 상관을 추적한다.
  • 리랭커 호출 비용: 쿼리 단위 과금이므로 QPS × 단가로 월 비용이 직결된다. 후보 수 N 변경이 비용에 주는 영향은 없지만(쿼리 단위), 자체 호스팅 시에는 N × forward pass가 GPU 비용이 된다.
  • 융합 점수 분포: 가중 선형 결합 사용 시 서브쿼리별 점수 분포(평균·분산)를 주기적으로 로깅한다. 코퍼스 성장에 따른 BM25 통계 변화가 가중치 유효성을 조용히 무너뜨리는 것을 조기 감지한다.

평가셋 구축과 지표 정의 자체는 검색 평가 장을 따른다.

체크리스트 ​

  • [ ] recall@20 실패율을 계측하고 있고, 현재 값이 3% 임계치 대비 어디인지 알고 있다
  • [ ] 실패 쿼리를 유형별(의미형/키워드·ID형)로 분류해 dense 단독의 구조적 실패인지 확인했다
  • [ ] 조치 순서를 지켰다: contextual retrieval → Contextual BM25 하이브리드 → 리랭커 (건너뛴 단계가 있다면 근거를 문서화했다)
  • [ ] 융합 방식을 의식적으로 선택했다: 평가셋 없으면 RRF(k=60), 있으면 가중 결합 실험 + RRF 베이스라인 비교
  • [ ] 가중 선형 결합을 쓴다면 정규화 기법(min_max/l2/z_score)을 명시적으로 지정했다
  • [ ] 리랭킹 후보 수 N을 지연 SLO에서 역산해 정했고, N별 p95 지연을 프로파일링했다
  • [ ] 리랭커 모델의 리전 지원(서울 미지원, us-east-1의 Amazon Rerank 1.0 미지원)을 아키텍처에 반영했다
  • [ ] Bedrock KB 사용 시 벡터 스토어가 HYBRID를 실제 지원하는 구성(OpenSearch Serverless/RDS/MongoDB + filterable text field)인지 확인했다
  • [ ] dense/sparse 인덱스가 동일 파이프라인에서 동기 갱신된다
  • [ ] 융합 파라미터·리랭커 변경이 평가셋 회귀 테스트를 거쳐 배포된다

참고 ​

⚠️ 비공식 출처 기반 — 공식 문서 교차확인 필요: RRF vs 가중 결합의 실무 비교 논의는 커뮤니티 자료(예: BigData Boutique — Reciprocal Rank Fusion: How It Works and When to Use It)에 흩어져 있으며, 결론은 코퍼스·쿼리 분포에 따라 달라진다. 자신의 평가셋으로 검증하라.