마케팅팀에서 사내 FAQ 챗봇을 만들었는데, 답변이 그럴듯해 보이긴 합니다. 그런데 "이게 정말 맞는 답이야?"라고 물으면 답을 못 합니다. 이 글은 그 질문을 숫자로 바꾸는 4가지 지표 이야기예요.
마케터가 이 글을 읽어야 하는 이유: RAG 챗봇을 만들고 "잘 되는 것 같다"는 인상에 의존하면, 언제 망가졌는지 모릅니다. 4가지 지표를 매주 한 번만 돌려도 "검색이 문제인지, 생성이 문제인지"를 회의에서 5분 안에 설명할 수 있게 됩니다.

질문에서 답변까지 두 단계, 그리고 각 단계마다 두 개씩의 평가 지표. 이 4개를 매주 본다.
1. RAG 평가가 필요한 이유 — 두 축으로 보기
RAG는 Retrieval-Augmented Generation의 약자입니다. 풀어쓰면 "답변하기 전에 자료를 검색하는 LLM"이에요. 마케팅 도메인에 적용하면:
- 사내 위키의 광고 정책을 검색 → 마케터 질문에 답하는 챗봇
- 과거 캠페인 리포트를 검색 → "비슷한 KPI의 캠페인 결과 보여줘"
- 경쟁사 분석 문서를 검색 → "X 브랜드 최근 CPM 트렌드 알려줘"
문제는 답변이 그럴듯해 보일 뿐 진짜 맞는지를 어떻게 검증하느냐입니다.
흔한 오해는 "답변이 정확한가만 보면 된다"입니다. 실제로는 두 단계가 있어요.
사용자 질문
│
▼
[검색 단계] ── 평가 ──▶ Context Relevance (관련 자료를 가져왔나?)
│ Context Recall (필요한 자료를 빠뜨리지 않았나?)
▼
관련 문서들
│
▼
[생성 단계] ── 평가 ──▶ Faithfulness (자료 밖 내용을 지어내지 않았나?)
│ Answer Relevance (질문에 직접 답했나?)
▼
최종 답변
따라서 평가 지표는 검색 품질과 답변 품질 두 축에서 각각 측정됩니다.
📌 왜 두 축이 다 중요한가
검색이 잘못되면 답변은 출처가 없는 환각(hallucination)이 되고,
검색은 맞는데 생성이 엉뚱하면 좋은 자료를 두고 헛소리를 합니다.
마케팅 챗봇에서 둘 중 하나라도 망가지면 신뢰가 무너집니다.
2. 4가지 지표 — 한 표로
| 지표 | 무엇을 보는가 | 일상어로 |
|---|---|---|
| Context Relevance | 검색된 문서가 질문과 얼마나 관련 있나 | "검색이 진짜 답에 가까운 자료를 가져왔어?" |
| Context Recall | 정답에 필요한 자료를 빠뜨리지 않았나 | "필요한 문서가 다 들어왔어?" |
| Faithfulness | 답변이 검색된 문서 안에서만 말하는가 | "지어내지 않고 자료를 진짜로 봤어?" |
| Answer Relevance | 답변이 질문에 정확히 답했나 | "동문서답 아니야?" |
이 4가지를 한 번씩 계산하면 RAG 시스템의 건강 상태가 입체적으로 보입니다.
3. 각 지표를 코드 한 묶음으로
Ragas 라이브러리가 이 4가지를 모두 LLM-as-judge 방식으로 계산해줍니다. 한 번 돌려보면 이렇게 나와요.
```python title="evaluate_rag.py"
from datasets import Dataset
from ragas import evaluate
from ragas.metrics import (
context_relevancy, context_recall,
faithfulness, answer_relevancy
)
마케팅 FAQ 챗봇 테스트 케이스
data = {
"question": ["우리 회사 광고 채널 중 ROAS 가장 높은 채널은?"],
"answer": ["지난 분기 기준 Meta 광고 ROAS가 4.2로 가장 높았습니다."],
"contexts": [["분기 보고서: Meta ROAS 4.2, Google 3.5, Naver 2.8..."]],
"ground_truth": ["Meta 광고가 ROAS 4.2로 가장 높음"],
}
result = evaluate(
Dataset.from_dict(data),
metrics=[context_relevancy, context_recall,
faithfulness, answer_relevancy],
)
print(result)
```text title="출력"
{'context_relevancy': 0.91,
'context_recall': 1.00,
'faithfulness': 0.95,
'answer_relevancy': 0.88}
Context Relevance 0.91
검색된 문서의 91%가 질문과 관련 있다는 뜻. 90% 이상이면 좋고, 70% 아래로 떨어지면 검색기를 손봐야 합니다.
Context Recall 1.00
정답 생성에 필요한 자료를 모두 가져왔습니다. 0.7 이하면 정답 정보가 빠졌다는 뜻이에요. 인덱싱 누락·청크 크기 문제를 의심합니다.
Faithfulness 0.95
답변의 95%가 검색 문서에서 직접 지지됩니다. 0.8 이하면 LLM이 자기 지식으로 빈 칸을 채우고 있다는 신호 — 환각 위험입니다.
수식으로 보면 단순합니다.
답변 안의 명제(claim)를 LLM이 쪼갠 뒤, 각 명제가 검색 문서에 의해 지지되는지 검사합니다. 분모가 작아지면 점수가 흔들리니, 답변을 너무 짧게 만들어 점수만 올리는 함정도 조심해야 해요.
Answer Relevance 0.88
질문 자체에 88% 직접적으로 답했습니다. 0.7 이하면 동문서답이 섞이고 있어요.
직관적으로 말하면, 답변에서 거꾸로 질문을 생성해보고 원 질문과 얼마나 가까운지를 봅니다. 임베딩 코사인 유사도로 환산하면 다음과 같아요.
- — 임베딩 함수
- — 원 질문, — 답변에서 역생성된 질문 후보
- — 후보 개수 (보통 3~5개)
4. 골든셋 — 어디서부터 시작하나
마케터 입장에서 가장 큰 장벽은 "정답이 적힌 데이터(ground truth)를 어디서 구하나"입니다. 답: 30-50개로 충분합니다.
만드는 절차
- 실제 마케터·운영팀이 챗봇에 자주 물을 만한 질문 50개를 적습니다.
- 각 질문에 사람이 직접 정답을 작성합니다 (15분짜리 문서 1쪽).
- 챗봇을 돌려서 4가지 지표를 매주 계산합니다.
이게 회귀 테스트가 됩니다. 챗봇 모델·프롬프트를 바꿨을 때 4가지 지표가 어떻게 움직이는지 한눈에 보여요.
골든셋의 다양성을 챙기는 방법
50개를 무작위로 뽑으면 비슷한 질문 패턴에 쏠립니다. 다음 4분면을 고르게 채우면 됩니다.
| 축 \ 축 | 사실형 (정답 1개) | 해석형 (정답 다수) |
|---|---|---|
| 단순 (한 문장) | "Meta CPM 기준값은?" | "최근 ROAS 좋은 캠페인은?" |
| 복합 (여러 단계) | "Q3 Naver 클릭 대비 전환은?" | "지난 분기 캠페인 중 다음에도 쓸 만한 건?" |
각 셀에 12~13개씩, 총 50개. 이렇게 다양성을 강제하면 4가지 지표가 어느 종류 질문에서 약해지는지 한눈에 드러납니다.
골든셋이 진화하는 단계
- 0주차: 50개 직접 작성, 정답을 사람이 작성
- 2-4주차: 챗봇 답변 중 좋은 케이스를 골라 골든셋에 편입 (사람 검수 후)
- 2-3개월차: 사용자 로그에서 자주 나오는 질문을 추가, 100-200개로 확장
- 반기: 더 이상 통과 못 하는 도메인 영역 발견, 도메인별 별도 골든셋
골든셋은 살아 있는 데이터셋입니다. 한 번 만들고 끝이 아니에요.
{/* TODO_HUNY: 실제 사내에서 RAG 챗봇을 만들거나 검토한 케이스가 있다면 이 자리에 — 어떤 도메인, 골든셋 몇 개, 가장 빨리 망가졌던 지표 */}
5. 검색기를 어떻게 고르고 튜닝하나
지표가 나빠졌을 때, 어디를 손대야 할지 모르면 무용지물입니다. 4지표가 가리키는 손볼 위치는 다음과 같아요.
| 나빠진 지표 | 의심 위치 | 첫 조치 |
|---|---|---|
| Context Relevance | 검색기(retriever) | 임베딩 모델 교체, 또는 hybrid (BM25 + dense) |
| Context Recall | 청크 분할 / 인덱싱 | 청크 크기 줄이기, 메타데이터 필터 보강 |
| Faithfulness | 생성기(LLM) 프롬프트 | "검색 문서에 없는 내용 금지" 명시, temperature 낮추기 |
| Answer Relevance | 생성기 추론 단계 | rerank 추가, few-shot 예시로 답변 형식 고정 |
지표를 보고 어디를 조이는지가 정해진 매핑이 있으니, 회의에서 모호하지 않습니다.
Hybrid 검색 — BM25 + Dense
마케팅 도메인은 고유명사(브랜드명·캠페인 ID)가 많아서, dense embedding만으로는 정확 매칭이 약할 수 있어요. BM25 같은 키워드 검색을 함께 쓰는 hybrid 방식이 자주 효과적입니다.
python title="hybrid_search.py"
from rank_bm25 import BM25Okapi
Top comments (0)