RAG(Retrieval-Augmented Generation) 파이프라인에서 LLM이 정확한 답변을 생성하려면, 검색 단계에서 관련 문서를 빠짐없이, 높은 순위로 가져와야 한다. 하지만 “검색이 잘 되고 있는가?“를 감으로 판단할 수는 없다.

이 글에서는 Vector Search의 품질을 정량적으로 측정하는 5가지 핵심 메트릭을 정리한다. 각 메트릭이 무엇을 측정하는지, 어떻게 계산하는지, 그리고 어떤 상황에서 활용하는지를 구체적인 예시와 함께 살펴본다.


사전 개념: 골든 증거(Golden Evidence)

메트릭을 이해하기 전에 골든 증거의 개념을 먼저 알아야 한다.

골든 증거란 특정 질문에 대해 **“이 청크가 있어야 정답을 생성할 수 있다”**고 사람이 미리 판정해 둔 정답 문서(청크) 집합이다. 평가 데이터셋을 만들 때 각 질문마다 골든 증거를 함께 라벨링한다.

질문: "카프카에서 auto-commit의 기본 주기는?"
골든 증거: [chunk_42, chunk_87]

질문: "PostgreSQL의 MVCC란?"
골든 증거: [chunk_15, chunk_23, chunk_91]

모든 메트릭은 이 골든 증거 대비 검색 결과가 얼마나 잘 매칭되는지를 측정한다.


1. Recall@K — “관련 문서를 얼마나 찾았는가?”

정의

전체 골든 증거 중 Top-K 검색 결과에서 찾아낸 비율이다.

Recall@K = (Top-K에서 매칭된 골든 증거 수) / (전체 골든 증거 수)

구체적인 예시

사용자가 “Kafka consumer가 crash하면 어떤 일이 발생하는가?“라고 질문했다고 하자. 이 질문에 대한 골든 증거가 3개라고 가정한다.

골든 증거 (3개):
  ① chunk_12: "auto-commit 주기 사이에 crash가 발생하면..."
  ② chunk_45: "재시작 시 마지막 커밋된 offset부터 소비..."
  ③ chunk_78: "중복 범위는 마지막 auto-commit 시점부터..."

검색 결과 Top-10:
  1위: chunk_12  ← 골든 ✅
  2위: chunk_99  ← 무관
  3위: chunk_45  ← 골든 ✅
  4위: chunk_33  ← 무관
  5위: chunk_55  ← 무관
  ...
  10위: chunk_21 ← 무관
  • Recall@5 = 2/3 = 0.667 (Top-5에서 2개 찾음)
  • Recall@10 = 2/3 = 0.667 (Top-10에서도 2개, chunk_78을 못 찾음)
  • Recall@20 = 3/3 = 1.0 (Top-20으로 넓히면 chunk_78도 포함)

K 값에 따른 의미

K 값의미
Recall@5상위 5개만으로 충분한지 — 비용/속도 최적화 시 기준
Recall@10일반적인 RAG 컨텍스트 크기에서의 커버리지
Recall@20리랭킹 전 후보 풀의 커버리지 — 리랭킹이 의미 있으려면 이 값이 높아야 함

왜 RAG에서 가장 중요한 메트릭인가?

LLM은 컨텍스트에 포함된 정보만으로 답변을 생성한다. Recall이 낮으면 아무리 뛰어난 LLM을 사용하더라도 정답을 만들어낼 수 없다. 반대로 순서가 조금 뒤바뀌더라도(MRR이 낮더라도) 청크가 컨텍스트에 포함되기만 하면 LLM은 정답을 생성할 수 있다.

Recall@20 높음 + Recall@5 낮음
→ 후보 풀에는 다 있지만 상위 랭킹이 안 좋다
→ 리랭킹(Reranker) 개선으로 해결 가능

Recall@20 자체가 낮음
→ 후보 풀에 관련 문서가 아예 없다
→ 임베딩 모델 교체, 청킹 전략 변경, 검색 쿼리 리라이팅 필요

2. MRR@K (Mean Reciprocal Rank) — “첫 번째 정답이 어디에 있는가?”

정의

첫 번째 관련 결과가 몇 번째에 등장하는지의 역수다.

MRR@K = 1 / (첫 번째 관련 청크의 순위)     (순위 ≤ K일 때)
      = 0.0                              (Top-K에 관련 청크 없을 때)

구체적인 예시

세 개의 쿼리에 대한 검색 결과를 비교해 보자.

쿼리 A: "PostgreSQL의 VACUUM이란?"
  검색 결과: [정답, 무관, 무관, ...]
  첫 번째 정답 위치: 1위
  MRR = 1/1 = 1.0 ✅

