v0.3에서 v0.4로 마이그레이션

v0.3에서 v0.4로 마이그레이션 (Migration from v0.3 to v0.4)

Ragas v0.4는 **실험 기반 아키텍처(experiment-based architecture)**로의 근본적인 전환을 도입해요. 이는 v0.2 이후 가장 큰 변화로, 고립된 지표 평가에서 평가·분석·반복이 긴밀하게 통합되는 하나의 실험 프레임워크로 이동해요.

출처: 문서

본문

이 아키텍처 변화는 다음과 같은 몇 가지 구체적인 개선을 가져왔어요.

  1. 컬렉션 기반 지표 시스템 (Collections-Based Metrics System) - 실험 안에서 매끄럽게 동작하는 표준화된 지표 접근
  2. 통합 LLM 팩토리 시스템 (Unified LLM Factory System) - 범용 공급자 지원으로 단순해진 LLM 초기화
  3. 현대적 프롬프트 시스템 (Modern Prompt System) - 더 조합하기 쉽고 재사용 가능한 함수 기반 프롬프트

이 가이드는 주요 변경 사항을 안내하고 단계별 마이그레이션 지침을 제공해요.

주요 변경 사항 개요

실험 기반 아키텍처로의 전환은 세 가지 핵심 개선에 집중해요.

  1. 실험 중심 설계 (Experiment-Centric Design) - 일회성 지표 실행에서 통합 분석이 포함된 구조화된 실험 워크플로로 이동
  2. 컬렉션 기반 지표 (Collections-Based Metrics) - 더 나은 분석과 추적을 위해 구조화된 결과를 반환하도록 설계된 지표
  3. 향상된 LLM·프롬프트 시스템 (Enhanced LLM & Prompt System) - 더 나은 실험을 가능하게 하는 범용 공급자 지원과 현대적 프롬프트 패턴

주요 수치

  • 마이그레이션된 지표 (Metrics Migrated): 20개 이상의 핵심 지표가 새 컬렉션 시스템으로 전환
  • 브레이킹 체인지 (Breaking Changes): 7개 이상의 주요 API 변경
  • Deprecation (Deprecations): 레거시 래퍼 클래스와 기존 프롬프트 정의
  • 새 기능 (New Features): GPT-5/o-시리즈 지원, 자동 제약 처리, 범용 공급자 지원

실험 기반 아키텍처 이해하기

마이그레이션 전에 사고의 전환을 이해하면 도움이 돼요.

v0.3 (지표 중심):

Data → Individual Metric → Score → Analysis

각 지표 실행은 비교적 고립돼 있었어요. 지표를 실행하고 float 점수를 얻은 뒤, 추적/분석을 외부에서 처리했죠.

v0.4 (실험 중심):

Data → Experiment → [Metrics Collection] → Structured Results → Integrated Analysis

이제 지표는 평가·분석·반복이 통합된 실험 컨텍스트 안에서 동작해요. 이를 통해 다음이 가능해요.

  • 설명이 포함된 지표 결과의 더 나은 추적
  • 실험 실행 간 더 쉬운 비교
  • 지표 동작 분석을 위한 내장 지원
  • 시스템을 반복 개선하기 위한 더 깔끔한 워크플로

마이그레이션 경로

다음 순서로 마이그레이션하는 것을 권장해요.

  1. 평가 접근 업데이트 (섹션: Evaluation to Experiment) - evaluate()에서 experiment()로 전환
  2. LLM 설정 업데이트 (섹션: LLM Initialization)
  3. 지표 마이그레이션 (섹션: Metrics Migration)
  4. 임베딩 마이그레이션 (섹션: Embeddings Migration)
  5. 프롬프트 업데이트 (섹션: Prompt System Migration) - 프롬프트를 커스터마이징하는 경우
  6. 데이터 스키마 업데이트 (섹션: Data Schema Changes)
  7. 커스텀 지표 리팩터링 (섹션: Custom Metrics)

평가에서 실험으로 (Evaluation to Experiment)

v0.4는 반복적 평가 워크플로와 구조화된 결과 추적을 더 잘 지원하기 위해 evaluate() 함수를 experiment() 기반 접근으로 대체해요.

무엇이 바뀌었나

핵심 전환은 점수를 반환하는 단순 평가 함수(evaluate())에서, 내장 추적과 버저닝으로 구조화된 워크플로를 지원하는 실험 데코레이터(@experiment())로 옮겨가는 것이에요.

Before (v0.3)

from ragas import evaluate
from ragas.metrics.collections import Faithfulness, AnswerRelevancy

# Setup
dataset = ...  # Your dataset
metrics = [Faithfulness(llm=llm), AnswerRelevancy(llm=llm)]

# Simple evaluation
result = evaluate(
    dataset=dataset,
    metrics=metrics,
    llm=llm,
    embeddings=embeddings
)

print(result)  # Returns EvaluationResult with scores

After (v0.4)

from ragas import experiment
from ragas.metrics.collections import Faithfulness, AnswerRelevancy
from pydantic import BaseModel

# Define experiment result structure
class ExperimentResult(BaseModel):
    faithfulness: float
    answer_relevancy: float

# Create experiment function
@experiment(ExperimentResult)
async def run_evaluation(row):
    faithfulness = Faithfulness(llm=llm)
    answer_relevancy = AnswerRelevancy(llm=llm)

    faith_result = await faithfulness.ascore(
        response=row.response,
        retrieved_contexts=row.contexts
    )

    relevancy_result = await answer_relevancy.ascore(
        user_input=row.user_input,
        response=row.response
    )

    return ExperimentResult(
        faithfulness=faith_result.value,
        answer_relevancy=relevancy_result.value
    )

# Run experiment
exp_results = await run_evaluation(dataset)

experiment() 사용의 장점

  1. 구조화된 결과 (Structured Results) - 추적하고 싶은 것을 정확히 정의
  2. 행 단위 제어 (Per-Row Control) - 필요하면 샘플별로 평가 커스터마이징
  3. 버전 추적 (Version Tracking) - version_experiment()로 선택적 git 통합
  4. 반복 워크플로 (Iterative Workflows) - 실험 수정·재실행이 쉬움
  5. 더 나은 통합 (Better Integration) - 최신 지표·데이터셋과 매끄럽게 동작

LLM 초기화

무엇이 바뀌었나

v0.3 시스템은 사용 사례에 따라 서로 다른 팩토리 함수를 요구했어요.

  • instructor가 필요한 지표용 instructor_llm_factory()
  • 일반 LLM 작업용 llm_factory()
  • LangChain·LlamaIndex용 다양한 래퍼 클래스

v0.4는 모든 것을 단일 통합 팩토리로 정리해요.

from ragas.llms import llm_factory

이 팩토리는:

  • 보장된 구조화 출력을 가진 InstructorBaseRagasLLM을 반환
  • 공급자별 제약을 자동 감지·구성
  • temperature·top_p 제약을 자동 적용하며 GPT-5와 o-시리즈 모델 지원
  • OpenAI, Anthropic, Cohere, Google, Azure, Bedrock 등 모든 주요 공급자와 동작

Before (v0.3)

