🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

RAG 평가와 개선 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 18. · 6 Views

RAG 평가와 개선 완벽 가이드

RAG 시스템의 성능을 측정하고 개선하는 방법을 배웁니다. 검색 정확도부터 응답 품질까지, 실전에서 바로 적용할 수 있는 평가 지표와 개선 프로세스를 다룹니다.


목차

  1. RAG_평가_지표
  2. 검색_정확도_측정
  3. 응답_관련성_평가
  4. RAGAS_프레임워크_소개
  5. 평가_데이터셋_구축
  6. 지속적_개선_프로세스

1. RAG 평가 지표

어느 날 김개발 씨가 회사에서 RAG 챗봇을 만들어 배포했습니다. 그런데 사용자들로부터 "가끔 영뚱한 답변을 한다"는 피드백이 들어왔습니다.

박시니어 씨가 물었습니다. "RAG 시스템의 성능을 어떻게 측정하고 있나요?"

RAG 평가 지표는 검색 증강 생성 시스템의 품질을 정량적으로 측정하는 방법입니다. 마치 학생의 성적표처럼, 시스템이 얼마나 정확하게 정보를 찾고 적절한 답변을 생성하는지 숫자로 보여줍니다.

이를 통해 개선이 필요한 부분을 명확히 파악할 수 있습니다.

다음 코드를 살펴봅시다.

from ragas.metrics import (
    context_precision,
    context_recall,
    faithfulness,
    answer_relevancy
)

# RAG 시스템의 핵심 평가 지표
evaluation_metrics = {
    "context_precision": context_precision,  # 검색된 문서가 얼마나 정확한가
    "context_recall": context_recall,        # 필요한 정보를 모두 찾았는가
    "faithfulness": faithfulness,            # 답변이 문서에 충실한가
    "answer_relevancy": answer_relevancy     # 답변이 질문과 관련있는가
}

# 각 지표는 0~1 사이의 점수로 표현됩니다
# 1에 가까울수록 좋은 성능을 의미합니다

김개발 씨는 지난 달 열심히 RAG 챗봇을 만들었습니다. 회사 문서를 벡터 데이터베이스에 저장하고, 사용자 질문에 관련 문서를 찾아 답변을 생성하는 시스템이었습니다.

처음에는 잘 작동하는 것처럼 보였습니다. 그런데 며칠 후, 사용자들의 불만이 접수되기 시작했습니다.

"휴가 정책을 물어봤는데 복지 포인트 얘기를 한다", "필요한 정보의 절반만 알려준다" 같은 피드백이었습니다. 김개발 씨는 난감했습니다.

뭐가 문제인지 어떻게 알 수 있을까요? 박시니어 씨가 다가와 물었습니다.

"RAG 시스템의 성능을 측정하고 있나요? 눈으로만 확인하면 문제를 발견하기 어렵습니다." 그렇다면 RAG 시스템은 어떻게 평가해야 할까요?

쉽게 비유하자면, RAG 평가는 마치 레스토랑 평가와 같습니다. 레스토랑을 평가할 때 음식의 맛만 보지 않습니다.

재료의 신선도, 서빙 속도, 가격 대비 만족도 등 여러 측면을 봅니다. RAG 시스템도 마찬가지입니다.

단순히 "답변이 괜찮네"로 끝나면 안 됩니다. RAG 시스템을 평가할 때는 크게 두 단계를 봐야 합니다.

첫 번째는 검색 단계입니다. 사용자의 질문에 대해 적절한 문서를 찾아왔는가를 평가합니다.

필요한 정보가 담긴 문서를 모두 찾았는지, 불필요한 문서는 없는지 확인합니다. 두 번째는 생성 단계입니다.

찾아온 문서를 바탕으로 적절한 답변을 만들었는가를 평가합니다. 답변이 질문과 관련 있는지, 문서의 내용에 충실한지 확인합니다.

전통적인 방법으로는 이런 평가가 어려웠습니다. 개발자들은 직접 눈으로 답변을 확인하며 "이건 좋네, 이건 별로네" 판단해야 했습니다.

테스트 케이스가 10개면 괜찮지만, 1000개라면 어떨까요? 사람이 일일이 확인하는 것은 불가능합니다.

더 큰 문제는 주관적이라는 점입니다. 김개발 씨가 보기엔 괜찮은 답변이 박시니어 씨가 보기엔 부족할 수 있습니다.

바로 이런 문제를 해결하기 위해 정량적인 평가 지표가 등장했습니다. Context Precision은 검색된 문서 중 실제로 유용한 문서의 비율을 측정합니다.

10개의 문서를 가져왔는데 그중 7개만 관련 있다면 0.7의 점수를 받습니다. 이 지표가 낮다면 불필요한 문서를 너무 많이 가져오고 있다는 뜻입니다.

Context Recall은 필요한 정보를 얼마나 빠짐없이 찾았는지 측정합니다. 완벽한 답변을 위해 5개의 핵심 정보가 필요한데 3개만 찾았다면 0.6의 점수를 받습니다.

이 지표가 낮다면 중요한 정보를 놓치고 있다는 신호입니다. Faithfulness는 답변이 검색된 문서에 충실한지 측정합니다.

LLM이 문서에 없는 내용을 지어내지 않았는지 확인합니다. 이 지표가 낮다면 환각(hallucination) 문제가 있다는 뜻입니다.

Answer Relevancy는 답변이 질문과 얼마나 관련 있는지 측정합니다. 사용자가 "휴가 일수"를 물어봤는데 "휴가 신청 방법"을 설명하면 이 지표가 낮아집니다.

위의 코드를 살펴보겠습니다. RAGAS 라이브러리에서 제공하는 4가지 핵심 지표를 임포트합니다.

