내장 평가자

내장 평가자 (Native Evaluators)

Pydantic Evals는 흔한 평가 작업을 위한 여러 내장 평가자를 제공해요.

출처: 문서

본문

비교 평가자

EqualsExpected

출력이 케이스의 기대 출력과 정확히 같은지 확인해요.

from pydantic_evals.evaluators import EqualsExpected

EqualsExpected()

매개변수: 없음

반환: bool - ctx.output == ctx.expected_output이면 True

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import EqualsExpected

dataset = Dataset(
    name='equals_expected_demo',
    cases=[
        Case(
            name='addition',
            inputs='2 + 2',
            expected_output='4',
        ),
    ],
    evaluators=[EqualsExpected()],
)

참고:

  • expected_outputNone이면 평가를 건너뛰어요 (빈 딕셔너리 {} 반환)
  • 그 건너뜀 때문에, 기대 출력이 실제로 None인 케이스는 아무 판정도 기록하지 않아서 작업이 무엇을 반환하든 통과해요. 출력이 None임을 판정하려면 값을 명시적으로 받는 Equals(value=None)를 사용해요.
  • Python의 == 연산자를 쓰므로 비교 가능한 어떤 타입이든 동작해요
  • 구조화된 데이터에서는 중첩 동등성을 고려해요

Equals

출력이 특정 값과 같은지 확인해요.

from pydantic_evals.evaluators import Equals

Equals(value='expected_result')

매개변수:

  • value (Any): 비교할 값
  • evaluation_name (str | None): 보고서에서 이 평가의 커스텀 이름

반환: bool - ctx.output == value이면 True

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import Equals

# 출력이 항상 "success"인지 확인
dataset = Dataset(
    name='equals_demo',
    cases=[Case(inputs='test')],
    evaluators=[
        Equals(value='success', evaluation_name='is_success'),
    ],
)

사용 사례:

  • 센티널 값 확인
  • 일관된 출력 검증
  • 특정 범주로의 분류 테스트

Contains

출력이 특정 값이나 부분 문자열을 포함하는지 확인해요.

from pydantic_evals.evaluators import Contains

Contains(
    value='substring',
    case_sensitive=True,
    as_strings=False,
)

매개변수:

  • value (Any): 찾을 값
  • case_sensitive (bool): 문자열에 대한 대소문자 구분 비교 (기본: True)
  • as_strings (bool): 확인 전에 두 값을 문자열로 변환 (기본: False)
  • evaluation_name (str | None): 보고서에서 이 평가의 커스텀 이름

반환: EvaluationReason - 설명과 함께 합격/불합격

동작:

문자열의 경우: 부분 문자열 포함 여부 확인

  • Contains(value='hello', case_sensitive=False)
    • 일치: "Hello World", "say hello", "HELLO"
    • 불일치: "hi there"

리스트/튜플의 경우: 멤버십 확인

  • Contains(value='apple')
    • 일치: ['apple', 'banana'], ('apple',)
    • 불일치: ['apples', 'orange']

딕셔너리의 경우: 키-값 쌍 확인

  • Contains(value={'name': 'Alice'})
    • 일치: {'name': 'Alice', 'age': 30}
    • 불일치: {'name': 'Bob'}

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import Contains

dataset = Dataset(
    name='contains_demo',
    cases=[Case(inputs='test')],
    evaluators=[
        # 필수 키워드 확인
        Contains(value='terms and conditions', case_sensitive=False),
        # PII 확인 (찾으면 실패)
        # 참고: PII가 발견되면 False를 반환하는 커스텀 평가자를 사용하세요
    ],
)

사용 사례:

  • 필수 콘텐츠 검증
  • 키워드 탐지
  • PII/민감 데이터 탐지
  • 다중 값 검증

타입 검증

IsInstance

출력이 주어진 이름을 가진 타입의 인스턴스인지 확인해요.

from pydantic_evals.evaluators import IsInstance

IsInstance(type_name='str')

매개변수:

  • type_name (str): 확인할 타입 이름 (__name__ 또는 __qualname__ 사용)
  • evaluation_name (str | None): 보고서에서 이 평가의 커스텀 이름

반환: EvaluationReason - 타입 정보와 함께 합격/불합격

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import IsInstance

dataset = Dataset(
    name='isinstance_demo',
    cases=[Case(inputs='test')],
    evaluators=[
        # 출력이 항상 문자열인지 확인
        IsInstance(type_name='str'),
        # Pydantic 모델 확인
        IsInstance(type_name='MyModel'),
        # dict 확인
        IsInstance(type_name='dict'),
    ],
)

참고:

  • 타입의 __name____qualname__ 둘 다에 대해 일치 확인
  • 내장 타입(str, int, dict, list 등)과 동작
  • 커스텀 클래스와 Pydantic 모델과 동작
  • 상속을 위해 전체 MRO(Method Resolution Order) 확인

