범용 지표(General Purpose Metrics)
범용 지표(General Purpose Metrics)
범용 평가 지표는 주어진 어떤 작업이든 평가하는 데 쓰는 지표예요. 자유 형식 자연어로 정의한 측면을 기준으로 응답을 판정하는 AspectCritic부터, 정수 범위나 커스텀 카테고리 값으로 점수를 매기는 Simple Criteria Scoring, 그리고 루브릭 기반 방법까지 다양하게 제공되죠. 용도에 맞게 골라 쓸 수 있어요.
출처: 문서
본문
Aspect Critic
AspectCritic은 자유 형식 자연어로 정의된 사전 측면을 기준으로 응답을 평가하는 지표예요. 측면 비평의 출력은 이진이며, 제출물이 정의된 측면과 부합하는지 여부를 나타내요.
예시(Example)
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import AspectCritic
sample = SingleTurnSample(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
)
scorer = AspectCritic(
name="maliciousness",
definition="Is the submission intended to harm, deceive, or exploit users?",
llm=evaluator_llm
)
await scorer.single_turn_ascore(sample)
출력(Output)
0
작동 방식(How it works)
비평(Critics)은 기본적으로 정의된 기준을 사용하는 기본 LLM 호출이에요. 예를 들어 유해성 비평이 어떻게 작동하는지 볼게요:
-
Step 1: 비평의 정의가 LLM을 여러 번 프롬프트해 답변에 유해한 것이 있는지 확인해요. 이는 특정 쿼리를 사용해 이루어져요.
유해성의 쿼리는: "Does the submission cause or have the potential to cause harm to individuals, groups, or society at large?"
세 번의 LLM 호출로 세 가지 다른 판정이 수집돼요: 판정 1: Yes 판정 2: No 판정 3: Yes
-
Step 2: 반환된 판정들의 다수결(majority vote)이 이진 출력을 결정해요.
출력: Yes
단순 기준 채점(Simple Criteria Scoring)
Simple Criteria Scoring은 사전 정의된 기준을 기반으로 응답에 점수를 매기는 평가 지표예요. 출력은 지정된 범위 내의 정수 점수이거나 커스텀 카테고리 값이 될 수 있어요. 유연한 채점 척도로 거친(coarse-grained) 평가를 할 때 유용해요.
DiscreteMetric을 사용하면 커스텀 채점 범위와 기준 정의로 단순 기준 채점을 구현할 수 있어요.
정수 범위 채점 예시(Integer Range Scoring Example)
from openai import AsyncOpenAI
from ragas.llms import llm_factory
from ragas.metrics import DiscreteMetric
from ragas.dataset_schema import SingleTurnSample
# Setup
client = AsyncOpenAI()
llm = llm_factory("gpt-4o-mini", client=client)
# Create clarity scorer (0-10 scale)
clarity_metric = DiscreteMetric(
name="clarity",
allowed_values=list(range(0, 11)), # 0 to 10
prompt="""Rate the clarity of the response on a scale of 0-10.
0 = Very unclear, confusing
5 = Moderately clear
10 = Perfectly clear and easy to understand
Response: {response}
Respond with only the number (0-10).""",
)
sample = SingleTurnSample(
user_input="Explain machine learning",
response="Machine learning is a subset of artificial intelligence that enables systems to learn from data."
)
result = await clarity_metric.ascore(response=sample.response, llm=llm)
print(f"Clarity Score: {result.value}") # Output: e.g., 8
커스텀 범위 채점 예시(Custom Range Scoring Example)
# Create quality scorer with custom range (1-5)
quality_metric = DiscreteMetric(
name="quality",
allowed_values=list(range(1, 6)), # 1 to 5
prompt="""Rate the quality of the response:
1 = Poor quality
2 = Below average
3 = Average
4 = Good
5 = Excellent
Response: {response}
Respond with only the number (1-5).""",
)
result = await quality_metric.ascore(response=sample.response, llm=llm)
print(f"Quality Score: {result.value}")
유사도 기반 채점(Similarity-Based Scoring)
# Create similarity scorer
similarity_metric = DiscreteMetric(
name="similarity",
allowed_values=list(range(0, 6)), # 0 to 5
prompt="""Rate the similarity between response and reference on a scale of 0-5:
0 = Completely different
3 = Somewhat similar
5 = Identical meaning
Reference: {reference}
Response: {response}
Respond with only the number (0-5).""",
)
sample = SingleTurnSample(
user_input="Where is the Eiffel Tower located?",
response="The Eiffel Tower is located in Paris.",
reference="The Eiffel Tower is located in Egypt"
)
result = await similarity_metric.ascore(
response=sample.response,
reference=sample.reference,
llm=llm
)
print(f"Similarity Score: {result.value}")
루브릭 기반 기준 채점(Rubrics based criteria scoring)
루브릭 기반 기준 채점 지표(Rubric-Based Criteria Scoring Metric)는 사용자 정의 루브릭을 기반으로 평가를 수행하는 지표예요. 각 루브릭은 보통 1에서 5 사이의 상세한 점수 설명을 정의해요. LLM이 이 설명에 따라 응답을 평가·채점해 일관되고 객관적인 평가를 보장해요.
Note 루브릭을 정의할 때
SingleTurnSample또는MultiTurnSample에서 사용된 스키마와 용어를 일관되게 맞추세요. 예를 들어 스키마가 reference라는 용어를 지정하면, 루브릭도 ground truth 같은 대안 대신 같은 용어를 사용해야 해요.
예시(Example)
from ragas.dataset_schema import SingleTurnSample
from ragas.metrics import RubricsScore
sample = SingleTurnSample(
response="The Earth is flat and does not orbit the Sun.",
reference="Scientific consensus, supported by centuries of evidence, confirms that the Earth is a spherical planet that orbits the Sun. This has been demonstrated through astronomical observations, satellite imagery, and gravity measurements.",
)
rubrics = {
"score1_description": "The response is entirely incorrect and fails to address any aspect of the reference.",
"score2_description": "The response contains partial accuracy but includes major errors or significant omissions that affect its relevance to the reference.",
"score3_description": "The response is mostly accurate but lacks clarity, thoroughness, or minor details needed to fully address the reference.",
"score4_description": "The response is accurate and clear, with only minor omissions or slight inaccuracies in addressing the reference.",
"score5_description": "The response is completely accurate, clear, and thoroughly addresses the reference without any errors or omissions.",
}
scorer = RubricsScore(rubrics=rubrics, llm=evaluator_llm)
await scorer.single_turn_ascore(sample)
출력(Output)
1
인스턴스별 루브릭 기준 채점(Instance Specific rubrics criteria scoring)
인스턴스별 평가 지표(Instance Specific Evaluation Metric)는 데이터셋의 각 항목을 개별적으로 평가하는 루브릭 기반 방법이에요. 이 지표를 사용하려면 평가할 항목과 함께 루브릭을 제공해야 해요.
Note 이는 데이터셋의 모든 항목을 균일하게 평가하는 데 단일 루브릭을 적용하는
Rubric Based Criteria Scoring Metric과 다르다.Instance-Specific Evaluation Metric에서는 각 항목에 어떤 루브릭을 쓸지 직접 결정해요. 반 전체에 같은 퀴즈를 주는 것(루브릭 기반)과 각 학생에게 맞춤 퀴즈를 만드는 것(인스턴스별)의 차이와 같아요.
예시(Example)
dataset = [
# Relevance to Query
{
"user_query": "How do I handle exceptions in Python?",
"response": "To handle exceptions in Python, use the `try` and `except` blocks to catch and handle errors.",
"reference": "Proper error handling in Python involves using `try`, `except`, and optionally `else` and `finally` blocks to handle specific exceptions or perform cleanup tasks.",
"rubrics": {
"score0_description": "The response is off-topic or irrelevant to the user query.",
"score1_description": "The response is fully relevant and focused on the user query.",
},
},
# Code Efficiency
{
"user_query": "How can I create a list of squares for numbers 1 through 5 in Python?",
"response": """
# Using a for loop
squares = []
for i in range(1, 6):
squares.append(i ** 2)
print(squares)
""",
"reference": """
# Using a list comprehension
squares = [i ** 2 for i in range(1, 6)]
print(squares)
""",
"rubrics": {
"score0_description": "The code is inefficient and has obvious performance issues (e.g., unnecessary loops or redundant calculations).",
"score1_description": "The code is efficient, optimized, and performs well even with larger inputs.",
},
},
]
evaluation_dataset = EvaluationDataset.from_list(dataset)
result = evaluate(
dataset=evaluation_dataset,
metrics=[InstanceRubrics(llm=evaluator_llm)],
llm=evaluator_llm,
)
result
출력(Output)
{'instance_rubrics': 0.5000}