이들은 각각 독립적으로 동작하면서도 전체 시스템의 품질을 입체적으로 보여줍니다. 각 지표는 0에서 1 사이의 값을 반환하며, 1에 가까울수록 좋은 성능을 의미합니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 고객 지원 챗봇을 운영한다고 가정해봅시다.

매일 수백 건의 질문이 들어오는데, 모든 답변을 사람이 확인할 수는 없습니다. 대신 이 4가지 지표를 매일 자동으로 측정합니다.

Context Precision이 0.6 이하로 떨어지면 알림을 받고, Faithfulness가 낮아지면 프롬프트를 조정합니다. 많은 기업에서 이런 지표를 대시보드로 만들어 실시간으로 모니터링하고 있습니다.

성능이 떨어지는 순간을 즉시 포착하여 대응할 수 있기 때문입니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 하나의 지표만 보는 것입니다. Context Precision만 높다고 좋은 시스템이 아닙니다.

정확한 문서를 찾더라도 답변 생성이 엉망이면 소용없습니다. 4가지 지표를 종합적으로 봐야 합니다.

또 다른 실수는 점수에만 집착하는 것입니다. 0.85와 0.87의 차이는 실제 사용자 경험에서 큰 차이가 없을 수 있습니다.

점수는 방향성을 보는 도구이지 절대적인 기준이 아닙니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 조언을 들은 김개발 씨는 4가지 지표를 측정해봤습니다. Context Recall이 0.5로 나왔습니다.

필요한 정보의 절반만 찾고 있었던 것입니다. 문제를 찾았으니 이제 개선할 수 있습니다.

RAG 평가 지표를 제대로 이해하면 시스템의 약점을 정확히 파악하고 개선할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 4가지 지표를 모두 측정하고 종합적으로 판단하세요

  • 점수보다 변화 추이를 보는 것이 중요합니다
  • 지표별 목표 점수를 설정하고 지속적으로 개선하세요

2. 검색 정확도 측정

김개발 씨가 RAG 시스템의 검색 성능을 개선하려고 합니다. 그런데 "검색이 잘 되고 있는가"를 어떻게 판단해야 할까요?

박시니어 씨가 말했습니다. "Precision과 Recall, 이 두 가지를 이해해야 합니다."

검색 정확도는 RAG 시스템이 얼마나 정확하게 관련 문서를 찾는지 측정합니다. Precision은 찾아온 문서 중 유용한 문서의 비율이고, Recall은 필요한 문서를 얼마나 빠짐없이 찾았는지를 나타냅니다.

이 두 지표의 균형이 중요합니다.

다음 코드를 살펴봅시다.

def calculate_retrieval_metrics(retrieved_docs, relevant_docs):
    # retrieved_docs: 시스템이 찾아온 문서들
    # relevant_docs: 실제로 필요한 문서들

    true_positives = len(set(retrieved_docs) & set(relevant_docs))

    # Precision: 찾아온 것 중 정답 비율
    precision = true_positives / len(retrieved_docs) if retrieved_docs else 0

    # Recall: 필요한 것 중 찾은 비율
    recall = true_positives / len(relevant_docs) if relevant_docs else 0

    # F1 Score: 두 지표의 조화평균
    f1 = 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0

    return {"precision": precision, "recall": recall, "f1": f1}

김개발 씨는 RAG 시스템의 검색 성능을 개선하고 싶었습니다. 하지만 뭐부터 손봐야 할지 막막했습니다.

검색 결과를 눈으로 보면 어떤 때는 괜찮고 어떤 때는 이상해 보이는데, 이걸 어떻게 수치로 표현할 수 있을까요? 박시니어 씨가 화이트보드에 그림을 그리며 설명하기 시작했습니다.

"검색 정확도는 두 가지 측면에서 봐야 해요. 하나는 정확성, 다른 하나는 완결성입니다." 그렇다면 정확성과 완결성은 무엇일까요?

쉽게 비유하자면, 검색은 마치 물고기를 잡는 것과 같습니다. 그물을 던져서 물고기를 잡는데, 두 가지를 확인해야 합니다.

첫째, 잡은 것 중에 진짜 물고기가 얼마나 되는가? 쓰레기나 해초가 섞여 있으면 안 됩니다.

둘째, 잡아야 할 물고기를 모두 잡았는가? 놓친 물고기가 있으면 안 됩니다.

RAG 검색도 똑같습니다. **Precision(정밀도)**은 첫 번째 물음에 답합니다.

시스템이 10개의 문서를 가져왔는데, 그중 실제로 유용한 문서가 7개라면 Precision은 0.7입니다. 이 지표가 낮다면 쓸모없는 문서를 너무 많이 가져오고 있다는 뜻입니다.

LLM이 답변을 생성할 때 혼란스러워질 수 있습니다. **Recall(재현율)**은 두 번째 물음에 답합니다.

완벽한 답변을 위해 5개의 문서가 필요한데, 시스템이 그중 3개만 찾았다면 Recall은 0.6입니다. 이 지표가 낮다면 중요한 정보를 놓치고 있어 답변이 불완전해질 수 있습니다.

검색 성능 측정이 없던 시절에는 어땠을까요? 개발자들은 "대충 괜찮아 보이는데?"라는 느낌에 의존했습니다.

테스트 질문 몇 개를 던져보고 답변이 그럴듯하면 배포했습니다. 문제는 실제 서비스에서 예상치 못한 질문이 들어왔을 때 발생했습니다.

사용자들은 "왜 이런 엉뚱한 답변을 하죠?"라며 불만을 토로했습니다. 더 큰 문제는 개선 방향을 알 수 없다는 점이었습니다.

검색이 안 좋다는 건 알겠는데, 뭐가 문제인지 모릅니다. 임베딩 모델을 바꿔야 할까요?

청크 크기를 조정해야 할까요? 아니면 검색 알고리즘을 바꿔야 할까요?

