Custom Native JavaScript Scorer
This example shows how to create a custom evaluation scorer using JavaScript logic. The scorer accepts a query
and a response
, and returns a score and an analyzeStepResult
object containing the total and matched words.
Installation
npm install @mastra/evals
For complete API documentation and configuration options, see
createScorer
.
Create a custom scorer
A custom scorer in Mastra can use native JavaScript methods to evaluate conditions.
See createScorer for the full API and configuration options.
import { createScorer } from "@mastra/core/scores";
const wordInclusionScorer = createScorer({
name: 'Word Inclusion',
description: 'Check if the output contains any of the words in the input',
analyze: async ({ input, output }) => {
const tokenize = (text: string) => text.toLowerCase().match(/\b\w+\b/g) || [];
const inputText = input[0].query.toLowerCase();
const referenceWords = [...new Set(tokenize(inputText))];
const outputText = output.text.toLowerCase();
const matchedWords = referenceWords.filter(word => outputText.includes(word));
const totalWords = referenceWords.length;
const score = totalWords > 0 ? matchedWords.length / totalWords : 0;
return {
score,
result: {
totalWords,
matchedWords: matchedWords.length,
},
};
},
});
Note: The
analyze
function should return{ score, result: { ... } }
. When you call.run()
, the returned object will have ananalyzeStepResult
field containing yourresult
object.
High custom example
In this example, the response contains all the words listed in the input query. The scorer returns a high score indicating complete word inclusion.
const query = 'apple, banana, orange';
const response = 'My favorite fruits are: apple, banana, and orange.';
const result = await wordInclusionScorer.run({
input: [{ query }],
output: { text: response },
});
console.log('Score:', result.score);
console.log('AnalyzeStepResult:', result.analyzeStepResult);
High custom output
{
score: 1,
analyzeStepResult: {
totalWords: 3,
matchedWords: 3
}
}
Partial custom example
In this example, the response includes some but not all of the words from the input query. The scorer returns a partial score reflecting this incomplete word coverage.
const query = 'programming, python, javascript, java';
const response = 'I love programming with python for data science projects.';
const result = await wordInclusionScorer.run({
input: [{ query }],
output: { text: response },
});
console.log('Score:', result.score);
console.log('AnalyzeStepResult:', result.analyzeStepResult);
Partial custom output
{
score: 0.5,
analyzeStepResult: {
totalWords: 4,
matchedWords: 2
}
}
Low custom example
In this example, the response does not contain any of the words from the input query. The scorer returns a low score indicating no word inclusion.
const query = 'soccer, basketball, tennis';
const response = 'I enjoy reading books and watching movies in my free time.';
const result = await wordInclusionScorer.run({
input: [{ query }],
output: { text: response },
});
console.log('Score:', result.score);
console.log('AnalyzeStepResult:', result.analyzeStepResult);
Low custom output
{
score: 0,
analyzeStepResult: {
totalWords: 3,
matchedWords: 0
}
}
Understanding the results
.run()
returns a result in the following shape:
{
runId: string,
analyzeStepResult: {
totalWords: number,
matchedWords: number
},
score: number
}
score
A score between 0 and 1:
- 1.0: The response includes all words from the input.
- 0.5–0.9: The response includes some but not all words.
- 0.0: None of the input words appear in the response.
runId
The unique identifier for this scorer run.
analyzeStepResult
Object with word inclusion statistics:
- totalWords: The number of unique words found in the input.
- matchedWords: The count of those words that also appear in the response.