Aller au contenu principal

Seuils bloquants et verdicts

Les seuils bloquants et les verdicts ajoutent une sémantique de gravité à runEvals. Les seuils bloquants sont des scorers qui doivent obtenir un score de 1.0 : ce sont des exigences strictes qui bloquent une exécution. Les seuils de qualité correspondent aux scores minimaux acceptables pour les métriques suivies. Le verdict résume le résultat par passed, scored ou failed.

Quand utiliser les seuils bloquants et les verdicts
Lien direct vers Quand utiliser les seuils bloquants et les verdicts

  • Imposer des exigences strictes dans la CI, par exemple « l’agent doit appeler le bon outil »
  • Suivre des métriques de qualité avec des seuils minimaux, par exemple « fidélité supérieure à 0,7 »
  • Obtenir un signal de verdict unique (passed, scored ou failed) à partir d’une exécution d’évaluation, sans écrire de logique d’assertion personnalisée
  • Séparer les seuils bloquants qui doivent réussir des métriques suivies qui sont simplement souhaitables

Démarrage rapide
Lien direct vers Démarrage rapide

src/evals/weather-eval.ts
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'
import { weatherAgent } from '../agents'
import { faithfulnessScorer } from '../scorers'

const result = await runEvals({
data: [{ input: 'What is the weather in Brooklyn?' }],
target: weatherAgent,

// Gates: must all score 1.0 or the run fails
gates: [checks.calledTool('get_weather'), checks.noToolErrors()],

// Scorers: tracked with optional thresholds
scorers: [
{ scorer: faithfulnessScorer, threshold: 0.7 },
checks.includes('Brooklyn'), // no threshold = tracked only
],
})

console.log(result.verdict) // 'passed' | 'scored' | 'failed'

Fonctionnement des verdicts
Lien direct vers Fonctionnement des verdicts

Le verdict est calculé à partir des seuils bloquants et des seuils de qualité une fois tous les éléments de données traités :

  • failed : au moins un seuil bloquant a obtenu une moyenne inférieure à 1.0 sur l’ensemble des éléments de données
  • scored : tous les seuils bloquants ont réussi, mais au moins un scorer assorti d’un seuil n’a pas atteint celui-ci
  • passed : tous les seuils bloquants ont obtenu 1.0 et tous les seuils de qualité ont été atteints

Lorsqu’aucun seuil bloquant ni scorer assorti d’un seuil de qualité n’est fourni, le champ de verdict est omis et runEvals se comporte exactement comme auparavant.

Seuils bloquants
Lien direct vers Seuils bloquants

Les seuils bloquants sont des scorers transmis par le champ gates. Ils s’exécutent avant les scorers ordinaires sur chaque élément de données. Pour réussir, un seuil bloquant doit obtenir une moyenne de 1.0 sur l’ensemble des éléments de données.

src/evals/tool-gate.ts
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'

const result = await runEvals({
data: [{ input: 'What is the weather?' }],
target: weatherAgent,
gates: [checks.calledTool('get_weather')],
scorers: [qualityScorer],
})

// result.gateResults: [{ id: 'check-called-tool', passed: true, score: 1 }]

N’importe quel scorer peut servir de seuil bloquant. Les vérifications rapides conviennent naturellement, car elles renvoient des scores binaires de 1 ou 0. Consultez la référence de runEvals() pour obtenir la documentation complète sur les paramètres et le type de retour.

Exécutions avec seuils bloquants uniquement
Lien direct vers Exécutions avec seuils bloquants uniquement

scorers est facultatif lorsqu’au moins un seuil bloquant est fourni. Cette possibilité est utile pour les vérifications déterministes dans la CI, lorsque seuls les seuils bloquants de réussite ou d’échec vous intéressent et que vous n’avez pas besoin de suivre de métriques de qualité.

src/evals/gate-only.ts
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'

const result = await runEvals({
data: [{ input: 'What is the weather in Brooklyn?' }],
target: weatherAgent,
gates: [checks.calledTool('get_weather'), checks.noToolErrors()],
})

Vous devez fournir au moins un scorer ou un seuil bloquant ; une exécution sans aucun des deux lève une erreur.

Seuils de qualité
Lien direct vers Seuils de qualité

Enveloppez un scorer dans { scorer, threshold } pour définir les limites de réussite et d’échec. Le seuil est comparé au score moyen du scorer sur l’ensemble des éléments de données.

Un threshold peut être :

  • Un nombre : implique une valeur minimale ; le score doit être supérieur ou égal pour réussir : { scorer, threshold: 0.7 }
  • Un objet avec min et/ou max : permet des vérifications fondées sur une plage : { scorer, threshold: { max: 0.3 } }

Utilisez max pour les scorers dont un score élevé est mauvais, par exemple l’hallucination ou la toxicité. Utilisez { min, max } lorsque le score doit rester dans une plage précise.

src/evals/threshold-example.ts
import { runEvals } from '@mastra/core/evals'

const result = await runEvals({
data: [{ input: 'Explain quantum computing' }],
target: myAgent,
scorers: [
{ scorer: faithfulnessScorer, threshold: 0.7 }, // min threshold (number shorthand)
{ scorer: hallucinationScorer, threshold: { max: 0.3 } }, // max threshold — high score = bad
{ scorer: verbosityScorer, threshold: { min: 0.3, max: 0.8 } }, // range threshold
toneScorer, // bare scorer, no threshold — tracked only
],
})

// result.thresholdResults:
// [
// { id: 'faithfulness', passed: true, averageScore: 0.85, threshold: 0.7 },
// { id: 'hallucination', passed: true, averageScore: 0.1, threshold: { max: 0.3 } },
// { id: 'verbosity', passed: false, averageScore: 0.9, threshold: { min: 0.3, max: 0.8 } },
// ]

Un scorer sans seuil apparaît toujours dans result.scores, mais n’influence pas le verdict.

Utiliser les verdicts dans la CI
Lien direct vers Utiliser les verdicts dans la CI

Le verdict fournit un signal unique aux pipelines de CI :

src/evals/ci-check.ts
import { runEvals } from '@mastra/core/evals'
import { checks } from '@mastra/evals/checks'

const result = await runEvals({
data: testDataset,
target: myAgent,
gates: [checks.calledTool('search'), checks.noToolErrors()],
scorers: [{ scorer: faithfulnessScorer, threshold: 0.7 }],
})

if (result.verdict === 'failed') {
console.error(
'Gate failures:',
result.gateResults?.filter(g => !g.passed),
)
process.exit(1)
}

if (result.verdict === 'scored') {
console.warn(
'Threshold misses:',
result.thresholdResults?.filter(t => !t.passed),
)
}