감으로 이것저것 시도하다 시간만 낭비했습니다. 바로 이런 문제를 해결하기 위해 정량적인 검색 평가가 등장했습니다.

Precision과 Recall을 측정하면 문제가 명확해집니다. Precision이 낮다면 검색 범위를 좁혀야 합니다.

Top-K 값을 줄이거나, 유사도 임계값을 높입니다. 반대로 Recall이 낮다면 검색 범위를 넓혀야 합니다.

Top-K를 늘리거나, 하이브리드 검색을 도입합니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 검색된 문서와 실제 필요한 문서의 교집합을 구합니다. 이것이 True Positives, 즉 제대로 찾은 문서입니다.

Precision은 이를 검색된 전체 문서 수로 나눕니다. "찾은 것 중 정답 비율"입니다.

Recall은 이를 필요한 전체 문서 수로 나눕니다. "필요한 것 중 찾은 비율"입니다.

F1 Score는 두 지표의 조화평균입니다. Precision과 Recall이 모두 높아야 F1도 높아집니다.

하나만 높고 하나가 낮으면 F1은 낮게 나옵니다. 전체 검색 성능을 하나의 숫자로 표현할 때 유용합니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 법률 문서 검색 시스템을 만든다고 가정해봅시다.

변호사가 "부동산 계약 해지" 관련 판례를 찾습니다. Precision이 낮으면 관련 없는 판례까지 섞여 나와 일일이 확인하는 시간이 늘어납니다.

Recall이 낮으면 중요한 판례를 놓쳐 송사에 불리할 수 있습니다. 두 지표 모두 0.9 이상을 목표로 설정합니다.

많은 기업에서 A/B 테스트를 할 때도 이 지표를 사용합니다. 새로운 임베딩 모델을 도입했는데 정말 성능이 좋아졌을까요?

Precision과 Recall을 비교하면 명확하게 알 수 있습니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 두 지표를 동시에 높이려다 실패하는 것입니다. Precision과 Recall은 트레이드오프 관계입니다.

검색 범위를 넓히면 Recall은 올라가지만 Precision은 떨어집니다. 반대로 범위를 좁히면 Precision은 올라가지만 Recall이 떨어집니다.

따라서 서비스 특성에 맞게 우선순위를 정해야 합니다. 의료 정보 검색이라면 Recall을 우선합니다.

중요한 정보를 놓치면 안 되기 때문입니다. 반대로 뉴스 추천이라면 Precision을 우선합니다.

관련 없는 기사가 섞이면 사용자 경험이 나빠지기 때문입니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 설명을 들은 김개발 씨는 테스트 데이터셋으로 측정해봤습니다. Precision은 0.8로 괜찮았지만 Recall이 0.5로 낮았습니다.

중요한 문서를 절반이나 놓치고 있었던 것입니다. Top-K를 5에서 10으로 늘렸더니 Recall이 0.75로 개선되었습니다.

검색 정확도를 제대로 측정하면 시스템의 약점을 정확히 파악하고 개선할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - Precision과 Recall의 균형을 맞추되, 서비스 특성에 맞게 우선순위를 정하세요

  • F1 Score로 전체 성능을 한눈에 파악할 수 있습니다
  • 테스트 데이터셋을 만들어 지속적으로 측정하세요

3. 응답 관련성 평가

검색은 잘 되는데 답변이 영뚱한 경우가 있었습니다. 김개발 씨가 박시니어 씨에게 물었습니다.

"문서는 제대로 찾았는데 왜 이상한 답변이 나올까요?" 박시니어 씨가 답했습니다. "검색과 생성은 별개예요.

생성 품질도 따로 평가해야 합니다."

응답 관련성 평가는 LLM이 생성한 답변이 질문과 얼마나 관련 있는지 측정합니다. 또한 답변이 검색된 문서에 충실한지도 확인합니다.

좋은 검색도 중요하지만, 그것을 바탕으로 적절한 답변을 만드는 것도 똑같이 중요합니다.

다음 코드를 살펴봅시다.

from ragas.metrics import answer_relevancy, faithfulness
from ragas import evaluate
from datasets import Dataset

# 평가할 데이터 준비
eval_data = {
    "question": ["연차는 몇 일인가요?"],
    "answer": ["연차는 15일이며, 입사 1년 후부터 사용 가능합니다."],
    "contexts": [["직원 연차는 연 15일입니다. 입사일로부터 1년 후 발생합니다."]],
    "ground_truth": ["15일"]
}

dataset = Dataset.from_dict(eval_data)

# 답변 관련성과 충실도 평가
result = evaluate(
    dataset,
    metrics=[answer_relevancy, faithfulness]
)

print(f"Answer Relevancy: {result['answer_relevancy']}")
print(f"Faithfulness: {result['faithfulness']}")

김개발 씨는 검색 성능을 개선한 후 뿌듯했습니다. Precision도 0.8, Recall도 0.75로 괜찮았습니다.

그런데 실제 답변을 보니 이상했습니다. "연차는 몇 일인가요?"라는 질문에 "연차 신청은 인사팀에 문의하세요"라고 답하는 것입니다.

문서는 제대로 찾았습니다. 연차 관련 규정 문서가 정확히 검색되었습니다.

문제는 LLM이 그 문서를 제대로 활용하지 못했다는 점입니다. 박시니어 씨가 설명했습니다.

"검색과 생성은 다른 문제예요. 둘 다 평가해야 합니다." 그렇다면 생성 품질은 어떻게 평가할까요?

쉽게 비유하자면, 생성 평가는 마치 요리사를 평가하는 것과 같습니다. 좋은 재료를 주는 것(검색)도 중요하지만, 그 재료로 요리를 잘 하는 것(생성)도 중요합니다.