from ragas.llms import instructor_llm_factory, llm_factory
from openai import AsyncOpenAI

# For metrics that need instructor
llm = instructor_llm_factory("openai", model="gpt-4o-mini", client=AsyncOpenAI(api_key="..."))

# Or, the old way (not recommended, still supported in 0.3)
client = AsyncOpenAI(api_key="sk-...")
llm = llm_factory("openai", model="gpt-4o-mini", client=client)

After (v0.4)

from ragas.llms import llm_factory
from openai import AsyncOpenAI

# Single unified approach - works everywhere
client = AsyncOpenAI(api_key="sk-...")
llm = llm_factory("gpt-4o-mini", client=client)

주요 차이점:

Aspect v0.3 v0.4
Factory function instructor_llm_factory() or llm_factory() llm_factory()
Provider detection Manual via provider string Automatic from model name
Return type BaseRagasLLM (various) InstructorBaseRagasLLM
Constraint handling Manual configuration Automatic for GPT-5/o-series
Async client required Yes Yes

마이그레이션 단계

  1. import 업데이트:
# Remove this
from ragas.llms import instructor_llm_factory

# Use this instead
from ragas.llms import llm_factory
  1. 팩토리 호출 교체:
# Old - v0.3
llm = instructor_llm_factory("openai", model="gpt-4o", client=client)

# New - v0.4
llm = llm_factory("gpt-4o", client=client)
  1. 다른 공급자로 업데이트 (모델 이름 감지는 자동으로 동작해요):
# OpenAI
llm = llm_factory("gpt-4o-mini", client=AsyncOpenAI(api_key="..."))

# Anthropic
llm = llm_factory("claude-3-sonnet-20240229", client=AsyncAnthropic(api_key="..."))

# Google
llm = llm_factory("gemini-2.0-flash", client=...)

LLM 래퍼 클래스 (Deprecated)

래퍼 클래스를 사용 중이라면 이제 deprecated이며 향후 제거될 거예요.

# Deprecated - will be removed
from ragas.llms import LangchainLLMWrapper, LlamaIndexLLMWrapper
# Recommended - use llm_factory directly
from ragas.llms import llm_factory

마이그레이션: 래퍼 초기화를 직접 llm_factory() 호출로 교체해요. 팩토리가 이제 공급자 감지를 자동으로 처리해요.

지표 마이그레이션

지표가 왜 바뀌었나

실험 기반 아키텍처로의 전환은 지표가 실험 워크플로와 더 잘 통합되도록 요구했어요.

  • 구조화된 결과 (Structured Results): 지표가 이제 원시 float 대신 MetricResult 객체(점수 + 추론)를 반환해 실험 안에서 더 풍부한 분석과 추적을 가능하게 해요
  • 키워드 인자 (Keyword Arguments): 샘플 객체에서 직접 키워드 인자로 이동해 지표를 실험 파이프라인과 더 쉽게 구성·통합하게 해요
  • 표준화된 입출력 (Standardized Input/Output): 컬렉션 기반 지표가 일관된 패턴을 따라, 그 위에 메타 분석·실험 기능을 만들기 쉬워져요

아키텍처 변경

지표 시스템은 실험 워크플로를 지원하도록 완전히 재설계됐어요. 핵심 차이점은 다음과 같아요.

기본 클래스 변경

Aspect v0.3 v0.4
Import from ragas.metrics import Metric from ragas.metrics.collections import Metric
Base Class MetricWithLLM, SingleTurnMetric BaseMetric (from collections)
Scoring Method async def single_turn_ascore(sample: SingleTurnSample) async def ascore(**kwargs)
Input Type SingleTurnSample objects Individual keyword arguments
Output Type float score MetricResult (with .value and optional .reason)
LLM Parameter Required at initialization Required at initialization

점수 매기기 워크플로

v0.3 방식:

# 1. Create a sample object containing all data
sample = SingleTurnSample(
    user_input="What is AI?",
    response="AI is artificial intelligence...",
    retrieved_contexts=["Context 1", "Context 2"],
    ground_truths=["AI definition"]
)

# 2. Call metric with the sample
metric = Faithfulness(llm=llm)
score = await metric.single_turn_ascore(sample)  # Returns: 0.85

v0.4 방식:

# 1. Call metric with individual arguments
metric = Faithfulness(llm=llm)
result = await metric.ascore(
    user_input="What is AI?",
    response="AI is artificial intelligence...",
    retrieved_contexts=["Context 1", "Context 2"]
)

# 2. Access result properties
print(result.value)      # Score: 0.85 (float)
print(result.reason)     # Optional explanation

v0.4에서 사용 가능한 지표

다음 지표들이 v0.4에서 컬렉션 시스템으로 성공적으로 마이그레이션됐어요.

RAG 평가 지표

  • Faithfulness - 응답이 검색된 컨텍스트에 근거하고 있나? (v0.3.9+)
  • AnswerRelevancy - 응답이 사용자 질의와 관련 있나? (v0.3.9+)
  • AnswerCorrectness - 응답이 참조 답변과 일치하나? (v0.3.9+)
  • AnswerAccuracy - 답변이 사실적으로 정확한가?
  • ContextPrecision - 검색된 컨텍스트가 관련성 순으로 정렬됐나? (v0.3.9+)
    • 참조 포함: ContextPrecisionWithReference
    • 참조 없음: ContextPrecisionWithoutReference
    • 레거시 이름: ContextUtilization (이제 ContextPrecisionWithoutReference의 래퍼)
  • ContextRecall - 관련 컨텍스트가 모두 성공적으로 검색됐나? (v0.3.9+)
  • ContextRelevance - 검색된 컨텍스트 중 관련 있는 비율은? (v0.3.9+)
  • ContextEntityRecall - 참조의 중요한 엔터티가 컨텍스트에 있나? (v0.3.9+)
  • NoiseSensitivity - 지표가 무관한 컨텍스트에 얼마나 강한가? (v0.3.9+)
  • ResponseGroundedness - 모든 주장이 검색된 컨텍스트에 근거하고 있나?

텍스트 비교 지표

  • SemanticSimilarity - 두 텍스트가 의미적으로 비슷한가? (v0.3.9+)
  • FactualCorrectness - 사실적 주장이 올바르게 검증됐나? (v0.3.9+)
  • BleuScore - 이중언어 평가 대용물 점수 (v0.3.9+)
  • RougeScore - gisting 평가를 위한 재현 중심 대용물 (v0.3.9+)

문자열 기반 지표 (비-LLM)

  • ExactMatch - 정확한 문자열 일치
  • StringPresence - 부분 문자열 존재 확인
  • LevenshteinDistance - 편집 거리 유사도
  • MatchingSubstrings - 일치하는 부분 문자열 수
  • NonLLMStringSimilarity - 다양한 문자열 유사도 알고리즘

요약 지표

  • SummaryScore - 전반적인 요약 품질 평가 (v0.3.9+)

제거된 지표 (더 이상 사용 불가)

  • AspectCritic - 대신 @discrete_metric() 데코레이터 사용
  • SimpleCriteria - 대신 @discrete_metric() 데코레이터 사용
  • AnswerSimilarity - 대신 SemanticSimilarity 사용

