Spaces:
Running
Running
File size: 2,365 Bytes
9c84f9d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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)}
|