Aller au contenu principal

Évaluateurs de précision de trajectoire

Mastra fournit deux évaluateurs de précision de trajectoire pour déterminer si un agent ou un workflow suit une séquence d'actions attendue :

  1. Évaluateur basé sur le code — évaluation déterministe fondée sur la correspondance exacte et l'ordre des étapes
  2. Évaluateur basé sur un LLM — évaluation sémantique utilisant l'IA pour apprécier la qualité et la pertinence de la trajectoire

Les deux évaluateurs fonctionnent avec les agents et les workflows. Le pipeline runEvals extrait automatiquement les trajectoires ; les évaluateurs reçoivent donc directement un objet Trajectory.

Extraction de la trajectoire
Lien direct vers Extraction de la trajectoire

Le pipeline runEvals utilise deux stratégies d'extraction, selon qu'un stockage d'observabilité est configuré ou non :

Extraction basée sur les traces (méthode recommandée)
Lien direct vers Extraction basée sur les traces (méthode recommandée)

Lorsque le stockage est configuré pour l'instance Mastra de la cible, le pipeline récupère la trace d'exécution complète dans le stockage d'observabilité et appelle extractTrajectoryFromTrace(). Il produit ainsi une trajectoire hiérarchique dotée de children imbriqués qui représente l'intégralité de l'arbre d'exécution. Cet arbre comprend les exécutions d'agents imbriquées et les appels d'outils au sein des étapes du workflow. Il comprend également les générations de modèles.

Par exemple, un workflow qui appelle un agent, lequel appelle à son tour des outils, produit :

workflow_run
└─ workflow_step (validate-input)
└─ workflow_step (process-data)
└─ agent_run (my-agent)
└─ model_generation
└─ tool_call (search)
└─ model_generation
└─ tool_call (summarize)
└─ workflow_step (save-result)

Extraction de secours
Lien direct vers Extraction de secours

Lorsque le stockage n'est pas disponible, le pipeline utilise les méthodes de secours suivantes :

  • Agents : extractTrajectory(), extrait les entrées ToolCallStep de toolInvocations dans la sortie de message de l'agent. Produit une liste plate d'appels d'outils.
  • Workflows : extractWorkflowTrajectory(), extrait les entrées WorkflowStepStep de stepResults. Produit une liste plate d'étapes de workflow.

Ces méthodes de secours ne capturent ni les exécutions imbriquées ni les spans qui ne correspondent pas à des appels d'outils.

Types de trajectoires
Lien direct vers Types de trajectoires

Les étapes de trajectoire utilisent une union discriminée sur stepType. Chaque type d'étape possède des propriétés spécifiques :

ToolCallStep
Lien direct vers toolcallstep

Représente un appel d'outil effectué par un agent.

stepType:

'tool_call'
Discriminant.

name:

string
Nom de l'outil.

toolArgs?:

Record<string, unknown>
Arguments transmis à l'outil.

toolResult?:

Record<string, unknown>
Résultat renvoyé par l'outil.

success?:

boolean
Indique si l'appel a réussi.

durationMs?:

number
Temps d'exécution en millisecondes.

metadata?:

Record<string, unknown>
Métadonnées arbitraires.

children?:

TrajectoryStep[]
Sous-étapes imbriquées.

WorkflowStepStep
Lien direct vers workflowstepstep

Représente l'exécution d'une étape de workflow.

stepType:

'workflow_step'
Discriminant.

name:

string
Identifiant de l'étape.

stepId?:

string
ID de l'étape dans le workflow.

status?:

string
Statut du résultat de l'étape (success, failed, suspended, etc.).

output?:

Record<string, unknown>
Données de sortie de l'étape.

durationMs?:

number
Temps d'exécution en millisecondes.

metadata?:

Record<string, unknown>
Métadonnées arbitraires.

children?:

TrajectoryStep[]
Sous-étapes imbriquées (par ex. appels d'outils dans l'étape).

Autres types d'étapes
Lien direct vers Autres types d'étapes

L'union discriminée comprend les types d'étapes supplémentaires suivants :