쿼리 B: "Redis의 eviction 정책 종류는?"
  검색 결과: [무관, 무관, 정답, 무관, ...]
  첫 번째 정답 위치: 3위
  MRR = 1/3 = 0.333

쿼리 C: "gRPC의 양방향 스트리밍이란?"
  검색 결과: [무관, 무관, ..., 무관]  (Top-10에 정답 없음)
  MRR = 0.0 ❌

세 쿼리의 평균 MRR@10 = (1.0 + 0.333 + 0.0) / 3 = 0.444

값의 해석

값 범위해석
0.8~1.0대부분 1~2번째에 정답 등장 — 우수
0.5~0.82~3번째 정도 — 양호
< 0.3정답이 뒤쪽에 묻힘 — 랭킹 개선 필요

Recall과의 핵심 차이

Recall은 “찾았는가?”(양), MRR은 “얼마나 빨리 찾았는가?”(질)를 측정한다.

시나리오: Recall@10 = 1.0인데 MRR@10 = 0.1

→ 골든 증거를 모두 찾긴 했지만, 첫 번째 정답이 10번째에 있다.
→ RAG 컨텍스트로는 문제없지만, 사용자에게 결과를 직접 보여주는 UI에서는 UX가 나쁘다.

MRR은 검색 결과를 사용자에게 직접 노출하는 서비스(문서 검색 UI, 고객센터 FAQ 검색 등)에서 특히 중요하다. “첫 번째 결과가 바로 정답인가?“를 직접 측정하기 때문이다.


3. nDCG@K (Normalized Discounted Cumulative Gain) — “랭킹 순서가 최적인가?”

정의

관련 결과가 상위에 집중되어 있는지를 측정하는 순위 가중 메트릭이다. MRR이 “첫 번째 정답"만 보는 반면, nDCG는 모든 관련 결과의 순위 분포를 종합 평가한다.

DCG@K  = Σ (rel(r) / log₂(r + 1))     for r = 1 to K
IDCG@K = 관련성 플래그를 최적 정렬했을 때의 DCG (이상적 순서)
nDCG@K = DCG@K / IDCG@K

구체적인 예시

어떤 질문에 대해 골든 증거가 2개이고, Top-5 검색 결과에서 관련성이 [0, 1, 0, 1, 0]이라고 하자. (1 = 관련 있음, 0 = 관련 없음)

실제 검색 결과의 DCG 계산:

위치 1: rel=0 → 0 / log₂(2) = 0 / 1.000 = 0.000
위치 2: rel=1 → 1 / log₂(3) = 1 / 1.585 = 0.631
위치 3: rel=0 → 0 / log₂(4) = 0 / 2.000 = 0.000
위치 4: rel=1 → 1 / log₂(5) = 1 / 2.322 = 0.431
위치 5: rel=0 → 0 / log₂(6) = 0 / 2.585 = 0.000

DCG@5 = 0 + 0.631 + 0 + 0.431 + 0 = 1.062

이상적 순서 [1, 1, 0, 0, 0]의 IDCG 계산:

위치 1: rel=1 → 1 / log₂(2) = 1.000
위치 2: rel=1 → 1 / log₂(3) = 0.631

IDCG@5 = 1.000 + 0.631 = 1.631

nDCG@5 = 1.062 / 1.631 = 0.651

관련 청크 2개가 2위와 4위에 있으므로 이상적 순서(1위, 2위)와 비교하면 65.1%의 랭킹 품질을 보이는 것이다.

log₂ 할인의 직관

nDCG에서 log₂(r + 1)로 나누는 이유는 상위 순위의 가치가 훨씬 크기 때문이다. 사람은 검색 결과를 위에서부터 보기 때문에 1위에 있는 정답은 10위에 있는 정답보다 가치가 높다.

위치별 할인 계수 (1/log₂(r+1)):
  1위: 1.000  ← 할인 없음
  2위: 0.631
  3위: 0.500
  4위: 0.431
  5위: 0.387
  10위: 0.289  ← 1위 대비 약 29% 가치

MRR과 nDCG의 비교

비교 시나리오MRRnDCG
관련 청크 3개가 1, 2, 3위1.01.0
관련 청크 3개가 1, 8, 9위1.0< 1.0 (2개가 뒤로 밀림)
관련 청크 3개가 5, 8, 9위0.2낮음 (전부 뒤에 있음)

두 번째 시나리오가 핵심이다. MRR은 첫 번째 정답만 보기 때문에 1.0이지만, nDCG는 나머지 2개가 뒤에 밀린 것까지 반영하여 점수가 낮아진다. 여러 관련 문서의 순위 분포를 종합적으로 평가하고 싶을 때 nDCG가 적합하다.

주의사항