신선한 재료를 줬는데 요리사가 엉뚱한 요리를 만들면 소용없습니다. LLM도 마찬가지입니다.

좋은 문서를 줬는데 영뚱한 답변을 만들면 안 됩니다. 생성 품질을 평가할 때는 두 가지를 봅니다.

첫 번째는 **Answer Relevancy(답변 관련성)**입니다. 답변이 질문과 얼마나 관련 있는가를 측정합니다.

사용자가 "언제"를 물어봤는데 "어디서"를 답하면 안 됩니다. "연차 일수"를 물어봤는데 "연차 신청 방법"을 답하면 안 됩니다.

두 번째는 **Faithfulness(충실도)**입니다. 답변이 검색된 문서에 충실한가를 측정합니다.

LLM이 문서에 없는 내용을 지어내지 않았는지 확인합니다. 이것이 바로 환각(Hallucination) 문제입니다.

생성 평가가 없던 시절에는 어땠을까요? 개발자들은 프롬프트를 이것저것 바꿔보며 "이게 나은 것 같은데?"라고 추측했습니다.

명확한 기준이 없으니 주관적일 수밖에 없었습니다. 더 큰 문제는 환각을 발견하지 못한다는 점이었습니다.

LLM이 그럴듯하게 지어낸 내용을 진짜로 착각하고 배포하는 일이 자주 발생했습니다. 실제로 어떤 회사는 고객 지원 챗봇이 "30일 환불 보장"이라고 답변했는데, 실제 정책은 "7일 환불 가능"이었습니다.

문서에 없는 내용을 LLM이 지어냈던 것입니다. 고객과의 분쟁으로 이어졌습니다.

바로 이런 문제를 해결하기 위해 생성 품질 평가가 등장했습니다. Answer Relevancy는 LLM을 활용해 측정합니다.

생성된 답변으로부터 역으로 질문을 만들어봅니다. 그 질문이 원래 질문과 얼마나 유사한지 비교합니다.

유사도가 높으면 답변이 질문과 관련 있다는 뜻입니다. Faithfulness는 답변의 각 주장을 검증합니다.

답변을 여러 개의 진술로 분해한 후, 각 진술이 검색된 문서에서 지원되는지 확인합니다. 모든 진술이 문서에 근거가 있으면 Faithfulness가 1.0입니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 평가할 데이터를 준비합니다.

질문(question), 생성된 답변(answer), 검색된 문서들(contexts), 그리고 정답(ground_truth)이 필요합니다. Dataset 객체로 변환한 후 evaluate 함수에 전달합니다.

두 가지 지표를 동시에 평가합니다. Answer Relevancy는 답변이 질문에 얼마나 적절한지, Faithfulness는 답변이 문서에 얼마나 충실한지 측정합니다.

결과는 0에서 1 사이의 값으로 반환됩니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 의료 정보 챗봇을 운영한다고 가정해봅시다. 환자가 "이 약의 부작용은 무엇인가요?"라고 물었습니다.

Faithfulness가 중요합니다. 약품 설명서에 없는 부작용을 LLM이 지어내면 안 됩니다.

법적 책임 문제가 발생할 수 있습니다. 많은 기업에서 Faithfulness 임계값을 설정합니다.

0.9 이하면 답변을 사용자에게 보여주기 전에 경고를 띄웁니다. "이 답변은 확실하지 않습니다.

전문가와 상담하세요." 같은 메시지를 추가합니다. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수 중 하나는 Answer Relevancy만 보는 것입니다. 답변이 질문과 관련 있어 보여도, 거짓 정보일 수 있습니다.

Faithfulness도 함께 봐야 합니다. 또 다른 실수는 평가 데이터의 품질을 소홀히 하는 것입니다.

Ground truth가 부정확하면 평가 자체가 의미 없습니다. 실제 사용자 질문과 전문가가 작성한 정답을 모아 평가 데이터셋을 만들어야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언을 따라 생성 품질을 측정해봤습니다.

Answer Relevancy는 0.7, Faithfulness는 0.6이었습니다. 둘 다 낮았습니다.

프롬프트를 수정해 "문서에 명시된 내용만 답하라"고 강조했더니 Faithfulness가 0.85로 개선되었습니다. 응답 관련성과 충실도를 제대로 평가하면 신뢰할 수 있는 RAG 시스템을 만들 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - Answer Relevancy와 Faithfulness를 모두 측정하세요

  • Faithfulness 임계값을 설정해 환각을 방지하세요
  • 평가 데이터셋은 실제 사용자 질문으로 구성하세요

4. RAGAS 프레임워크 소개

김개발 씨가 여러 평가 지표를 직접 구현하려니 복잡했습니다. 코드도 길어지고 버그도 생겼습니다.

박시니어 씨가 말했습니다. "RAGAS라는 프레임워크가 있어요.

이미 검증된 방법들이 구현되어 있습니다."

RAGAS는 RAG 시스템 평가를 위한 오픈소스 프레임워크입니다. 검색 품질과 생성 품질을 측정하는 다양한 지표를 제공하며, 몇 줄의 코드로 쉽게 사용할 수 있습니다.

LLM을 활용한 자동 평가로 사람의 판단과 유사한 결과를 얻을 수 있습니다.

다음 코드를 살펴봅시다.

from ragas import evaluate
from ragas.metrics import (
    context_precision,
    context_recall,
    faithfulness,
    answer_relevancy
)
from datasets import Dataset

# 평가 데이터 준비
eval_dataset = Dataset.from_dict({
    "question": ["파이썬에서 리스트와 튜플의 차이는?"],
    "answer": ["리스트는 변경 가능하고 튜플은 불변입니다."],
    "contexts": [["리스트는 mutable하며 튜플은 immutable합니다."]],
    "ground_truth": ["리스트는 변경 가능, 튜플은 불변"]
})