Type d'étapePropriétés principales
mcp_tool_calltoolArgs, toolResult, mcpServer, success
model_generationmodelId, promptTokens, completionTokens, finishReason
agent_runagentId
workflow_runworkflowId, status
workflow_conditionalconditionCount, selectedSteps
workflow_parallelbranchCount, parallelSteps
workflow_looploopType, totalIterations
workflow_sleepdurationMs, sleepType
workflow_wait_eventeventName, eventReceived
processor_runprocessorId

Tous les types d'étapes partagent les propriétés de base name, durationMs, metadata et children.

Étapes attendues
Lien direct vers Étapes attendues

Lorsque vous définissez des trajectoires attendues, utilisez ExpectedStep plutôt que l'union discriminée TrajectoryStep complète. ExpectedStep est une union discriminée qui reflète TrajectoryStep : lorsque vous spécifiez un stepType, la saisie semi-automatique est disponible pour les champs de cette variante (par ex. toolArgs pour tool_call, modelId pour model_generation). Tous les champs propres aux variantes sont facultatifs ; vous ne formulez donc des assertions que sur les éléments qui vous intéressent.

Omettez entièrement stepType pour établir une correspondance avec n'importe quelle étape à partir de son seul nom.

name:

string
Nom de l'étape à mettre en correspondance (nom de l'outil, ID de l'agent, nom de l'étape du workflow, etc.).

stepType?:

TrajectoryStepType
Discriminant du type d'étape. Lorsqu'il est défini, active la saisie semi-automatique pour les champs de cette variante. S'il est omis, établit une correspondance avec tout type d'étape portant le nom indiqué.

(champs de variante)?:

varies
Champs propres au type de la variante TrajectoryStep correspondante. Par exemple, toolArgs et toolResult pour tool_call, modelId pour model_generation, output pour workflow_step. Tous sont facultatifs — seuls les champs spécifiés sont comparés.

children?:

TrajectoryExpectation
Configuration d'attentes imbriquée pour les enfants de cette étape. Remplace la configuration parente lors de l'évaluation des enfants de cette étape.

Étapes attendues simples
Lien direct vers Étapes attendues simples

const steps: ExpectedStep[] = [
// Match by name only (any step type)
{ name: 'search' },

// Match by name and step type (autocomplete for tool_call fields)
{ name: 'search', stepType: 'tool_call' },

// Match with specific toolArgs (auto-compared when present)
{ name: 'search', stepType: 'tool_call', toolArgs: { query: 'weather' } },

// Match a model generation step by model ID
{ name: 'gpt-4o', stepType: 'model_generation', modelId: 'gpt-4o' },
]

Attentes imbriquées
Lien direct vers Attentes imbriquées

Chaque étape attendue peut inclure une configuration children dotée de ses propres règles d'évaluation. Vous pouvez ainsi définir des règles d'ordre ou de comparaison différentes à chaque niveau de la hiérarchie.

const scorer = createTrajectoryScorerCode({
defaults: {
ordering: 'strict',
steps: [
{ name: 'validate-input', stepType: 'workflow_step' },
{
name: 'research-agent',
stepType: 'agent_run',
children: {
// Sub-agent can call tools in any order
ordering: 'unordered',
steps: [
{ name: 'search', stepType: 'tool_call' },
{ name: 'summarize', stepType: 'tool_call' },
],
},
},
{ name: 'save-result', stepType: 'workflow_step' },
],
},
})

Dans cet exemple, le workflow parent impose un ordre strict à ses étapes, tandis que le research-agent imbriqué autorise ses appels d'outils dans n'importe quel ordre.

Choisir entre les évaluateurs
Lien direct vers Choisir entre les évaluateurs

Utilisez l'évaluateur basé sur le code lorsque :
Lien direct vers Utilisez l'évaluateur basé sur le code lorsque :

  • Vous avez besoin de résultats déterministes et reproductibles
  • Vous disposez d'une trajectoire attendue connue à laquelle effectuer la comparaison
  • Vous souhaitez valider des séquences d'étapes exactes
  • La vitesse et le coût sont prioritaires (aucun appel de LLM)
  • Vous exécutez des tests automatisés en CI/CD