IDCG를 검색된 집합 내의 관련성으로 계산하는 경우, nDCG = 1.0이어도 Recall < 1.0일 수 있다. 찾은 것들은 완벽한 순서이지만, 일부 골든 증거를 아예 못 찾은 경우다. 이것이 Recall@K가 RAG에서 주력 메트릭인 이유다.


4. Hit@K — “검색이 성공했는가, 실패했는가?”

정의

Top-K에 관련 청크가 하나라도 있는지의 이진 판정이다.

Hit@K = True    (Top-K에 관련 청크 ≥ 1개)
      = False   (Top-K에 관련 청크 0개)

구체적인 예시

100개의 평가 쿼리에 대해 검색을 수행했다고 하자.

쿼리 1: Top-10에 관련 청크 3개 → Hit@10 = True ✅
쿼리 2: Top-10에 관련 청크 1개 → Hit@10 = True ✅
쿼리 3: Top-10에 관련 청크 0개 → Hit@10 = False ❌
...
쿼리 100: Top-10에 관련 청크 2개 → Hit@10 = True ✅

Hit Rate@10 = 87/100 = 0.87
→ 100개 쿼리 중 87개에서 검색이 성공, 13개에서 완전 실패

다른 메트릭과의 조합

Hit@K는 가장 단순한 메트릭이지만, 다른 메트릭과 조합하면 실패 유형을 분류할 수 있다.

상태의미
Hit@10 = False검색 완전 실패 (Recall 자체가 0)
Hit@10 = True, Recall@10 낮음일부만 찾음 — 부분 실패
Hit@10 = True, Recall@10 = 1.0완전 성공

실무 활용

Hit Rate는 시스템 전체의 검색 실패율을 모니터링하는 데 유용하다. Hit Rate@10이 0.95라면 “전체 쿼리의 5%에서 검색이 완전히 실패한다"고 바로 해석할 수 있다. 이 실패 쿼리들만 모아서 분석하면 임베딩 모델의 약점이나 청킹 전략의 문제점을 빠르게 파악할 수 있다.

Hit@20 = False인 쿼리들을 모아서 분석:
  → 전문 용어/약어를 포함한 쿼리가 많다면 → 쿼리 확장(query expansion) 도입
  → 특정 도메인의 문서가 빠져 있다면 → 데이터 수집 범위 확대
  → 긴 질문이 실패한다면 → 임베딩 모델의 max token 한계 확인

5. Faithfulness (충실도) — “답변이 소스에 근거하는가?”

정의

LLM 답변이 검색된 소스에 얼마나 근거하는지를 측정하는 메트릭이다. 측정 방법은 LLM-as-a-Judge(RAGAS 등)부터 키워드 오버랩까지 다양한데, 여기서는 가장 단순한 키워드 오버랩 기반 방식을 소개한다.

Faithfulness = (답변 단어 중 소스에 등장하는 수) / (답변의 의미 있는 단어 수)

여기서 “의미 있는 단어"란 3글자 이상이면서 불용어(the, is, 그리고, 이것 등)를 제외한 단어를 의미한다.

구체적인 예시

검색된 소스:
  "PostgreSQL의 VACUUM은 dead tuple을 정리하여 테이블의 저장 공간을
   재사용할 수 있게 한다. autovacuum은 기본적으로 활성화되어 있다."

LLM 답변 A (충실한 답변):
  "PostgreSQL에서 VACUUM은 dead tuple을 정리하는 작업입니다.
   autovacuum이 기본 활성화되어 있어 자동으로 수행됩니다."
  → 의미 있는 단어: [PostgreSQL, VACUUM, dead, tuple, 정리하는, autovacuum, 기본, 활성화, 자동으로, 수행]
  → 소스에 있는 단어: [PostgreSQL, VACUUM, dead, tuple, 정리, autovacuum, 기본, 활성화] = 8개
  → Faithfulness ≈ 8/10 = 0.80 ✅

LLM 답변 B (할루시네이션 포함):
  "PostgreSQL에서 VACUUM은 인덱스를 재구성하고 쿼리 플래너의
   통계를 갱신하는 작업입니다. 주로 야간 배치로 실행합니다."
  → 의미 있는 단어: [PostgreSQL, VACUUM, 인덱스, 재구성, 쿼리, 플래너, 통계, 갱신, 야간, 배치, 실행]
  → 소스에 있는 단어: [PostgreSQL, VACUUM] = 2개
  → Faithfulness ≈ 2/11 = 0.18 ❌ (할루시네이션 가능성 높음)

값의 해석

해석
0.9~1.0답변이 소스에 충실함
0.5~0.8일부 내용을 소스 외에서 가져옴
< 0.5할루시네이션 가능성 높음