에이전트 & 도구 지표 (마이그레이션됨)

  • ToolCallAccuracy - ragas.metrics.collections.ToolCallAccuracy
  • ToolCallF1 - ragas.metrics.collections.ToolCallF1
  • TopicAdherence - ragas.metrics.collections.TopicAdherence
  • AgentGoalAccuracy - ragas.metrics.collections.AgentGoalAccuracy

SQL & 데이터 지표 (마이그레이션됨)

  • DataCompy Score - ragas.metrics.collections.DataCompyScore
  • SQL Query Equivalence - ragas.metrics.collections.SQLSemanticEquivalence

루브릭 지표 (마이그레이션됨)

  • DomainSpecificRubrics - ragas.metrics.collections.DomainSpecificRubrics
  • InstanceSpecificRubrics - ragas.metrics.collections.InstanceSpecificRubrics

문자열 & NLP 지표 (마이그레이션됨)

  • CHRF Score - ragas.metrics.collections.CHRFScore (문자 n-gram F-score)
  • Quoted Spans Alignment - ragas.metrics.collections.QuotedSpansAlignment (인용 검증)

특수 지표 (아직 마이그레이션 안 됨)

  • Multi-Modal Faithfulness - 여전히 구 아키텍처 (마이그레이션 대기)
  • Multi-Modal Relevance - 여전히 구 아키텍처 (마이그레이션 대기)

마이그레이션 상태

대부분의 핵심 지표가 컬렉션 시스템으로 마이그레이션됐어요. 멀티모달 지표만 레거시 아키텍처에 남아 있어요.

나머지 지표는 향후 v0.4.x 릴리스에서 마이그레이션될 거예요. 레거시 지표를 기존 API로 계속 사용할 수 있지만, deprecation 경고가 표시돼요.

단계별 마이그레이션

1단계: Import 업데이트

# v0.3
from ragas.metrics import (
    Faithfulness,
    AnswerRelevancy,
    ContextPrecision,
    ContextRecall
)
# v0.4
from ragas.metrics.collections import (
    Faithfulness,
    AnswerRelevancy,
    ContextPrecision,
    ContextRecall
)

2단계: 지표 초기화 (변경 필요 없음)

# v0.3
metric = Faithfulness(llm=llm)
# v0.4 - Same initialization
metric = Faithfulness(llm=llm)

3단계: 지표 점수 호출 업데이트

single_turn_ascore(sample)ascore(**kwargs)로 교체해요.

# v0.3
sample = SingleTurnSample(
    user_input="What is AI?",
    response="AI is artificial intelligence.",
    retrieved_contexts=["AI is a technology..."],
    ground_truths=["AI definition"]
)

score = await metric.single_turn_ascore(sample)
print(score)  # Output: 0.85
# v0.4
result = await metric.ascore(
    user_input="What is AI?",
    response="AI is artificial intelligence.",
    retrieved_contexts=["AI is a technology..."]
)

print(result.value)   # Output: 0.85
print(result.reason)  # Optional: "Response is faithful to context"

4단계: MetricResult 객체 처리

v0.4에서 지표는 원시 float 대신 MetricResult 객체를 반환해요.

from ragas.metrics.collections.base import MetricResult

result = await metric.ascore(...)

# Access the score
score_value = result.value  # float between 0 and 1

# Access the explanation (if available)
if result.reason:
    print(f"Reason: {result.reason}")

# Convert to float for compatibility
score_float = float(result.value)

지표별 마이그레이션

Faithfulness

Before (v0.3):

sample = SingleTurnSample(
    user_input="What is machine learning?",
    response="ML is a subset of AI.",
    retrieved_contexts=["ML involves algorithms..."]
)
score = await metric.single_turn_ascore(sample)

After (v0.4):

result = await metric.ascore(
    user_input="What is machine learning?",
    response="ML is a subset of AI.",
    retrieved_contexts=["ML involves algorithms..."]
)
score = result.value

AnswerRelevancy

Before (v0.3):

sample = SingleTurnSample(
    user_input="What is Python?",
    response="Python is a programming language..."
)
score = await metric.single_turn_ascore(sample)

After (v0.4):

result = await metric.ascore(
    user_input="What is Python?",
    response="Python is a programming language..."
)
score = result.value

AnswerCorrectness

참고: 이 지표는 이제 ground_truths 대신 reference를 사용해요.

Before (v0.3):

sample = SingleTurnSample(
    user_input="What is AI?",
    response="AI is artificial intelligence.",
    ground_truths=["AI is artificial intelligence and machine learning."]
)
score = await metric.single_turn_ascore(sample)

After (v0.4):

result = await metric.ascore(
    user_input="What is AI?",
    response="AI is artificial intelligence.",
    reference="AI is artificial intelligence and machine learning."
)
score = result.value

ContextPrecision

Before (v0.3):

sample = SingleTurnSample(
    user_input="What is RAG?",
    response="RAG improves LLM accuracy.",
    retrieved_contexts=["RAG = Retrieval Augmented Generation...", "..."],
    ground_truths=["RAG definition"]
)
score = await metric.single_turn_ascore(sample)

After (v0.4):

result = await metric.ascore(
    user_input="What is RAG?",
    response="RAG improves LLM accuracy.",
    retrieved_contexts=["RAG = Retrieval Augmented Generation...", "..."],
    reference="RAG definition"
)
score = result.value

프롬프트 시스템 마이그레이션

프롬프트가 왜 바뀌었나

모듈형 아키텍처로의 전환은 프롬프트가 이제 일급(first-class) 컴포넌트가 된다는 뜻이에요. 다시 말해:

  • 지표별 커스터마이징 (Customized per metric) - 각 지표에 잘 정의된 프롬프트 인터페이스
  • 타입 안전 (Type-safe) - 입력/출력 모델이 기대하는 정확한 구조를 정의
  • 재사용 가능 (Reusable) - 프롬프트 클래스가 지표 전반에 걸쳐 일관된 패턴을 따름
  • 테스트 가능 (Testable) - 프롬프트를 독립적으로 생성·검사 가능

v0.3은 지표에 흩어져 있는 단순 문자열·dataclass 프롬프트를 사용했어요. v0.4는 그것들을 전용 입력/출력 모델을 가진 통합 BasePrompt 아키텍처로 정리해요.

아키텍처 변경

기본 프롬프트 시스템

Aspect v0.3 v0.4
Prompt Definition PydanticPrompt dataclasses or strings BasePrompt classes with to_string() method
Input/Output Types Generic Pydantic models Metric-specific Input/Output models
Access Method Scatter across metric code Centralized in metric's util.py module
Customization Difficult, requires deep changes Simple subclassing with instruction and examples properties
Organization Mixed in metric files Organized in separate util.py files

v0.4에서 사용 가능한 지표 프롬프트