Utilisez l'évaluateur basé sur un LLM lorsque :
Lien direct vers Utilisez l'évaluateur basé sur un LLM lorsque :

  • Vous avez besoin d'une compréhension sémantique pour déterminer si les étapes étaient appropriées
  • La trajectoire optimale n'est pas prédéterminée (évaluation fondée sur les exigences de la tâche)
  • Vous souhaitez détecter les étapes inutiles, redondantes ou manquantes
  • Vous avez besoin d'explications sur les décisions d'attribution du score
  • Vous évaluez le comportement d'un agent en production

Évaluateur de précision de trajectoire basé sur le code
Lien direct vers Évaluateur de précision de trajectoire basé sur le code

La fonction createTrajectoryAccuracyScorerCode() de @mastra/evals/scorers/prebuilt fournit un score déterministe fondé sur la correspondance et l'ordre des étapes par rapport à une trajectoire attendue.

Paramètres
Lien direct vers Paramètres

expectedTrajectory?:

Trajectory | ExpectedStep[]
Trajectoire attendue statique à laquelle effectuer la comparaison. Accepte une Trajectory complète ou un tableau d'éléments de correspondance ExpectedStep. Lorsqu'elle est omise, l'évaluateur lit expectedTrajectory dans chaque élément du jeu de données au moment de l'exécution.

comparisonOptions?:

TrajectoryComparisonOptions
Contrôle la manière dont la comparaison est effectuée.
boolean
boolean

Cette fonction renvoie une instance de la classe MastraScorer. Consultez la référence de MastraScorer pour plus de détails sur la méthode .run() et ses entrées/sorties.

Sources de la trajectoire attendue
Lien direct vers Sources de la trajectoire attendue

L'évaluateur basé sur le code détermine expectedTrajectory à partir de deux sources, par ordre de priorité :

  1. Option du constructeur : trajectoire statique transmise lors de la création de l'évaluateur. Utilisée pour tous les éléments du jeu de données.
  2. Élément du jeu de données : champ expectedTrajectory de l'élément du jeu de données, transmis par le pipeline runEvals. Permet de définir une trajectoire attendue différente pour chaque élément.
src/static-expected.ts
// Static: same expected trajectory for all items
const scorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search' },
{ stepType: 'tool_call', name: 'summarize' },
],
},
})
src/per-item-expected.ts
// Per-item: each dataset item has its own expectedTrajectory
const scorer = createTrajectoryAccuracyScorerCode()

await runEvals({
target: myAgent,
scorers: { trajectory: [scorer] },
data: [
{
input: 'Search and summarize weather',
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search' },
{ stepType: 'tool_call', name: 'summarize' },
],
},
},
{
input: 'Just search for weather',
expectedTrajectory: {
steps: [{ stepType: 'tool_call', name: 'search' }],
},
},
],
})

Modes d'évaluation
Lien direct vers Modes d'évaluation

L'évaluateur basé sur le code fonctionne selon deux modes déterminés par strictOrder :

Mode strict (strictOrder: true)
Lien direct vers strict-mode-strictorder-true

Exige une correspondance exacte. Les étapes réelles doivent correspondre aux étapes attendues dans le même ordre, sans étape supplémentaire ni manquante. Renvoie 1.0 en cas de correspondance exacte et 0.0 dans le cas contraire.

Mode souple (strictOrder: false, par défaut)
Lien direct vers relaxed-mode-strictorder-false-default

Autorise les étapes supplémentaires. Les étapes attendues doivent apparaître dans le bon ordre relatif. Le score est calculé selon le nombre d'étapes attendues mises en correspondance, avec des pénalités facultatives pour les étapes supplémentaires ou répétées.

Détails du score basé sur le code
Lien direct vers Détails du score basé sur le code

  • Scores continus : renvoie des valeurs comprises entre 0.0 et 1.0 en mode souple ; résultat binaire (0 ou 1) en mode strict
  • Déterministe : une même entrée produit toujours la même sortie
  • Rapide : aucun appel d'API externe

Résultats de l'évaluateur basé sur le code
Lien direct vers Résultats de l'évaluateur basé sur le code

{
runId: string,
preprocessStepResult: {
actualTrajectory: Trajectory,
expectedTrajectory: Trajectory,
comparison: {
score: number,
matchedSteps: number,
totalExpectedSteps: number,
totalActualSteps: number,
missingSteps: string[],
extraSteps: string[],
outOfOrderSteps: string[],
repeatedSteps: string[]
},
actualStepNames: string[],
expectedStepNames: string[]
},
score: number
}