# 한 번에 모든 지표 평가
result = evaluate(eval_dataset, metrics=[
    context_precision, context_recall,
    faithfulness, answer_relevancy
])

print(result)

김개발 씨는 평가 지표의 중요성을 깨달았습니다. Context Precision, Context Recall, Faithfulness, Answer Relevancy를 모두 측정해야 한다는 것도 알았습니다.

그런데 문제가 있었습니다. 이걸 어떻게 구현하죠?

직접 구현하려니 막막했습니다. Answer Relevancy를 계산하려면 임베딩도 필요하고, Faithfulness를 측정하려면 LLM API도 호출해야 합니다.

코드가 수백 줄로 늘어났습니다. 버그도 계속 생겼습니다.

더 좋은 방법은 없을까요? 박시니어 씨가 추천했습니다.

"RAGAS라는 프레임워크를 써보세요. 이미 다 구현되어 있어요." 그렇다면 RAGAS는 무엇일까요?

쉽게 비유하자면, RAGAS는 마치 건강검진 패키지와 같습니다. 병원에 가면 혈압, 혈당, 콜레스테롤 등을 일일이 검사하는데, 종합검진 패키지를 신청하면 한 번에 다 해줍니다.

RAGAS도 마찬가지입니다. RAG 시스템의 여러 지표를 한 번에 측정해줍니다.

**RAGAS(RAG Assessment)**는 2023년에 등장한 오픈소스 프레임워크입니다. 전 세계 연구자들이 협력해 만든 검증된 평가 방법을 제공합니다.

직접 구현하면 수백 줄의 코드가 필요하지만, RAGAS를 쓰면 10줄 이내로 해결됩니다. 게다가 지속적으로 업데이트되어 최신 연구 결과가 반영됩니다.

RAGAS가 없던 시절에는 어땠을까요? 각 회사가 자체적으로 평가 방법을 만들었습니다.

문제는 회사마다 기준이 달랐다는 점입니다. A회사에서 0.8점인 시스템이 B회사에서는 0.6점으로 나올 수 있었습니다.

논문에서 "우리 시스템은 성능이 0.9입니다"라고 해도 믿을 수 없었습니다. 평가 방법이 다르기 때문입니다.

또 다른 문제는 사람이 직접 평가해야 한다는 점이었습니다. 전문가를 고용해 답변의 품질을 일일이 판단하게 했습니다.

비용도 많이 들고, 시간도 오래 걸렸습니다. 무엇보다 평가자마다 기준이 달라 일관성이 떨어졌습니다.

바로 이런 문제를 해결하기 위해 RAGAS가 등장했습니다. RAGAS의 핵심은 LLM을 활용한 자동 평가입니다.

사람 대신 GPT-4 같은 강력한 LLM이 평가합니다. 연구 결과에 따르면 RAGAS의 평가 점수는 사람의 판단과 85% 이상 일치합니다.

자동화되어 있어 빠르고, 일관성도 높습니다. RAGAS가 제공하는 주요 지표는 네 가지입니다.

Context Precision은 검색된 문서의 정확성을 측정합니다. 불필요한 문서가 섞여 있는지 확인합니다.

Context Recall은 필요한 문서를 빠짐없이 찾았는지 측정합니다. Faithfulness는 답변이 문서에 충실한지, 환각은 없는지 확인합니다.

Answer Relevancy는 답변이 질문과 관련 있는지 측정합니다. 위의 코드를 한 줄씩 살펴보겠습니다.

먼저 필요한 모듈과 지표를 임포트합니다. 평가 데이터는 Dataset 형태로 준비합니다.

question, answer, contexts, ground_truth 네 가지 필드가 필요합니다. evaluate 함수에 데이터셋과 측정할 지표 리스트를 전달하면 끝입니다.

실행하면 각 지표별 점수가 딕셔너리 형태로 반환됩니다. 별도의 설정 없이도 자동으로 LLM API를 호출하고 계산합니다.

기본적으로 OpenAI API를 사용하지만, 다른 LLM으로 변경할 수도 있습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 매주 새로운 기능을 배포하는 스타트업이라고 가정해봅시다. RAG 시스템을 개선할 때마다 성능이 좋아졌는지 확인해야 합니다.

RAGAS를 CI/CD 파이프라인에 통합합니다. 새 버전을 배포하기 전에 자동으로 평가를 돌립니다.

점수가 이전보다 떨어지면 배포를 막습니다. 많은 기업에서 RAGAS를 사용해 A/B 테스트도 진행합니다.

새로운 임베딩 모델, 새로운 청킹 전략, 새로운 프롬프트 등을 테스트할 때 RAGAS로 정량적으로 비교합니다. 어떤 방법이 실제로 더 나은지 숫자로 증명할 수 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 RAGAS를 맹신하는 것입니다.

RAGAS도 완벽하지 않습니다. LLM을 사용하기 때문에 가끔 잘못된 평가를 할 수 있습니다.

특히 도메인 특수적인 질문에서는 정확도가 떨어질 수 있습니다. 따라서 주기적으로 사람이 샘플링해서 확인해야 합니다.

또 다른 실수는 평가 데이터셋을 소홀히 하는 것입니다. RAGAS는 훌륭한 도구지만, 데이터가 엉망이면 결과도 의미 없습니다.

실제 사용자 질문을 모으고, 전문가가 정답을 작성한 고품질 데이터셋이 필요합니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 추천대로 RAGAS를 도입했습니다. 직접 구현하느라 쓴 200줄의 코드를 10줄로 줄일 수 있었습니다.

평가도 훨씬 정확해졌습니다. 이제 매주 배포 전에 RAGAS로 자동 평가를 돌립니다.

