Claude
feat(evaluation): Sprint A14-S5 — contrats des vues d'évaluation + MetricRegistry explicite
3116157 unverified
Raw
History Blame
4.22 kB
"""``EvaluationViewExecutor`` (Protocol) + ``ViewResult`` — Sprint A14-S5.
Le contrat d'exécution d'une vue d'évaluation. Implémentation
concrète au Sprint S13 dans
``picarones.evaluation.views.executor``.
Pattern d'utilisation cible :
.. code-block:: python
from picarones.evaluation.registry import MetricRegistry
from picarones.evaluation.views.executor import DefaultViewExecutor
registry = build_default_registry() # S20
executor = DefaultViewExecutor(registry, projector_registry)
for view in eval_spec.views:
result = executor.evaluate(
view=view,
candidate=pipeline_artifact,
ground_truth=gt_artifact,
)
# result.metric_values : dict[str, Any]
# result.projection_report : ProjectionReport | None
# result.warnings : tuple[str, ...]
"""
from __future__ import annotations
from typing import Any, Protocol, runtime_checkable
from pydantic import BaseModel, ConfigDict, Field
from picarones.domain.artifacts import Artifact
from picarones.domain.evaluation_spec import EvaluationView
from picarones.evaluation.projectors.base import ProjectionReport
class ViewResult(BaseModel):
"""Résultat de l'évaluation d'une vue sur une paire (candidat, GT).
Immuable. Sérialisable JSON pour persistance dans le
``view_results.jsonl`` du run.
Attributs
---------
view_name:
Nom de la vue qui a produit ce résultat.
candidate_artifact_id:
Id de l'artefact évalué (avant projection éventuelle).
ground_truth_artifact_id:
Id de l'artefact GT utilisé pour la comparaison.
metric_values:
Dict ``{metric_name: value}`` pour chaque métrique calculée
avec succès. Une métrique qui a échoué est absente du dict
et apparaît dans ``failed_metrics`` avec le message d'erreur.
failed_metrics:
Dict ``{metric_name: error_message}`` pour les métriques qui
ont levé une exception. Permet au rapport d'afficher
"métrique X non calculée : raison" plutôt que de la cacher.
projection_report:
``ProjectionReport`` produit si la vue a appliqué une
projection. ``None`` si la vue compare l'artefact tel quel.
warnings:
Avertissements à propager dans le rapport (typiquement les
``warnings`` de ``EvaluationView`` + ceux du
``ProjectionReport`` éventuel).
ignored_dimensions:
Récapitulatif des dimensions ignorées par cette évaluation
(combinaison de la vue + de la projection).
"""
model_config = ConfigDict(frozen=True, extra="forbid")
view_name: str
candidate_artifact_id: str
ground_truth_artifact_id: str
metric_values: dict[str, Any] = Field(default_factory=dict)
failed_metrics: dict[str, str] = Field(default_factory=dict)
projection_report: ProjectionReport | None = None
warnings: tuple[str, ...] = Field(default_factory=tuple)
ignored_dimensions: tuple[str, ...] = Field(default_factory=tuple)
@runtime_checkable
class EvaluationViewExecutor(Protocol):
"""Contrat de l'exécuteur de vues.
Une implémentation prend en entrée :
- une ``EvaluationView`` (déclarative),
- un ``Artifact`` candidat (sortie d'un pipeline),
- un ``Artifact`` GT (référence du corpus),
et produit un ``ViewResult`` qui :
1. applique la projection si la vue en spécifie une (et capture
le ``ProjectionReport``),
2. applique le profil de normalisation si spécifié,
3. calcule chaque métrique listée dans
``view.metric_names`` (en propageant les erreurs dans
``failed_metrics`` plutôt que de planter),
4. retourne un ``ViewResult`` immuable.
Cas particulier : si l'artefact candidat n'est pas dans
``view.candidate_types``, l'executor lève ``ValueError`` —
c'est au caller (typiquement le service applicatif) de filtrer
en amont les pipelines qui ne produisent pas l'artefact attendu.
"""
def evaluate(
self,
view: EvaluationView,
candidate: Artifact,
ground_truth: Artifact,
) -> ViewResult: ...
__all__ = ["EvaluationViewExecutor", "ViewResult"]