ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Mastra 评测框架 @mastra/evals 深度指南:Quick Checks、轨迹评分器与 Vitest 集成的完整实战

Mastra 评测框架 @mastra/evals 深度指南:Quick Checks、轨迹评分器与 Vitest 集成的完整实战 Mastra 评测框架 mastra/evals 深度指南Quick Checks、轨迹评分器与 Vitest 集成的完整实战【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastramastra/evals 是 Mastra 生态中面向 AI Agent 与工作流的评测Evaluation能力包提供从零成本确定性断言Quick Checks到 LLM-as-Judge 语义评分、再到整条执行轨迹评估的完整评分器体系。本文基于该包完整变更记录packages/evals/CHANGELOG.md与当前仓库源码系统讲解每个评分器族、配置参数、调用方式及其底层实现读完后你可以在自己的 Mastra Agent 项目中直接落地一套可量化的质量回归评测流水线。一、包概览两种评分器、多个子路径入口mastra/evals的定位在 packages/evals/README.md 中写得很清楚它shipped 一批评分工具scoring utilities可以本地运行也可以嵌入你自己的评测管道。所有评分器分为两大类LLM ScorersLLM 评分器——借助一个 judge 模型例如 OpenAI、Anthropic对输出进行语义层面的打分例如忠实度faithfulness、毒性toxicity、上下文相关性等Code/NLP Scorers代码/NLP 评分器——纯确定性的启发式算法关键词覆盖、文本相似度等不依赖任何外部模型成本为零、结果可复现。安装方式来自 READMEnpm install mastra/evals该包的依赖约束在 packages/evals/package.json 中明确Node.js 最低版本 22.13.0engines字段v1.0.0 起强制要求peerDependenciesmastra/core范围1.0.0-0 2.0.0-0v1.0.0 起将 core 提升为 peer 依赖0.10.0 即已开始迁移vitest范围3.0.0 5.0.0且为可选仅在引入mastra/evals/vitest时才需要自 v1.2.3 起zod 不再是必需的 peer 依赖内部 schema 改用纯 JSON Schema 对象自身依赖仅有compromise、keyword-extractor、sentiment、string-similarity四个 NLP 工具库。包采用subpath exportssrc/index.ts 明确提示 This package uses subpath exports官方入口如下导入路径用途mastra/evals主入口导出常用工具与预置评分器v1.0.0 起提供.入口mastra/evals/scorers/prebuilt预置评分器工厂函数LLM Code 两类mastra/evals/scorers/utils评分器工具函数输入/输出提取等mastra/evals/checksQuick Checks 微评分器命名空间mastra/evals/vitest把runEvals评测包装成 Vitest 测试的断言 APImastra/evals/vitest/setup注册自定义 matcher 的 Vitest setup 文件二、Quick Checks零 LLM 成本的微评分器v1.5.0PR #18392引入了checks——一组针对常见评测断言设计的微评分器micro-scorers。它们内部就是标准的createScorer()实例见 checks/index.ts 源码注释因此天然享有与其他评分器一致的观测、存储与流水线集成同时又不需要任何模型调用。2.1 文本检查Output Text Checks检查器语义关键参数与默认值checks.includes(sunny)输出包含目标子串则得 1 分ignoreCase默认true大小写不敏感checks.excludes(error)输出不包含指定子串则得 1 分ignoreCase默认truechecks.equals(Hello, world!)输出与期望完全相等则得 1 分ignoreCase默认true归一化后比较checks.matches(/\d{1,3}°[FC]/)输出命中正则则得 1 分exact默认false子串匹配为true时用^...$锚定全文checks.similarity(Sunny, 72°F)返回输出与期望的相似度0–1可带阈值转成 0/1threshold默认0.7ignoreCase默认true不传 threshold 时直接返回相似度原值从源码实现看文本检查在preprocess阶段把run.output中所有role assistant的消息用getTextContentFromMastraDBMessage提取文本后拼接再执行比较similarity底层使用string-similarity库的compareTwoStrings源码见 checks/index.ts。2.2 工具调用检查Tool Call Checks检查器语义checks.calledTool(get_weather)指定工具被调用过至少times次默认 1则得 1 分checks.didNotCall(delete_user)指定工具从未被调用则得 1 分checks.toolOrder([search, summarize])工具按给定顺序允许中间穿插其他调用子序列匹配被调用则得 1 分checks.maxToolCalls(5)工具调用总数不超过上限则得 1 分checks.usedNoTools()完全没有工具调用则得 1 分checks.noToolErrors()没有任何工具调用以失败结束则得 1 分工具检查在preprocess中通过extractToolCalls(run.output)提取工具名序列再计数/比较。一个标准的组合用法CHANGELOG 示例import { checks } from mastra/evals/checks; const scorers [ checks.includes(sunny), checks.calledTool(get_weather), checks.toolOrder([search, summarize]), checks.noToolErrors(), ];2.3 一个重要的正确性修复noToolErrors与抛错工具调用v1.10.2-alpha.1PR #23596修复了一个值得注意的缺陷工具抛出异常时noToolErrors()之前可能给出满分 1。根因在于 Agent 原生抛出的工具调用以state: output-error存储而 Quick Checks 只识别state: call同时仅存在于content.parts中的调用会被同消息携带的旧版toolInvocations数组遮蔽。这导致一系列连锁误判noToolErrors()对失败的调用打出 1 分、calledTool少计数、didNotCall/usedNoTools/maxToolCalls/toolOrder在工具确实运行且抛错的情况下仍可能通过。修复方案源码可见于 checks/index.ts调用mergeToolInvocations将两种消息存储形式合并保证只出现在content.parts里的抛错调用不再被隐藏isErrorInvocation将state: call、state: output-error、isError true、result.error存在这四种失败表示全部视为错误该判定与mastra/core中extractTrajectory的成功定义state result isError ! true保持一致。三、runEvals 的 gates、threshold 与 verdictv1.5.0PR #18394为runEvals引入了三个能力gates闸门、阈值判定与综合裁决verdict完整示例import { runEvals } from mastra/core/evals; import { checks } from mastra/evals/checks; const result await runEvals({ data: [{ input: What is the weather? }], target: weatherAgent, gates: [checks.calledTool(get_weather)], scorers: [ { scorer: faithfulnessScorer, threshold: 0.7 }, { scorer: hallucinationScorer, threshold: { max: 0.3 } }, ], }); result.verdict; // passed | scored | failed语义说明gates可选一组必须得1.0分评测才能通过的评分器适合表达硬性前置条件例如必须调用过get_weather工具。门控结果记录在gateResultsthreshold可选作用于每个{ scorer, threshold }条目可以是一个数字最低分要求也可以是一个{ min, max }范围对象——后者对分数越高越糟的指标典型如 hallucination越高越幻觉尤其关键阈值结果记录在thresholdResultsverdict综合判定结果取值passed | scored | failed。这套机制完全向后兼容——不传gates/threshold时行为与旧版本一致。四、预置 LLM Judge 评分器Prebuilt Scorers预置评分器全部通过 scorers/prebuilt/index.ts 聚合导出内部export * from ../llm与../code。LLM 类评分器在仓库中每个都有独立的子目录且都附带prompts.ts提示词模板与index.test.ts录制回放测试例如 answer-relevancy、faithfulness、hallucination、toxicity 等。__recordings__目录中保存着基于 OpenAI gpt-4o/gpt-4o-mini 的真实 LLM 调用录制文件JSON测试可在无网络、零成本的前提下回放验证。4.1 统一的模型配置MastraModelConfigv0.14.0PR #8626把模型配置在所有组件间标准化为MastraModelConfig作用于createScorer与所有内置评分器。支持的四种书写格式// 1. Magic string openai/gpt-4o-mini // 2. 配置对象 { id: openai/gpt-4o-mini } { providerId: openai, modelId: gpt-4o-mini } // 3. 自定义端点 { id: custom/model, url: https://..., apiKey: ... } // 4. 动态解析按上下文运行时决定 (ctx) openai/gpt-4o-mini这与Agent类的模型配置体验保持一致方便跨组件切换模型、接入自定义 Provider。4.2 静态上下文与动态上下文getContext以 hallucination 评分器为例v1.1.0PR #12639。静态上下文模式直接传入上下文数组const scorer createHallucinationScorer({ model: openai(gpt-4o), options: { context: [The capital of France is Paris., France is in Europe.], }, });动态上下文模式适合上下文如工具结果只在评分运行时刻才可得的在线评分场景——通过getContext钩子在运行时解析上下文并配合extractToolResults工具函数从输出中抽取工具结果import { extractToolResults } from mastra/evals/scorers; const scorer createHallucinationScorer({ model: openai(gpt-4o), options: { getContext: ({ run }) { const toolResults extractToolResults(run.output); return toolResults.map(t JSON.stringify({ tool: t.toolName, result: t.result })); }, }, });4.3 Prompt Alignment 的多轮会话上下文v1.8.0PR #21683为 Prompt Alignment 评分器新增includeConversationHistory选项。此前评分器只看到当前轮次——在真实对话中A这种简短回复脱离上文毫无意义judge 无法判断用户问的是什么会把完美回答误判为 misaligned。开启后评分器会读取 Agent 记忆中的先前轮次来帮助解释当前 prompt但仍然只对当前轮次的响应评分// Before const scorer createPromptAlignmentScorerLLM({ model: openai/gpt-5-mini, options: { evaluationMode: user }, }); // After const scorer createPromptAlignmentScorerLLM({ model: openai/gpt-5-mini, options: { evaluationMode: user, includeConversationHistory: true, // 或 { maxMessages: 6 } 限制回看条数 }, });该选项默认关闭因此既有评分结果不会变化且只对携带记忆消息的 Agent 运行生效。4.4 面向 Agent 自纠错的 Rubric 评分器v1.3.0PR #17724新增createRubricScorerLLM-as-judge 按照一组标准对 Agent 输出评分返回二元判定只有全部必需标准满足时才得 1 分并给出逐条标准的反馈。它可以作为isTaskComplete的评分器注入让 Agent 在未达标时自我修正直到满足 rubricimport { createRubricScorer } from mastra/evals/scorers/prebuilt; const rubricScorer createRubricScorer({ model: __GATEWAY_OPENAI_MODEL_MINI__, criteria: [ { description: The response includes an analysis section }, { description: The response includes concrete recommendations }, ], }); await supervisor.stream(Research AI in education, { maxSteps: 10, isTaskComplete: { scorers: [rubricScorer], strategy: all }, });rubric 支持 criteria 数组或换行分隔字符串两种写法、支持可选非门控标准还可以通过 request context 中的rubrickey 按运行覆盖。4.5 多轮会话整体评分createMultiTurnJudgeScorerv1.9.0PR #21936新增createMultiTurnJudgeScorer。既有的预置 LLM judge 都只读取单条assistant 消息无法对runEvals多轮inputs形式产生的整段对话评分。该评分器会读取run.output中累积的每一轮 assistant 回复当满足用自然语言描述的 criterion 时返回 1否则返回 0import { runEvals } from mastra/core/evals; import { createMultiTurnJudgeScorer } from mastra/evals/scorers/prebuilt; const result await runEvals({ data: [{ inputs: [Hows the weather in London?, And Paris?, Should I pack an umbrella?] }], target: weatherAgent, scorers: [ { scorer: createMultiTurnJudgeScorer({ model: anthropic/claude-haiku-4-5, criterion: The agent gave forecasts for London and Paris, and weather-appropriate packing advice., }), threshold: 1, }, ], });4.6 Summarization 摘要评分器双轴取低v1.7.0PR #20293新增createSummarizationScorer从两个维度评价摘要并返回较低分——这样一份忠实但空洞或详尽但错误的摘要都无法蒙混过关Alignment对齐检查摘要中的每个论断是否都能在源文本中找到依据Coverage覆盖从源文本生成封闭式问题只用摘要单独作答第二次独立调用、不喂源文本从而无法靠从源文本里现查蒙混过关。最终得分min(alignment, coverage) × scalereason会指明是哪一轴拉低了分数。源文本默认取运行输入的 user 消息当被摘要文本来自其他位置如工具结果时可传source或sourceExtractormaxQuestions限制覆盖性问题数量防止成本随文档长度线性增长import { createSummarizationScorer } from mastra/evals/scorers/prebuilt; const scorer createSummarizationScorer({ model: openai/gpt-5.5, options: { maxQuestions: 10 }, }); const result await scorer.run(run); result.score;CHANGELOG 特别说明这等价于把旧版 evals 体系中移除的 summarization 指标在全新 scorers 流水线上重建。4.7 Context Recall检索完整度度量v1.6.0PR #19733新增createContextRecallScorer衡量检索到的上下文在多大程度上覆盖了标准参考答案ground-truth中的论断与既有的 context-precision衡量相关性的排序质量互补——一个测查全一个测查准import { createContextRecallScorer } from mastra/evals/scorers/prebuilt; const scorer createContextRecallScorer({ model: openai/gpt-5-mini, options: { context: [ Einstein was born on 14 March 1879 in Ulm, Germany., Einstein developed the theory of special relativity in 1905., ], }, });五、轨迹评分器评估 Agent 与 Workflow 的执行路径v1.2.0PR #14697引入了整条**轨迹trajectory**评估体系从输出质量延伸到执行过程质量。5.1 评分器与工具函数三个评分器createTrajectoryScorerCode——统一评分器一趟完成 accuracy准确性、efficiency效率、blacklist黑名单违规、tool failures工具失败模式四个维度的评估支持数据集逐条期望per-item expectations与静态默认值ExpectedStep.children支持嵌套配置可在不同层级使用不同的评估规则createTrajectoryAccuracyScorerCode——确定性准确性评分器提供 strict / relaxed / unordered 三种顺序模式createTrajectoryAccuracyScorerLLM——基于 LLM 的语义化轨迹评分器。配套工具函数源码在 scorers/code/trajectory/index.tsextractTrajectory/extractWorkflowTrajectory——把 Agent 运行与 Workflow 执行转换成结构化轨迹extractTrajectoryFromTrace——从可观测性 trace spans 构建层级化轨迹含嵌套的 agent/tool 调用compareTrajectories——按可配置的排序与数据匹配规则比较实际/期望轨迹接受ExpectedStep[]checkTrajectoryEfficiency——按预算评估步骤数、token 用量与耗时checkTrajectoryBlacklist——检测被禁止的工具或工具序列analyzeToolFailures——检测重试模式、fallback 与参数修正。5.2 统一评分器配置示例import { createTrajectoryScorerCode } from mastra/evals/scorers; const scorer createTrajectoryScorerCode({ defaults: { ordering: strict, steps: [ { name: validate-input }, { name: research-agent, stepType: agent_run, children: { ordering: unordered, steps: [{ name: search }, { name: summarize }], }, }, { name: save-result }, ], maxSteps: 10, blacklistedTools: [deleteAll], }, });5.3 可配置权重与 ExpectedStep 重构v1.2.0-alpha.1PR #14740补充了两个关键设计weights控制四个维度得分的合成权重默认{ accuracy: 0.4, efficiency: 0.3, toolFailures: 0.2, blacklist: 0.1 }。例如对重准确率的场景可调成const scorer createTrajectoryScorerCode({ defaults: { steps: [{ name: search }], maxSteps: 5 }, weights: { accuracy: 0.6, efficiency: 0.2, toolFailures: 0.1, blacklist: 0.1 }, });ExpectedStep判别联合重构ExpectedStep现在是与TrajectoryStep对应的判别联合。指定stepType后即可对该变体的字段如tool_call的toolArgs、model_generation的modelId获得自动补全原先笼统的data: Recordstring, unknown字段被各变体专有字段取代// Before: { name: search, stepType: tool_call, data: { input: { query: weather } } } // After: { name: search, stepType: tool_call, toolArgs: { query: weather } }移除compareStepData数据字段改为出现在期望步骤上就自动参与比较——指定了toolArgs就与实际步骤比较省略则只按 name 与 stepType 匹配。5.4 预算评分器的严谨化v1.10.1PR #23510修复了轨迹预算评分器budget scorers的两个问题缺失的 token 或耗时测量不再被当作零成功且嵌套的 model-generation 用量不再被重复计入 token 总额。修复后配置了 token 预算就要求完整的模型测量数据配置了耗时预算就要求有效的总额或完整的最顶层耗时数据证据不完整时走评分器既有的预处理错误路径拒绝评分而不是给出一个虚假的满分。六、把评测跑进 CImastra/evals/vitestv1.10.0PR #22665新增mastra/evals/vitest让runEvals评测直接以 Vitest 测试的形式运行从而可以进入 CI 门槛。核心 API 与特性源码见 src/vitest/expect-evals.ts、matchers.ts、reporter.tsexpectEvals/expectEval——评测未通过时测试失败可选自定义 matcher通过mastra/evals/vitest/setup注册toHaveVerdict、toHaveScoreAbove、toHaveScoreBelow、toPassGates、toPassThresholdsMastraEvalsReporter——在 runner 输出中打印每条测试的得分。基础用法import { test } from vitest; import { expectEvals } from mastra/evals/vitest; test(capitals agent answers with the expected city, { timeout: 60_000 }, async () { await expectEvals({ target: capitalsAgent, data: [{ input: What is the capital of France?, groundTruth: Paris }], gates: [containsGroundTruth], }).toPass(); });注意package.json中 vitest 是可选peer 依赖peerDependenciesMeta.vitest.optional只有使用该入口时才需要安装。七、消息模型与兼容性MastraDBMessage 与新消息格式v1.0.0PR #9589、#9702是一组大版本破坏性变更理解它们有助于排查升级问题Scorers 的消息类型从UIMessage切换为MastraDBMessage输入/输出使用嵌套的content对象结构新增getTextContentFromMastraDBMessage()提取文本、createTestMessage()构造测试消息支持可选工具调用、extractToolCalls()从嵌套content读取工具调用、getUserMessageFromRunInput()/getAssistantMessageFromRunOutput()按新结构工作createUIMessage()被移除移除 legacy evals 系统统一到新的 scorers 流水线评分器必须提供 idRuntimeContext更名为RequestContextAgent 大量废弃 API 被清理如agent.llm → agent.getLLM()、agent.tools → agent.getTools()等新增getReasoningFromRunOutput工具可在 preprocess 中读取 deepseek-reasoner 一类模型的 chain-of-thought 推理文本v1.0.0-beta.2PR #10684npm 包内开始附带dist/docs/内嵌文档SKILL.md、SOURCE_MAP.json、主题目录便于 AI 编码助手直接阅读node_modulesPR #11472CHANGELOG 自 v1.10.0 起不再随 npm 包分发以缩小体积PR #22737。后续版本持续围绕多消息格式做兼容性加固例如 v1.3.1 修复 AnswerRelevancy 忽略 format-2 消息parts数组导致活体 Agent 轮次被误打 0 分的问题改为从parts取最后一段文本v1.2.4 修复开启可观测记忆observable memory时 hallucination 与 tool-usage 评分器因无法识别新消息格式中的工具调用而误判完全幻觉或零工具的问题v1.2.2 让所有预置 LLM judgefaithfulness、answer-relevancy、bias、hallucination、toxicity 等不再因output.find is not a function崩溃而是直接支持string、ModelMessage[]、workflow 输入{ prompt }、workflow/task 输出{ text }/{ content }以及单条 assistant 消息对象等目标形态。v1.5.1 还修复了经 Agent subscription /sendMessageAPI 启动的运行拿不到原始用户消息的问题——此前只有agent.stream与agent.generate可行。八、源码结构导航继续深入的方向如果你希望深入底层当前仓库中 packages/evals/src 的布局非常清晰scorers/code——确定性评分器checksQuick Checks、completeness、content-similarity、keyword-coverage、textual-difference、tone、tool-call-accuracy、trajectory每个子目录都带index.test.tsscorers/llm——LLM judge 评分器answer-relevancy、answer-similarity、bias、context-precision、context-recall、context-relevance、faithfulness、hallucination、multi-turn-judge、noise-sensitivity、prompt-alignment、rubric、summarization、tool-call-accuracy、toxicity、trajectory均含prompts.ts与index.test.tsscorers/prebuilt/index.ts——统一导出scorers/utils.ts——输入/输出提取与工具结果抽取等共享工具src/vitest——expect-evals、matchers、reporter、setup四个模块recordings——LLM 调用录制 JSON用于离线、确定性重放测试。九、快速上手指南把以上知识串成一个最小落地流程npm install mastra/evals mastra/core离线断言优先用checks.includes(...)、checks.calledTool(...)、checks.noToolErrors()等零成本检查覆盖可机械判定的属性放进runEvals的scorers或gates语义指标按需引入针对忠实度/幻觉/毒性等用预置 LLM judge模型通过MastraModelConfig统一配置多轮对话用createMultiTurnJudgeScorer摘要场景用双轴的createSummarizationScorer过程质量对 Agent/Workflow 的执行路径用createTrajectoryScorerCodeweights与ExpectedStep表达期望步骤序列与禁止工具固化进 CI用mastra/evals/vitest的expectEvals把评测变成会失败的测试并注册自定义 matcher 精确断言 verdict 与阈值。需要强调的是本文所有 API 名称、默认值、版本行为均以当前仓库 packages/evals/package.json 与 CHANGELOG.md 为准当前包版本为 1.10.2-alpha.1要求 Node ≥ 22.13.0、mastra/core版本范围1.0.0-0 2.0.0-0。迁移到新版本时请重点核对第三节提到的消息模型与废弃 API 变更以及第 2.3、5.4 节中针对失败工具调用与缺失预算测量的行为修正。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表