다음 지표들이 이제 잘 정의되고 커스터마이징 가능한 프롬프트를 가져요.

  • Faithfulness - FaithfulnessPrompt, FaithfulnessInput, FaithfulnessOutput
  • Context Recall - ContextRecallPrompt, ContextRecallInput, ContextRecallOutput
  • Context Precision - ContextPrecisionPrompt, ContextPrecisionInput, ContextPrecisionOutput
  • Answer Relevancy - AnswerRelevancyPrompt, AnswerRelevancyInput, AnswerRelevancyOutput
  • Answer Correctness - AnswerCorrectnessPrompt, AnswerCorrectnessInput, AnswerCorrectnessOutput
  • Response Groundedness - ResponseGroundednessPrompt, ResponseGroundednessInput, ResponseGroundednessOutput
  • Answer Accuracy - AnswerAccuracyPrompt, AnswerAccuracyInput, AnswerAccuracyOutput
  • Context Relevance - ContextRelevancePrompt, ContextRelevanceInput, ContextRelevanceOutput
  • Context Entity Recall - ContextEntityRecallPrompt, ContextEntityRecallInput, ContextEntityRecallOutput
  • Factual Correctness - ClaimDecompositionPrompt, VerificationPrompt, 관련 Input/Output 모델 포함
  • Noise Sensitivity - NoiseAugmentationPrompt 및 관련 모델
  • Summary Score - SummaryScorePrompt, SummaryScoreInput, SummaryScoreOutput

단계별 마이그레이션

1단계: 지표에서 프롬프트 접근하기

from ragas.metrics.collections import Faithfulness
from ragas.llms import llm_factory

# Create metric instance
metric = Faithfulness(llm=llm)

# Access the prompt object
print(metric.prompt)  # <ragas.metrics.collections.faithfulness.util.FaithfulnessPrompt>

2단계: 프롬프트 문자열 보기

from ragas.metrics.collections.faithfulness.util import FaithfulnessInput

# Create sample input
sample_input = FaithfulnessInput(
    response="The Eiffel Tower is in Paris.",
    context="The Eiffel Tower is located in Paris, France."
)

# Generate prompt string
prompt_string = metric.prompt.to_string(sample_input)
print(prompt_string)

3단계: 프롬프트 커스터마이징 (필요한 경우)

옵션 A: 기본 프롬프트 서브클래싱

from ragas.metrics.collections import Faithfulness
from ragas.metrics.collections.faithfulness.util import FaithfulnessPrompt

# Create custom prompt by subclassing
class CustomFaithfulnessPrompt(FaithfulnessPrompt):
    @property
    def instruction(self):
        return """Your custom instruction here."""

# Apply to metric
metric = Faithfulness(llm=llm)
metric.prompt = CustomFaithfulnessPrompt()

옵션 B: 도메인별 평가를 위한 예시 커스터마이징

from ragas.metrics.collections.faithfulness.util import (
    FaithfulnessInput,
    FaithfulnessOutput,
    FaithfulnessPrompt,
    StatementFaithfulnessAnswer,
)

class DomainSpecificPrompt(FaithfulnessPrompt):
    examples = [
        (
            FaithfulnessInput(
                response="ML uses statistical techniques.",
                context="Machine learning is a field that uses algorithms to learn from data.",
            ),
            FaithfulnessOutput(
                statements=[
                    StatementFaithfulnessAnswer(
                        statement="ML uses statistical techniques.",
                        reason="Related to learning from data, but context doesn't explicitly mention statistical techniques.",
                        verdict=0
                    ),
                ]
            ),
        ),
    ]

# Apply custom prompt
metric = Faithfulness(llm=llm)
metric.prompt = DomainSpecificPrompt()

흔한 프롬프트 커스터마이징

지시문 변경하기

대부분의 지표는 instruction 프로퍼티를 재정의할 수 있게 해요.

class StrictFaithfulnessPrompt(FaithfulnessPrompt):
    @property
    def instruction(self):
        return """Be very strict when judging faithfulness.
Only mark statements as faithful (verdict=1) if they are directly stated or strongly implied."""

도메인 예시 추가하기

도메인별 예시는 지표 정확도를 크게 향상시켜요 (10-20% 개선).

class MedicalFaithfulnessPrompt(FaithfulnessPrompt):
    examples = [
        # Medical domain examples here
    ]

출력 형식 변경하기

고급 커스터마이징을 위해 프롬프트를 서브클래싱하고 to_string() 메서드를 재정의해요.

class CustomPrompt(FaithfulnessPrompt):
    def to_string(self, input: FaithfulnessInput) -> str:
        # Custom prompt generation logic
        return "..."

커스텀 프롬프트 검증하기

커스텀 프롬프트를 사용하기 전에 항상 검증해요.

# Test prompt generation
sample_input = FaithfulnessInput(
    response="Test response.",
    context="Test context."
)

custom_metric = Faithfulness(llm=llm)
custom_metric.prompt = MyCustomPrompt()

# View the generated prompt
prompt_string = custom_metric.prompt.to_string(sample_input)
print(prompt_string)

# Then use it for evaluation
result = await custom_metric.ascore(
    response="Test response.",
    context="Test context."
)

v0.3 커스텀 프롬프트에서 마이그레이션

v0.3에서 PydanticPrompt를 사용하는 커스텀 프롬프트가 있었다면:

Before (v0.3) - Dataclass 방식:

from ragas.prompt.pydantic_prompt import PydanticPrompt
from pydantic import BaseModel

class MyInput(BaseModel):
    response: str
    context: str

class MyOutput(BaseModel):
    is_faithful: bool

class MyPrompt(PydanticPrompt[MyInput, MyOutput]):
    instruction = "Check if response is faithful to context"
    input_model = MyInput
    output_model = MyOutput
    examples = [...]

After (v0.4) - BasePrompt 방식:

from ragas.metrics.collections.base import BasePrompt
from pydantic import BaseModel

class MyInput(BaseModel):
    response: str
    context: str

class MyOutput(BaseModel):
    is_faithful: bool

class MyPrompt(BasePrompt):
    @property
    def instruction(self):
        return "Check if response is faithful to context"

    @property
    def input_model(self):
        return MyInput

    @property
    def output_model(self):
        return MyOutput

    @property
    def examples(self):
        return [...]

    def to_string(self, input: MyInput) -> str:
        # Generate prompt string from input
        return f"Check if this is faithful: {input.response}"

BasePrompt.adapt()를 이용한 언어 적응

v0.4는 언어 번역을 위해 BasePrompt 인스턴스에 adapt() 메서드를 도입해요. deprecated된 PromptMixin.adapt_prompts() 방식의 뒤를 잇는 방식이에요.

Before (v0.3) - PromptMixin 방식

from ragas.prompt.mixin import PromptMixin
from ragas.metrics import Faithfulness

# Metrics inherited from PromptMixin to use adapt_prompts
class MyFaithfulness(Faithfulness, PromptMixin):
    pass

metric = MyFaithfulness(llm=llm)

# Adapt ALL prompts to another language
adapted_prompts = await metric.adapt_prompts(
    language="spanish",
    llm=llm,
    adapt_instruction=True
)

# Apply all adapted prompts
metric.set_prompts(**adapted_prompts)

v0.3 방식의 문제점:

  • mixin 상속 필요 (강한 결합)
  • 모든 프롬프트가 함께 적응됨 (유연하지 않음)
  • mixin 메서드가 코드베이스에 흩어져 있음