사용 사례:

  • 포맷 검증
  • 구조화된 출력 검증
  • 타입 일관성 검사

성능 평가

MaxDuration

작업 실행 시간이 최대 임계값 미만인지 확인해요.

from datetime import timedelta

from pydantic_evals.evaluators import MaxDuration

MaxDuration(seconds=2.0)
# 또는
MaxDuration(seconds=timedelta(seconds=2))

매개변수:

  • seconds (float | timedelta): 허용 최대 지속 시간

반환: bool - ctx.duration <= seconds이면 True

예시:

from datetime import timedelta

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import MaxDuration

dataset = Dataset(
    name='max_duration_demo',
    cases=[Case(inputs='test')],
    evaluators=[
        # SLA: 2초 안에 응답해야 함
        MaxDuration(seconds=2.0),
        # 또는 timedelta 사용
        MaxDuration(seconds=timedelta(milliseconds=500)),
    ],
)

사용 사례:

  • SLA 준수
  • 성능 회귀 테스트
  • 지연 시간 요구사항
  • 타임아웃 검증

참고: 동시성 & 성능


LLM-as-a-Judge

LLMJudge

LLM을 사용해 루브릭을 기준으로 주관적 특성을 평가해요.

from pydantic_evals.evaluators import LLMJudge

LLMJudge(
    rubric='Response is accurate and helpful',
    model='openai:gpt-5.2',
    include_input=False,
    include_expected_output=False,
    model_settings=None,
    score=False,
    assertion={'include_reason': True},
)

매개변수:

  • rubric (str): 평가 기준 (필수)
  • model (Model | KnownModelName | None): 사용할 모델 (기본: 'openai:gpt-5.2')
  • include_input (bool): 프롬프트에 작업 입력 포함 (기본: False)
  • include_expected_output (bool): 프롬프트에 기대 출력 포함 (기본: False)
  • model_settings (ModelSettings | None): 커스텀 모델 설정
  • score (OutputConfig | False): 점수 출력 구성 (기본: False)
  • assertion (OutputConfig | False): 판정 출력 구성 (기본: 이유 포함)

반환: scoreassertion 매개변수에 따라 다름 (아래 참고)

출력 모드:

기본적으로는 이유가 포함된 불리언 판정을 반환해요:

  • LLMJudge(rubric='Response is polite')
    • 반환: {'LLMJudge_pass': EvaluationReason(value=True, reason='...')}

대신 점수(0.0 ~ 1.0)를 반환할 수도 있어요:

  • LLMJudge(rubric='Response quality', score={'include_reason': True}, assertion=False)
    • 반환: {'LLMJudge_score': EvaluationReason(value=0.85, reason='...')}

점수와 판정 둘 다 반환:

  • LLMJudge(rubric='Response quality', score={'include_reason': True}, assertion={'include_reason': True})
    • 반환: {'LLMJudge_score': EvaluationReason(value=0.85, reason='...'), 'LLMJudge_pass': EvaluationReason(value=True, reason='...')}

평가 이름 커스터마이즈:

  • LLMJudge(rubric='Response is factually accurate', assertion={'evaluation_name': 'accuracy', 'include_reason': True})
    • 반환: {'accuracy': EvaluationReason(value=True, reason='...')}

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import LLMJudge

dataset = Dataset(
    name='llm_judge_demo',
    cases=[Case(inputs='test', expected_output='result')],
    evaluators=[
        # 기본 정확성 확인
        LLMJudge(
            rubric='Response is factually accurate',
            include_input=True,
        ),
        # 다른 모델로 품질 점수
        LLMJudge(
            rubric='Overall response quality',
            model='anthropic:claude-sonnet-4-6',
            score={'evaluation_name': 'quality', 'include_reason': False},
            assertion=False,
        ),
        # 기대 출력과 대조
        LLMJudge(
            rubric='Response matches the expected answer semantically',
            include_input=True,
            include_expected_output=True,
        ),
    ],
)

참고: LLM Judge 심화

GEval

G-Eval 방법(Liu et al., 2023)을 따르는 chain-of-thought 평가예요. 판단자가 명시적 평가 단계를 적용하고, 추론 트레이스와 함께 score_range 안의 정수 점수를 반환해요.

from pydantic_evals.evaluators import GEval

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).',
    ],
    score_range=(1, 5),
    include_input=False,
)

