맞춤 채점자
Mastra는 통합된createScorer각 단계에 대해 JavaScript 함수 또는 LLM 기반 Prompt 개체를 사용하여 사용자 정의 평가 논리를 구축할 수 있는 팩토리입니다. 이러한 유연성을 통해 평가 파이프라인의 각 부분에 가장 적합한 접근 방식을 선택할 수 있습니다.
4단계 파이프라인4단계 파이프라인에 대한 직접 링크
Mastra의 모든 득점자는 일관된 4단계 평가 파이프라인을 따릅니다.
- 전처리(선택사항): 입력/출력 데이터 준비 또는 변환
- 분석하다(선택): 평가 분석을 수행하고 인사이트를 수집합니다.
- 생성점수(필수) : 분석을 수치 점수로 변환
- 생성 이유(선택 사항): 사람이 읽을 수 있는 설명 생성
각 단계에는 함수 또는 Prompt 객체(LLM 기반 평가)를 사용할 수 있어, 필요에 따라 결정적 알고리즘과 AI 판단을 유연하게 조합할 수 있습니다.
함수와 Prompt 객체함수와 Prompt 객체에 대한 직접 링크
기능결정론적 논리를 위해 JavaScript를 사용합니다. 다음과 같은 경우에 이상적입니다.
- 명확한 기준을 갖춘 알고리즘 평가
- 성능이 중요한 시나리오
- 기존 라이브러리와의 통합
- 일관되고 재현 가능한 결과
Prompt 개체평가를 위해 LLM을 심사위원으로 활용합니다. 다음과 같은 경우에 적합합니다.
- 인간과 같은 판단이 필요한 주관적 평가
- 알고리즘적으로 코딩하기 어려운 복잡한 기준
- 자연어 이해 작업
- 미묘한 맥락 평가
"Prompt 객체"의 의미: 함수 대신 단계에 description + createPrompt(preprocess/analyze의 경우 outputSchema도 포함)를 가진 객체를 사용합니다. 이 객체는 Mastra가 해당 단계에서 판정 LLM을 실행하고 구조화된 출력을 results.<step>StepResult에 저장하도록 지시합니다.
단일 채점자 내에서 접근 방식을 혼합하고 일치시킬 수 있습니다. 예를 들어 데이터 전처리를 위한 기능과 품질 분석을 위한 LLM을 사용할 수 있습니다.
득점자 초기화득점자 초기화에 대한 직접 링크
모든 채점자는 createScorer 팩토리 함수로 생성합니다. 이 함수에는 ID와 설명이 필요하며, 선택적으로 유형 명세와 판정 Model 구성을 받을 수 있습니다.
import { createScorer } from '@mastra/core/evals';
const glutenCheckerScorer = createScorer({
id: 'gluten-checker',
description: 'Check if recipes contain gluten ingredients',
judge: { // Optional: for prompt object steps
model: 'openai/gpt-5.6-sol',
instructions: 'You are a Chef that identifies if recipes contain gluten.'
}
})
// Chain step methods here
.preprocess(...)
.analyze(...)
.generateScore(...)
.generateReason(...)
판단 구성은 모든 단계에서 Prompt 개체를 사용하려는 경우에만 필요합니다. 개별 단계는 자체 판단 설정으로 이 기본 구성을 재정의할 수 있습니다.
모든 단계가 기능 기반인 경우 심사위원은 호출되지 않으며 심사위원 출력도 없습니다. LLM 출력을 보려면 하나 이상의 단계를 Prompt 개체로 정의하고 해당 단계 결과를 읽으십시오(예:results.analyzeStepResult).
최소 판단 예시(Prompt 객체)최소 판단 예시(Prompt 객체)에 대한 직접 링크
이 예제에서는 analyze에 Prompt 객체를 사용하므로 판정 Model이 실행되고 구조화된 출력을 results.analyzeStepResult에서 사용할 수 있습니다.
import { createScorer } from '@mastra/core/evals'
import { z } from 'zod'
const quoteSourcesScorer = createScorer({
id: 'quote-sources',
description: 'Check if the response includes sources',
judge: {
model: 'openai/gpt-5-mini',
instructions: 'You are a strict evaluator.',
},
})
.analyze({
description: 'Detect whether sources are present',
outputSchema: z.object({
hasSources: z.boolean(),
sources: z.array(z.string()),
}),
createPrompt: ({ run }) => `
Does the response contain sources? Extract them as a list.
Response:
${run.output}
`,
})
.generateScore(({ results }) => (results.analyzeStepResult.hasSources ? 1 : 0))
// Run the scorer and inspect judge output
const result = await quoteSourcesScorer.run({
input: 'What is the capital of France?',
output: 'Paris is the capital of France [1]. Source: [1] Wikipedia',
})
console.log(result.score) // 1
console.log(result.analyzeStepResult) // { hasSources: true, sources: ["Wikipedia"] }
Agent 평가를 위한 Agent 유형Agent 평가를 위한 Agent 유형에 대한 직접 링크
유형 안전성을 확보하고 실시간 Agent 채점과 Trace 채점 모두와 호환되게 하려면 Agent 평가용 채점자를 생성할 때 type: 'agent'를 사용하세요. 그러면 같은 채점자를 Agent에 사용하면서 Trace 채점에도 사용할 수 있습니다.
const myScorer = createScorer({
type: 'agent', // Automatically handles agent input/output types
}).generateScore(({ run, results }) => {
// run.output is automatically typed as ScorerRunOutputForAgent
// run.input is automatically typed as ScorerRunInputForAgent
})
단계별 분석단계별 분석에 대한 직접 링크
전처리 단계(선택사항)전처리 단계(선택사항)에 대한 직접 링크
특정 요소를 추출하거나 콘텐츠를 필터링해야 하거나 복잡한 데이터 구조를 변환해야 할 때 입력/출력 데이터를 준비합니다.
기능: ({ run, results }) => any
const glutenCheckerScorer = createScorer(...)
.preprocess(({ run }) => {
// Extract and clean recipe text
const recipeText = run.output.text.toLowerCase();
const wordCount = recipeText.split(' ').length;
return {
recipeText,
wordCount,
hasCommonGlutenWords: /flour|wheat|bread|pasta/.test(recipeText)
};
})
Prompt 객체: description, outputSchema, createPrompt를 사용하여 LLM 기반 전처리를 구조화하세요.
const glutenCheckerScorer = createScorer(...)
.preprocess({
description: 'Extract ingredients from the recipe',
outputSchema: z.object({
ingredients: z.array(z.string()),
cookingMethods: z.array(z.string())
}),
createPrompt: ({ run }) => `
Extract all ingredients and cooking methods from this recipe:
${run.output.text}
Return JSON with ingredients and cookingMethods arrays.
`
})
데이터 흐름:결과는 다음 단계에서 다음과 같이 사용할 수 있습니다.results.preprocessStepResult
분석 단계(선택 사항)분석 단계(선택 사항)에 대한 직접 링크
핵심 평가 분석을 수행하여 점수 결정에 도움이 되는 통찰력을 수집합니다.
기능: ({ run, results }) => any
const glutenCheckerScorer = createScorer({...})
.preprocess(...)
.analyze(({ run, results }) => {
const { recipeText, hasCommonGlutenWords } = results.preprocessStepResult;
// Simple gluten detection algorithm
const glutenKeywords = ['wheat', 'flour', 'barley', 'rye', 'bread'];
const foundGlutenWords = glutenKeywords.filter(word =>
recipeText.includes(word)
);
return {
isGlutenFree: foundGlutenWords.length === 0,
detectedGlutenSources: foundGlutenWords,
confidence: hasCommonGlutenWords ? 0.9 : 0.7
};
})
Prompt 객체: LLM 기반 분석에 description, outputSchema, createPrompt를 사용하세요.
const glutenCheckerScorer = createScorer({...})
.preprocess(...)
.analyze({
description: 'Analyze recipe for gluten content',
outputSchema: z.object({
isGlutenFree: z.boolean(),
glutenSources: z.array(z.string()),
confidence: z.number().min(0).max(1)
}),
createPrompt: ({ run, results }) => `
Analyze this recipe for gluten content:
"${results.preprocessStepResult.recipeText}"
Look for wheat, barley, rye, and hidden sources like soy sauce.
Return JSON with isGlutenFree, glutenSources array, and confidence (0-1).
`
})
데이터 흐름:결과는 다음 단계에서 다음과 같이 사용할 수 있습니다.results.analyzeStepResult
generateScore단계(필수)generatescore-step-required에 대한 직접 링크
분석 결과를 수치 점수로 변환합니다. 이는 파이프라인에서 유일하게 필요한 단계입니다.
기능: ({ run, results }) => number
const glutenCheckerScorer = createScorer({...})
.preprocess(...)
.analyze(...)
.generateScore(({ results }) => {
const { isGlutenFree, confidence } = results.analyzeStepResult;
// Return 1 for gluten-free, 0 for contains gluten
// Weight by confidence level
return isGlutenFree ? confidence : 0;
})
Prompt 객체: 필수 calculateScore 함수를 포함하여 generateScore에서 Prompt 객체를 사용하는 방법은 createScorer API 레퍼런스를 참조하세요.
데이터 흐름:점수는 generateReason에 사용할 수 있습니다.score parameter
generateReason단계(선택사항)generatereason-step-optional에 대한 직접 링크
디버깅, 투명성 또는 사용자 피드백에 유용한 점수에 대해 사람이 읽을 수 있는 설명을 생성합니다.
기능: ({ run, results, score }) => string
const glutenCheckerScorer = createScorer({...})
.preprocess(...)
.analyze(...)
.generateScore(...)
.generateReason(({ results, score }) => {
const { isGlutenFree, glutenSources } = results.analyzeStepResult;
if (isGlutenFree) {
return `Score: ${score}. This recipe is gluten-free with no harmful ingredients detected.`;
} else {
return `Score: ${score}. Contains gluten from: ${glutenSources.join(', ')}`;
}
})
Prompt 객체: LLM이 생성하는 설명에 description과 createPrompt를 사용하세요.
const glutenCheckerScorer = createScorer({...})
.preprocess(...)
.analyze(...)
.generateScore(...)
.generateReason({
description: 'Explain the gluten assessment',
createPrompt: ({ results, score }) => `
Explain why this recipe received a score of ${score}.
Analysis: ${JSON.stringify(results.analyzeStepResult)}
Provide a clear explanation for someone with dietary restrictions.
`
})
입력 필터링입력 필터링에 대한 직접 링크
Agent 대화에는 Tool 호출, 데이터 부분 및 시스템 메타데이터가 포함된 수백 개의 메시지가 있을 수 있습니다. 대부분의 채점자에게는 이 데이터의 일부만 필요합니다. prepareRun 옵션은 채점자 파이프라인이 실행되기 전에 실행 데이터를 변환하여 노이즈를 줄이고 채점자가 필요한 정보에 집중하도록 합니다.
선언적 필터링filterRun()declarative-filtering-with-filterrun에 대한 직접 링크
filterRun() 유틸리티는 선언적 옵션으로 prepareRun 함수를 생성합니다.
import { createScorer, filterRun } from '@mastra/core/evals'
const toolScorer = createScorer({
id: 'tool-quality',
description: 'Evaluates tool usage quality',
type: 'agent',
prepareRun: filterRun({
partTypes: ['tool-invocation', 'text'],
maxRememberedMessages: 20,
}),
}).generateScore(({ run }) => {
// run.input.rememberedMessages has only tool and text messages, max 20
return 1
})
일반적인 옵션은 다음과 같습니다.
partTypes: 부분 유형이 일치하는 메시지만 유지합니다(예:'tool-invocation','text','reasoning')toolNames: 특정 Tool와 관련된 메시지만 보관합니다(예:['write_file', 'execute_command'])maxRememberedMessages: 컨텍스트 창 크기 제한dropRequestContext,dropGroundTruth,dropExpectedTrajectory: Remove unused fields
전체 옵션 목록은 filterRun() 레퍼런스를 참조하세요.
관습prepareRun functionscustom-preparerun-functions에 대한 직접 링크
filterRun()으로 처리할 수 없는 로직은 prepareRun 함수를 직접 작성하세요.
import { createScorer } from '@mastra/core/evals'
const customScorer = createScorer({
id: 'recent-output',
description: 'Scores only the last response',
type: 'agent',
prepareRun: (run) => ({
...run,
output: run.output.slice(-1), // Keep only the last message
requestContext: undefined,
}),
})
.generateScore(({ run }) => {
return run.output.length > 0 ? 1 : 0
})
prepareRun 함수는 비동기 함수일 수도 있습니다.
:::note[시스템 메시지는 항상 보존됩니다.]
filterRun()은 systemMessages 또는 taggedSystemMessages를 필터링하지 않습니다. 여기에는 Agent 지침이 포함되며 채점에 중요한 컨텍스트입니다.
:::
예: 사용자 정의 채점자 생성예: 사용자 정의 채점자 생성에 대한 직접 링크
Mastra의 커스텀 채점자는 네 가지 핵심 구성 요소와 함께 createScorer를 사용합니다.
이러한 구성 요소를 함께 사용하면 LLM을 판정 Model로 활용하는 커스텀 평가 로직을 정의할 수 있습니다. 전체 API와 구성 옵션은 createScorer를 참조하세요.
import { createScorer } from '@mastra/core/evals'
import { z } from 'zod'
export const GLUTEN_INSTRUCTIONS = `You are a Chef that identifies if recipes contain gluten.`
export const generateGlutenPrompt = ({
output,
}: {
output: string
}) => `Check if this recipe is gluten-free.
Check for:
- Wheat
- Barley
- Rye
- Common sources like flour, pasta, bread
Example with gluten:
"Mix flour and water to make dough"
Response: {
"isGlutenFree": false,
"glutenSources": ["flour"]
}
Example gluten-free:
"Mix rice, beans, and vegetables"
Response: {
"isGlutenFree": true,
"glutenSources": []
}
Recipe to analyze:
${output}
Return your response in this format:
{
"isGlutenFree": boolean,
"glutenSources": ["list ingredients containing gluten"]
}`
export const generateReasonPrompt = ({
isGlutenFree,
glutenSources,
}: {
isGlutenFree: boolean
glutenSources: string[]
}) => `Explain why this recipe is${isGlutenFree ? '' : ' not'} gluten-free.
${glutenSources.length > 0 ? `Sources of gluten: ${glutenSources.join(', ')}` : 'No gluten-containing ingredients found'}
Return your response in this format:
"This recipe is [gluten-free/contains gluten] because [explanation]"`
export const glutenCheckerScorer = createScorer({
id: 'gluten-checker',
description: 'Check if the output contains any gluten',
judge: {
model: 'openai/gpt-5-mini',
instructions: GLUTEN_INSTRUCTIONS,
},
})
.analyze({
description: 'Analyze the output for gluten',
outputSchema: z.object({
isGlutenFree: z.boolean(),
glutenSources: z.array(z.string()),
}),
createPrompt: ({ run }) => {
const { output } = run
return generateGlutenPrompt({ output: output.text })
},
})
.generateScore(({ results }) => {
return results.analyzeStepResult.isGlutenFree ? 1 : 0
})
.generateReason({
description: 'Generate a reason for the score',
createPrompt: ({ results }) => {
return generateReasonPrompt({
glutenSources: results.analyzeStepResult.glutenSources,
isGlutenFree: results.analyzeStepResult.isGlutenFree,
})
},
})
판사 구성판사 구성에 대한 직접 링크
LLM Model을 설정하고 도메인 전문가로서의 역할을 정의합니다.
judge: {
model: 'openai/gpt-5-mini',
instructions: GLUTEN_INSTRUCTIONS,
}
분석 단계분석 단계에 대한 직접 링크
LLM이 입력을 분석하는 방법과 반환할 구조화된 출력을 정의합니다.
.analyze({
description: 'Analyze the output for gluten',
outputSchema: z.object({
isGlutenFree: z.boolean(),
glutenSources: z.array(z.string()),
}),
createPrompt: ({ run }) => {
const { output } = run;
return generateGlutenPrompt({ output: output.text });
},
})
분석 단계에서는 Prompt 개체를 사용하여 다음을 수행합니다.
- 분석 작업에 대한 명확한 설명을 제공합니다.
- 표준 JSON 스키마(부울 결과 및 글루텐 소스 목록 모두)를 사용하여 예상 출력 구조를 정의합니다.
- 입력 콘텐츠를 기반으로 런타임 Prompt 생성
점수 생성점수 생성에 대한 직접 링크
LLM의 구조화된 분석을 수치 점수로 변환합니다.
.generateScore(({ results }) => {
return results.analyzeStepResult.isGlutenFree ? 1 : 0;
})
점수 생성 기능은 분석 결과를 가져와 비즈니스 로직을 적용하여 점수를 생성합니다. 이 경우 LLM은 레시피에 글루텐이 없는지 직접 확인하므로 해당 부울 결과를 사용합니다. 즉, 글루텐이 없는 경우 1, 글루텐이 포함된 경우 0입니다.
이유 생성이유 생성에 대한 직접 링크
다른 LLM 호출을 사용하여 점수에 대해 사람이 읽을 수 있는 설명을 제공합니다.
.generateReason({
description: 'Generate a reason for the score',
createPrompt: ({ results }) => {
return generateReasonPrompt({
glutenSources: results.analyzeStepResult.glutenSources,
isGlutenFree: results.analyzeStepResult.isGlutenFree,
});
},
})
이유 생성 단계에서는 부울 결과와 분석 단계에서 식별된 특정 글루텐 소스를 모두 사용하여 점수가 할당된 이유를 사용자가 이해하는 데 도움이 되는 설명을 생성합니다.
글루텐 프리 함량이 높은 예글루텐 프리 함량이 높은 예에 대한 직접 링크
const result = await glutenCheckerScorer.run({
input: [{ role: 'user', content: 'Mix rice, beans, and vegetables' }],
output: { text: 'Mix rice, beans, and vegetables' },
})
console.log('Score:', result.score)
console.log('Gluten sources:', result.analyzeStepResult.glutenSources)
console.log('Reason:', result.reason)
높은 글루텐 프리 생산량높은 글루텐 프리 생산량에 대한 직접 링크
{
score: 1,
analyzeStepResult: {
isGlutenFree: true,
glutenSources: []
},
reason: 'This recipe is gluten-free because rice, beans, and vegetables are naturally gluten-free ingredients that are safe for people with celiac disease.'
}
부분 글루텐 예부분 글루텐 예에 대한 직접 링크
const result = await glutenCheckerScorer.run({
input: [{ role: 'user', content: 'Mix flour and water to make dough' }],
output: { text: 'Mix flour and water to make dough' },
})
console.log('Score:', result.score)
console.log('Gluten sources:', result.analyzeStepResult.glutenSources)
console.log('Reason:', result.reason)
부분적인 글루텐 생산량부분적인 글루텐 생산량에 대한 직접 링크
{
score: 0,
analyzeStepResult: {
isGlutenFree: false,
glutenSources: ['flour']
},
reason: 'This recipe is not gluten-free because it contains flour. Regular flour is made from wheat and contains gluten, making it unsafe for people with celiac disease or gluten sensitivity.'
}
글루텐 프리가 낮은 예글루텐 프리가 낮은 예에 대한 직접 링크
const result = await glutenCheckerScorer.run({
input: [{ role: 'user', content: 'Add soy sauce and noodles' }],
output: { text: 'Add soy sauce and noodles' },
})
console.log('Score:', result.score)
console.log('Gluten sources:', result.analyzeStepResult.glutenSources)
console.log('Reason:', result.reason)
낮은 글루텐 프리 생산량낮은 글루텐 프리 생산량에 대한 직접 링크
{
score: 0,
analyzeStepResult: {
isGlutenFree: false,
glutenSources: ['soy sauce', 'noodles']
},
reason: 'This recipe is not gluten-free because it contains soy sauce, noodles. Regular soy sauce contains wheat and most noodles are made from wheat flour, both of which contain gluten and are unsafe for people with gluten sensitivity.'
}
예시 및 리소스:
- createScorer API 참조: 완전한 기술 문서
- 내장 득점자 소스 코드: 참고용 실제 구현