BM25 Retrieval (키워드 검색)
Dense Retrieval (임베딩 기반 벡터 검색)
RRF (BM25 + Dense 결과 결합)
HyDE (질문 → 가상 문서 생성 → 검색)
Cohere Re-ranking (후보를 뽑은 뒤 정렬만 다시)
문서를 "의미"로 보지 않고 단어 매칭으로 점수 부여
한국어에서 중요한 점 : 토큰화(형태소 분석)
BM25는 "단어 단위"가 핵심이라 한국어에선 형태소 토큰화 품질이 성능을 좌우
- Kiwi같은 형태소 분석기로 문서/쿼리를 동일 방식으로 토큰화하는게 중요
장/단점
문장을 임베딩 벡터로 바꿔서 “의미적으로 가까운 문서”를 찾음
ir에서 유사한 벡터 top-k검색(cosine)장/단점
BM25와 Dense는 장단점이 반대라서 실무에서는 “하이브리드”가 흔함
점수 스케일을 섞지 않고 순위(RANK)만 이용해 합침
문서가 BM25에서도 상위, Dense에서도 상위면 점수가 누적되어 올라감
k는 보통 60 같은 값을 사용해 1등/2등 차이를 완만하게 함
Dense Retrieval을 더 잘 되게 만드는 트릭
일반 Dense : 질문을 임베딩해 검색 / HyDE : 질문->LLM이 "그럴듯한 답변" 생성 / 그 답변을 임베딩 해 검색
효과 : 질문은 짧고 애매 -> 가상 문서는 길고 구체적(임베딩 선명)
“새 문서를 찾는 게 아니라” 이미 뽑은 후보의 순서만 다시 매기는 단계
필요한 이유
- 1단계(BM25/Dense)은 빠르게 후보 뽑는 용도라 "대충 관련있는 문서"
- 2단계(Re-ranker)는 후보가 적으니 더 정교하게 판단해 순서 개선
후보 doc_id 리스트를 얻음 (예: top20~50)
doc_id → 문서 본문(content)로 변환
Cohere rerank 모델에 (query, documents[text])를 넣음
rerank가 “관련도 점수”를 매김 → 점수 내림차순으로 재정렬
최종 top5 선택
중요 : 1단계 후보품질이 기본(후보에 정답 없으면 re-ranking X)
Contextual Compression Index: 문서를 미리 압축해서 새 인덱스에 저장
Contextual Compression Retriever: 검색 후 문서를 질문 기준으로 즉석 압축(발췌)
Index : 문서를 사전에 요약/압축(offline) → ir-compressed 같은 새 벡터 인덱스에 저장 → 검색은 Dense로 그대로 수행
Retriever : 문서는 원문 그대로 인덱스(online) → 검색으로 후보를 가져온 뒤 → LLM이 질문에 맞게 관련 부분만 발췌/압축
query를 이용해 기존 ir에서 Dense로 후보 문서 top-k를 가져온다 (원문 통째로)
LLM이 각 후보 문서를 읽고 질문에 필요한 문장/문단만 남기고 나머지는 버린다
“압축된 문서”를 최종 검색 결과로 사용한다
같은 문서라도 질문이 달라지면 발췌되는 내용이 달라짐 (질문 맞춤형)
인덱스를 새로 만들 필요 없음
대신 검색할 때마다 LLM을 돌리므로 비용/시간이 추가된다
| 구분 | Index | Retriever |
|---|---|---|
| 압축 시점 | 인덱싱 단계(미리) | 검색 이후(매번) |
| 압축 기준 | 문서 중심 요약(고정) | 질문 중심 발췌(가변) |
| 인덱스 | 원문+요약 인덱스 2개 | 보통 원문 인덱스 1개 |
| 비용/속도 | 검색 시 저렴/빠름 | 검색 시 LLM 비용/지연 발생 |
| 장점 | 운영 단순, 빠른 검색 | 질문 맞춤 컨텍스트, 노이즈 제거 |
| 리스크 | 요약 누락 시 품질 하락 | LLM 호출 비용/지연, 후보 품질 의존 |
검색 속도/비용이 중요하고, LLM 호출을 최소화하고 싶을 때
문서가 너무 길어서 “요약만 저장해도 주제가 잘 살아나는” 도메인
인덱스 1개 더 운영 가능한 상황
질문이 다양하고, 같은 문서에서도 질문에 따라 필요한 부분이 크게 달라질 때
RAG 답변 품질(컨텍스트 정제)이 최우선일 때
인덱스 추가 없이 즉석 정제가 필요할 때