createScorer
Mastra fournit une factory createScorer unifiée qui permet de définir des Scorers personnalisés pour évaluer des paires entrée/sortie. Chaque étape d'évaluation peut utiliser des fonctions JavaScript natives ou des objets de prompt fondés sur un LLM. Les Scorers personnalisés peuvent être ajoutés aux Agents et aux étapes de Workflow.
Création d'un Scorer personnaliséLien direct vers Création d'un Scorer personnalisé
Utilisez la factory createScorer pour définir votre Scorer avec un nom, une description et une configuration facultative du juge. Enchaînez ensuite les méthodes d'étape afin de construire votre pipeline d'évaluation. Vous devez fournir au moins une étape generateScore.
Les étapes sous forme d'objet de prompt sont des configurations exprimées comme des objets avec description + createPrompt (et outputSchema pour preprocess/analyze). Elles invoquent le LLM juge. Les étapes sous forme de fonction sont de simples fonctions qui n'appellent jamais le juge.
import { createScorer } from '@mastra/core/evals'
const scorer = createScorer({
id: 'my-custom-scorer',
name: 'My Custom Scorer', // Optional, defaults to id
description: 'Evaluates responses based on custom criteria',
type: 'agent', // Optional: for agent evaluation with automatic typing
judge: {
model: myModel,
instructions: 'You are an expert evaluator...',
},
})
.preprocess({/* step config */})
.analyze({/* step config */})
.generateScore(({ run, results }) => {
// Return a number
})
.generateReason({/* step config */})
Options de createScorerLien direct vers createscorer-options
id:
name n'est pas fourni.name?:
id par défaut s'il n'est pas fourni.description:
judge?:
model:
instructions:
jsonPromptInjection?:
inputProcessors?:
outputProcessors?:
errorProcessors?:
processAPIError, peuvent examiner les rejets de l'API LLM et demander une nouvelle tentative, par exemple avec StreamErrorRetryProcessor. Les anciens adaptateurs de modèle utilisent generateLegacy() et n'exécutent pas les Processors d'erreur.maxProcessorRetries?:
type?:
prepareRun?:
Cette fonction renvoie un builder de Scorer sur lequel vous pouvez enchaîner des méthodes d'étape. Consultez la référence de MastraScorer pour plus de détails sur la méthode .run() et ses entrées/sorties.
Le juge s'exécute uniquement pour les étapes définies comme objets de prompt (preprocess, analyze, generateScore, generateReason en mode prompt). Si vous utilisez seulement des étapes sous forme de fonction, le juge n'est jamais appelé et aucune sortie de LLM ne peut être examinée. Dans ce cas, vos fonctions doivent produire elles-mêmes le score et la justification.
Lorsqu'une étape sous forme d'objet de prompt s'exécute, sa sortie LLM structurée est stockée dans le champ de résultat correspondant (preprocessStepResult, analyzeStepResult ou la valeur consommée par calculateScore dans generateScore).
Nouvelles tentatives des requêtes du jugeLien direct vers Nouvelles tentatives des requêtes du juge
Utilisez la configuration errorProcessors existante du juge pour réessayer les échecs transitoires au sein d'une requête du juge ayant échoué. Cela ne relance ni le Workflow du Scorer, ni la cible de Trace, ni l'élément du lot, ni l'écriture du score, ni une étape du Scorer déjà terminée.
@mastra/core 1.49.0 n'inclut pas la configuration des Processors d'erreur des Scorers. Avant d'utiliser cette configuration, passez à une version prenant en charge les Processors de Scorer ou rétroportez cette modification ciblée.
L'exemple suivant utilise un seul budget limité de nouvelles tentatives. Définissez maxRetries du Processor et judge.maxProcessorRetries sur la même valeur. Conservez les tentatives du modèle de l'Agent juge interne à leur valeur par défaut de 0 afin qu'elles ne multiplient pas celles du Processor.
import { createScorer } from '@mastra/core/evals'
import { StreamErrorRetryProcessor } from '@mastra/core/processors'
const isTransientNetworkError = (error: unknown) =>
error instanceof Error && /ECONNRESET|ETIMEDOUT|socket hang up/i.test(error.message)
const retryProcessor = new StreamErrorRetryProcessor({
maxRetries: 2,
maxRetryAfterMs: 30_000,
delayMs: ({ retryCount }) => Math.min(1_000 * 2 ** retryCount, 30_000),
matchers: [isTransientNetworkError],
retryUnknownErrors: false,
})
export const responseQuality = createScorer({
id: 'response-quality',
description: 'Scores response quality',
judge: {
model: myModel,
instructions: 'Return a score and concise reason.',
errorProcessors: [retryProcessor],
maxProcessorRetries: 2,
},
})
.generateScore({
description: 'Score the response quality.',
createPrompt: ({ run }) => `Score: ${run.output}`,
})
.generateReason({
description: 'Explain the score.',
createPrompt: () => 'Explain the score.',
})
Avec cette configuration, une requête ayant échoué donne lieu à trois tentatives au maximum auprès du Provider : la requête initiale et deux nouvelles tentatives du Processor. Si generateScore se termine et que generateReason rencontre un échec réessayable, seul generateReason est relancé.
StreamErrorRetryProcessor respecte les métadonnées réessayables du Provider et les matchers personnalisés précis. Il conserve retryUnknownErrors désactivé par défaut ; les erreurs d'authentification, de requête non valide et de longueur de contexte échouent donc immédiatement, sauf si vous les faites correspondre explicitement. Il limite par défaut les valeurs Retry-After à 30_000 millisecondes. Utilisez maxRetryAfterMs pour modifier cette limite.
Évitez d'ajouter des tentatives externes au Scorer ou au Workflow. Ne combinez pas une valeur non nulle de tentatives du modèle avec ce Processor, sauf si vous acceptez volontairement des tentatives supplémentaires.
Remplacement des tentatives pour une étapeLien direct vers Remplacement des tentatives pour une étape
La configuration judge d'une étape remplace les champs du juge au niveau du Scorer. Les tableaux de Processors remplacent ceux du Scorer. Omettez maxProcessorRetries dans la configuration de l'étape pour hériter de la limite numérique du Scorer.
Les nouvelles tentatives coordonnées des Processors nécessitent un modèle juge utilisant l'API de génération actuelle de Mastra. Les anciens adaptateurs appellent generateLegacy(), contournent les Processors d'erreur et utilisent le maxRetries distinct du SDK AI de cette API, dont la valeur par défaut est 2.
Sécurité des typesLien direct vers Sécurité des types
Vous pouvez préciser les types d'entrée/sortie lors de la création des Scorers afin d'améliorer l'inférence de type et la prise en charge d'IntelliSense :
Raccourci pour le type AgentLien direct vers Raccourci pour le type Agent
Pour évaluer des Agents, utilisez type: 'agent' afin d'obtenir automatiquement les types appropriés pour leurs entrées/sorties :
import { createScorer } from '@mastra/core/evals'
// Agent scorer with automatic typing
const agentScorer = createScorer({
id: 'agent-response-quality',
description: 'Evaluates agent responses',
type: 'agent', // Automatically provides ScorerRunInputForAgent/ScorerRunOutputForAgent
})
.preprocess(({ run }) => {
// run.input is automatically typed as ScorerRunInputForAgent
const userMessage = run.inputData.inputMessages[0]?.content
return { userMessage }
})
.generateScore(({ run, results }) => {
// run.output is automatically typed as ScorerRunOutputForAgent
const response = run.output[0]?.content
return response.length > 10 ? 1.0 : 0.5
})
Types personnalisés avec des génériquesLien direct vers Types personnalisés avec des génériques
Pour des types d'entrée/sortie personnalisés, utilisez l'approche générique :
import { createScorer } from '@mastra/core/evals'
type CustomInput = { query: string; context: string[] }
type CustomOutput = { answer: string; confidence: number }
const customScorer = createScorer<CustomInput, CustomOutput>({
id: 'custom-scorer',
description: 'Evaluates custom data',
}).generateScore(({ run }) => {
// run.input is typed as CustomInput
// run.output is typed as CustomOutput
return run.output.confidence
})
Types Agent intégrésLien direct vers Types Agent intégrés
ScorerRunInputForAgent- ContientinputMessages,rememberedMessages,systemMessagesettaggedSystemMessagespour l'évaluation des AgentsScorerRunOutputForAgent- Tableau des messages de réponse de l'Agent
Ces types offrent l'autocomplétion, la validation à la compilation et une meilleure documentation de votre logique de scoring.
Scoring des Traces avec les types AgentLien direct vers Scoring des Traces avec les types Agent
Lorsque vous utilisez type: 'agent', votre Scorer peut aussi bien être ajouté directement aux Agents que noter les Traces issues de leurs interactions. Le Scorer transforme automatiquement les données de Trace au format d'entrée/sortie approprié de l'Agent :
const agentTraceScorer = createScorer({
id: 'agent-trace-length',
description: 'Evaluates agent response length',
type: 'agent',
}).generateScore(({ run }) => {
// Trace data is automatically transformed to agent format
const userMessages = run.inputData.inputMessages
const agentResponse = run.output[0]?.content
// Score based on response length
return agentResponse?.length > 50 ? 0 : 1
})
// Register with Mastra for trace scoring
const mastra = new Mastra({
scorers: {
agentTraceScorer,
},
})
Signatures des méthodes d'étapeLien direct vers Signatures des méthodes d'étape
preprocessLien direct vers preprocess
Étape facultative de prétraitement qui peut extraire ou transformer les données avant l'analyse.
Mode fonction :
Function: ({ run, results }) => any
run.input:
[{ role: 'user', content: 'hello world' }]. S'il est utilisé dans un Workflow, il s'agit de l'entrée du Workflow.run.output:
run.runId:
run.requestContext?:
results:
Renvoie : any
La méthode peut renvoyer n'importe quelle valeur. Celle-ci sera accessible aux étapes suivantes sous la forme preprocessStepResult.
Mode objet de prompt :
description:
outputSchema:
createPrompt:
judge?:
analyzeLien direct vers analyze
Étape d'analyse facultative qui traite les entrées/sorties et les éventuelles données prétraitées.
Mode fonction :
Function: ({ run, results }) => any
run.input:
[{ role: 'user', content: 'hello world' }]. S'il est utilisé dans un Workflow, il s'agit de l'entrée du Workflow.run.output:
run.runId:
run.requestContext?:
results.preprocessStepResult?:
Renvoie : any
La méthode peut renvoyer n'importe quelle valeur. Celle-ci sera accessible aux étapes suivantes sous la forme analyzeStepResult.
Mode objet de prompt :
description:
outputSchema:
createPrompt:
judge?:
generateScoreLien direct vers generatescore
Étape obligatoire qui calcule le score numérique final.
Mode fonction :
Function: ({ run, results }) => number
run.input:
[{ role: 'user', content: 'hello world' }]. S'il est utilisé dans un Workflow, il s'agit de l'entrée du Workflow.run.output:
run.runId:
run.requestContext?:
results.preprocessStepResult?:
results.analyzeStepResult?:
Renvoie : number
La méthode doit renvoyer un score numérique.
Mode objet de prompt :
description:
outputSchema:
createPrompt:
judge?:
En mode objet de prompt, vous devez également fournir une fonction calculateScore pour convertir la sortie du LLM en score numérique :
calculateScore:
generateReasonLien direct vers generatereason
Étape facultative qui fournit une explication du score.
Mode fonction :
Function: ({ run, results, score }) => string
run.input:
[{ role: 'user', content: 'hello world' }]. S'il est utilisé dans un Workflow, il s'agit de l'entrée du Workflow.run.output:
run.runId:
run.requestContext?:
results.preprocessStepResult?:
results.analyzeStepResult?:
score:
Renvoie : string
La méthode doit renvoyer une chaîne qui explique le score.
Mode objet de prompt :
description:
createPrompt:
judge?:
Toutes les fonctions d'étape peuvent être asynchrones.