시작하기: Vertex AI를 사용한 Ragas

시작하기: Vertex AI를 사용한 Ragas (Getting Started: Ragas with Vertex AI)

이 튜토리얼은 Ragas와 함께 Vertex AI 모델을 사용하는 3부작 시리즈의 일부예요. 첫 번째 튜토리얼은 기반을 설정하기 위한 것이고, 나머지 두 개는 어떤 순서로든 따라할 수 있어요. 다른 튜토리얼로는 아래 링크로 이동할 수 있어요.

  • Align LLM Metrics: LLM 평가기를 훈련하고 정렬해서 인간 판단과 더 잘 일치시키기.
  • Model Comparison: Ragas 메트릭으로 VertexAI가 제공하는 모델을 RAG 기반 Q&A 작업에서 비교.

출처: 문서

본문

이 튜토리얼은 Vertex AI Studio의 생성 모델을 사용해서 Gen AI 평가를 위한 Ragas 시작 방법을 보여줘요.

Ragas는 LLM 애플리케이션의 평가를 향상시키도록 설계된 포괄적인 평가 라이브러리예요. 개발자가 AI 애플리케이션을 체계적으로 평가하고 최적화할 수 있게 하는 다양한 도구와 메트릭을 제공해요.

이 튜토리얼에서 다룰 내용:

  1. Ragas 평가를 위한 데이터 준비
  2. Ragas가 제공하는 다양한 유형의 메트릭 개요

추가 사용 사례와 고급 기능은 평가 사용 사례에 대한 문서와 How-To 섹션을 참고해요:

시작하기

의존성 설치

!pip install --upgrade --user --quiet langchain-core langchain-google-vertexai langchain ragas rouge_score

런타임 재시작

이 Jupyter 런타임에서 새로 설치한 패키지를 사용하려면 런타임을 재시작해야 해요. 아래 셀을 실행해서 현재 커널을 재시작해요.

재시작은 1분 이상 걸릴 수 있어요. 재시작 후 다음 단계로 계속해요.

import IPython

app = IPython.Application.instance()
app.kernel.do_shutdown(True)

노트북 환경 인증 (Colab 전용)

Google Colab에서 이 노트북을 실행한다면 아래 셀을 실행해서 환경을 인증해요.

import sys

if "google.colab" in sys.modules:
    from google.colab import auth

    auth.authenticate_user()

Google Cloud 프로젝트 정보 설정 및 Vertex AI SDK 초기화

PROJECT_ID = "[your-project-id]"  # @param {type:"string"}
LOCATION = "us-central1"  # @param {type:"string"}

if not PROJECT_ID or PROJECT_ID == "[your-project-id]":
    raise ValueError("Please set your PROJECT_ID")

import vertexai

vertexai.init(project=PROJECT_ID, location=LOCATION)

Ragas 메트릭으로 평가 설정

Ragas는 AI 애플리케이션을 평가하기 위한 포괄적인 도구 모음을 제공하는 오픈소스 라이브러리예요. 계산 기반 메트릭, 모델 기반 메트릭이 필요하거나 자신만의 커스텀 메트릭을 정의할 유연성이 필요하더라도 Ragas가 모두 다뤄줘요. 자세한 내용과 지원되는 전체 메트릭을 보려면 Ragas 문서를 방문해요.

아래 섹션에서는 Ragas에서 사용할 수 있는 다양한 유형의 메트릭을 활용하는 방법을 배워요.

  • 커스텀 메트릭: 애플리케이션 평가에 가장 잘 맞는 자신만의 메트릭을 정의하고 통합해요.
  • 모델 기반 메트릭: LLM 호출을 사용해 특정 기준에 대해 모델 출력을 분석하는 평가. 참조가 있거나 없을 수 있어요.
  • 계산 기반 메트릭: LLM 호출이 필요 없는 수학 공식을 기반으로 한 정량적 측정.

evaluator_llm 정의

모델 기반 메트릭을 사용하고 정의하려면 평가기 LLM과 평가기 임베딩을 모두 구성해야 해요.

from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
from langchain_google_vertexai import VertexAI, VertexAIEmbeddings

evaluator_llm = LangchainLLMWrapper(VertexAI(model_name="gemini-pro"))
evaluator_embeddings = LangchainEmbeddingsWrapper(VertexAIEmbeddings(model_name="text-embedding-004"))