한계

키워드 오버랩 기반이기 때문에 의미적 패러프레이징은 감지하지 못한다.

소스: "프로세스가 비정상적으로 종료되면"
답변: "프로세스가 crash하면"

→ 같은 의미이지만 "crash"가 소스에 없으므로 오버랩으로 잡히지 않는다.

LLM 기반 충실도 판정(LLM-as-a-Judge)보다 가볍고 빠르지만, 정밀도는 낮다. 대규모 평가에서 빠르게 할루시네이션 후보를 걸러내는 1차 스크리닝 용도로 적합하다.


메트릭 간 관계 요약

5가지 메트릭을 질문 유형별로 정리하면 다음과 같다.

검색 품질: “검색이 됐는가?”

Hit@K ──── 이진 판정: 됐다 / 안 됐다
  │
  └── Recall@K ──── 비율: 전체 중 얼마나 찾았는가

랭킹 품질: “검색 순서가 좋은가?”

MRR@K ──── 첫 번째 정답의 위치 (단일 포인트)
  │
  └── nDCG@K ──── 모든 정답의 순위 분포 (종합 점수)

생성 품질: “답변이 신뢰할 수 있는가?”

Faithfulness ──── 소스에 근거하는가 (할루시네이션 감지)
Answer Accuracy ─ 정답인가 (최종 정확도, 별도 주제)

실전: RAG 파이프라인 개선 시 메트릭 활용 순서

RAG 시스템을 개선할 때 메트릭을 보는 순서가 중요하다. 검색 → 랭킹 → 생성 순서로 문제를 추적해야 한다. 검색 자체가 실패하면 랭킹이나 생성을 아무리 개선해도 소용없기 때문이다.

Step 1: Recall@20 — 후보 풀의 커버리지 확인

Recall@20이 낮다면 (< 0.8):
  → 리랭킹 이전에 후보 풀 자체에 관련 문서가 없다
  → 개선 방향: 임베딩 모델 교체, 청킹 전략 변경, 하이브리드 검색(dense + sparse) 도입

Step 2: Recall@10 vs Recall@20 격차 — 리랭킹 효과 측정

Recall@20 = 0.95, Recall@10 = 0.70
  → 격차 0.25: 리랭킹이 상위 10개를 잘 선별하지 못하고 있다
  → 개선 방향: Cross-encoder 리랭커 도입/교체, 리랭킹 피처 추가

Recall@20 = 0.95, Recall@10 = 0.92
  → 격차 0.03: 리랭킹이 잘 작동하고 있다

Step 3: MRR@10 — 상위 랭킹 품질 확인

MRR@10이 낮다면 (< 0.5):
  → 정답이 상위에 오지 못하고 있다
  → 개선 방향: 리랭킹 모델의 스코어링 조정, 메타데이터 부스팅, 쿼리-문서 매칭 개선

Step 4: Hit Rate — 완전 실패 쿼리 식별

Hit Rate@10 = 0.92
  → 8%의 쿼리에서 검색이 완전히 실패
  → 실패 쿼리를 모아서 패턴 분석 (전문 용어? 복합 질문? 특정 도메인?)

Step 5: Accuracy + Faithfulness — LLM 생성 품질 확인

검색 메트릭은 좋은데 (Recall@10 > 0.9) 최종 정확도가 낮다면:
  → 검색은 성공했지만 LLM이 답변을 잘 생성하지 못하는 것
  → 개선 방향: 프롬프트 엔지니어링, 컨텍스트 포맷 변경, LLM 모델 교체

Faithfulness가 낮다면 (< 0.5):
  → LLM이 소스에 없는 정보를 지어내고 있다
  → 개선 방향: "주어진 정보만으로 답하라" 등의 프롬프트 제약 강화

정리

메트릭측정 대상핵심 질문주 활용처
Recall@K검색 커버리지관련 문서를 얼마나 찾았는가?RAG의 핵심 메트릭
MRR@K상위 랭킹첫 번째 정답이 어디에 있는가?검색 UI, UX 품질
nDCG@K종합 랭킹모든 정답의 순위 분포가 최적인가?랭킹 모델 비교
Hit@K성공/실패검색이 아예 실패했는가?실패율 모니터링
Faithfulness생성 충실도답변이 소스에 근거하는가?할루시네이션 감지

RAG 파이프라인에서 가장 중요한 것은 Recall@K다. 검색이 관련 문서를 찾지 못하면 후속 단계를 아무리 개선해도 정확한 답변을 생성할 수 없다. 개선 순서는 항상 검색(Recall) → 랭킹(MRR, nDCG) → 생성(Accuracy, Faithfulness) 순서로 진행하는 것이 효율적이다.