Exemples d'évaluateur basé sur le code
Lien direct vers Exemples d'évaluateur basé sur le code

Trajectoire d'agent avec ordre strict
Lien direct vers Trajectoire d'agent avec ordre strict

Vérifie qu'un agent suit une séquence exacte d'appels d'outils :

src/example-strict-trajectory.ts
import { createTrajectoryAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt'
import { runEvals } from '@mastra/core/evals'

const scorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'auth-tool' },
{ stepType: 'tool_call', name: 'fetch-tool' },
],
},
comparisonOptions: { strictOrder: true },
})

const result = await runEvals({
target: myAgent,
scorers: { trajectory: [scorer] },
data: [{ input: 'Get my data' }],
})

console.log(result.scores.trajectory['trajectory-accuracy']) // 1.0

Trajectoire d'agent avec ordre souple
Lien direct vers Trajectoire d'agent avec ordre souple

Autorise des étapes supplémentaires tant que les étapes attendues apparaissent dans le bon ordre relatif :

src/example-relaxed-trajectory.ts
const scorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search-tool' },
{ stepType: 'tool_call', name: 'summarize-tool' },
],
},
comparisonOptions: { strictOrder: false },
})

// Agent called search-tool → log-tool → summarize-tool
// The extra log-tool is allowed in relaxed mode
// score: 0.75 — all expected steps matched, small penalty for extra step

Trajectoire de workflow
Lien direct vers Trajectoire de workflow

Évalue le chemin d'exécution d'un workflow :

src/example-workflow-trajectory.ts
import { createTrajectoryAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt'
import { runEvals } from '@mastra/core/evals'

const scorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'workflow_step', name: 'validate-input' },
{ stepType: 'workflow_step', name: 'process-data' },
{ stepType: 'workflow_step', name: 'save-result' },
],
},
})

const result = await runEvals({
target: myWorkflow,
scorers: { trajectory: [scorer] },
data: [{ input: { data: 'test' } }],
})

console.log(result.scores.trajectory['trajectory-accuracy'])

Comparaison des données d'étape
Lien direct vers Comparaison des données d'étape

Valide les noms des étapes et les données propres à chacune. Pour les appels d'outils, cette opération compare toolArgs et toolResult. Pour les étapes de workflow, elle compare output.

src/example-trajectory-with-data.ts
const scorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{
stepType: 'tool_call',
name: 'search-tool',
toolArgs: { query: 'weather in NYC' },
},
],
},
})
// Data fields like toolArgs are auto-compared when present on expected steps

Évaluateur de précision de trajectoire basé sur un LLM
Lien direct vers Évaluateur de précision de trajectoire basé sur un LLM

La fonction createTrajectoryAccuracyScorerLLM() de @mastra/evals/scorers/prebuilt utilise un LLM pour déterminer si la trajectoire d'un agent ou d'un workflow était appropriée, efficace et complète.

Paramètres
Lien direct vers Paramètres

model:

MastraModelConfig
Le modèle LLM à utiliser pour évaluer la qualité de la trajectoire.

expectedTrajectory?:

Trajectory | ExpectedStep[]
Trajectoire attendue statique facultative à laquelle effectuer la comparaison. Accepte une Trajectory complète ou un tableau d'éléments de correspondance ExpectedStep. Lorsqu'elle est omise, le LLM évalue la trajectoire uniquement à partir des exigences de la tâche. Peut également provenir des éléments du jeu de données au moment de l'exécution.

Fonctionnalités
Lien direct vers Fonctionnalités

L'évaluateur basé sur un LLM offre les fonctionnalités suivantes :

  • Évaluation tenant compte de la tâche : détermine si chaque étape était nécessaire au regard de la demande de l'utilisateur
  • Évaluation de l'ordre : détermine si les étapes ont été réalisées dans un ordre logique
  • Détection des étapes manquantes : identifie les étapes qui auraient dû être réalisées
  • Détection des redondances : signale les étapes inutiles ou répétées
  • Génération du raisonnement : fournit des explications lisibles sur les décisions d'attribution du score