매개변수:

  • criteria (str): 평가할 측면, 예: 'coherence' (필수)
  • evaluation_steps (list[str]): 판단자가 따라야 할 명시적 chain-of-thought 단계 (필수)
  • score_range (tuple[int, int]): 양끝 포함 정수 점수 범위 (기본: (1, 5))
  • include_input (bool): 프롬프트에 작업 입력 포함 (기본: False)
  • model (Model | KnownModelName | None): 사용할 모델 (기본: 'openai:gpt-5.2')
  • model_settings (ModelSettings | None): 커스텀 모델 설정
  • evaluation_name (str | None): 결과의 커스텀 이름 (기본: 'GEval')

반환: 정수 점수와 판단자의 추론을 담은 EvaluationReason

판단자 모델이 텍스트를 생성할 수 없을 때(예: TypeSafe의 Jev), 점수는 요청된 정수 척도를 유지하고 reason은 None이 돼요. 채점은 점수당 한 수준을 가진 한 질문이 되므로, score_range에는 최대 20개 수준만 들어갈 수 있어요.

참고: 표준 품질 메트릭


스팬 기반 평가

HasMatchingSpan

OpenTelemetry 스팬이 쿼리와 일치하는지 확인해요 (logfire SDK 구성 필요, Pydantic Logfire 계정은 불필요).

from pydantic_evals.evaluators import HasMatchingSpan

HasMatchingSpan(
    query={'name_contains': 'tool_call'},
    evaluation_name='called_tool',
)

매개변수:

  • query (SpanQuery): 스팬과 대조할 쿼리
  • evaluation_name (str | None): 보고서에서 이 평가의 커스텀 이름

반환: bool - 쿼리와 일치하는 스팬이 하나라도 있으면 True

예시:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import HasMatchingSpan

dataset = Dataset(
    name='span_check_demo',
    cases=[Case(inputs='test')],
    evaluators=[
        # 특정 툴이 호출됐는지 확인
        HasMatchingSpan(
            query={'name_contains': 'search_database'},
            evaluation_name='used_database',
        ),
        # 오류 확인
        HasMatchingSpan(
            query={'has_status': 'error'},
            evaluation_name='had_errors',
        ),
        # 기간 제약 확인
        HasMatchingSpan(
            query={
                'name_equals': 'llm_call',
                'max_duration': 2.0,  # 초
            },
            evaluation_name='llm_fast_enough',
        ),
    ],
)

참고: 스팬 기반 평가


내장 리포트 평가자

위의 케이스 수준 평가자 외에도, Pydantic Evals는 전체 실험 결과를 분석하는 리포트 평가자를 제공해요. 이것들은 Datasetreport_evaluators 매개변수로 전달돼요.

리포트 평가자 목적 출력
ConfusionMatrixEvaluator 분류 혼동 행렬 ConfusionMatrix
PrecisionRecallEvaluator AUC가 있는 PR 곡선 PrecisionRecall

참고: ScalarResultTableResult 분석을 만드는 커스텀 리포트 평가자 작성법을 포함한 전체 문서·매개변수·예시는 리포트 평가자를 참고해요.


빠른 참조 표

케이스 수준 평가자

평가자 목적 반환 타입 비용 속도
EqualsExpected 기대값과 정확히 일치 bool 무료 즉시
Equals 특정 값과 동일 bool 무료 즉시
Contains 값/부분 문자열 포함 bool + reason 무료 즉시
IsInstance 타입 검증 bool + reason 무료 즉시
MaxDuration 성능 임계값 bool 무료 즉시
LLMJudge 주관적 품질 bool 및/또는 float $$ 느림
GEval Chain-of-thought 채점 int + reason $$ 느림
HasMatchingSpan 동작 검사 bool 무료 빠름

리포트 수준 평가자

평가자 목적 출력 타입 비용 속도
ConfusionMatrixEvaluator 분류 행렬 ConfusionMatrix 무료 즉시
PrecisionRecallEvaluator AUC가 있는 PR 곡선 PrecisionRecall 무료 즉시

평가자 조합하기

모범 사례는 빠른 결정적 검사와 느린 LLM 평가를 조합하는 거예요:

from pydantic_evals import Case, Dataset
from pydantic_evals.evaluators import (
    Contains,
    IsInstance,
    LLMJudge,
    MaxDuration,
)

dataset = Dataset(
    name='combined_evaluators',
    cases=[Case(inputs='test')],
    evaluators=[
        # 먼저 빠른 검사 (fail fast)
        IsInstance(type_name='str'),
        Contains(value='required_field'),
        MaxDuration(seconds=2.0),
        # 비싼 LLM 검사는 마지막에
        LLMJudge(rubric='Response is helpful and accurate'),
    ],
)

이 접근 방식은:

  1. 포맷/구조 문제를 즉시 잡아내요
  2. 필수 콘텐츠를 빠르게 검증해요
  3. 기본 검사가 통과할 때만 비싼 LLM 평가를 실행해요
  4. 포괄적인 품질 평가를 제공해요

다음 단계

더 알아보기 (Learn more)