RAGAS를 제대로 활용하면 RAG 시스템의 품질을 지속적으로 관리할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - RAGAS를 CI/CD 파이프라인에 통합해 자동 평가하세요

  • 평가 데이터셋은 실제 사용자 질문으로 구성하세요
  • 정기적으로 사람이 샘플링해서 RAGAS 평가를 검증하세요

5. 평가 데이터셋 구축

RAGAS를 도입한 김개발 씨가 평가를 돌려보니 점수가 이상했습니다. 너무 높게 나오거나 너무 낮게 나왔습니다.

박시니어 씨가 물었습니다. "평가 데이터셋은 어떻게 만들었어요?" 김개발 씨는 당황했습니다.

"그냥 제가 생각나는 질문 몇 개 적었는데요..."

평가 데이터셋은 RAG 시스템의 성능을 측정하는 기준이 됩니다. 실제 사용자 질문, 정답, 관련 문서로 구성되어야 하며, 다양한 난이도와 유형을 포함해야 정확한 평가가 가능합니다.

좋은 평가 데이터셋 없이는 좋은 평가도 불가능합니다.

다음 코드를 살펴봅시다.

from datasets import Dataset
import json

# 좋은 평가 데이터셋의 구조
def create_eval_dataset():
    eval_data = []

    # 1. 실제 사용자 질문 수집
    user_questions = [
        {"question": "연차는 몇 일인가요?", "difficulty": "easy"},
        {"question": "재택근무 시 VPN 접속 방법은?", "difficulty": "medium"},
        {"question": "해외 출장 시 경비 처리 기준은?", "difficulty": "hard"}
    ]

    for item in user_questions:
        eval_data.append({
            "question": item["question"],
            "ground_truth": "전문가가 작성한 정답",  # 실제로는 도메인 전문가가 작성
            "contexts": ["관련 문서 1", "관련 문서 2"],  # 실제 검색 결과
            "answer": "RAG 시스템이 생성한 답변",
            "metadata": {"difficulty": item["difficulty"]}
        })

    return Dataset.from_list(eval_data)

# 데이터셋 저장
dataset = create_eval_dataset()
dataset.save_to_disk("eval_dataset")

김개발 씨는 RAGAS를 돌려봤는데 뭔가 이상했습니다. 분명히 잘 작동하는 것 같은 시스템인데 점수가 0.4로 낮게 나왔습니다.

반대로 문제가 많다고 생각한 부분은 0.9로 높게 나왔습니다. 도대체 왜 이런 일이 생긴 걸까요?

박시니어 씨가 평가 데이터를 살펴봤습니다. "아, 문제가 여기 있네요.

평가 데이터셋이 너무 단순해요." 김개발 씨는 그제야 깨달았습니다. 자기가 임의로 만든 5개 질문으로 평가했던 것입니다.

그렇다면 좋은 평가 데이터셋은 어떻게 만들까요? 쉽게 비유하자면, 평가 데이터셋은 마치 학교의 기말고사와 같습니다.

시험이 너무 쉬우면 실력을 제대로 평가할 수 없습니다. 반대로 너무 어려워도 문제입니다.

다양한 난이도의 문제가 골고루 섞여 있어야 학생의 진짜 실력을 알 수 있습니다. RAG 평가도 마찬가지입니다.

평가 데이터셋은 네 가지 요소로 구성됩니다. **Question(질문)**은 실제 사용자가 물어볼 법한 질문이어야 합니다.

개발자가 상상으로 만든 질문이 아니라, 실제 로그에서 수집한 질문이 좋습니다. **Ground Truth(정답)**는 도메인 전문가가 작성한 표준 답변입니다.

이것이 평가의 기준이 됩니다. **Contexts(문맥)**는 정답을 도출하는 데 필요한 문서들입니다.

RAG 시스템이 이 문서들을 찾아야 합니다. **Answer(답변)**는 실제로 RAG 시스템이 생성한 답변입니다.

이것을 Ground Truth와 비교해 점수를 매깁니다. 평가 데이터셋 구축이 제대로 안 되던 시절에는 어땠을까요?

개발자들은 테스트 질문을 대충 몇 개 만들었습니다. "안녕", "회사 주소는?", "CEO는 누구?" 같은 단순한 질문들이었습니다.

이런 질문으로 평가하면 모든 시스템이 높은 점수를 받습니다. 진짜 어려운 질문에서 실패하는 문제는 발견할 수 없었습니다.

더 큰 문제는 정답의 품질이었습니다. 정답을 개발자가 임의로 작성했습니다.

도메인 지식이 부족해 틀린 정답을 쓰는 경우도 많았습니다. 틀린 정답으로 평가하면 오히려 좋은 시스템이 낮은 점수를 받습니다.

바로 이런 문제를 해결하기 위해 체계적인 데이터셋 구축 방법이 등장했습니다. 첫 번째 단계는 실제 사용자 질문 수집입니다.

서비스를 운영 중이라면 로그를 분석합니다. 사용자들이 자주 묻는 질문, 답변이 부정확했던 질문 등을 모읍니다.

서비스 전이라면 도메인 전문가와 함께 예상 질문을 만듭니다. 두 번째 단계는 난이도와 유형 분류입니다.

단순 사실 질문, 복잡한 추론 질문, 비교 질문 등 다양한 유형을 포함합니다. 쉬운 질문 30%, 중간 질문 50%, 어려운 질문 20% 정도로 구성하면 좋습니다.

세 번째 단계는 전문가 정답 작성입니다. 이것이 가장 중요합니다.

도메인 전문가가 직접 정답을 작성해야 합니다. 단순히 맞다/틀리다가 아니라, "이런 내용이 포함되어야 한다"는 기준을 명확히 합니다.

네 번째 단계는 관련 문서 매핑입니다. 각 질문에 대해 정답을 도출하는 데 필요한 문서를 미리 표시합니다.