Processus d'évaluation
Lien direct vers Processus d'évaluation

  1. Réception de la trajectoire : récupère auprès du pipeline un objet Trajectory préalablement extrait
  2. Analyse des étapes : évalue avec le LLM la nécessité et l'ordre de chaque étape
  3. Génération du score : calcule un score pondéré à 60 % pour la nécessité et à 30 % pour l'ordre, puis retranche une pénalité de 10 % pour les éléments manquants
  4. Génération du raisonnement : fournit une explication lisible

Détails du score basé sur un LLM
Lien direct vers Détails du score basé sur un LLM

  • Scores fractionnaires : renvoie des valeurs comprises entre 0.0 et 1.0
  • Prise en compte du contexte : tient compte de l'intention de l'utilisateur et des exigences de la tâche
  • Explicatif : justifie les scores
  • Flexible : fonctionne avec ou sans trajectoire attendue

Options de l'évaluateur basé sur un LLM
Lien direct vers Options de l'évaluateur basé sur un LLM

// Evaluate based on task requirements (no expected trajectory)
const openScorer = createTrajectoryAccuracyScorerLLM({
model: { provider: 'openai', name: 'gpt-5.4' },
})

// Evaluate against a static expected trajectory
const guidedScorer = createTrajectoryAccuracyScorerLLM({
model: { provider: 'openai', name: 'gpt-5.4' },
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search-tool' },
{ stepType: 'tool_call', name: 'summarize-tool' },
],
},
})

Résultats de l'évaluateur basé sur un LLM
Lien direct vers Résultats de l'évaluateur basé sur un LLM

{
runId: string,
preprocessStepResult: {
actualTrajectory: Trajectory,
actualTrajectoryFormatted: string,
expectedTrajectoryFormatted?: string,
hasSteps: boolean
},
analyzeStepResult: {
stepEvaluations: Array<{
stepName: string,
wasNecessary: boolean,
wasInOrder: boolean,
reasoning: string
}>,
missingSteps?: string[],
extraSteps?: string[],
overallAssessment: string
},
score: number,
reason: string
}

Évaluateur de trajectoire unifié
Lien direct vers Évaluateur de trajectoire unifié

La fonction createTrajectoryScorerCode() de @mastra/evals/scorers/prebuilt fournit une évaluation multidimensionnelle de la trajectoire qui vérifie en une seule passe la précision, l'efficacité, les outils placés sur liste noire et les schémas d'échec des outils.

Paramètres
Lien direct vers Paramètres

defaults?:

TrajectoryExpectation
Attentes par défaut appliquées à tous les éléments du jeu de données. Les valeurs expectedTrajectory propres à chaque élément remplacent ces valeurs par défaut.
ExpectedStep[]
'strict' | 'relaxed' | 'unordered'
boolean
number
number
number
boolean
string[]
string[][]
number

weights?:

TrajectoryScoreWeights
Pondérations personnalisées pour combiner les scores des dimensions. Les pondérations sont normalisées afin que leur somme soit égale à 1.0.
number
number
number
number

Comportement du calcul du score
Lien direct vers Comportement du calcul du score

L'évaluateur unifié analyse quatre dimensions :

  1. Précision : compare les étapes réelles aux étapes attendues (si steps est configuré). Utilise le mode ordering.
  2. Efficacité : vérifie les budgets d'étapes (maxSteps, maxTotalTokens, maxTotalDurationMs) et les appels redondants (noRedundantCalls).
  3. Liste noire : recherche les outils ou séquences interdits. Toute infraction entraîne immédiatement un score de 0.0, indépendamment des autres dimensions.
  4. Échecs d'outils : détecte les schémas de nouvelles tentatives et de repli. Détecte également les schémas de correction des arguments.

Le score final est une combinaison pondérée des dimensions actives, normalisée en fonction de celles qui sont actives. Les pondérations par défaut sont de 0.4 pour la précision, 0.3 pour l'efficacité, 0.2 pour les échecs d'outils et 0.1 pour la liste noire, mais vous pouvez les personnaliser avec l'option weights. Les infractions à la liste noire prévalent sur tout le reste et fixent le score à 0. Lorsque des évaluations imbriquées sont présentes, le score se compose à 70 % du niveau supérieur et à 30 % de la moyenne imbriquée.

