다중 실행 평가

다중 실행 평가 (Multi-Run Evaluation)

각 케이스를 여러 번 실행해서 변동성을 측정하고 더 신뢰할 수 있는 집계 결과를 얻어요.

AI 시스템은 본질적으로 확률적이에요. 같은 입력이 실행마다 다른 출력을 만들 수 있죠. repeat 매개변수를 쓰면 각 케이스를 여러 번 실행하고 결과를 자동으로 집계해서, 시스템의 전형적인 동작을 더 명확하게 볼 수 있어요.

출처: 문서

본문

기본 사용법

evaluate() 또는 evaluate_sync()repeat를 전달해요:

from pydantic_evals import Case, Dataset

dataset = Dataset(
    name='multi_run_basic',
    cases=[
        Case(name='greeting', inputs='Say hello'),
        Case(name='farewell', inputs='Say goodbye'),
    ]
)


def task(inputs: str) -> str:
    return inputs.upper()


# 각 케이스를 5번 실행
report = dataset.evaluate_sync(task, repeat=5)

# 2 케이스 × 5 반복 = 총 10회 실행
print(len(report.cases))
#> 10

repeat > 1이면 각 실행은 greeting [1/5], greeting [2/5] 등과 같은 인덱스 이름을 얻고, 원래 케이스 이름은 그룹핑을 위해 source_case_name에 보존돼요.

그룹화된 결과 접근

case_groups()를 사용해 원래 케이스별로 구성된 실행에 접근하고, 그룹별 집계 통계를 얻어요:

from pydantic_evals import Case, Dataset

dataset = Dataset(
    name='grouped_results',
    cases=[
        Case(name='greeting', inputs='Say hello'),
        Case(name='farewell', inputs='Say goodbye'),
    ]
)


def task(inputs: str) -> str:
    return inputs.upper()


report = dataset.evaluate_sync(task, repeat=3)

groups = report.case_groups()
assert groups is not None  # 단일 실행(repeat=1)에서는 None

print(len(groups))
#> 2

group_names = [g.name for g in groups]
print(group_names)
#> ['greeting', 'farewell']

# 각 그룹에는 3번의 실행과 집계 통계가 있음
for group in groups:
    assert len(group.runs) == 3
    assert len(group.failures) == 0
    assert group.summary.task_duration > 0

ReportCaseGroup은 다음을 담아요:

  • name -- 원래 케이스 이름
  • runs -- 개별 ReportCase 결과들
  • failures -- 예외를 던진 실행들
  • summary -- 평균 점수, 메트릭, 라벨, 판정, 기간을 담은 ReportCaseAggregate

집계

repeat > 1이면 보고서의 averages()는 두 수준 집계 전략을 사용해요:

  1. 그룹별 평균: 각 케이스의 실행들이 그룹 요약으로 평균화돼요
  2. 그룹 간 평균: 그룹 요약들이 평균화되어 최종 결과를 만들어요

이렇게 하면 성공하거나 실패한 실행 수와 관계없이 각 원래 케이스가 전체 평균에 동등하게 기여해요.

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

dataset = Dataset(
    name='aggregation',
    cases=[
        Case(name='easy', inputs='hello', expected_output='HELLO'),
        Case(name='hard', inputs='world', expected_output='WORLD'),
    ],
    evaluators=[EqualsExpected()],
)


def task(inputs: str) -> str:
    return inputs.upper()


report = dataset.evaluate_sync(task, repeat=3)

averages = report.averages()
assert averages is not None
print(f'Overall assertion rate: {averages.assertions}')
#> Overall assertion rate: 1.0

기본 동작

repeat=1(기본값)이면 동작은 표준 평가와 동일해요. 실행 인덱싱도, source_case_name도 없고 case_groups()None을 반환해요:

from pydantic_evals import Case, Dataset

dataset = Dataset(name='default_behavior', cases=[Case(name='test', inputs='hello')])


def task(inputs: str) -> str:
    return inputs.upper()


report = dataset.evaluate_sync(task)  # 기본적으로 repeat=1

assert report.case_groups() is None
assert all(c.source_case_name is None for c in report.cases)

다음 단계

더 알아보기 (Learn more)