이것으로 Context Recall을 측정할 수 있습니다. 위의 코드를 한 줄씩 살펴보겠습니다.

실제 사용자 질문을 난이도와 함께 정리합니다. 각 질문마다 전문가가 작성한 정답(ground_truth)과 관련 문서(contexts)를 매핑합니다.

메타데이터에 난이도를 저장해 나중에 난이도별 분석을 할 수 있습니다. Dataset 객체로 변환한 후 디스크에 저장하면 재사용할 수 있습니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 금융 상담 챗봇을 만든다고 가정해봅시다.

평가 데이터셋을 만들 때 실제 고객센터에 들어온 질문 1000개를 샘플링합니다. 금융 전문가가 각 질문에 대한 표준 답변을 작성합니다.

관련 규정 문서를 매핑합니다. 그리고 질문을 유형별로 분류합니다.

예금 관련 30%, 대출 관련 30%, 카드 관련 20%, 기타 20% 식으로 실제 분포를 반영합니다. 이렇게 하면 평가 결과가 실제 서비스 성능을 잘 반영합니다.

많은 기업에서 평가 데이터셋을 분기마다 업데이트합니다. 새로운 상품이 나오면 관련 질문을 추가합니다.

사용자 피드백을 반영해 어려운 질문을 보강합니다. 평가 데이터셋도 살아있는 문서입니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 평가 데이터셋이 너무 적다는 것입니다.

5개나 10개의 질문으로는 신뢰할 수 있는 평가가 불가능합니다. 최소 50개, 가능하면 100개 이상을 준비해야 합니다.

또 다른 실수는 쉬운 질문만 포함하는 것입니다. 시스템이 잘 작동한다는 착각을 하게 됩니다.

의도적으로 어려운 질문, 모호한 질문, 복잡한 질문을 포함해야 진짜 약점을 발견할 수 있습니다. 마지막으로 정답의 품질을 소홀히 하는 실수가 있습니다.

정답이 틀리면 평가가 무의미해집니다. 반드시 도메인 전문가의 검토를 받아야 합니다.

가능하면 두 명 이상의 전문가가 교차 검증하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

박시니어 씨의 조언대로 평가 데이터셋을 다시 만들었습니다. 실제 사용자 로그에서 100개 질문을 샘플링하고, HR 팀의 도움을 받아 정답을 작성했습니다.

다시 평가를 돌리니 점수가 현실적으로 나왔고, 개선할 부분도 명확해졌습니다. 좋은 평가 데이터셋을 구축하면 RAG 시스템의 진짜 성능을 정확히 측정할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 최소 50개 이상의 질문으로 평가 데이터셋을 구성하세요

  • 난이도와 유형을 다양하게 포함하세요
  • 반드시 도메인 전문가가 정답을 작성하도록 하세요

6. 지속적 개선 프로세스

김개발 씨가 RAG 시스템을 개선해 점수를 0.7까지 올렸습니다. 뿌듯했습니다.

그런데 한 달 후 다시 측정해보니 점수가 0.6으로 떨어졌습니다. 박시니어 씨가 말했습니다.

"한 번 개선하고 끝이 아니에요. 지속적으로 관리해야 합니다."

지속적 개선 프로세스는 RAG 시스템의 품질을 장기적으로 유지하고 향상시키는 방법입니다. 정기적인 평가, 문제 분석, 개선, 재배포의 사이클을 반복합니다.

데이터가 변하고 사용자의 질문이 진화하기 때문에 계속해서 시스템을 업데이트해야 합니다.

다음 코드를 살펴봅시다.

import schedule
import time
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy

def monitor_rag_performance():
    """주기적으로 RAG 성능 모니터링"""
    # 최근 사용자 질문으로 평가 데이터셋 구성
    recent_questions = get_recent_user_questions()  # 실제로는 DB에서 조회

    # 평가 실행
    result = evaluate(recent_questions, metrics=[faithfulness, answer_relevancy])

    # 임계값 확인
    if result['faithfulness'] < 0.8 or result['answer_relevancy'] < 0.75:
        alert_team(f"성능 저하 감지: {result}")
        trigger_improvement_workflow()

    # 결과 로깅
    log_metrics(result)
    return result

# 매일 오전 9시에 자동 평가
schedule.every().day.at("09:00").do(monitor_rag_performance)

# 지속적 모니터링 루프
while True:
    schedule.run_pending()
    time.sleep(60)

김개발 씨는 RAG 시스템을 열심히 개선했습니다. Faithfulness 0.85, Answer Relevancy 0.8, 모든 지표가 목표치를 달성했습니다.

배포하고 한 달 동안 사용자 피드백도 좋았습니다. 이제 다른 프로젝트를 시작해도 될까요?

그런데 한 달 후, 사용자들의 불만이 다시 들어오기 시작했습니다. "예전엔 잘 됐는데 요즘 이상해요." 김개발 씨는 당황해서 평가를 다시 돌려봤습니다.

Faithfulness가 0.65로 떨어졌습니다. 무슨 일이 일어난 걸까요?

박시니어 씨가 설명했습니다. "RAG 시스템은 한 번 만들고 끝이 아니에요.

계속 관리해야 합니다." 그렇다면 지속적 개선은 어떻게 할까요? 쉽게 비유하자면, RAG 시스템 관리는 마치 정원 가꾸기와 같습니다.

정원을 한 번 예쁘게 만든다고 끝이 아닙니다. 잡초가 자라고, 계절이 바뀌고, 날씨가 변합니다.

지속적으로 물을 주고, 가지를 치고, 관리해야 아름다운 정원을 유지할 수 있습니다. RAG 시스템도 마찬가지입니다.

RAG 시스템의 성능이 떨어지는 이유는 여러 가지입니다. 첫째, 데이터가 변합니다.