Résultats de l'évaluateur unifié
Lien direct vers Résultats de l'évaluateur unifié

{
runId: string,
preprocessStepResult: {
accuracy?: TrajectoryComparisonResult,
efficiency?: TrajectoryEfficiencyResult,
blacklist?: TrajectoryBlacklistResult,
toolFailures?: ToolFailureAnalysisResult,
nested?: NestedEvaluationResult[],
},
score: number,
reason: string
}

Attentes propres à chaque élément
Lien direct vers Attentes propres à chaque élément

Chaque élément du jeu de données peut remplacer les valeurs par défaut par son propre expectedTrajectory. Vous pouvez ainsi faire varier les attentes pour chaque prompt :

src/unified-per-item.ts
import { createTrajectoryScorerCode } from '@mastra/evals/scorers/prebuilt'
import { runEvals } from '@mastra/core/evals'

// Default blacklist applies to all items
const scorer = createTrajectoryScorerCode({
defaults: {
blacklistedTools: ['deleteAll'],
maxSteps: 5,
},
})

const result = await runEvals({
target: myAgent,
scorers: { trajectory: [scorer] },
data: [
{
input: 'Search for weather',
expectedTrajectory: {
steps: [{ stepType: 'tool_call', name: 'search' }],
maxSteps: 2,
},
},
{
input: 'Search and summarize',
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search' },
{ stepType: 'tool_call', name: 'summarize' },
],
},
},
],
})

Exemple : efficacité et liste noire
Lien direct vers Exemple : efficacité et liste noire

src/unified-scorer.ts
import { createTrajectoryScorerCode } from '@mastra/evals/scorers/prebuilt'

const scorer = createTrajectoryScorerCode({
defaults: {
blacklistedTools: ['escalate', 'admin-override'],
blacklistedSequences: [['escalate', 'admin-override']],
maxSteps: 10,
noRedundantCalls: true,
maxRetriesPerTool: 2,
},
// Customize how dimensions contribute to the final score
weights: {
accuracy: 0.5, // prioritize step accuracy
efficiency: 0.3,
toolFailures: 0.1,
blacklist: 0.1,
},
})

Utiliser les évaluateurs de trajectoire avec runEvals
Lien direct vers using-trajectory-scorers-with-runevals

Les évaluateurs de trajectoire sont configurés sous la clé trajectory dans la configuration de l'évaluateur. Le pipeline runEvals prend automatiquement en charge l'extraction des trajectoires.

Évaluation de la trajectoire d'un agent
Lien direct vers Évaluation de la trajectoire d'un agent

src/agent-trajectory-eval.ts
import { runEvals } from '@mastra/core/evals'
import { createTrajectoryAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt'

const trajectoryScorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'tool_call', name: 'search' },
{ stepType: 'tool_call', name: 'format' },
],
},
})

const result = await runEvals({
target: myAgent,
scorers: {
agent: [qualityScorer], // receives raw MastraDBMessage[] output
trajectory: [trajectoryScorer], // receives pre-extracted Trajectory
},
data: [{ input: 'Find and format the data' }],
})

// result.scores.agent['quality'] — agent-level score
// result.scores.trajectory['trajectory-accuracy'] — trajectory score

Évaluation de la trajectoire d'un workflow
Lien direct vers Évaluation de la trajectoire d'un workflow

src/workflow-trajectory-eval.ts
import { runEvals } from '@mastra/core/evals'
import { createTrajectoryAccuracyScorerCode } from '@mastra/evals/scorers/prebuilt'

const workflowTrajectoryScorer = createTrajectoryAccuracyScorerCode({
expectedTrajectory: {
steps: [
{ stepType: 'workflow_step', name: 'validate' },
{ stepType: 'workflow_step', name: 'process' },
{ stepType: 'workflow_step', name: 'notify' },
],
},
})

const result = await runEvals({
target: myWorkflow,
scorers: {
workflow: [outputScorer], // receives workflow output
trajectory: [workflowTrajectoryScorer], // receives pre-extracted Trajectory from step results
},
data: [{ input: { userId: '123' } }],
})

// result.scores.workflow['output-quality'] — workflow-level score
// result.scores.trajectory['trajectory-accuracy'] — trajectory score