RAG 성능 측정: RAGAS

wldbs._.·2025년 10월 10일

RAG

목록 보기
22/22
post-thumbnail

참고

rag의 정량적 성능 측정 방법으로 가장 잘 알려진 것이 RAGAS이다.
RAGAS는 검색(retrieval)과 생성(generation) 두 측명을 동시에 평가할 수 있다.
이에 대해서 알아보자.


📊 앞서

RAG(Retrieval-Augmented Generation)는 대규모 데이터베이스에서 필요한 정보를 검색하고, 이를 바탕으로 답변을 생성하는 기술이다.

기술이 아무리 뛰어나더라도, 정확한 성능 평가 없이는 그 가치를 제대로 보여줄 수는 없다.

RAG 성능 평가란, RAG가 얼마나 효과적으로 작동하는지 측정하는 과정이다.

  • RAG의 성능을 제대로 측정하는 일을 생각보다 복잡하다.
  • 단순히 얼마나 빠르고 정확한지만 보는 것이 아니라, 실제 업무 환경에서 얼마나 도움이 되는지까지 살펴봐야 한다.

RAG는 크게 두 단계로 작동한다.
1. 검색 단계: 질문과 관련된 정보를 찾아오는 단계
2. 생성 단계: 찾아온 정보를 바탕으로 답변을 만드는 단계

  • 이처럼 RAG는 두 단계가 유기적으로 연결되어 작동하기에, 각 단계의 성능을 개별적으로 & 전체적으로 평가해야 한다
  • 검색된 정보의 관련성과 생성된 답변의 정확성을 체계적으로 평가함으로써, 일관된 UX와 신뢰할 수 있는 성능을 보장하고자 한다.

📊 RAG 성능 평가

✅ 검색 단계 평가

Retrieval Eveluation

정보를 찾아오는 능력을 쳥가하는 단계이다.

  1. 관련성 Relevance
    : 검색된 문서가 질문과 얼마나 관련 있는지를 평가한다.
  • 필요없는 정보를 가져온다 → 그 답변은 소용 없다
  1. 정밀도 Precision
    : 검색된 문서 중 유용한 문서의 비율을 평가한다.
  • 많은 문서를 가져오지만 그중 중요한 정보를 놓친다면 좋은 평가를 받을 수 없다.

✅ 생성 단계 평가

Generation Evaluation

검색된 정보를 바탕으로 얼마나 정확한 답변을 생성하는지 평가한다.

  1. 유창성 Fluency
    : 답변이 사실에 기반해 정확한 정보를 제공하는지 평가한다.

  2. 적응성 Adaptability
    : 검색된 정보가 완벽히 일치하지 않더라도, 질문에 적합한 답변을 유연하게 제공할 수 있는지를 평가한다.

  3. 일관성 Consistency
    : 여러 출처에서 얻은 정보가 서로 모순되지 않고, 논리적으로 연결되어 있는지 평가한다.


✅ 종합 평가

End-to-End Evaluation

시스템 전체의 성능을 평가하는 단계로, 검색과 생성이 얼마나 조화를 이루고 있는지 종합적으로 평가한다.

  1. 전체적인 유용성 Overall Utility
    : 사용자 질문에 실제로 도움이 되는 답변을 제공하는지 평가한다.
  • 이를 위해 실사용자 피드백과 전문가의 평가가 함께 이루어진다.
  1. 응답 속도 Latency
    : 질문부터 답변까지 걸리는 시간을 평가한다.
  • 정확도와 속도 간의 균형을 맞추는 것이 중요하다.
  • 너무 빠르면 정확도가 떨어지고, 너무 정확하게만 하려다가 응답 시간이 느려지면 UX가 저하될 수 있다.
  • 최적의 균형을 찾는 것이 핵심이다.

⭐ RAGAS

✨ 개요

기본의 BLEU, ROUGE와 같은 지표는 주로 기계 번역이나 요약과 같은 특정 태스크에서 사용되며, 주어진 텍스트와 모델이 생성한 텍스트 간의 유사성을 측정한다.

RAG는 정보 검색과 생성이 결합된 복합적인 과정이기 때문에, 단순한 텍스트 유사성 지표로는 그 성능을 충분히 평가하기 어렵다.

  • RAG에서는 단순히 생성된 텍스트의 품질뿐만 아니라, 모델이 검색한 정보의 관련성과 유용성, 그리고 그 정보가 생성된 답변에 얼마나 잘 반영되었는지를 평가한다.

즉, RAG의 성능 평가는 정보 검색의 정확성과 생성된 텍스트의 질을 함께 고려해야 한다.

  • 검색된 정보의 적합성
  • 생성된 답변의 일관성
  • 두 과정 간의 시너지 효과를 반영할 수 있는 새로운 지표가 필요

✨ RAGAS란?

RAGAS(Retrieval-Augmented Generation Assessment)는 RAG 파이프라인의 정량적 평가를 지원하는 오픈 소스 프레임워크이다.

주요 지표는 아래와 같다.

  • Faithfulness 충실성: 생성된 답변이 주어진 컨텍스트에 얼마나 충실한가? (답변이 컨텍스트에 기반하여 정확한 정보를 제공하는가)
  • Answer Relevancy 답변 관련성: 생성된 답변이 주어진 질문과 얼마나 관련성이 있는가? (질문에 대한 명확하고 적절한 답변을 제공하는가)
  • Context Precision 컨텍스트 정밀도: 질문에 대한 컨텍스트 정보를 검색하여 가져온 컨텍스트 중, 질문에 대한 답변과 관련 있는 문서가 얼마나 상위에 랭크되어 있는가? (검색된 정보의 정확도)
  • Context Recall 컨텍스트 재현율: 질문에 대한 답변을 생성하는데 필요한 컨텍스트 정보를 검색할 수 있는가? (필요한 정보를 얼마나 잘 찾아내는가)