회사 정책이 업데이트되고, 새로운 제품이 출시되고, 오래된 문서가 누적됩니다. 문서 데이터베이스가 변하면 검색 품질도 변합니다.

둘째, 사용자 질문이 진화합니다. 처음에는 단순한 질문이 많았는데, 시간이 지나면 복잡하고 구체적인 질문이 늘어납니다.

사용자가 시스템에 익숙해지면서 더 어려운 것을 물어봅니다. 셋째, LLM이 업데이트됩니다.

GPT-4에서 GPT-4 Turbo로 바뀌면 답변 스타일이 달라집니다. 같은 프롬프트도 다르게 해석할 수 있습니다.

지속적 관리가 없던 시절에는 어땠을까요? 개발자들은 시스템을 배포하고 잊어버렸습니다.

사용자 불만이 쌓여 임계점에 도달할 때까지 모릅니다. 그때야 부랴부랴 문제를 파악하고 수정합니다.

이미 사용자 신뢰를 잃은 후였습니다. 어떤 회사는 분기마다 "RAG 대수술"을 했습니다.

3개월 동안 누적된 문제를 한꺼번에 고치려니 시간이 오래 걸렸습니다. 무엇보다 문제의 원인을 파악하기 어려웠습니다.

3개월 전에 뭐가 바뀌었는지 기억이 안 났습니다. 바로 이런 문제를 해결하기 위해 지속적 개선 프로세스가 등장했습니다.

지속적 개선 프로세스는 4단계로 구성됩니다. 첫 번째 단계는 모니터링입니다.

매일 또는 매주 정기적으로 평가를 자동 실행합니다. 핵심 지표를 추적하고, 임계값 이하로 떨어지면 알림을 받습니다.

문제를 조기에 발견할 수 있습니다. 두 번째 단계는 분석입니다.

점수가 떨어진 원인을 파악합니다. 어떤 유형의 질문에서 실패하는가?

검색이 문제인가, 생성이 문제인가? 데이터 분석을 통해 근본 원인을 찾습니다.

세 번째 단계는 개선입니다. 원인에 맞는 해결책을 적용합니다.

새로운 문서를 추가하거나, 프롬프트를 조정하거나, 검색 알고리즘을 개선합니다. 작은 변경을 하나씩 테스트합니다.

네 번째 단계는 검증입니다. 개선 후 다시 평가를 돌려 실제로 좋아졌는지 확인합니다.

A/B 테스트를 통해 부작용은 없는지도 확인합니다. 검증이 끝나면 배포하고, 다시 모니터링 단계로 돌아갑니다.

위의 코드를 한 줄씩 살펴보겠습니다. monitor_rag_performance 함수는 주기적으로 실행됩니다.

최근 사용자 질문을 가져와 평가 데이터셋을 구성합니다. RAGAS로 평가를 실행하고, 임계값과 비교합니다.

기준 이하로 떨어지면 팀에 알림을 보내고 개선 워크플로를 시작합니다. schedule 라이브러리를 사용해 매일 오전 9시에 자동 실행되도록 설정합니다.

무한 루프를 돌며 스케줄을 체크합니다. 이렇게 하면 사람이 직접 실행하지 않아도 자동으로 모니터링됩니다.

실제 현업에서는 어떻게 활용할까요? 예를 들어 이커머스 챗봇을 운영한다고 가정해봅시다.

매일 수천 건의 질문이 들어옵니다. 매일 밤 자정에 자동 평가를 돌립니다.

당일 질문 중 랜덤으로 100개를 샘플링해 평가합니다. 평가 결과를 대시보드에 표시합니다.

Faithfulness가 0.85에서 0.78로 떨어졌다면 빨간불이 켜집니다. Slack으로 알림이 옵니다.

담당자가 로그를 분석해 원인을 파악합니다. 신제품 관련 질문에서 환각이 많이 발생한다는 것을 발견합니다.

신제품 문서를 벡터 DB에 추가하고 다시 평가합니다. 많은 기업에서 이런 프로세스를 자동화합니다.

성능이 떨어지면 자동으로 재학습을 트리거하거나, 프롬프트 변형을 자동으로 테스트합니다. 사람은 최종 승인만 하면 됩니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 너무 자주 바꾸는 것입니다.

점수가 0.01 떨어졌다고 바로 수정하면 시스템이 불안정해집니다. 통계적으로 유의미한 변화인지 확인해야 합니다.

며칠간 추이를 보고 판단합니다. 또 다른 실수는 한 번에 여러 가지를 바꾸는 것입니다.

프롬프트도 바꾸고, 임베딩 모델도 바꾸고, 청크 크기도 바꾸면 무엇이 효과가 있었는지 알 수 없습니다. 한 번에 하나씩 변경하고 측정해야 합니다.

마지막으로 사용자 피드백을 무시하는 실수가 있습니다. 점수는 높은데 사용자는 불만족할 수 있습니다.

평가 지표는 도구일 뿐, 최종 목표는 사용자 만족입니다. 정량적 지표와 정성적 피드백을 모두 봐야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 박시니어 씨의 조언대로 지속적 개선 프로세스를 구축했습니다.

매주 자동 평가를 돌리고, 점수 변화를 추적하고, 문제가 발견되면 즉시 대응합니다. 3개월 후 Faithfulness는 0.9를 유지하고 있고, 사용자 만족도도 높아졌습니다.

지속적 개선 프로세스를 구축하면 RAG 시스템의 품질을 장기적으로 유지할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 정기적인 자동 평가를 설정하고 알림을 받으세요

  • 한 번에 하나씩 변경하고 효과를 측정하세요
  • 정량적 지표와 정성적 사용자 피드백을 모두 고려하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#Python#RAG#RAGAS#Evaluation#LLM#AWS

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.