Définir des objectifs

Les objectifs vous permettent de définir des critères de réussite/échec pour les scores des évaluateurs. Lorsqu’un objectif est défini, le SDK affiche les verdicts PASS ou FAIL dans la sortie du terminal à côté de chaque score.

Un objectif est un point de contrôle binaire réussite/échec. Le sens favorable (et la façon dont les scores sont normalisés) relève de la sémantique de la métrique que vous définissez sur l’Evaluator lui-même — voir Direction et normalisation ci-dessous.

Types d’objectifs

Types d’objectifs

MéthodeSignification
Goal.gte(0,8)Le score doit être >= 0,8
Goal.lte(0,1)Le score doit être <= 0,1
Goal.between(0,2, 0,8)Le score doit être dans l’intervalle [0,2, 0,8]

Toutes les méthodes d’objectif acceptent un paramètre metric optionnel ("avg", "min", "max", "std") pour cibler une statistique spécifique au lieu de la moyenne par défaut.

Utilisation de base

Utilisation de base

from mistralai.evaluations import Evaluator, Goal

Evaluator(
    name="accuracy",
    description="1 if the expected answer appears in the output.",
    scorer=accuracy_scorer,
    goal=Goal.gte(0.8),
)
Objectifs par génération et agrégés

Objectifs par génération et agrégés

Les évaluateurs prennent en charge deux niveaux d’objectifs :

  • goal : évalué par rapport au score de chaque génération individuelle.
  • Un objectif sur une statistique : évalué par rapport à cette statistique au niveau du run, comme la moyenne sur toutes les générations et tous les enregistrements.
from mistralai.evaluations import Evaluator, Goal, Statistic

Evaluator(
    name="accuracy",
    description="1 if the expected answer appears in the output.",
    scorer=accuracy_scorer,
    goal=Goal.gte(0.7),                              # each generation must score >= 0.7
    statistics=[Statistic.avg(goal=Goal.gte(0.9))],  # overall average must be >= 0.9
)
Note

Le paramètre aggregate_goal est obsolète. Attachez plutôt l'objectif à une Statistic déclarée, comme ci-dessus. Déclarer statistics fait de cette liste la référence : l'évaluateur n'expose que les statistiques qu'elle contient.

Lorsque vous appelez run.show() :

  • Niveau du run : indique si chaque objectif sur une statistique est atteint. Si vous ne déclarez pas statistics, ce niveau revient à goal appliqué à la moyenne.
  • Niveau de l'enregistrement (avec num_generations > 1) : indique combien de générations atteignent le goal (par exemple, "2/3 PASS"), avec le verdict au niveau de la statistique, le cas échéant.
  • Niveau de la génération : affiche PASS/FAIL pour chaque score individuel par rapport à goal.
Objectifs sur les évaluateurs d’exécution

Objectifs sur les évaluateurs d’exécution

Les évaluateurs d’exécution prennent également en charge les objectifs :

from mistralai.evaluations import RunEvaluator, Goal

RunEvaluator(
    name="f1",
    description="Harmonic mean of precision and recall across all records.",
    scorer=f1_scorer,
    goal=Goal.gte(0.85),
)
Direction et normalisation

Direction et normalisation

Un objectif ne contrôle que la réussite ou l’échec. Pour indiquer le sens favorable et l’échelle d’une métrique, définissez ces champs sur l’Evaluator :

ChampTypeDescription
direction"maximize" | "minimize"Sens dans lequel la valeur est meilleure. Déduit de l’objectif quand il n’est pas défini (gte → maximize, lte → minimize, sinon maximize).
min_value / max_valuefloatFenêtre de normalisation min-max. Définissez les deux ou aucun des deux ; min_value doit être < max_value.
weightfloatPression d’optimisation (par défaut 1.0). Définissez weight=0 pour faire de la métrique une contrainte pure : son objectif continue de contrôler la réussite, mais elle est exclue de l’objectif d’optimisation.
Evaluator(
    name="latency_ms",
    description="End-to-end response time in milliseconds.",
    scorer=latency_scorer,
    goal=Goal.lte(1000),     # gate + infers direction="minimize"
    min_value=200,
    max_value=2000,          # 850 ms normalizes to ~0.64 (lower is better)
)

Evaluator(
    name="accuracy",
    description="1 if the expected answer appears in the output.",
    scorer=accuracy_scorer,  # no goal → direction defaults to "maximize", window to [0, 1]
)
Exemple complet

Exemple complet

import asyncio
import os

from mistralai.evaluations import (
    Evaluation, Evaluator, Goal, Mistral, Project,
    RunEvaluator, RunEvaluatorContext, ScorerContext, Statistic, System, TaskContext,
)

client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])

dataset = [
    {"prompt": "What is 2+2?", "expected": "4"},
    {"prompt": "Capital of France?", "expected": "Paris"},
    {"prompt": "Largest planet?", "expected": "Jupiter"},
]

async def task(ctx: TaskContext) -> str:
    r = await client.chat.complete_async(
        model=str(ctx.system.params["model"]),
        messages=[{"role": "user", "content": ctx.input_record["prompt"]}],
    )
    return str(r.choices[0].message.content)

def accuracy_scorer(ctx: ScorerContext) -> int:
    return 1 if ctx.input_record["expected"].lower() in str(ctx.output).lower() else 0

def accuracy_gate(ctx: RunEvaluatorContext):
    return ctx.statistics["accuracy"].avg

async def main():
    run = await client.evaluation.run(
        project=Project(name="QA Pipeline"),
        evaluation=Evaluation(name="Accuracy with Goals"),
        system=System(name="mistral-small", params={"model": "mistral-small-latest"}),
        dataset=dataset,
        task=task,
        evaluators=[
            Evaluator(
                name="accuracy",
                description="1 if the expected answer appears in the output.",
                scorer=accuracy_scorer,
                goal=Goal.gte(0.8),
                statistics=[Statistic.avg(goal=Goal.gte(0.9))],
            ),
        ],
        run_evaluators=[
            RunEvaluator(
                name="accuracy_avg",
                description="Average accuracy across all records.",
                scorer=accuracy_gate,
                goal=Goal.gte(0.85),
            ),
        ],
        num_generations=3,
    )
    run.show(level="generations")

asyncio.run(main())