After (v0.4) - BasePrompt.adapt() 메서드

from ragas.metrics.collections import Faithfulness

# Create metric with default prompt
metric = Faithfulness(llm=llm)

# Adapt individual prompt to another language
adapted_prompt = await metric.prompt.adapt(
    target_language="spanish",
    llm=llm,
    adapt_instruction=True
)

# Apply adapted prompt
metric.prompt = adapted_prompt

# Use metric with adapted language
result = await metric.ascore(
    response="...",
    retrieved_contexts=[...]
)

프롬프트 저장·불러오기는 향후 v0.4.x 버전에서 BasePrompt를 사용할 수 있게 돼요. 현재는 PromptMixin만 그 기능을 갖고 있어요.

언어 적응 예시

지시문 텍스트 없이 적응 (가벼운 방식):

from ragas.metrics.collections import AnswerRelevancy

metric = AnswerRelevancy(llm=llm)

# Only update language field, keep instruction in English
adapted_prompt = await metric.prompt.adapt(
    target_language="french",
    llm=llm,
    adapt_instruction=False  # Default - just updates language
)

metric.prompt = adapted_prompt
print(metric.prompt.language)  # "french"

지시문 번역과 함께 적응 (전체 번역):

# Translate both instruction and examples
adapted_prompt = await metric.prompt.adapt(
    target_language="german",
    llm=llm,
    adapt_instruction=True  # Translate instruction text too
)

metric.prompt = adapted_prompt

# Examples are also automatically translated
# Both instruction and examples in German now

커스텀 프롬프트 적응:

from ragas.metrics.collections.faithfulness.util import FaithfulnessPrompt

class CustomFaithfulnessPrompt(FaithfulnessPrompt):
    @property
    def instruction(self):
        return "Custom instruction in English"

prompt = CustomFaithfulnessPrompt(language="english")

# Adapt to Italian
adapted = await prompt.adapt(
    target_language="italian",
    llm=llm,
    adapt_instruction=True
)

# Check language was updated
assert adapted.language == "italian"

v0.3에서 v0.4로 마이그레이션

Step 1: PromptMixin 상속 제거

# v0.3
from ragas.prompt.mixin import PromptMixin
from ragas.metrics import Faithfulness

class MyMetric(Faithfulness, PromptMixin):  # ← Remove PromptMixin
    pass

# v0.4
from ragas.metrics.collections import Faithfulness

# No mixin needed - just use the metric directly
metric = Faithfulness(llm=llm)

Step 2: adapt_prompts()를 adapt()로 교체

# v0.3
adapted_prompts = await metric.adapt_prompts(
    language="spanish",
    llm=llm,
    adapt_instruction=True
)
metric.set_prompts(**adapted_prompts)

# v0.4
adapted_prompt = await metric.prompt.adapt(
    target_language="spanish",
    llm=llm,
    adapt_instruction=True
)
metric.prompt = adapted_prompt

완전한 마이그레이션 예제

Before (v0.3):

from ragas.prompt.mixin import PromptMixin
from ragas.metrics import Faithfulness, AnswerRelevancy

class MyMetrics(Faithfulness, AnswerRelevancy, PromptMixin):
    pass

# Setup
metrics = MyMetrics(llm=llm)

# Adapt multiple metrics to Spanish
adapted = await metrics.adapt_prompts(
    language="spanish",
    llm=best_llm,
    adapt_instruction=True
)

metrics.set_prompts(**adapted)
metrics.save_prompts("./spanish_prompts")

After (v0.4):

from ragas.metrics.collections import Faithfulness, AnswerRelevancy

# Setup individual metrics
faith_metric = Faithfulness(llm=llm)
answer_metric = AnswerRelevancy(llm=llm)

# Adapt each metric's prompt independently
faith_adapted = await faith_metric.prompt.adapt(
    target_language="spanish",
    llm=best_llm,
    adapt_instruction=True
)
faith_metric.prompt = faith_adapted

answer_adapted = await answer_metric.prompt.adapt(
    target_language="spanish",
    llm=best_llm,
    adapt_instruction=True
)
answer_metric.prompt = answer_adapted

# Use metrics with adapted prompts
faith_result = await faith_metric.ascore(...)
answer_result = await answer_metric.ascore(...)

데이터 스키마 변경

SingleTurnSample 업데이트

SingleTurnSample 스키마에 브레이킹 체인지가 적용됐어요.

ground_truthsreference

ground_truths 파라미터가 전반적으로 reference로 이름이 바뀌었어요.

Before (v0.3):

sample = SingleTurnSample(
    user_input="...",
    response="...",
    ground_truths=["correct answer"]  # List of strings
)

After (v0.4):

sample = SingleTurnSample(
    user_input="...",
    response="...",
    reference="correct answer"  # Single string
)
  • v0.3은 ground_truths리스트로 사용
  • v0.4는 reference단일 문자열로 사용
  • 여러 참조가 필요하면 별도의 평가 실행을 사용

업데이트된 스키마

from ragas import SingleTurnSample

# v0.4 complete sample
sample = SingleTurnSample(
    user_input="What is AI?",                      # Required
    response="AI is artificial intelligence.",     # Required
    retrieved_contexts=["Context 1", "Context 2"], # Optional
    reference="Correct definition of AI"           # Optional (was ground_truths)
)

EvaluationDataset 업데이트

EvaluationDataset를 사용 중이라면 데이터 로딩을 업데이트해요.

Before (v0.3):

dataset = EvaluationDataset(
    samples=[
        SingleTurnSample(
            user_input="Q1",
            response="A1",
            ground_truths=["correct"]
        )
    ]
)

After (v0.4):

dataset = EvaluationDataset(
    samples=[
        SingleTurnSample(
            user_input="Q1",
            response="A1",
            reference="correct"
        )
    ]
)

CSV/JSON에서 로드한다면 데이터 파일을 업데이트해요.

Before (v0.3) CSV 형식:

user_input,response,retrieved_contexts,ground_truths
"Q1","A1","[""ctx1""]","[""correct""]"

After (v0.4) CSV 형식:

user_input,response,retrieved_contexts,reference
"Q1","A1","[""ctx1""]","correct"

커스텀 지표

컬렉션 기반 아키텍처를 사용하는 지표의 경우

이미 컬렉션의 BaseMetric을 상속하는 커스텀 지표를 작성했다면 최소한의 변경만 필요해요.

from ragas.metrics.collections.base import BaseMetric, MetricResult
from pydantic import BaseModel

class MyCustomMetric(BaseMetric):
    name: str = "my_metric"
    dimensions: list[str] = ["my_dimension"]

    async def ascore(self, **kwargs) -> MetricResult:
        # Your metric logic
        score = 0.85
        reason = "Explanation of the score"
        return MetricResult(value=score, reason=reason)

핵심 고려 사항:

  • 기존 MetricWithLLM이 아니라 BaseMetric을 상속
  • single_turn_ascore(sample) 대신 async def ascore(**kwargs) 구현
  • 원시 float가 아니라 MetricResult 객체 반환
  • SingleTurnSample 대신 키워드 인자 사용

레거시 아키텍처를 사용하는 지표의 경우

