표준 품질 메트릭
표준 품질 메트릭 (Standard Quality Metrics)
이 페이지는 널리 쓰이는 LLM 평가 방법을 Pydantic Evals 기본 요소로 표현하는 방법을 보여줘요:
GEval-- G-Eval chain-of-thought 채점을 구현하는 일급 평가자 (Liu et al., 2023).- Ragas로 대중화된 RAG 메트릭(faithfulness, answer relevance, context precision, context recall)과 GEMBA 번역 품질(Kocmi & Federmann, 2023)을 위한 바로 쓸 수 있는
LLMJudge루브릭.
RAG와 GEMBA 메트릭은 평가자 클래스가 아니라 _루브릭 레시피_로 제공돼요. 각각은 LLMJudge에 루브릭 하나만 더하면 되는 형태이고, 여러분이 소유한 루브릭은 데이터셋 구조와 도메인에 맞게 자유롭게 적응시킬 수 있어요 -- 라이브러리 릴리스를 기다리지 않고 필드를 이름 바꾸고, 기준을 강화하고, 지시사항을 번역하면 되죠. 프로젝트에 복사해서 필요에 따라 편집해요.
루브릭 근사치이지 상위 구현이 아니에요
이 루브릭들은 각 메트릭을 단일 LLM-judge 호출로 근사해요. 상위 알고리즘을 재현하지는 않아요 (예: Ragas의 answer_relevancy는 답변에서 질문을 생성하고 임베딩을 비교해요). 게시된 수치와의 동등성이 필요하다면 타사 통합에서 보여주는 대로 실제 라이브러리를 감싸요.
출처: 문서
본문
G-Eval
GEval은 chain-of-thought 평가를 구현해요. 평가할 측면(criteria)과 명시적 evaluation_steps 목록을 제공하면, 판단자가 추론 트레이스와 함께 score_range(양끝 포함) 안의 정수 점수를 반환해요. 기준과 단계는 사용자가 제공하므로 GEval은 입력에 구조적 요구사항을 두지 않으며, 직렬화된 데이터셋에서도 바로 동작해요.
from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import GEval
dataset = Dataset(
name='g_eval_demo',
cases=[Case(inputs='Explain how black holes form.')],
evaluators=[
GEval(
criteria='coherence',
evaluation_steps=[
'Read the output carefully.',
'Check that each sentence follows logically from the previous one.',
'Assign a score from 1 (incoherent) to 5 (fully coherent).',
],
include_input=True,
),
],
)
결과는 원시 정수 점수를 값으로 가진 EvaluationReason이에요. LLMJudge 점수처럼 0.0-1.0으로 정규화되지 않고, score_range로 선택한 척도 그대로예요. 판단자가 score_range 밖의 점수를 반환하면 오해를 불러일으키는 값을 기록하는 대신 평가가 실패해요. 판단자가 텍스트를 생성할 수 없을 때 GEval은 같은 척도의 최대 20개 수준 정수 루브릭을 사용하고 추론 트레이스 대신 reason=None을 반환해요.
단순화된 G-Eval
게시된 G-Eval 방법은 판단자 모델의 log-prob를 사용해 점수 토큰에 대한 확률 가중 기대치를 계산해요. Pydantic Evals는 대신 모델에 직접 정수 점수를 요청해서, 사람 판단과의 상관관계를 약간 희생하는 대신 제공자에 구애받지 않는 단순함을 얻어요. Liu et al., 2023, "G-Eval: NLG Evaluation using GPT-4 with Better Human Alignment"를 참고해요.
RAG 메트릭 루브릭
이 레시피들은 각 케이스의 inputs가 사용자 질문과 출력이 의존해야 하는 컨텍스트 구절을 담고 있다고 가정해요 -- 제공된 컨텍스트지, 에이전트가 실행 중에 검색한 것이 아니에요. include_input=True로 LLMJudge는 판단자에게 전체 입력 객체를 보여주므로, 루브릭이 그것을 설명하기만 하면 어떤 입력 구조든 동작해요. 필드 이름이 다르면 표현을 조정해요.
from dataclasses import dataclass
from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import LLMJudge
faithfulness = LLMJudge(
rubric=(
'Every factual claim in the Output must be directly supported by the context passages '
'in the Input. Unsupported claims, contradictions, and fabrications constitute failure; '
'ignore claims that are true in the real world but absent from the provided context. '
'The score is the fraction of claims that are supported (0.0 = none, 1.0 = all); '
'pass only if every claim is supported.'
),
include_input=True,
score={'evaluation_name': 'faithfulness'},
assertion=False,
)
answer_relevance = LLMJudge(
rubric=(
'Judge whether the Output directly and completely answers the question in the Input, '
'without padding or unrelated tangents. '
'The score reflects how directly the Output addresses the question '
'(0.0 = unrelated, 1.0 = a direct, on-point answer).'
),
include_input=True,
score={'evaluation_name': 'answer_relevance'},
assertion=False,
)
context_precision = LLMJudge(
rubric=(
'This metric judges the retrieval, not the answer: assess the context passages in the '
'Input against the question in the Input, and disregard the Output. '
'The score is the fraction of the context that is relevant to answering the question '
'(0.0 = none is relevant, 1.0 = all of it is relevant).'
),
include_input=True,
score={'evaluation_name': 'context_precision'},
assertion=False,
)
context_recall = LLMJudge(
rubric=(
'This metric judges the retrieval, not the answer: determine whether the context '
'passages in the Input contain enough information to produce the ground-truth answer '
'in the Expected Output, and disregard the Output. '
'The score is the fraction of the ground-truth answer that is supported by the context '
'(0.0 = none of it, 1.0 = all of it).'
),
include_input=True,
include_expected_output=True,
score={'evaluation_name': 'context_recall'},
assertion=False,
)
@dataclass
class RagInputs:
question: str
context: list[str]
dataset = Dataset(
name='rag_quality',
cases=[
Case(
inputs=RagInputs(
question='Where is the Eiffel Tower?',
context=['The Eiffel Tower is in Paris, France.'],
),
expected_output='The Eiffel Tower is in Paris.',
),
],
evaluators=[faithfulness, answer_relevance, context_precision, context_recall],
)
각 레시피는 score OutputConfig로 이름 붙여진 0.0-1.0 점수를 내보내요. 합격/불합격 열도 원한다면 LLM Judge에서 설명된 대로 assertion=False를 assertion 구성으로 바꾸거나(또는 둘 다 유지) 해요.
GEMBA 번역 품질
GEMBA Direct Assessment 프롬프트(Kocmi & Federmann, 2023, "Large Language Models Are State-of-the-Art Evaluators of Translation Quality")는 번역을 0부터 100까지 점수 매겨요. 여기서 케이스의 inputs는 원문, 출력은 후보 번역, 그리고 (선택적으로) expected_output은 사람 참조 번역이에요:
from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import LLMJudge
gemba_da = LLMJudge(
rubric=(
'The Input is the English source text and the Output is its French translation '
'(the Expected Output, if present, is a human reference translation). '
'Score the translation on a continuous scale from 0 to 100, where 0 means '
'"no meaning preserved" and 100 means "perfect meaning and grammar", '
'then report it normalized to the 0.0-1.0 range by dividing by 100.'
),
include_input=True,
include_expected_output=True,
score={'evaluation_name': 'gemba_da'},
assertion=False,
)
dataset = Dataset(
name='translation_quality',
cases=[
Case(
inputs='Hello, world!',
expected_output='Bonjour, le monde !',
),
],
evaluators=[gemba_da],
)
언어 이름을 여러분의 언어 쌍에 맞게 조정해요. GEMBA-SQM 변형에서는 척도 문장을 논문의 고정 0-6 척도로 바꿔요 (0 = 의미 보존 안 됨, 2 = 일부 의미 보존, 4 = 문법 오류는 거의 없이 대부분의 의미 보존, 6 = 의미와 문법 완벽).
적절한 도구 고르기
| 필요 | 사용 |
|---|---|
| 명시적 CoT 단계로 정수 척도에서 품질 차원 점수 매기기 | GEval |
| 근거 강도, 관련성, 검색 품질, 번역 품질 | 위의 LLMJudge 레시피들 |
| 맞춤형 무언가 | 자신만의 루브릭을 가진 LLMJudge |
| 상위 프레임워크와의 정확한 동등성 | 타사 통합 |
더 알아보기 (Learn more)
- Pydantic Evals 문서: 표준 품질 메트릭