ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RAGAS로 RAG 시스템 평가하기 — 지표별 의미와 Python 실전 사용법
    IT 2026. 3. 27. 21:00
    RAGAS로 RAG 시스템 평가하기 — 지표별 의미와 Python 실전 사용법

    RAG를 만들었다 — 그런데 이게 잘 되는 건가?

    RAG(Retrieval Augmented Generation) 파이프라인을 구축하면 자연스럽게 드는 질문이 있습니다. "이 시스템이 진짜 잘 동작하고 있는 건가?"

    임베딩 모델을 바꿔봤는데 더 나아진 건지, 청킹 전략을 변경했는데 효과가 있는 건지, 체감으로는 알기 어렵습니다. 그렇다고 매번 사람이 질문 100개를 던져보고 답변을 일일이 채점할 수도 없고요.

    바로 이 문제를 해결하기 위해 등장한 것이 RAGAS(Retrieval Augmented Generation Assessment)입니다.

    RAGAS가 나오기 전 — RAG 평가의 한계

    RAGAS 이전에 RAG 시스템을 평가하려면 크게 세 가지 방법뿐이었습니다.

    1. 사람이 직접 채점: 정확하지만 느리고 비쌉니다. 100개 질문-답변 쌍을 평가하는 데 하루가 걸릴 수 있어요. 실험할 때마다 이러면 개발 속도가 나올 수 없습니다.

    2. BLEU, ROUGE 같은 전통 NLG 메트릭: 정답 텍스트와 생성 텍스트의 단어 겹침을 측정합니다. 하지만 "아인슈타인은 1879년에 태어났다"와 "1879년생인 아인슈타인"이 같은 뜻이라는 걸 이 메트릭은 제대로 잡지 못해요. 의미를 보는 게 아니라 표면 형태를 보기 때문이죠.

    3. End-to-end 정확도만 측정: 최종 답변이 맞는지 틀린지만 볼 수 있었습니다. 문제는 어디서 잘못된 건지 알 수 없다는 점이에요. 검색기(retriever)가 엉뚱한 문서를 가져온 건지, 생성기(generator)가 맞는 문서를 받고도 헛소리를 한 건지 구분이 안 됩니다.

    diagram

    RAGAS의 핵심 아이디어

    RAGAS는 2023년 9월 Shahul Es 등이 발표한 논문("RAGAS: Automated Evaluation of Retrieval Augmented Generation", EACL 2024)에서 소개되었습니다. 핵심 아이디어 두 가지:

    첫째, Reference-free 평가. 사람이 작성한 정답(ground truth) 없이도 RAG를 평가할 수 있습니다. LLM 자체를 심사위원(judge)으로 활용하는 LLM-as-a-Judge 방식이에요.

    둘째, Retriever와 Generator를 분리 평가. "어디가 문제인가?"를 정확히 짚어줍니다. 검색이 문제면 검색을 고치고, 생성이 문제면 프롬프트를 고치면 됩니다.

    모든 지표는 0~1 범위이고, 높을수록 좋습니다.

    핵심 지표 ① — Faithfulness (충실도)

    한 줄 요약: 생성된 답변이 검색된 context에 근거하는가? = Hallucination 감지기

    평가 대상: Generator

    계산 방법:

    1. LLM이 답변을 개별 claim(주장)으로 분해합니다
    2. 각 claim이 검색된 context에서 추론 가능한지 판정합니다
    3. Faithfulness = 지지되는 claim 수 / 전체 claim 수

    예시로 이해하기:

    질문: "파이썬은 누가 만들었나?"
    검색된 context: "파이썬은 귀도 반 로썸이 1991년에 발표한 프로그래밍 언어이다."
    생성된 답변: "파이썬은 귀도 반 로썸이 만들었고, 세계에서 가장 인기 있는 언어입니다."

    답변에서 추출된 claim:

    • ✅ "파이썬은 귀도 반 로썸이 만들었다" → context에 근거 있음
    • ❌ "세계에서 가장 인기 있는 언어이다" → context에 근거 없음 (사실일 수 있지만, context에 없으니 hallucination)

    Faithfulness = 1/2 = 0.5

    ⚠️ 핵심 포인트: Faithfulness가 낮다 = LLM이 context에 없는 정보를 지어내고 있다. 이건 "거짓"이 아니라 "근거 없음"입니다. 사실이더라도 context에 없으면 0점이에요. RAG의 목적 자체가 "근거 기반 답변"이니까요.

    핵심 지표 ② — Answer Relevancy (응답 관련성)

    한 줄 요약: 답변이 원래 질문에 적절하게 대응하는가? = 딴소리 감지기

    평가 대상: Generator

    계산 방법: 독특한 역발상 접근법을 씁니다.

    1. 답변을 기반으로 LLM에게 "이 답변에 해당하는 질문을 만들어봐"라고 역으로 질문 N개를 생성시킵니다
    2. 원래 질문과 생성된 질문들의 임베딩 cosine similarity를 계산합니다
    3. Answer Relevancy = 평균 cosine similarity

    예시로 이해하기:

    질문: "파이썬의 GIL이 뭔가요?"
    답변 A: "GIL은 Global Interpreter Lock으로, 한 번에 하나의 스레드만 파이썬 바이트코드를 실행하도록 하는 뮤텍스입니다."

    → 역생성된 질문: "파이썬에서 GIL이란 무엇인가요?", "Global Interpreter Lock의 역할은?"
    → 원래 질문과 유사도 높음 → Answer Relevancy ≈ 0.95

    답변 B: "파이썬은 귀도 반 로썸이 만든 인터프리터 언어이며, 들여쓰기로 블록을 구분합니다. GIL이라는 것도 있긴 합니다."

    → 역생성된 질문: "파이썬은 어떤 언어인가요?", "파이썬의 특징은?"
    → 원래 질문과 유사도 낮음 → Answer Relevancy ≈ 0.4

    💡 왜 이렇게 측정하나: 직접 "질문과 답변이 관련 있나요?"라고 물으면 LLM이 거의 항상 "예"라고 합니다. 역으로 질문을 생성시키면 답변이 실제로 다루는 주제가 뭔지 객관적으로 드러나요.

    핵심 지표 ③ — Context Precision (컨텍스트 정밀도)

    한 줄 요약: 검색 결과에서 관련 문서가 상위에 잘 랭킹되었는가? = 검색 품질 측정기

    평가 대상: Retriever

    계산 방법:

    1. 검색된 각 문서(chunk)가 질문 답변에 관련 있는지 LLM이 판정합니다
    2. 관련 문서가 상위에 올수록 높은 점수를 받습니다 (Precision@K의 가중 평균)

    예시로 이해하기:

    질문: "쿠버네티스에서 Pod가 뭔가?"
    검색된 문서 5개 (순서대로):

    순위 문서 내용 관련성
    1 Pod는 쿠버네티스의 최소 배포 단위이다
    2 Pod는 하나 이상의 컨테이너를 포함한다
    3 Docker Hub 사용법
    4 Pod의 생명주기와 상태 관리
    5 AWS EC2 인스턴스 타입 비교

    관련 문서 3개 중 2개가 1, 2위 → Context Precision ≈ 0.83 (꽤 높음)

    만약 관련 없는 "Docker Hub 사용법"이 1위였다면? → 점수가 크게 하락합니다. 상위 랭킹의 정확도가 점수에 더 큰 영향을 미치기 때문이에요.

    핵심 지표 ④ — Context Recall (컨텍스트 재현율)

    한 줄 요약: 답변에 필요한 정보를 검색이 빠뜨리지 않았는가? = 검색 누락 감지기

    평가 대상: Retriever

    ⚠️ 유일하게 Ground Truth(정답)가 필요한 지표입니다. 참조 답변이 있어야 "빠뜨린 정보"를 판단할 수 있기 때문이에요.

    계산 방법:

    1. 참조 답변(reference)을 개별 claim으로 분해합니다
    2. 각 claim이 검색된 context에서 지지되는지 확인합니다
    3. Context Recall = 지지되는 claim 수 / 전체 reference claim 수

    예시로 이해하기:

    질문: "Python의 GIL을 우회하는 방법은?"
    참조 답변(ground truth): "multiprocessing 모듈 사용, C 확장 모듈에서 GIL 해제, asyncio를 활용한 비동기 I/O"

    참조 답변의 claim 3개:

    • ✅ "multiprocessing 모듈 사용" → 검색된 context에 있음
    • ✅ "C 확장 모듈에서 GIL 해제" → 검색된 context에 있음
    • ❌ "asyncio를 활용한 비동기 I/O" → 검색된 context에 없음

    Context Recall = 2/3 ≈ 0.67 — 검색기가 asyncio 관련 문서를 놓치고 있다는 뜻이에요.

    4개 지표를 한눈에 정리

    diagram

    지표 평가 대상 측정 내용 Ground Truth 낮을 때 조치
    Faithfulness Generator Hallucination 정도 불필요 프롬프트 강화, 모델 변경
    Answer Relevancy Generator 답변-질문 대응도 불필요 "질문에 집중" 프롬프트
    Context Precision Retriever 검색 랭킹 정확도 불필요 리랭커 도입, top-k 조정
    Context Recall Retriever 검색 누락률 필요 임베딩 모델/청킹 변경

    추가 지표들 — 필요할 때 골라 쓰기

    위 4개가 핵심이지만, RAGAS는 상황에 따라 쓸 수 있는 추가 지표도 제공합니다.

    Noise Sensitivity (노이즈 민감도)

    검색 결과에 무관한 문서가 섞였을 때 Generator가 얼마나 흔들리는지 측정합니다. 답변에서 잘못된 claim의 비율로 계산하며, 이 지표만 낮을수록 좋습니다 (0에 가까울수록 노이즈에 강건).

    Context Entities Recall

    참조 답변에 등장하는 엔티티(사람 이름, 기관명, 기술 용어 등)가 검색된 context에 얼마나 포함되는지 NER 기반으로 측정합니다. Context Recall의 세밀한 보완 지표예요.

    Factual Correctness (사실 정확도)

    참조 답변 대비 생성된 답변이 사실적으로 맞는지 NLI(Natural Language Inference)로 판정합니다. Faithfulness가 "context 대비 근거"를 보는 것이라면, 이건 "정답 대비 정확도"를 봅니다.

    Semantic Similarity

    생성된 답변과 참조 답변 간의 의미적 유사도를 임베딩 cosine similarity로 단순하게 측정합니다.

    Python으로 바로 써보기 — ragas 라이브러리

    RAGAS를 직접 구현할 필요 없이 ragas 파이썬 라이브러리를 설치하면 바로 사용할 수 있습니다.

    pip install ragas

    현재 버전 0.4.x 기준, Python 3.9 이상이 필요합니다.

    기본 사용 예제

    from ragas import evaluate
    from ragas.dataset_schema import SingleTurnSample, EvaluationDataset
    from ragas.metrics import Faithfulness, ResponseRelevancy
    from ragas.metrics import LLMContextPrecisionWithoutReference
    from ragas.metrics import LLMContextRecall
    from ragas.llms import llm_factory
    
    # 1. 평가용 LLM 설정 (OpenAI 예시)
    evaluator_llm = llm_factory("gpt-4o")
    
    # 2. 평가 데이터 구성
    sample = SingleTurnSample(
        user_input="쿠버네티스에서 Pod란 무엇인가?",
        response="Pod는 쿠버네티스의 최소 배포 단위로, "
                 "하나 이상의 컨테이너를 포함합니다.",
        retrieved_contexts=[
            "Pod는 쿠버네티스에서 생성하고 관리할 수 있는 "
            "가장 작은 배포 단위이다.",
            "하나의 Pod에는 하나 이상의 컨테이너가 포함된다.",
        ],
        # Context Recall 사용 시에만 필요
        reference="Pod는 쿠버네티스의 최소 배포 단위이며, "
                  "하나 이상의 컨테이너를 포함한다.",
    )
    
    dataset = EvaluationDataset(samples=[sample])
    
    # 3. 평가 실행
    results = evaluate(
        dataset=dataset,
        metrics=[
            Faithfulness(),
            ResponseRelevancy(),
            LLMContextPrecisionWithoutReference(),
            LLMContextRecall(),
        ],
        llm=evaluator_llm,
    )
    
    print(results)
    # {'faithfulness': 1.0, 'answer_relevancy': 0.92,
    #  'context_precision': 0.88, 'context_recall': 1.0}

    지원되는 LLM 목록

    ragasllm_factory를 통해 다양한 provider를 지원합니다.

    Provider 모델 예시 비고
    OpenAI gpt-4o, gpt-4o-mini 기본 지원
    Anthropic claude-sonnet-4-20250514 기본 지원
    Google gemini-2.0-flash 기본 지원
    Ollama (로컬) llama3, mistral 등 OpenAI 호환 API 경유
    💡 팁: 평가용 LLM은 가능하면 평가 대상 RAG에서 사용하는 LLM보다 성능이 같거나 높은 모델을 쓰는 것이 좋습니다. 심사위원이 수험생보다 실력이 낮으면 채점이 부정확해질 수 있으니까요.

    LangChain / LlamaIndex와 통합

    ragas는 LangChain, LlamaIndex와도 공식 통합을 지원합니다. 기존 RAG 파이프라인에서 나온 결과물을 그대로 평가 데이터셋으로 변환할 수 있어요.

    # LangChain 통합 예시
    from ragas.integrations.langchain import EvaluatorChain
    from ragas.metrics import Faithfulness
    
    # LangChain의 chain 결과를 바로 평가
    evaluator = EvaluatorChain(metric=Faithfulness())
    result = evaluator.invoke({"query": query, "result": answer, "source_documents": docs})

    실전 활용 시나리오

    RAGAS 지표를 보고 구체적으로 어떤 조치를 취할 수 있는지 시나리오별로 정리합니다.

    시나리오 1: Faithfulness만 낮다 (0.3)

    → Generator가 hallucination을 일으키고 있습니다. 조치: 시스템 프롬프트에 "제공된 context에 없는 정보는 '모르겠다'고 답하라"를 추가하거나, temperature를 낮추세요.

    시나리오 2: Context Recall만 낮다 (0.4)

    → Retriever가 필요한 문서를 못 찾고 있습니다. 조치: 청킹 전략 변경, 임베딩 모델 업그레이드, top-k 값 증가를 시도하세요.

    시나리오 3: Context Precision만 낮다 (0.3)

    → 관련 문서를 찾긴 하는데 순위가 뒤죽박죽입니다. 조치: Cohere Reranker나 Cross-encoder 같은 리랭커(re-ranker)를 검색 결과에 적용하세요.

    시나리오 4: 전부 낮다

    → 데이터 자체의 품질을 먼저 점검하세요. 전처리, 청킹, 임베딩, 프롬프트 전체를 재검토해야 할 수 있습니다.

    RAGAS의 한계와 대안

    RAGAS가 만능은 아닙니다. 알아두면 좋은 한계점:

    • LLM 의존: 평가 자체에 LLM을 쓰므로 API 비용이 발생합니다. 샘플 100개를 4개 지표로 평가하면 수백 번의 LLM 호출이 필요해요.
    • 평가의 평가: LLM-as-a-Judge가 항상 정확하진 않습니다. 특히 작은 모델을 evaluator로 쓰면 판정 품질이 떨어질 수 있어요.
    • 평가만 해줌: 모니터링, 실험 추적, A/B 테스트 같은 기능은 없습니다. 별도 도구가 필요해요.

    대안 프레임워크도 있습니다:

    프레임워크 특징
    DeepEval pytest 스타일 LLM 테스트. CI/CD 파이프라인에 통합하기 좋음
    LangSmith LangChain 네이티브. 평가 + observability + 실험 추적 통합
    Arize Phoenix 오픈소스. OpenTelemetry 기반 LLM observability
    Giskard LLM 취약점 탐지에 특화 (adversarial testing)

    정리

    RAGAS는 RAG 시스템의 "어디가 잘 되고, 어디가 안 되는지"를 숫자로 보여주는 도구입니다. 핵심은 Retriever와 Generator를 분리 평가한다는 점이에요.

    • Faithfulness → 답변이 근거 있는가 (hallucination 체크)
    • Answer Relevancy → 답변이 질문에 맞는가
    • Context Precision → 검색 랭킹이 정확한가
    • Context Recall → 필요한 정보를 다 찾았는가

    pip install ragas 한 줄이면 바로 사용할 수 있고, OpenAI/Anthropic/Ollama 등 다양한 LLM을 evaluator로 쓸 수 있습니다. RAG 시스템을 운영하고 있다면, 체감이 아닌 수치 기반으로 시스템을 개선해보세요.


    이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.

Designed by Tistory.