SingleTurnMetric 또는 MetricWithLLM을 상속하는 커스텀 지표가 있다면:

# v0.3 - Legacy approach
from ragas.metrics.base import MetricWithLLM

class MyMetric(MetricWithLLM):
    async def single_turn_ascore(self, sample: SingleTurnSample) -> float:
        # Extract values from sample
        user_input = sample.user_input
        response = sample.response
        contexts = sample.retrieved_contexts or []

        # Your logic
        return 0.85

마이그레이션 경로:

  1. 대신 collections의 BaseMetric을 상속
  2. 메서드 시그니처를 키워드 인자를 쓰도록 변경
  3. float 대신 MetricResult 반환
  4. 없으면 dimensions 프로퍼티 추가
# v0.4 - Collections approach
from ragas.metrics.collections.base import BaseMetric, MetricResult

class MyMetric(BaseMetric):
    name: str = "my_metric"
    dimensions: list[str] = ["quality"]

    async def ascore(self,
                    user_input: str,
                    response: str,
                    retrieved_contexts: list[str] | None = None,
                    **kwargs) -> MetricResult:
        # Use keyword arguments directly
        contexts = retrieved_contexts or []

        # Your logic
        score = 0.85
        return MetricResult(value=score, reason="Optional explanation")

프롬프트 시스템 업데이트

v0.3 - Dataclass 기반 프롬프트

from ragas.prompt.pydantic_prompt import PydanticPrompt
from pydantic import BaseModel

class Input(BaseModel):
    query: str
    document: str

class Output(BaseModel):
    is_relevant: bool

class RelevancePrompt(PydanticPrompt[Input, Output]):
    instruction = "Is the document relevant to the query?"
    input_model = Input
    output_model = Output
    examples = [...]

v0.4 - 함수 기반 프롬프트

새 접근 방식은 단순한 함수를 사용해요.

def relevance_prompt(query: str, document: str) -> str:
    return f"""Determine if the document is relevant to the query.

Query: {query}
Document: {document}

Respond with YES or NO."""

장점:

  • 더 단순하고 조합하기 쉬움
  • 보일러플레이트 클래스 정의 없음
  • 테스트·수정이 쉬움
  • 네이티브 Python 타입 힌트

마이그레이션:

  • 커스텀 지표에서 프롬프트를 정의하는 위치를 찾기
  • dataclass 정의를 함수로 변환
  • 지표가 함수를 직접 사용하도록 업데이트

제거된 기능

다음 기능들은 v0.4에서 완전히 제거되어, 사용하면 오류가 발생해요.

함수

instructor_llm_factory() - 완전히 제거됨

  • 병합됨: llm_factory() 함수로
  • 마이그레이션: instructor_llm_factory() 호출을 모두 llm_factory()로 교체
  • 영향: 직접적인 브레이킹 체인지, 폴백 없음

Before (v0.3) - 더 이상 동작하지 않음:

llm = instructor_llm_factory("openai", model="gpt-4o", client=client)

After (v0.4) - 이것을 대신 사용:

llm = llm_factory("gpt-4o", client=client)

지표

세 개의 지표가 collections API에서 완전히 제거됐어요. 더 이상 사용할 수 없고 직접적인 대체도 없어요.

1. AspectCritic - 제거됨

  • 이유: 더 유연한 이산(discrete) 지표 패턴으로 대체
  • 대안: 커스텀 측면 평가에 @discrete_metric() 데코레이터 사용
  • 사용법:
# Instead of AspectCritic, use:
from ragas.metrics import discrete_metric

@discrete_metric(name="aspect_critic", allowed_values=["positive", "negative", "neutral"])
def evaluate_aspect(response: str, aspect: str) -> str:
    # Your evaluation logic
    return "positive"

2. SimpleCriteria - 제거됨

  • 이유: 더 유연한 이산 지표 패턴으로 대체
  • 대안: 커스텀 기준에 @discrete_metric() 데코레이터 사용
  • 사용법:
from ragas.metrics import discrete_metric

@discrete_metric(name="custom_criteria", allowed_values=["pass", "fail"])
def evaluate_criteria(response: str, criteria: str) -> str:
    return "pass" if criteria in response else "fail"

3. AnswerSimilarity - 제거됨 (불필요)

  • 이유: 기능이 SemanticSimilarity에 완전히 포함
  • 직접 대체: SemanticSimilarity
  • 사용법:
# v0.3 - No longer available
from ragas.metrics import AnswerSimilarity  # ERROR

# v0.4 - Use this instead
from ragas.metrics.collections import SemanticSimilarity
metric = SemanticSimilarity(llm=llm)
result = await metric.ascore(
    reference="Expected answer",
    response="Actual answer"
)

Deprecated 메서드 (v0.4에서 제거)

Metric.ascore()Metric.score() - 제거됨

  • 제거 시점: v0.3에서 제거 예정 표시, v0.4에서 제거
  • 이유: 컬렉션 기반 ascore(**kwargs) 패턴으로 대체
  • 마이그레이션: 컬렉션 지표 사용

레거시 샘플 기반 메서드 - 제거됨

  • single_turn_ascore(sample: SingleTurnSample) - 레거시 지표에만 존재
  • 대체: ascore(**kwargs)를 쓰는 컬렉션 지표

Deprecated 기능

이 기능들은 여전히 동작하지만 deprecation 경고를 보여줘요. 향후 릴리스에서 제거될 거예요.

evaluate() 함수 - Deprecated

  • 상태: 여전히 동작하지만 권장되지 않음
  • 이유: 더 구조화된 워크플로를 위해 @experiment() 데코레이터로 대체
  • 마이그레이션: Evaluation to Experiment 섹션 참조

Before (v0.3) - Deprecated:

from ragas import evaluate

result = evaluate(dataset=dataset, metrics=metrics, llm=llm, embeddings=embeddings)

After (v0.4) - 권장:

from ragas import experiment
from pydantic import BaseModel

class Results(BaseModel):
    score: float

@experiment(Results)
async def run(row):
    result = await metric.ascore(**row.dict())
    return Results(score=result.value)

result = await run(dataset)

LLM 래퍼 클래스

LangchainLLMWrapper - Deprecated

  • 상태: 여전히 동작하지만 권장되지 않음
  • Deprecation 경고: Direct usage of LangChain LLMs with Ragas prompts is deprecated and will be removed in a future version. Use Ragas LLM interfaces instead
  • 마이그레이션: 네이티브 클라이언트로 llm_factory() 사용

Before (v0.3) - Deprecated:

from ragas.llms import LangchainLLMWrapper
from langchain_openai import ChatOpenAI

langchain_llm = ChatOpenAI(model="gpt-4o")
ragas_llm = LangchainLLMWrapper(langchain_llm)

After (v0.4) - 권장:

from ragas.llms import llm_factory
from openai import AsyncOpenAI

client = AsyncOpenAI(api_key="...")
ragas_llm = llm_factory("gpt-4o", client=client)

LlamaIndexLLMWrapper - Deprecated

  • 상태: 여전히 동작하지만 권장되지 않음
  • 경고: LangchainLLMWrapper와 유사
  • 마이그레이션: 네이티브 클라이언트로 llm_factory() 사용