✨ 지표 알아보기

평가 데이터셋에는 ‘question’, ‘ground_truth’ 컬럼이 존재해야 한다.

  • question: 사용자 입력에 해당하는 질문
  • ground_truth: 질문에 대응되는 정답
  1. Faithfulness
  • 주어진 문맥을 얼마나 잘 반영하여 답변을 생성하였는가
  • 점수 범위: 0~1 (1에 가까울수록 좋음)

  1. Answer Relevancy
  • 생성된 답변이 질문에 얼마나 잘 부합하는가
  • 점수 범위: -1~1 (1에 가까울수록 좋음)
  • 생성된 답변을 기반으로 생성한 질문과 원래 질문의 cosine 유사도 활용
    • answer과 context만으로 question을 재구성할 수 있다는 개념을 활용한 방식

  1. Context Precision
  • 검색된 각 k개의 context가 question, ground truth와 연관이 있는가
  • 점수 범위: 0~1 (1에 가까울수록 좋음)
  • 이상적으로는 모든 관련 chunks가 상위 순위에 나타나야 한다

  1. Context Recall
  • 검색된 context가 ground truth와 얼마나 잘 일치하는가
  • 점수 범위: 0~1 (1에 가까울수록 좋음)


✨ 예시 코드

from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

# 단계 1: 문서 로드(Load Documents)
loader = PyMuPDFLoader("data/SPRI_AI_Brief_2023년12월호_F.pdf")
docs = loader.load()

# 단계 2: 문서 분할(Split Documents)
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=50)
split_documents = text_splitter.split_documents(docs)

# 단계 3: 임베딩(Embedding) 생성
embeddings = OpenAIEmbeddings()

# 단계 4: DB 생성(Create DB) 및 저장
# 벡터스토어를 생성합니다.
vectorstore = FAISS.from_documents(documents=split_documents, embedding=embeddings)

# 단계 5: 검색기(Retriever) 생성
# 문서에 포함되어 있는 정보를 검색하고 생성합니다.
retriever = vectorstore.as_retriever()

# 단계 6: 프롬프트 생성(Create Prompt)
# 프롬프트를 생성합니다.
prompt = PromptTemplate.from_template(
    """You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer the question. 
If you don't know the answer, just say that you don't know. 

#Context: 
{context}

#Question:
{question}

#Answer:"""
)

# 단계 7: 언어모델(LLM) 생성
# 모델(LLM) 을 생성합니다.
llm = ChatOpenAI(model_name="gpt-4o", temperature=0)

# 단계 8: 체인(Chain) 생성
chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

→ 배치 데이터셋을 생성

batch_dataset = [question for question in test_dataset["question"]]
batch_dataset[:3]

→ batch() 를 호출하여 배치 데이터셋에 대한 답변 받기

answer = chain.batch(batch_dataset)
answer[:3]

→ LLM이 생성한 답변을 answer 컬럼에 저장

# 'answer' 컬럼 덮어쓰기 또는 추가
if "answer" in test_dataset.column_names:
    test_dataset = test_dataset.remove_columns(["answer"]).add_column("answer", answer)
else:
    test_dataset = test_dataset.add_column("answer", answer)

⭐ RAGAS 메인 코드

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

result = evaluate(
    dataset=test_dataset,
    metrics=[
        context_precision,
        faithfulness,
        answer_relevancy,
        context_recall,
    ],
)

result
# {'context_precision': 0.8000, 'faithfulness': 0.6689, 'answer_relevancy': 0.7836, 'context_recall': 0.7667}

⭐ RAGAS 구현

Q. question, answer, ground truth, context가 제공되면 라이브러리를 활용해 별도의 추가 구현 없이 faithfulness, context recall 등을 구할 수 있는가?
A. 가능. 다만 “완전 무설정”은 아님. 컬럼 형식과 LLM/임베딩 백엔드 설정이 필요하다.

✅ 핵심 요건

  • 컬럼: question:str, answer:str, contexts:list[str], ground_truths:list[str](※ context_recall에 필요)
  • 백엔드: 평가에 쓸 LLM과 임베딩 모델 지정

✅ 지원 예

  • faithfulness(LLM 필요)
  • answer_relevancy(LLM 필요)
  • context_precision(LLM+임베딩)
  • context_recall(LLM+임베딩+ground_truths 필요)

✅ 최소 예시

from datasets import Dataset
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall
from ragas.llms import OpenAI as RagasOpenAI
from ragas.embeddings import OpenAIEmbeddings

data = {
    "question": ["Q1", "Q2"],
    "answer": ["A1", "A2"],
    "contexts": [["ctx1a","ctx1b"], ["ctx2a","ctx2b"]],
    "ground_truths": [["gt1"], ["gt2"]],  # 없으면 context_recall 계산 불가
}
ds = Dataset.from_dict(data)

llm = RagasOpenAI(model="gpt-5", api_key="...")          # 또는 litellm/로컬 LLM
emb = OpenAIEmbeddings(model="text-embedding-3-large", api_key="...")

result = evaluate(
    ds,
    metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
    llm=llm,
    embeddings=emb,
)
print(result)  # 각 지표의 평균과 샘플별 점수 포함

✅ 정리

  • 추가 구현 없이도 계산 가능하되, 컬럼 스키마와 모델 설정은 필수.
  • ground_truths가 없으면 context_recall은 제외하고 faithfulness 등만 계산하면 된다.
profile
공부 기록용 24.08.05~ #LLM #RAG

0개의 댓글