dev-strender's picture
Replace v24-era demo with v34 pipeline demo (engine-vendored bundle)
9c84f9d verified
Raw History Blame
2.37 kB
from typing import Any
from solar_eval.evaluators.base import BaseEvaluator
from solar_eval.models.sample import EvalSample
from solar_eval.providers.base import BaseProvider
class CompositeEvaluator(BaseEvaluator):
"""Combines multiple evaluators with weights.
Example: 50% LLM Judge + 50% Rule-based for title evaluation.
"""
def __init__(self, components: list[dict[str, Any]]) -> None:
"""Components: [{evaluator: BaseEvaluator, weight: float}]"""
self.components = components
@property
def required_fields(self) -> frozenset[str]:
"""κ΅¬μ„±λœ ν•˜μœ„ 평가기 μš”κ΅¬ ν•„λ“œμ˜ ν•©μ§‘ν•©.
`components` λŠ” μΈμŠ€ν„΄μŠ€λ§ˆλ‹€ λ‹€λ₯΄κ²Œ κ΅¬μ„±λ˜λ―€λ‘œ(μƒμ„±μž 인자) κ³ μ •λœ
클래슀 μ†μ„±μœΌλ‘œλŠ” ν‘œν˜„ν•  수 μ—†λ‹€ -- `BaseEvaluator.required_fields`
λ₯Ό `@property` 둜 μ˜€λ²„λΌμ΄λ“œν•΄ 맀번 ν•˜μœ„ ν‰κ°€κΈ°μ—μ„œ 합쳐낸닀.
"""
fields: frozenset[str] = frozenset()
for comp in self.components:
fields |= comp["evaluator"].required_fields
return fields
async def evaluate(
self,
sample: EvalSample,
provider: BaseProvider | None = None,
judge_model: str = "gpt-4o",
) -> dict[str, Any]:
component_results = []
weighted_score = 0.0
for comp in self.components:
evaluator = comp["evaluator"]
weight = comp["weight"]
result = await evaluator.evaluate(
sample=sample,
provider=provider,
judge_model=judge_model,
)
weighted_score += result["score"] * weight
component_results.append(
{
"weight": weight,
"score": result["score"],
"details": result.get("details", {}),
}
)
return {
"score": weighted_score,
"components": component_results,
"details": {"components": component_results},
}
def aggregate(self, results: list[dict[str, Any]]) -> dict[str, Any]:
if not results:
return {"overall_score": 0.0, "scores": {}}
overall = sum(r["score"] for r in results) / len(results)
return {"overall_score": overall, "num_samples": len(results)}