Before (v0.3) - Deprecated:

from ragas.llms import LlamaIndexLLMWrapper
from llama_index.llms.openai import OpenAI

llamaindex_llm = OpenAI(model="gpt-4o")
ragas_llm = LlamaIndexLLMWrapper(llamaindex_llm)

After (v0.4) - 권장:

from ragas.llms import llm_factory
from openai import AsyncOpenAI

client = AsyncOpenAI(api_key="...")
ragas_llm = llm_factory("gpt-4o", client=client)

임베딩 마이그레이션

LangchainEmbeddingsWrapper & LlamaIndexEmbeddingsWrapper - Deprecated

  • 상태: 여전히 동작하지만 deprecation 경고 표시
  • 이유: 클라이언트 라이브러리와 직접 통합하는 네이티브 임베딩 공급자로 대체
  • 마이그레이션: Embeddings Migration 섹션 참조

v0.4는 래퍼 클래스를 LangChain 래퍼 대신 클라이언트 라이브러리와 직접 통합하는 네이티브 임베딩 공급자로 대체해요.

무엇이 바뀌었나

Aspect v0.3 v0.4
Class LangchainEmbeddingsWrapper, LlamaIndexEmbeddingsWrapper OpenAIEmbeddings, GoogleEmbeddings, HuggingFaceEmbeddings
Client LangChain/LlamaIndex wrapper Native client (OpenAI, Google, etc.)
Methods embed_query(), embed_documents() embed_text(), embed_texts()
Setup Wrap existing LangChain object Pass native client directly

OpenAI 마이그레이션

Before (v0.3):

from langchain_openai import OpenAIEmbeddings as LangChainEmbeddings
from ragas.embeddings import LangchainEmbeddingsWrapper

embeddings = LangchainEmbeddingsWrapper(
    LangChainEmbeddings(api_key="sk-...")
)
embedding = embeddings.embed_query("text")

After (v0.4):

from openai import AsyncOpenAI
from ragas.embeddings import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(
    client=AsyncOpenAI(api_key="sk-..."),
    model="text-embedding-3-small"
)
embedding = embeddings.embed_text("text")  # Different method name

Google 임베딩 마이그레이션

Before (v0.3):

from langchain_community.embeddings import VertexAIEmbeddings
from ragas.embeddings import LangchainEmbeddingsWrapper

embeddings = LangchainEmbeddingsWrapper(
    VertexAIEmbeddings(model_name="textembedding-gecko@001", project="my-project")
)

After (v0.4):

from ragas.embeddings import GoogleEmbeddings

embeddings = GoogleEmbeddings(
    model="text-embedding-004",
    use_vertex=True,
    project_id="my-project"
)

HuggingFace 마이그레이션

Before (v0.3):

from ragas.embeddings import HuggingfaceEmbeddings

embeddings = HuggingfaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")

After (v0.4):

from ragas.embeddings import HuggingFaceEmbeddings  # Capitalization changed

embeddings = HuggingFaceEmbeddings(
    model="sentence-transformers/all-MiniLM-L6-v2",
    device="cuda"  # Optional GPU acceleration
)

embedding_factory() 사용하기

Before (v0.3):

from ragas.embeddings import embedding_factory

embeddings = embedding_factory()  # Defaults to OpenAI

After (v0.4):

from ragas.embeddings import embedding_factory
from openai import AsyncOpenAI

embeddings = embedding_factory(
    provider="openai",
    model="text-embedding-3-small",
    client=AsyncOpenAI(api_key="sk-...")
)

프롬프트 시스템

Dataclass 기반 프롬프트 (PydanticPrompt) - Deprecated

  • 상태: 레거시 프롬프트가 여전히 동작하지만 권장되지 않음
  • Deprecation: 모듈형 BasePrompt 아키텍처를 선호
  • 마이그레이션: Prompt System Migration 섹션 참조

Before (v0.3) - Deprecated 방식:

from ragas.prompt.pydantic_prompt import PydanticPrompt
from pydantic import BaseModel

class Input(BaseModel):
    query: str

class Output(BaseModel):
    is_relevant: bool

class RelevancePrompt(PydanticPrompt[Input, Output]):
    instruction = "Is this relevant?"
    input_model = Input
    output_model = Output

After (v0.4) - 권장 방식:

# Use BasePrompt classes instead - see Prompt System Migration section
from ragas.metrics.collections.faithfulness.util import FaithfulnessPrompt

class CustomPrompt(FaithfulnessPrompt):
    @property
    def instruction(self):
        return "Your custom instruction here"

레거시 지표 메서드

single_turn_ascore(sample) - Deprecated

  • 상태: 레거시(비-컬렉션) 지표에만 존재
  • Deprecation: ascore()를 쓰는 컬렉션 지표 사용
  • 타임라인: 모든 지표가 마이그레이션되면 향후 릴리스에서 제거될 예정

Before (v0.3) - Deprecated:

sample = SingleTurnSample(user_input="...", response="...", ...)
score = await metric.single_turn_ascore(sample)

After (v0.4) - 권장:

result = await metric.ascore(user_input="...", response="...")
score = result.value

ContextUtilization

ContextUtilization은 이제 하위 호환성을 위해 ContextPrecisionWithoutReference의 래퍼예요.

Before (v0.3):

from ragas.metrics import ContextUtilization
metric = ContextUtilization(llm=llm)
score = await metric.single_turn_ascore(sample)

After (v0.4):

from ragas.metrics.collections import ContextUtilization
# or use the modern name directly:
from ragas.metrics.collections import ContextPrecisionWithoutReference

metric = ContextUtilization(llm=llm)  # Still works (wrapper)
# or
metric = ContextPrecisionWithoutReference(llm=llm)  # Preferred

result = await metric.ascore(
    user_input="...",
    response="...",
    retrieved_contexts=[...]
)
score = result.value

브레이킹 체인지 요약

v0.3과 v0.4 사이의 브레이킹 체인지 전체 목록이에요.

Change v0.3 v0.4 Migration
Evaluation approach evaluate() function @experiment() decorator See Evaluation to Experiment
Metrics location ragas.metrics ragas.metrics.collections Update import paths
Scoring method single_turn_ascore(sample) ascore(**kwargs) Change method calls
Score return type float MetricResult Use .value property
LLM factory instructor_llm_factory() llm_factory() Use unified factory
Embeddings approach Wrapper classes (LangChain) Native providers See Embeddings Migration
Embedding methods embed_query(), embed_documents() embed_text(), embed_texts() Update method calls
ground_truths param ground_truths: list[str] reference: str Rename, change type
Sample type SingleTurnSample SingleTurnSample (updated) Update sample creation
Prompt system Dataclass-based Function-based Refactor custom prompts

Deprecation과 제거

v0.4에서 제거됨

이 기능들은 완전히 제거되어 오류를 발생시켜요.

  • instructor_llm_factory() - llm_factory() 사용
  • collections의 AspectCritic - 직접 대체 없음
  • collections의 SimpleCriteriaScore - 직접 대체 없음
  • AnswerSimilarity - SemanticSimilarity 사용

Deprecated (향후 릴리스에서 제거 예정)

