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
| Méthode | Signification |
|---|---|
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
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
Les évaluateurs prennent en charge deux niveaux d’objectifs :
goal: évalué par rapport au score de chaque génération individuelle.aggregate_goal: évalué par rapport au résultat agrégé sur toutes les générations.
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
aggregate_goal=Goal.gte(0.9), # overall average must be >= 0.9
)Lorsque vous appelez run.show() :
- Niveau de l’exécution : indique si l’agrégat respecte l’
aggregate_goal(revient àgoalsur la moyenne si aucun agrégat n’est défini). - Niveau de l’enregistrement (avec
num_generations > 1) : indique combien de générations ont respecté legoal(par exemple, « 2/3 PASS »), avec le verdict agrégé le cas échéant. - Niveau de la génération : affiche
PASS/FAILpour chaque score individuel par rapport àgoal.
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
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 :
| Champ | Type | Description |
|---|---|---|
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_value | float | Fenêtre de normalisation min-max. Définissez les deux ou aucun des deux ; min_value doit être < max_value. |
weight | float | Pression 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
import asyncio
import os
from mistralai.evaluations import (
Evaluation, Evaluator, Goal, Mistral, Project,
RunEvaluator, RunEvaluatorContext, ScorerContext, 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),
aggregate_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())