> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ko/llms.txt # 득점자 유틸리티 Mastra는 득점자 실행 입력 및 출력에서 ​​데이터를 추출하고 처리하는 데 도움이 되는 유틸리티 기능을 제공합니다. 이러한 유틸리티는 다음과 같은 경우에 특히 유용합니다.`preprocess`커스텀 스코어러 단계. ## 수입 ```typescript import { getAssistantMessageFromRunOutput, getReasoningFromRunOutput, getUserMessageFromRunInput, getSystemMessagesFromRunInput, getCombinedSystemPrompt, extractToolCalls, extractInputMessages, extractAgentResponseMessages, compareTrajectories, createTrajectoryTestRun, } from '@mastra/evals/scorers/utils' ``` 궤적 추출 기능은 다음에서 사용할 수 있습니다.`@mastra/core/evals`: ```typescript import { extractTrajectory, extractWorkflowTrajectory, extractTrajectoryFromTrace, } from '@mastra/core/evals' ``` ## 메시지 추출 ### `getAssistantMessageFromRunOutput` 실행 출력의 첫 번째 보조 메시지에서 텍스트 콘텐츠를 추출합니다. ```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`): 채점기 실행 출력(MastraDBMessage 배열) **반환:** `string | undefined` - 어시스턴트 메시지 텍스트이며, 어시스턴트 메시지를 찾을 수 없으면 undefined입니다. ### `getUserMessageFromRunInput` 실행 입력의 첫 번째 사용자 메시지에서 텍스트 콘텐츠를 추출합니다. ```typescript .preprocess(({ run }) => { const userMessage = getUserMessageFromRunInput(run.input); return { userMessage }; }) ``` **input** (`ScorerRunInputForAgent`): 입력 메시지를 포함하는 채점기 실행 입력 **반환:** `string | undefined` - 사용자 메시지 텍스트이며, 사용자 메시지를 찾을 수 없으면 undefined입니다. ### `extractInputMessages` 모든 입력 메시지에서 텍스트 콘텐츠를 배열로 추출합니다. ```typescript .preprocess(({ run }) => { const allUserMessages = extractInputMessages(run.input); return { conversationHistory: allUserMessages.join("\n") }; }) ``` **반환:** `string[]` - 각 입력 메시지에서 가져온 텍스트 문자열 배열입니다. ### `extractAgentResponseMessages` 모든 어시스턴트 응답 메시지에서 텍스트 콘텐츠를 배열로 추출합니다. ```typescript .preprocess(({ run }) => { const allResponses = extractAgentResponseMessages(run.output); return { allResponses }; }) ``` **반환:** `string[]` - 각 어시스턴트 메시지에서 가져온 텍스트 문자열 배열입니다. ## 추론 추출 ### `getReasoningFromRunOutput` 실행 출력에서 추론 텍스트를 추출합니다. 이는 사고 과정 추론을 생성하는 `deepseek-reasoner`와 같은 추론 Model의 응답을 평가할 때 특히 유용합니다. 추론은 두 위치에 저장될 수 있습니다. 1. `content.reasoning`- 메시지 내용의 문자열 필드 2. `content.parts`- 부품으로`type: 'reasoning'` containing `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`): 채점기 실행 출력(MastraDBMessage 배열) **반환:** `string | undefined` - 추론 텍스트이며, 추론이 없으면 undefined입니다. ## 시스템 메시지 추출 ### `getSystemMessagesFromRunInput` 표준 시스템 메시지와 태그가 지정된 시스템 메시지(Memory 지침과 같은 특수 Prompt)를 모두 포함하여 실행 입력에서 모든 시스템 메시지를 추출합니다. ```typescript .preprocess(({ run }) => { const systemMessages = getSystemMessagesFromRunInput(run.input); return { systemPromptCount: systemMessages.length, systemPrompts: systemMessages }; }) ``` **반환:** `string[]` - 시스템 메시지 문자열 배열입니다. ### `getCombinedSystemPrompt` 모든 시스템 메시지를 이중 줄 바꿈으로 결합된 단일 Prompt 문자열로 결합합니다. ```typescript .preprocess(({ run }) => { const fullSystemPrompt = getCombinedSystemPrompt(run.input); return { fullSystemPrompt }; }) ``` **보고:** `string` - Combined system prompt string. ## Tool 호출 추출 ### `extractToolCalls` Tool 이름, 호출 ID 및 메시지 배열에서의 해당 위치를 포함하여 실행 출력에서 ​​모든 Tool 호출에 대한 정보를 추출합니다. ```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 }) ``` **보고:** ```typescript { tools: string[]; // Array of tool names toolCallInfos: ToolCallInfo[]; // Detailed tool call information } ``` 여기서 `ToolCallInfo`는 다음과 같습니다. ```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 } ``` ## 테스트 유틸리티 이러한 유틸리티는 채점자 개발을 위한 테스트 데이터를 생성하는 데 도움이 됩니다. ### `createTestMessage` 테스트용 `MastraDBMessage` 객체를 생성합니다. ```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` 채점자 테스트를 위한 완전한 테스트 실행 개체를 생성합니다. ```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, }) ``` ## 궤적 유틸리티 ### `extractTrajectory` Agent 출력 메시지(`MastraDBMessage[]`)에서 `Trajectory`를 추출합니다. Tool 호출을 `ToolCallStep` 객체로 변환합니다. `runEvals` 파이프라인은 궤적 채점기에 대해 이를 자동으로 호출하므로 직접 테스트할 때만 필요합니다. 에서 사용 가능`@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 ``` **반환:** `Trajectory`: `steps: TrajectoryStep[]`, `totalDurationMs` 및 `rawOutput`을 포함합니다. ### `extractWorkflowTrajectory` Workflow 단계 결과에서 `Trajectory`를 추출합니다. 실행 경로 순서를 준수하여 `StepResult` 레코드를 `WorkflowStepStep` 객체로 변환합니다. 에서 사용 가능`@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 ``` **반환:** `Trajectory`: `steps: TrajectoryStep[]`, `totalDurationMs` 및 `rawWorkflowResult`를 포함합니다. ### `extractTrajectoryFromTrace` Observability Trace Span(`SpanRecord[]`)에서 계층적 `Trajectory`를 구축합니다. 부모-자식 Span 트리를 재구성하고 각 Span을 중첩된 `children`이 있는 적절한 `TrajectoryStep` 판별 유니온 유형에 매핑합니다. 스토리지가 있는 경우 권장되는 추출 방법입니다. 대상의 `Mastra` 인스턴스에 스토리지 백엔드가 구성되어 있으면 `runEvals` 파이프라인이 이를 자동으로 호출합니다. 중첩된 Agent 실행, Tool 호출 및 Model 생성을 비롯한 전체 실행 트리를 포착하므로 `extractTrajectory` 또는 `extractWorkflowTrajectory`보다 더 풍부한 궤적을 생성합니다. 에서 사용 가능`@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 ``` **매개변수:** - `spans` (`SpanRecord[]`): Trace 쿼리에서 가져온 Span 레코드 배열입니다. - `rootSpanId` (`string`, 선택 사항): 시작점으로 사용할 Span ID입니다. 생략하면 부모가 없는 Span을 사용합니다. **반환:** `Trajectory`: 재귀적 `children`이 있는 `steps: TrajectoryStep[]`와 `totalDurationMs`를 포함합니다. #### 스팬 유형 매핑 | Span 유형 | 궤적 단계 유형 | 추출되는 주요 필드 | | ------------------------------------------------------------------------------------------------ | ---------------------- | ------------------------------------------------------------- | | `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`(엔터티 ID에서 가져옴) | | `WORKFLOW_RUN` | `workflow_run` | `workflowId`(엔터티 ID에서 가져옴) | | `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` | | 유형이 `GENERIC`, `MODEL_STEP`, `MODEL_CHUNK` 및 `WORKFLOW_CONDITIONAL_EVAL`인 Span은 노이즈로 간주되어 건너뜁니다. | | | ### `compareTrajectories` 실제 궤적과 예상 궤적을 비교하고 자세한 비교 결과를 반환합니다. 내부적으로 사용됨`createTrajectoryAccuracyScorerCode`. `expected` 매개변수에는 `Trajectory`(실제 궤적) 또는 `{ steps: ExpectedStep[] }`를 전달할 수 있습니다. `ExpectedStep[]`를 사용할 때는 이름만으로 일치시키거나 이름과 stepType으로 일치시킬 수 있습니다. 비교할 데이터를 포함할 수도 있습니다. 자세한 내용은 [예상 단계](https://mastra.zisheng.pro/ko/reference/evals/trajectory-accuracy)를 참조하세요. ```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 ``` **보고:** `TrajectoryComparisonResult` ### `createTrajectoryTestRun` 궤적 채점기용 테스트 실행 객체를 만듭니다. `Trajectory`를 예상되는 `ScorerRun` 형식으로 래핑합니다. ```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` 단계, 토큰 및 기간 예산에 대해 궤적 효율성을 평가합니다. 또한 중복 호출을 감지합니다(동일한 인수를 가진 동일한 Tool). ```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 ``` **보고:** `TrajectoryEfficiencyResult` ### `checkTrajectoryBlacklist` 궤적에 금지된 Tool나 Tool 호출 순서가 포함되어 있는지 확인합니다. ```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 ``` **보고:** `TrajectoryBlacklistResult` ### `analyzeToolFailures` 재시도, 대체, 인수 수정을 포함한 Tool 오류 패턴을 감지합니다. ```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) ``` **보고:** `ToolFailureAnalysisResult` ## 완전한 예 다음은 여러 유틸리티를 함께 사용하는 방법을 보여주는 전체 예입니다. ```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(', ')}.` }) ```