이 기능들은 여전히 동작하지만 deprecation 경고를 보여줘요.

  • LangchainLLMWrapper - llm_factory() 직접 사용
  • LlamaIndexLLMWrapper - llm_factory() 직접 사용
  • 레거시 프롬프트 클래스 - 함수 기반 프롬프트로 마이그레이션
  • 레거시 지표의 single_turn_ascore() - ascore()를 쓰는 컬렉션 지표 사용

v0.4의 새 기능 (참고)

v0.4는 마이그레이션 요구 사항 외에도 여러 새로운 기능을 도입해요. v0.3에서 마이그레이션하는 데 꼭 필요한 건 아니지만, 업그레이드에 유용할 수 있어요.

  • GPT-5 및 o-Series 지원 - 최신 OpenAI 모델에 대한 자동 제약 처리
  • 범용 공급자 지원 (Universal Provider Support) - 단일 llm_factory()가 모든 주요 공급자(Anthropic, Google, Azure 등)와 동작
  • 함수 기반 프롬프트 (Function-Based Prompts) - 더 유연하고 조합 가능한 프롬프트 정의
  • 지표 데코레이터 (Metric Decorators) - @discrete_metric, @numeric_metric, @ranking_metric으로 단순해진 커스텀 지표 생성
  • 추론이 있는 MetricResult (MetricResult with Reasoning) - 선택적 설명이 포함된 구조화된 결과
  • 향상된 지표 저장/로드 (Enhanced Metric Save/Load) - 지표 설정의 쉬운 직렬화
  • 더 나은 임베딩 지원 (Better Embeddings Support) - 동기·비동기 임베딩 작업 모두 지원

새 기능에 대한 자세한 내용은 v0.4 릴리스 노트를 참조하세요.

커스텀 지표 마이그레이션

AspectCriticSimpleCriteria 같은 제거된 지표를 사용했다면, v0.4는 대체할 데코레이터 기반 대안을 제공해요. 다른 커스텀 지표에도 새로 단순해진 지표 시스템을 사용할 수 있어요.

이산 지표 (Discrete Metrics, 범주형 출력)

Before (v0.3) - AspectCritic:

from ragas.metrics import AspectCritic
metric = AspectCritic(name="clarity", allowed_values=["clear", "unclear"])
result = await metric.single_turn_ascore(sample)

After (v0.4) - @discrete_metric 데코레이터:

from ragas.metrics import discrete_metric

@discrete_metric(name="clarity", allowed_values=["clear", "unclear"])
def clarity(response: str) -> str:
    return "clear" if len(response) > 50 else "unclear"

metric = clarity()
result = await metric.ascore(response="...")
print(result.value)  # "clear" or "unclear"

어떤 범주형 분류든 이산 지표를 사용해요. 제거된 모든 지표(AspectCritic, SimpleCriteria)를 이렇게 대체할 수 있어요.

수치 지표 (Numeric Metrics, 연속 값)

수치 척도의 점수 매기기에는 @numeric_metric을 사용해요.

from ragas.metrics import numeric_metric

@numeric_metric(name="length_score", allowed_values=(0.0, 1.0))
def length_score(response: str) -> float:
    return min(len(response) / 500, 1.0)

# Custom range
@numeric_metric(name="quality_score", allowed_values=(0.0, 10.0))
def quality_score(response: str) -> float:
    return 7.5

metric = length_score()
result = await metric.ascore(response="...")
print(result.value)  # float between 0 and 1

랭킹 지표 (Ranking Metrics, 순서 있는 목록)

여러 항목을 순위화하거나 정렬할 때는 @ranking_metric을 사용해요.

from ragas.metrics import ranking_metric

@ranking_metric(name="context_rank", allowed_values=5)
def context_ranking(question: str, contexts: list[str]) -> list[str]:
    """Rank contexts by relevance."""
    scored = [(len(set(question.split()) & set(c.split())), c) for c in contexts]
    return [c for _, c in sorted(scored, reverse=True)]

metric = context_ranking()
result = await metric.ascore(question="...", contexts=[...])
print(result.value)  # Ranked list

요약

이 데코레이터들은 자동 검증, 타입 안전성, 오류 처리, 결과 래핑을 제공해요. 커스텀 지표 코드를 v0.3의 50줄 이상에서 v0.4의 5-10줄로 줄여 줘요.

흔한 문제와 해결책

문제: instructor_llm_factory의 ImportError

오류:

ImportError: cannot import name 'instructor_llm_factory' from 'ragas.llms'

해결책:

# Instead of this
from ragas.llms import instructor_llm_factory

# Use this
from ragas.llms import llm_factory

문제: 지표가 float 대신 MetricResult 반환

오류:

score = await metric.ascore(...)
print(score)  # Prints: MetricResult(value=0.85, reason=None)

해결책:

result = await metric.ascore(...)
score = result.value  # Access the float value
print(score)  # Prints: 0.85

문제: SingleTurnSampleground_truths가 없음

오류:

TypeError: ground_truths is not a valid keyword

해결책:

# Change from
sample = SingleTurnSample(..., ground_truths=["correct"])

# To
sample = SingleTurnSample(..., reference="correct")

도움 받기

마이그레이션 중 문제가 생기면:

  1. 문서 확인하기

Metrics Documentation Collections API LLM Configuration

  1. GitHub 이슈

기존 이슈 검색 마이그레이션 관련 세부 내용으로 새 이슈 생성

  1. 커뮤니티 지원

우리 Discord 커뮤니티에 참여 메인테이너와 일정 잡기

요약

v0.4는 평가·분석·반복 워크플로의 더 나은 통합을 가능하게 하는 실험 기반 아키텍처로의 근본적인 전환이에요. 브레이킹 체인지가 있지만, 모두 Ragas를 더 나은 실험 플랫폼으로 만드는 목표를 위한 것이에요.

마이그레이션 경로는 간단해요.

  1. LLM 초기화를 llm_factory() 사용으로 업데이트
  2. 지표를 ragas.metrics.collections에서 import
  3. single_turn_ascore()ascore()로 교체
  4. ground_truthsreference로 이름 변경
  5. float 대신 MetricResult 객체 처리

이 기술적 변경들은 다음을 가능하게 해요.

  • 더 나은 실험 (Better Experimentation) - 더 깊은 분석을 위한 추론이 있는 구조화된 지표 결과
  • 더 깔끔한 API (Cleaner API) - 샘플 객체 대신 키워드 인자를 써서 구성이 쉬워짐
  • 통합된 워크플로 (Integrated Workflows) - 실험 파이프라인 안에서 매끄럽게 동작하도록 설계된 지표
  • 향상된 기능 (Enhanced Functionality) - 범용 공급자 지원과 자동 제약
  • 미래 지향 (Future-proof) - 산업 표준(시간제한 라이브러리, 표준화된 패턴) 기반 구축

실험 기반 아키텍처는 향후 릴리스에서도 계속 개선될 거예요. 평가를 관리·분석·반복하는 더 많은 기능이 추가될 예정이에요.

마이그레이션 행운을 빌어요! 막히면 도와드릴게요. 🎉

더 알아보기 (Learn more)