RAG 평가 프레임워크 — RAGAS로 성능 측정하기
RAG 파이프라인을 구축했다면 다음 질문이 생깁니다. "얼마나 잘 동작하고 있는가?" 인간이 직접 평가하는 건 느리고 비쌉니다. **RAGAS(RAG Assessment)**는 LLM을 심판으로 활용해 RAG 파이프라인을 자동으로 평가하는 프레임워크입니다.
RAGAS의 4가지 핵심 지표
1. Faithfulness (충실성)
생성된 답변이 검색된 컨텍스트에 얼마나 충실한가를 측정합니다. 컨텍스트에 없는 내용을 지어내면 점수가 낮아집니다.
점수 = (컨텍스트로 뒷받침되는 주장 수) / (답변의 총 주장 수)값이 낮으면 모델이 환각(Hallucination)을 일으키고 있다는 신호입니다.
2. Answer Relevancy (답변 관련성)
생성된 답변이 질문에 얼마나 적절한가를 측정합니다. 관련 없는 내용이 많으면 점수가 낮습니다.
점수 = avg(cosine_similarity(질문, 역생성된 질문들))RAGAS는 답변에서 역으로 질문을 여러 개 생성하고, 원래 질문과의 유사도를 계산합니다.
3. Context Precision (컨텍스트 정밀도)
검색된 컨텍스트 중 실제로 유용한 청크의 비율입니다. 관련 없는 문서가 많이 검색될수록 낮아집니다.
4. Context Recall (컨텍스트 재현율)
정답을 생성하는 데 필요한 정보가 검색된 컨텍스트에 얼마나 포함되어 있는가입니다. 정답 데이터셋이 필요합니다.
실전 코드
from ragas import evaluate
from ragas.metrics import (
faithfulness,
answer_relevancy,
context_precision,
context_recall,
)
from datasets import Dataset
# 평가 데이터셋 구성
eval_data = {
"question": ["RAG와 파인튜닝의 차이는?", "벡터 DB란?"],
"answer": ["RAG는 검색 기반...", "벡터 DB는..."],
"contexts": [
["RAG는 Retrieval-Augmented...", "파인튜닝은 모델 가중치를..."],
["벡터 데이터베이스는 고차원 벡터를..."],
],
"ground_truth": ["RAG는 지식을 외부에서 가져오고...", "벡터 DB는 임베딩을 저장하는..."],
}
dataset = Dataset.from_dict(eval_data)
result = evaluate(
dataset=dataset,
metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
)
print(result)
# {'faithfulness': 0.89, 'answer_relevancy': 0.92, 'context_precision': 0.85, 'context_recall': 0.78}점수 해석과 개선 방향
| 낮은 지표 | 원인 | 해결책 |
|---|---|---|
| Faithfulness | 환각 발생 | 프롬프트에 "컨텍스트만 참고" 강조, temperature 낮춤 |
| Answer Relevancy | 두루뭉술한 답변 | 프롬프트 구체화, 출력 형식 제한 |
| Context Precision | 노이즈 검색 | top_k 줄이기, 유사도 임계값 높이기 |
| Context Recall | 관련 문서 누락 | 청킹 전략 변경, 하이브리드 검색 도입 |
평가 데이터셋을 자동으로 생성하기
레이블된 Q&A 데이터가 없어도 RAGAS로 합성 데이터셋을 만들 수 있습니다.
from ragas.testset.generator import TestsetGenerator
from ragas.testset.evolutions import simple, reasoning, multi_context
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
generator = TestsetGenerator.from_langchain(
generator_llm=ChatOpenAI(model="gpt-4o"),
critic_llm=ChatOpenAI(model="gpt-4o"),
embeddings=OpenAIEmbeddings(),
)
testset = generator.generate_with_langchain_docs(
documents=docs,
test_size=50,
distributions={simple: 0.5, reasoning: 0.3, multi_context: 0.2},
)CI에 평가 통합하기
RAG 파이프라인을 변경할 때마다 자동으로 평가가 돌아가야 합니다.
# .github/workflows/rag-eval.yml
- name: RAG Evaluation
run: python eval/run_ragas.py
- name: Check Thresholds
run: |
python -c "
import json
r = json.load(open('eval/results.json'))
assert r['faithfulness'] > 0.85, 'Faithfulness 기준 미달'
assert r['context_recall'] > 0.75, 'Context Recall 기준 미달'
"점수가 기준치 아래로 떨어지면 PR을 블로킹할 수 있습니다.
이것으로 RAG 완전 정복 시리즈를 마칩니다. 개념 이해(EP 01) → 벡터 DB 선택(EP 02) → 청킹 전략(EP 03) → 평가(EP 04) 순서로 따라왔다면, 프로덕션 수준의 RAG 파이프라인을 설계하고 측정할 준비가 된 겁니다.
최소 평가 루프
# 개념: 골든셋 → RAGAS 메트릭 → 게이트
python eval_ragas.py --dataset golden.jsonl --threshold 0.7| 메트릭 | 의미 |
|---|---|
| faithfulness | 답이 컨텍스트에 근거하는가 |
| answer relevancy | 질문에 맞는가 |
| context precision/recall | 검색 품질 |
CI 게이트
- PR: 샘플 20건 스모크
- nightly: 전체 골든셋
- 임계 미달 시 인덱스/청킹 롤백
점수가 실행할 때마다 흔들릴 때
RAGAS 지표는 내부적으로 LLM을 평가자로 사용하므로, 같은 데이터로 다시 돌려도 점수가 조금씩 달라집니다. 이를 모르고 작은 차이로 설정 A/B를 판정하면 잘못된 결론을 내리기 쉽습니다.
원인
- 평가용 LLM의 출력이 완전히 결정적이지 않음
- 평가 세트가 작아 문항 몇 개의 변동이 평균을 크게 움직임
- 평가용 모델 버전이 바뀜(별칭 사용)
확인 방법: 같은 설정을 여러 번 평가해 변동 폭 측정
import statistics
runs = [evaluate(dataset, metrics=[faithfulness, answer_relevancy]).to_pandas() for _ in range(5)]
for m in ["faithfulness", "answer_relevancy"]:
means = [r[m].mean() for r in runs]
print(m, round(statistics.mean(means), 3), "±", round(statistics.stdev(means), 3))두 설정의 차이가 이 변동 폭보다 작다면 "차이 없음"으로 보는 것이 안전합니다.
해결
- 평가용 LLM은 스냅샷 버전으로 고정하고 temperature를 0으로 둡니다.
- 평가 세트를 늘리거나, 문항별로 두 설정의 점수 차를 보고 대응 표본 검정(예: 윌콕슨 부호 순위 검정)으로 판단합니다.
재발 방지
- CI 게이트 임계값은 측정한 변동 폭을 고려해 정하고, 임계값 근처에서는 사람이 결과를 확인하도록 합니다.
참고 자료
검증 환경·편집자 주
- 2026-09. LLM-as-judge 비용·편향을 감안해 샘플 크기를 조절하세요.
자주 묻는 질문 (FAQ)
Q. 사람이 아예 안 봐도 되나요?
아니요. 주기적으로 샘플을 사람 검수해 판정 기준을 보정하세요.
글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보
이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.
댓글
첫 번째 댓글을 남겨보세요.