본문 바로가기
C.W.K.
Stream
Lesson 01 of 06 · published

RAG 평가

~22 min · systems, rag, retrieval

Level 0추측자
0 XP0/55 lessons0/10 achievements
0/150 XP to next level150 XP to go0% complete

두 단계, 여러 실패 방식, 일곱 가지 지표

RAG 시스템은 두 단계로 이루어져 있고, 실패 방식은 적어도 4가지야. 검색 단계에서는 잘못되거나 불충분한 문서를 가져올 수 있어. 생성 단계에서는 환각을 일으키거나, 내용을 잘못 요약하거나, 엉뚱한 질문에 답할 수 있지. 각 단계는 독립적으로 평가해야 해.

검색 단계 지표

  • 재현율@k — 전체 관련 문서 가운데 상위 k개 결과로 검색된 문서의 비율을 측정해.
  • 정밀도@k — 상위 k개 문서 가운데 관련 문서가 차지하는 비율을 측정해.
  • nDCG@k — 정규화 할인 누적 이득이야. 관련 문서가 더 높은 순위에 배치될수록 높은 점수를 줘.
  • MRR — 평균 역순위야. 첫 번째 관련 문서 순위의 역수인 1/순위를 사례별로 구한 뒤 평균을 내.

생성 단계 지표

  • 충실성 — 답변의 주장이 검색된 맥락에 근거하고 있어?
  • 답변 관련성 — 답변이 사용자의 질문을 제대로 다뤄?
  • 인용 정확도 — 시스템이 출처를 인용한다면, 인용 링크가 실제 근거가 있는 문단을 가리켜?

왜 분해된 지표가 중요해

하나로 합친 "RAG 품질 점수"는 디버깅에 도움이 되지 않아. 단계별 지표를 보면 개발 노력을 어디에 집중해야 할지 정확히 알 수 있어:

  • 낮은 재현율 → 검색기를 개선해. 더 나은 임베딩, 혼합 검색, 질의 재작성 등을 적용할 수 있어.
  • 높은 재현율, 낮은 충실성 → 생성기 프롬프트를 개선하고, 온도를 낮추거나, 인용을 강제해.
  • 높은 충실성, 낮은 관련성 → 검색기는 올바른 문서를 찾았지만 생성기가 다른 질문에 답하고 있어. 보통 프롬프트 문제야.
원칙: RAG에서는 검색과 생성을 항상 독립적으로 측정해. 종합 점수는 문제를 감추지만, 단계별 지표는 원인을 알려줘.

RAG 평가 모음 만들기

각 사례에 question, expected_relevant_doc_ids, reference_answer를 기록해. 질문으로 검색을 실행하고, 기준 답변으로 생성 결과를 채점하며, 관련 문서 ID가 두 단계를 이어 줘. 셋 중 하나라도 없으면 평가할 수 있는 범위가 줄어들어.

Code

검색 지표 — 재현율과 nDCG·python
import math

def recall_at_k(retrieved_ids, relevant_ids, k):
    top_k = retrieved_ids[:k]
    return sum(1 for d in top_k if d in relevant_ids) / max(len(relevant_ids), 1)

def ndcg_at_k(retrieved_ids, relevant_ids, k):
    relevance_scores = [1.0 if d in relevant_ids else 0.0 for d in retrieved_ids[:k]]
    dcg = sum(rel / math.log2(i + 2) for i, rel in enumerate(relevance_scores))
    ideal = sum(1.0 / math.log2(i + 2) for i in range(min(len(relevant_ids), k)))
    return dcg / ideal if ideal > 0 else 0.0

retrieved = ["doc_5", "doc_2", "doc_9", "doc_1", "doc_7"]
relevant = {"doc_2", "doc_7", "doc_3"}
print(recall_at_k(retrieved, relevant, 5))   # 0.667
print(ndcg_at_k(retrieved, relevant, 5))     # ~0.59
RAGAS를 활용한 종단 간 RAG 평가·python
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall

data = Dataset.from_dict({
    "question": ["How many users does Acme have?"],
    "answer": ["Acme has 2.5M users as of Q1 2026."],
    "contexts": [["Acme grew to 2.5M users in Q1 2026.", "Acme has offices in 12 countries."]],
    "ground_truth": ["2.5 million users"],
})

result = evaluate(
    data,
    metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
)
print(result)
# Each metric scored independently — you can see exactly which axis failed.
인용 정확도 확인·python
import re

def citation_accuracy(answer, retrieved_docs):
    """Does every numbered citation point to a real retrieved doc?"""
    cited_ids = set(re.findall(r'\[doc_(\d+)\]', answer))
    retrieved_ids = {d['id'] for d in retrieved_docs}
    bogus = cited_ids - retrieved_ids
    if bogus:
        return 0.0, f"hallucinated citations: {bogus}"
    if not cited_ids:
        return 0.0, "no citations in answer"
    return 1.0, "all citations point to retrieved docs"

External links

Exercise

RAG 시스템을 위한 30개 사례의 평가 모음을 만들어. 각 사례에 질문, expected_doc_ids, reference_answer를 포함해. 재현율@5, 충실성, 답변 관련성을 독립적으로 계산하고, 가장 낮은 점수가 가리키는 파이프라인 단계를 다음 개선 대상으로 정해.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.