> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # Utilitaires de Scorer Mastra fournit des fonctions utilitaires qui facilitent l'extraction et le traitement des données issues des entrées et sorties d'exécution des Scorers. Ces utilitaires sont particulièrement utiles lors de l'étape `preprocess` des Scorers personnalisés. ## Import ```typescript import { getAssistantMessageFromRunOutput, getReasoningFromRunOutput, getUserMessageFromRunInput, getSystemMessagesFromRunInput, getCombinedSystemPrompt, extractToolCalls, extractInputMessages, extractAgentResponseMessages, compareTrajectories, createTrajectoryTestRun, } from '@mastra/evals/scorers/utils' ``` Les fonctions d'extraction des trajectoires sont disponibles depuis `@mastra/core/evals` : ```typescript import { extractTrajectory, extractWorkflowTrajectory, extractTrajectoryFromTrace, } from '@mastra/core/evals' ``` ## Extraction des messages ### `getAssistantMessageFromRunOutput` Extrait le contenu textuel du premier message de l'assistant dans la sortie d'exécution. ```typescript const scorer = createScorer({ id: 'my-scorer', description: 'My scorer', type: 'agent', }) .preprocess(({ run }) => { const response = getAssistantMessageFromRunOutput(run.output) return { response } }) .generateScore(({ results }) => { return results.preprocessStepResult?.response ? 1 : 0 }) ``` **output** (`ScorerRunOutputForAgent`): Sortie d'exécution du Scorer (tableau de MastraDBMessage) **Renvoie :** `string | undefined` - Le texte du message de l'assistant, ou undefined si aucun message de l'assistant n'est trouvé. ### `getUserMessageFromRunInput` Extrait le contenu textuel du premier message utilisateur dans l'entrée d'exécution. ```typescript .preprocess(({ run }) => { const userMessage = getUserMessageFromRunInput(run.input); return { userMessage }; }) ``` **input** (`ScorerRunInputForAgent`): Entrée d'exécution du Scorer contenant les messages d'entrée **Renvoie :** `string | undefined` - Le texte du message utilisateur, ou undefined si aucun message utilisateur n'est trouvé. ### `extractInputMessages` Extrait sous forme de tableau le contenu textuel de tous les messages d'entrée. ```typescript .preprocess(({ run }) => { const allUserMessages = extractInputMessages(run.input); return { conversationHistory: allUserMessages.join("\n") }; }) ``` **Renvoie :** `string[]` - Tableau de chaînes de texte provenant de chaque message d'entrée. ### `extractAgentResponseMessages` Extrait sous forme de tableau le contenu textuel de tous les messages de réponse de l'assistant. ```typescript .preprocess(({ run }) => { const allResponses = extractAgentResponseMessages(run.output); return { allResponses }; }) ``` **Renvoie :** `string[]` - Tableau de chaînes de texte provenant de chaque message de l'assistant. ## Extraction du raisonnement ### `getReasoningFromRunOutput` Extrait le texte de raisonnement de la sortie d'exécution. Cette fonction est particulièrement utile pour évaluer les réponses de modèles de raisonnement tels que `deepseek-reasoner`, qui produisent un raisonnement en chaîne de pensée. Le raisonnement peut être stocké à deux emplacements : 1. `content.reasoning` - un champ chaîne du contenu du message 2. `content.parts` - sous forme de parties avec `type: 'reasoning'` contenant `details` ```typescript import { getReasoningFromRunOutput, getAssistantMessageFromRunOutput, } from '@mastra/evals/scorers/utils' const reasoningQualityScorer = createScorer({ id: 'reasoning-quality', name: 'Reasoning Quality', description: 'Evaluates the quality of model reasoning', type: 'agent', }) .preprocess(({ run }) => { const reasoning = getReasoningFromRunOutput(run.output) const response = getAssistantMessageFromRunOutput(run.output) return { reasoning, response } }) .analyze(({ results }) => { const { reasoning } = results.preprocessStepResult || {} return { hasReasoning: !!reasoning, reasoningLength: reasoning?.length || 0, hasStepByStep: reasoning?.includes('step') || false, } }) .generateScore(({ results }) => { const { hasReasoning, reasoningLength } = results.analyzeStepResult || {} if (!hasReasoning) return 0 // Score based on reasoning length (normalized to 0-1) return Math.min(reasoningLength / 500, 1) }) .generateReason(({ results, score }) => { const { hasReasoning, reasoningLength } = results.analyzeStepResult || {} if (!hasReasoning) { return 'No reasoning was provided by the model.' } return `Model provided ${reasoningLength} characters of reasoning. Score: ${score}` }) ``` **output** (`ScorerRunOutputForAgent`): Sortie d'exécution du Scorer (tableau de MastraDBMessage) **Renvoie :** `string | undefined` - Le texte de raisonnement, ou undefined si aucun raisonnement n'est présent. ## Extraction des messages système ### `getSystemMessagesFromRunInput` Extrait tous les messages système de l'entrée d'exécution, notamment les messages système standard et ceux comportant des tags, tels que les prompts spécialisés d'instructions de mémoire. ```typescript .preprocess(({ run }) => { const systemMessages = getSystemMessagesFromRunInput(run.input); return { systemPromptCount: systemMessages.length, systemPrompts: systemMessages }; }) ``` **Renvoie :** `string[]` - Tableau de chaînes de messages système. ### `getCombinedSystemPrompt` Combine tous les messages système en une seule chaîne de prompt, séparés par deux retours à la ligne. ```typescript .preprocess(({ run }) => { const fullSystemPrompt = getCombinedSystemPrompt(run.input); return { fullSystemPrompt }; }) ``` **Renvoie :** `string` - Chaîne combinée du prompt système. ## Extraction des appels de Tool ### `extractToolCalls` Extrait des informations sur tous les appels de Tool de la sortie d'exécution, notamment les noms des Tools, les identifiants des appels et leur position dans le tableau de messages. ```typescript const toolUsageScorer = createScorer({ id: 'tool-usage', description: 'Evaluates tool usage patterns', type: 'agent', }) .preprocess(({ run }) => { const { tools, toolCallInfos } = extractToolCalls(run.output) return { toolsUsed: tools, toolCount: tools.length, toolDetails: toolCallInfos, } }) .generateScore(({ results }) => { const { toolCount } = results.preprocessStepResult || {} // Score based on appropriate tool usage return toolCount > 0 ? 1 : 0 }) ``` **Renvoie :** ```typescript { tools: string[]; // Array of tool names toolCallInfos: ToolCallInfo[]; // Detailed tool call information } ``` Où `ToolCallInfo` est : ```typescript type ToolCallInfo = { toolName: string // Name of the tool toolCallId: string // Unique call identifier messageIndex: number // Index in the output array invocationIndex: number // Index within message's tool invocations } ``` ## Utilitaires de test Ces utilitaires facilitent la création de données de test pour le développement des Scorers. ### `createTestMessage` Crée un objet `MastraDBMessage` destiné aux tests. ```typescript import { createTestMessage } from '@mastra/evals/scorers/utils' const userMessage = createTestMessage({ content: 'What is the weather?', role: 'user', }) const assistantMessage = createTestMessage({ content: 'The weather is sunny.', role: 'assistant', toolInvocations: [ { toolCallId: 'call-1', toolName: 'weatherTool', args: { location: 'London' }, result: { temp: 20 }, state: 'result', }, ], }) ``` ### `createAgentTestRun` Crée un objet d'exécution de test complet pour tester les Scorers. ```typescript import { createAgentTestRun, createTestMessage } from '@mastra/evals/scorers/utils' const testRun = createAgentTestRun({ inputMessages: [createTestMessage({ content: 'Hello', role: 'user' })], output: [createTestMessage({ content: 'Hi there!', role: 'assistant' })], }) // Run your scorer with the test data const result = await myScorer.run({ input: testRun.input, output: testRun.output, }) ``` ## Utilitaires de trajectoire ### `extractTrajectory` Extrait une `Trajectory` des messages de sortie de l'Agent (`MastraDBMessage[]`). Convertit les invocations de Tool en objets `ToolCallStep`. Le pipeline `runEvals` l'appelle automatiquement pour les Scorers de trajectoire : vous n'en avez besoin que pour les tests directs. Disponible depuis `@mastra/core/evals`. ```typescript import { extractTrajectory } from '@mastra/core/evals' const trajectory = extractTrajectory(agentOutputMessages) // trajectory.steps — ToolCallStep[] extracted from toolInvocations // trajectory.rawOutput — the original MastraDBMessage[] array ``` **Renvoie :** `Trajectory` : contient `steps: TrajectoryStep[]`, `totalDurationMs` et `rawOutput`. ### `extractWorkflowTrajectory` Extrait une `Trajectory` des résultats d'étapes du Workflow. Convertit les enregistrements `StepResult` en objets `WorkflowStepStep`, dans l'ordre du chemin d'exécution. Disponible depuis `@mastra/core/evals`. ```typescript import { extractWorkflowTrajectory } from '@mastra/core/evals' const trajectory = extractWorkflowTrajectory( workflowResult.steps, // Record workflowResult.stepExecutionPath, // string[] (optional) ) // trajectory.steps — WorkflowStepStep[] in execution order ``` **Renvoie :** `Trajectory` : contient `steps: TrajectoryStep[]`, `totalDurationMs` et `rawWorkflowResult`. ### `extractTrajectoryFromTrace` Construit une `Trajectory` hiérarchique à partir des spans d'une Trace d'Observability (`SpanRecord[]`). Reconstruit l'arborescence parent-enfant des spans et associe chaque span au type union discriminé `TrajectoryStep` approprié, avec des `children` imbriqués. Il s'agit de la méthode d'extraction privilégiée lorsque le stockage est disponible. Le pipeline `runEvals` l'appelle automatiquement lorsque l'instance `Mastra` de la cible dispose d'un backend de stockage configuré. Elle produit des trajectoires plus riches que `extractTrajectory` ou `extractWorkflowTrajectory`, car elle capture l'intégralité de l'arborescence d'exécution, notamment les exécutions d'Agents imbriquées, les appels de Tool et les générations de modèles. Disponible depuis `@mastra/core/evals`. ```typescript import { extractTrajectoryFromTrace } from '@mastra/core/evals' // After fetching a trace from the observability store const traceData = await observabilityStore.getTrace({ traceId }) const trajectory = extractTrajectoryFromTrace(traceData.spans, rootSpanId) // trajectory.steps — hierarchical TrajectoryStep[] with children ``` **Paramètres :** - `spans` (`SpanRecord[]`) : tableau d'enregistrements de spans provenant d'une requête de Trace. - `rootSpanId` (`string`, facultatif) : identifiant du span à utiliser comme point de départ. Lorsqu'il est omis, utilise les spans sans parent. **Renvoie :** `Trajectory` : contient `steps: TrajectoryStep[]` avec des `children` récursifs et `totalDurationMs`. #### Correspondance des types de span | Type de span | Type d'étape de trajectoire | Principaux champs extraits | | ---------------------- | --------------------------- | ------------------------------------------------------------- | | `TOOL_CALL` | `tool_call` | `toolArgs`, `toolResult`, `success` | | `MCP_TOOL_CALL` | `mcp_tool_call` | `toolArgs`, `toolResult`, `mcpServer`, `success` | | `MODEL_GENERATION` | `model_generation` | `modelId`, `promptTokens`, `completionTokens`, `finishReason` | | `AGENT_RUN` | `agent_run` | `agentId` (depuis l'identifiant de l'entité) | | `WORKFLOW_RUN` | `workflow_run` | `workflowId` (depuis l'identifiant de l'entité) | | `WORKFLOW_STEP` | `workflow_step` | `output` | | `WORKFLOW_CONDITIONAL` | `workflow_conditional` | `conditionCount`, `selectedSteps` | | `WORKFLOW_PARALLEL` | `workflow_parallel` | `branchCount`, `parallelSteps` | | `WORKFLOW_LOOP` | `workflow_loop` | `loopType`, `totalIterations` | | `WORKFLOW_SLEEP` | `workflow_sleep` | `sleepDurationMs`, `sleepType` | | `WORKFLOW_WAIT_EVENT` | `workflow_wait_event` | `eventName`, `eventReceived` | | `PROCESSOR_RUN` | `processor_run` | `processorId` | Les spans de type `GENERIC`, `MODEL_STEP`, `MODEL_CHUNK` et `WORKFLOW_CONDITIONAL_EVAL` sont ignorés, car ils constituent du bruit. ### `compareTrajectories` Compare une trajectoire réelle à une trajectoire attendue et renvoie un résultat de comparaison détaillé. Utilisée en interne par `createTrajectoryAccuracyScorerCode`. Le paramètre `expected` accepte soit une `Trajectory` (trajectoire réelle), soit `{ steps: ExpectedStep[] }`. Lorsque vous utilisez `ExpectedStep[]`, vous pouvez établir la correspondance uniquement par nom ou par nom + stepType. Vous pouvez également inclure des données à comparer. Consultez les [étapes attendues](https://mastra.zisheng.pro/fr/reference/evals/trajectory-accuracy) pour plus de détails. ```typescript import { compareTrajectories } from '@mastra/evals/scorers/utils' // Using ExpectedStep[] (recommended for expectations) // Data fields (e.g. toolArgs) are auto-compared when present on expected steps const result = compareTrajectories( actualTrajectory, { steps: [{ name: 'search' }, { name: 'summarize', stepType: 'tool_call' }] }, { allowRepeatedSteps: true }, ) // result.score — 0.0 to 1.0 // result.missingSteps — step names not found // result.extraSteps — unexpected step names // result.outOfOrderSteps — steps found but in wrong order ``` **Renvoie :** `TrajectoryComparisonResult` ### `createTrajectoryTestRun` Crée un objet d'exécution de test pour les Scorers de trajectoire. Enveloppe une `Trajectory` dans le format `ScorerRun` attendu. ```typescript import { createTrajectoryTestRun } from '@mastra/evals/scorers/utils' const run = createTrajectoryTestRun({ steps: [ { stepType: 'tool_call', name: 'search', toolArgs: { q: 'test' } }, { stepType: 'tool_call', name: 'summarize' }, ], }) const result = await trajectoryScorer.run(run) ``` ### `checkTrajectoryEfficiency` Évalue l'efficacité d'une trajectoire par rapport aux budgets d'étapes, de tokens et de durée. Détecte également les appels redondants, c'est-à-dire au même Tool avec les mêmes arguments. ```typescript import { checkTrajectoryEfficiency } from '@mastra/evals/scorers/utils' const result = checkTrajectoryEfficiency(trajectory, { maxSteps: 5, maxTotalTokens: 2000, maxTotalDurationMs: 5000, noRedundantCalls: true, }) // result.score — 1.0 if within all budgets, lower with penalties // result.redundantCalls — duplicate tool+args combos // result.overStepBudget — true if maxSteps exceeded // result.overTokenBudget — true if maxTotalTokens exceeded // result.overDurationBudget — true if maxTotalDurationMs exceeded ``` **Renvoie :** `TrajectoryEfficiencyResult` ### `checkTrajectoryBlacklist` Vérifie si une trajectoire contient des Tools ou des séquences d'appels de Tool interdits. ```typescript import { checkTrajectoryBlacklist } from '@mastra/evals/scorers/utils' const result = checkTrajectoryBlacklist(trajectory, { blacklistedTools: ['deleteAll', 'admin-override'], blacklistedSequences: [['escalate', 'admin-override']], }) // result.score — 1.0 if no violations, 0.0 if any found // result.violatedTools — blacklisted tools that were called // result.violatedSequences — blacklisted sequences that were detected ``` **Renvoie :** `TrajectoryBlacklistResult` ### `analyzeToolFailures` Détecte les modèles d'échec des Tools, notamment les nouvelles tentatives, les solutions de repli et les corrections d'arguments. ```typescript import { analyzeToolFailures } from '@mastra/evals/scorers/utils' const result = analyzeToolFailures(trajectory, { maxRetriesPerTool: 2, }) // result.score — 1.0 if no failure patterns, lower if patterns detected // result.patterns — detected patterns (retry, fallback, arg_correction) ``` **Renvoie :** `ToolFailureAnalysisResult` ## Exemple complet Voici un exemple complet qui montre comment utiliser plusieurs utilitaires ensemble : ```typescript import { createScorer } from '@mastra/core/evals' import { getAssistantMessageFromRunOutput, getReasoningFromRunOutput, getUserMessageFromRunInput, getCombinedSystemPrompt, extractToolCalls, } from '@mastra/evals/scorers/utils' const comprehensiveScorer = createScorer({ id: 'comprehensive-analysis', name: 'Comprehensive Analysis', description: 'Analyzes all aspects of an agent response', type: 'agent', }) .preprocess(({ run }) => { // Extract all relevant data const userMessage = getUserMessageFromRunInput(run.input) const response = getAssistantMessageFromRunOutput(run.output) const reasoning = getReasoningFromRunOutput(run.output) const systemPrompt = getCombinedSystemPrompt(run.input) const { tools, toolCallInfos } = extractToolCalls(run.output) return { userMessage, response, reasoning, systemPrompt, toolsUsed: tools, toolCount: tools.length, } }) .generateScore(({ results }) => { const { response, reasoning, toolCount } = results.preprocessStepResult || {} let score = 0 if (response && response.length > 0) score += 0.4 if (reasoning) score += 0.3 if (toolCount > 0) score += 0.3 return score }) .generateReason(({ results, score }) => { const { response, reasoning, toolCount } = results.preprocessStepResult || {} const parts = [] if (response) parts.push('provided a response') if (reasoning) parts.push('included reasoning') if (toolCount > 0) parts.push(`used ${toolCount} tool(s)`) return `Score: ${score}. The agent ${parts.join(', ')}.` }) ```