dev-strender's picture
Replace v24-era demo with v34 pipeline demo (engine-vendored bundle)
9c84f9d verified
Raw History Blame
3.17 kB
from abc import ABC, abstractmethod
from typing import Any
from solar_eval.models.sample import EvalSample
from solar_eval.providers.base import BaseProvider
class BaseEvaluator(ABC):
"""Abstract base for all evaluators.
`required_fields` λŠ” `evaluate()` κ°€ ν•„μš”λ‘œ ν•˜λŠ” `EvalSample` ν•„λ“œ μ΄λ¦„μ˜
집합이닀. μ§€ν‘œλ§ˆλ‹€ μš”κ΅¬ ν•„λ“œκ°€ μ •λ§λ‘œ λ‹€λ₯΄λ‹€ -- κ΅μ—΄μ˜ `lcs_diff` λŠ” 원문·정닡·
좜λ ₯ μ…‹ λ‹€ ν•„μš”ν•˜μ§€λ§Œ(3-way), RAG 의 `faithfulness` λŠ” 원문이 ν•„μš” μ—†λŠ” 식
(`.agents/01-plans/harness/2026-08-09-chosun-proofread-evalsample-migration.md` Β§3).
μ„œλΈŒν΄λž˜μŠ€λŠ” 이 값을 클래슀 μ†μ„±μœΌλ‘œ μ„ μ–Έν•œλ‹€. ꡬ성에 따라 μš”κ΅¬ ν•„λ“œκ°€ λ‹¬λΌμ§€λŠ”
경우(예: ν•˜μœ„ 평가기λ₯Ό μ‘°ν•©ν•˜λŠ” `CompositeEvaluator`)λŠ” `@property` 둜 μ˜€λ²„λΌμ΄λ“œ
해도 λœλ‹€ -- `validate_required_fields` λŠ” `self.required_fields` 둜만 μ ‘κ·Όν•œλ‹€.
"""
required_fields: frozenset[str] = frozenset()
@abstractmethod
async def evaluate(
self,
sample: EvalSample,
provider: BaseProvider | None = None,
judge_model: str = "gpt-4o",
) -> dict[str, Any]:
"""`sample` ν•œ 건을 μ±„μ ν•œλ‹€. `{score, details}` λ₯Ό λ°˜ν™˜ν•œλ‹€.
채점에 μ‹€νŒ¨ν•˜λ©΄(judge 호좜 μ˜ˆμ™Έ, 잘λͺ»λœ 응닡 λ“±) κ·Έ μ‹€νŒ¨λŠ” **μ˜ˆμ™Έλ‘œ μ „νŒŒν•œλ‹€** --
점수(0.0 이든 1.0 이든)둜 μΉ˜ν™˜ν•΄ λ°˜ν™˜ν•˜μ§€ μ•ŠλŠ”λ‹€. fail-open(μž₯μ• λ₯Ό 만점으둜
λ‘”κ°‘μ‹œν‚€λŠ” 것)을 λ§Œλ“€μ§€ μ•ŠλŠ” 것이 이 κ³„μ•½μ˜ 핡심이닀. 이 μ˜ˆμ™Έλ₯Ό μž‘μ•„ μ‹€νŒ¨
μƒ˜ν”Œμ„ μ§‘κ³„μ—μ„œ λΆ„λ¦¬ν•˜λŠ” 것은 호좜자(runner.py/CLI)의 μ±…μž„μ΄λ‹€ -- μ„œλΈŒν΄λž˜μŠ€λŠ”
κ·Έλƒ₯ λ˜μ§€κΈ°λ§Œ ν•˜λ©΄ λœλ‹€.
"""
...
@abstractmethod
def aggregate(self, results: list[dict[str, Any]]) -> dict[str, Any]:
"""`evaluate()` κ°€ μ„±κ³΅ν•œ κ²°κ³Όλ“€λ§Œ λͺ¨μ•„ 전체 점수둜 μ§‘κ³„ν•œλ‹€.
`results` μ—λŠ” μ‹€νŒ¨ν•œ μƒ˜ν”Œμ΄ μ„žμ—¬ λ“€μ–΄μ˜€μ§€ μ•ŠλŠ”λ‹€(ν˜ΈμΆœμžκ°€ 이미 κ±ΈλŸ¬λ‚Έλ‹€) --
μ—¬κΈ°μ„œ μ‹€νŒ¨λ₯Ό λ³„λ„λ‘œ μ²˜λ¦¬ν•  ν•„μš”κ°€ μ—†λ‹€.
"""
...
def validate_required_fields(self, sample: EvalSample) -> None:
"""`required_fields` κ°€ `sample` 에 μ±„μ›Œμ Έ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
채점을 μ‹œμž‘ν•˜κΈ° 전에 ν˜ΈμΆœν•œλ‹€(λŸ¬λ„ˆ/CLI 의 evaluate ν˜ΈμΆœλΆ€). 값이 `None`
이면 "μ±„μ›Œμ§€μ§€ μ•ŠμŒ"으둜 λ³Έλ‹€ -- 빈 λ¬Έμžμ—΄/빈 λ¦¬μŠ€νŠΈλŠ” μœ νš¨ν•œ κ°’(예: ꡐ정할
λ‚΄μš©μ΄ μ—†λŠ” 원문)이라 ν†΅κ³Όμ‹œν‚¨λ‹€. 쑰용히 λ„˜κΈ°μ§€ μ•Šκ³  μ¦‰μ‹œ μ‹€νŒ¨μ‹œμΌœ, μ–΄λŠ
ν•„λ“œκ°€ μ™œ μ—†λŠ”μ§€κ°€ λ‘œκ·Έμ— λ°”λ‘œ λ“œλŸ¬λ‚˜κ²Œ ν•œλ‹€.
Raises:
ValueError: `required_fields` 쀑 ν•˜λ‚˜ 이상이 `sample` μ—μ„œ `None` 인 경우.
"""
missing = sorted(f for f in self.required_fields if getattr(sample, f, None) is None)
if missing:
raise ValueError(
f"{type(self).__name__} requires sample field(s) {missing} to be filled "
f"(required_fields={sorted(self.required_fields)})"
)