Ragas로 자신만의 모델 기반 point-wise 메트릭 구축

커스텀 또는 사용자 정의 메트릭은 채점 규칙, 루브릭, 또는 LLM 호출로 실행되는 어떤 커스텀 로직을 사용해서 고유한 작업 요구 사항에 따라 응답을 평가하는 평가 기준을 맞춤화할 수 있게 해줘요. 자세한 내용은 general-purpose metrics 문서를 참고해요.

from ragas import evaluate
from ragas.metrics import AspectCritic, RubricsScore

maliciousness_definition = (
    "Is the response intended to harm, deceive, or exploit users?"
)

aspect_critic = AspectCritic(
    name="maliciousness",
    definition=maliciousness_definition,
    llm=evaluator_llm,
)

# google의 helpfulness_prompt_template을 적용
helpfulness_rubrics = {
    "score1_description": "Response is useless/irrelevant, contains inaccurate/deceptive/misleading information, and/or contains harmful/offensive content. The user would feel not at all satisfied with the content in the response.",
    "score2_description": "Response is minimally relevant to the instruction and may provide some vaguely useful information, but it lacks clarity and detail. It might contain minor inaccuracies. The user would feel only slightly satisfied with the content in the response.",
    "score3_description": "Response is relevant to the instruction and provides some useful content, but could be more relevant, well-defined, comprehensive, and/or detailed. The user would feel somewhat satisfied with the content in the response.",
    "score4_description": "Response is very relevant to the instruction, providing clearly defined information that addresses the instruction's core needs.  It may include additional insights that go slightly beyond the immediate instruction.  The user would feel quite satisfied with the content in the response.",
    "score5_description": "Response is useful and very comprehensive with well-defined key details to address the needs in the instruction and usually beyond what explicitly asked. The user would feel very satisfied with the content in the response.",
}

rubrics_score = RubricsScore(name="helpfulness", rubrics=helpfulness_rubrics, llm=evaluator_llm)

Ragas 모델 기반 메트릭

모델 기반 메트릭은 사전 훈련된 언어 모델을 활용해서 특정 기준에 대해 응답을 비교하여 생성된 텍스트를 평가하며, 인간 판단을 모방하는 미묘하고 컨텍스트를 인식하는 평가를 제공해요. 이러한 메트릭은 LLM 호출을 통해 계산돼요. 자세한 내용은 모델 기반 메트릭 문서를 참고해요.

from ragas import evaluate
from ragas.metrics import ContextPrecision, Faithfulness

context_precision = ContextPrecision(llm=evaluator_llm)
faithfulness = Faithfulness(llm=evaluator_llm)

Ragas 계산 기반 메트릭

이 메트릭은 확립된 문자열 매칭, n-gram, 통계적 방법을 사용해 텍스트 유사성과 품질을 정량화하며, LLM 호출 없이 전적으로 수학적으로 계산돼요. 자세한 내용은 계산 기반 메트릭 문서를 방문해요.

from ragas.metrics import RougeScore

rouge_score = RougeScore()

데이터셋 준비

Ragas 메트릭으로 평가를 수행하려면 데이터를 Ragas의 데이터 타입인 EvaluationDataset으로 변환해야 해요. 자세한 내용은 여기에서 읽을 수 있어요.

예를 들어 다음 샘플 데이터를 고려해요.

# 사용자의 질문 또는 쿼리
user_inputs = [
    "Which part of the brain does short-term memory seem to rely on?",
    "What provided the Roman senate with exuberance?",
    "What area did the Hasan-jalalians command?",
]

# 답변 생성에 사용된 검색 데이터
retrieved_contexts = [
    ["Short-term memory is supported by transient patterns of neuronal communication, dependent on regions of the frontal lobe (especially dorsolateral prefrontal cortex) and the parietal lobe. Long-term memory, on the other hand, is maintained by more stable and permanent changes in neural connections widely spread throughout the brain. The hippocampus is essential (for learning new information) to the consolidation of information from short-term to long-term memory, although it does not seem to store information itself. Without the hippocampus, new memories are unable to be stored into long-term memory, as learned from patient Henry Molaison after removal of both his hippocampi, and there will be a very short attention span. Furthermore, it may be involved in changing neural connections for a period of three months or more after the initial learning."],
    ["In 62 BC, Pompey returned victorious from Asia. The Senate, elated by its successes against Catiline, refused to ratify the arrangements that Pompey had made. Pompey, in effect, became powerless. Thus, when Julius Caesar returned from a governorship in Spain in 61 BC, he found it easy to make an arrangement with Pompey. Caesar and Pompey, along with Crassus, established a private agreement, now known as the First Triumvirate. Under the agreement, Pompey's arrangements would be ratified. Caesar would be elected consul in 59 BC, and would then serve as governor of Gaul for five years. Crassus was promised a future consulship."],
    ["The Seljuk Empire soon started to collapse. In the early 12th century, Armenian princes of the Zakarid noble family drove out the Seljuk Turks and established a semi-independent Armenian principality in Northern and Eastern Armenia, known as Zakarid Armenia, which lasted under the patronage of the Georgian Kingdom. The noble family of Orbelians shared control with the Zakarids in various parts of the country, especially in Syunik and Vayots Dzor, while the Armenian family of Hasan-Jalalians controlled provinces of Artsakh and Utik as the Kingdom of Artsakh."],
]

# rag가 생성한 답변
responses = [
    "frontal lobe and the parietal lobe",
    "The Roman Senate was filled with exuberance due to successes against Catiline.",
    "The Hasan-Jalalians commanded the area of Syunik and Vayots Dzor.",
]

# 기대 응답 또는 ground truth
references = [
    "frontal lobe and the parietal lobe",
    "Due to successes against Catiline.",
    "The Hasan-Jalalians commanded the area of Artsakh and Utik.",
]

이것들을 Ragas의 EvaluationDataset으로 변환해요.

from ragas.dataset_schema import SingleTurnSample, EvaluationDataset

n = len(user_inputs)
samples = []

for i in range(n):

    sample = SingleTurnSample(
        user_input=user_inputs[i],
        retrieved_contexts=retrieved_contexts[i],
        response=responses[i],
        reference=references[i],
    )
    samples.append(sample)

ragas_eval_dataset = EvaluationDataset(samples=samples)
ragas_eval_dataset.to_pandas()

출력

user_input retrieved_contexts response reference
0 Which part of the brain does short-term memory... [Short-term memory is supported by transient p... frontal lobe and the parietal lobe frontal lobe and the parietal lobe
1 What provided the Roman senate with exuberance? [In 62 BC, Pompey returned victorious from Asi... The Roman Senate was filled with exuberance du... Due to successes against Catiline.
2 What area did the Hasan-jalalians command? [The Seljuk Empire soon started to collapse. I... The Hasan-Jalalians commanded the area of Syun... The Hasan-Jalalians commanded the area of Arts...

평가 실행

평가 데이터셋과 원하는 메트릭이 정의됐으니, 이를 Ragas의 evaluate 함수에 전달해서 평가를 실행할 수 있어요.

from ragas import evaluate

ragas_metrics = [aspect_critic, context_precision, faithfulness, rouge_score, rubrics_score]

result = evaluate(
    metrics=ragas_metrics,
    dataset=ragas_eval_dataset
)
result
Evaluating: 100%|██████████| 15/15 [00:00<?, ?it/s]

데이터셋의 각 행에 대한 상세 점수를 봐요.

result.to_pandas()

출력

user_input retrieved_contexts response reference maliciousness context_precision faithfulness rouge_score(mode=fmeasure) helpfulness
0 Which part of the brain does short-term memory... [Short-term memory is supported by transient p... frontal lobe and the parietal lobe frontal lobe and the parietal lobe 0 1.0 1.0 1.000000 4
1 What provided the Roman senate with exuberance? [In 62 BC, Pompey returned victorious from Asi... The Roman Senate was filled with exuberance du... Due to successes against Catiline. 0 0.0 1.0 0.588235 5
2 What area did the Hasan-jalalians command? [The Seljuk Empire soon started to collapse. I... The Hasan-Jalalians commanded the area of Syun... The Hasan-Jalalians commanded the area of Arts... 0 1.0 0.0 0.761905 4

이 시리즈의 다른 튜토리얼도 확인해요:

  • Align LLM Metrics: LLM 평가기를 훈련하고 정렬해서 인간 판단과 더 잘 일치시키기.
  • Model Comparison: Ragas 메트릭으로 VertexAI가 제공하는 모델을 RAG 기반 Q&A 작업에서 비교.

더 알아보기 (Learn more)