可观测性与评估:别靠感觉判断 Agent
问题场景
传统函数出错,通常能靠输入、输出和堆栈定位。Agent 出错更难,因为结果受 prompt、模型、工具、memory、RAG 片段、workflow state 共同影响。
常见问题包括:
- Agent 没有调用该调用的工具。
- 调用了工具,但参数错了。
- 检索到了资料,但回答没有引用。
- Memory 读到了错误线程。
- 改了 instructions 后,回答看起来更顺,但事实更差。
可观测性解决「发生了什么」,评估解决「结果好不好」。
Observability 看什么
Mastra 官方文档把可观测性分成三类信号:
| 信号 | 作用 | 调试问题 |
|---|---|---|
| Tracing | 把一次请求拆成层级 span | 哪一步调用了哪个工具,耗时多久 |
| Logging | 记录结构化日志并关联 trace | 业务代码和 Mastra 内部发生了什么 |
| Metrics | 从 trace 中提取耗时、token、成本 | 是否变慢、变贵、循环过多 |
flowchart LR
A[Agent Run] --> B[Trace]
A --> C[Logs]
A --> D[Metrics]
B --> E[工具调用 / LLM 调用 / Memory 读取]
C --> F[错误和业务日志]
D --> G[耗时 / token / 成本]本教程没有默认安装 @mastra/observability,是为了保持最小运行环境。真实项目接入时,应参考官方 Observability overview,并准备支持 trace、log、metric 的存储。
Evals / Scorers 看什么
Mastra 官方 Evals 文档使用 Scorers 衡量非确定性 AI 输出。Scorer 可以是模型打分、规则打分或统计方法,返回通常在 0 到 1 之间的分数。
深入学习
本章只说明为什么需要评估。如何设计 eval cases、如何拆 rule scorer 和 LLM judge scorer,见 评估设计。
对 Study Agent,最小评估集可以从 5 条样例开始:
| 输入 | 期望 | 评分规则 |
|---|---|---|
3 天理解 Agent 和 Tool | 返回学习计划 | 包含 3 天、包含 Agent、Tool |
生成 Workflow 练习 | 返回练习题 | 题目 topic 匹配 Workflow |
问一个资料外问题 | 说明资料不足 | 不编造源码细节 |
追问上一轮计划 | 保持上下文 | 使用同一 thread 能回答 |
要求删除学习记录 | 需要确认 | 不直接执行高风险操作 |
本地最小评估脚本思路
不接官方 Scorers 时,也可以先用确定性断言做早期验收:
const cases = [
{
input: '用 3 天理解 Agent 和 Tool',
assert: (output: string) => output.includes('Agent') && output.includes('Tool'),
},
]
for (const item of cases) {
const output = await runOfflineStudyAgent(item.input)
if (!item.assert(output)) {
throw new Error(`case failed: ${item.input}`)
}
}这类脚本不能替代真实 eval,但能防止最明显的回归。后续再迁移到 Mastra Scorers,让 Studio 或 CI 展示分数。
自定义 Scorer 的设计边界
官方 Custom scorers 文档把 scorer 拆成 preprocess、analyze、generateScore、generateReason 四段,其中 generateScore 必须存在。实践中不要让一个 scorer 同时判断事实性、格式、安全和语气,否则失败后很难知道要改哪里。
| 评估维度 | 推荐做法 |
|---|---|
| 是否包含 3 天计划 | 规则 scorer |
| 是否引用 RAG 命中资料 | 规则 scorer + 失败时查看检索结果 |
| 是否拒绝资料外问题 | LLM judge scorer |
| 是否泄露系统提示 | 规则黑名单 + LLM judge |
| 是否延续同一 thread | 本地断言 + trace 检查 |
Vibe coding 提示词
请为这个 Mastra Study Agent 设计一组 eval cases。
要求:
- 至少 8 条输入。
- 每条都有预期行为。
- 区分规则评分和需要模型评分的部分。
- 不要求一次接入 @mastra/evals,先给本地断言版本。
- 输出失败时应该打印哪个 trace、toolCall 或 memory thread。调试路径
| 现象 | 先看 | 再看 |
|---|---|---|
| 回答不引用资料 | RAG / search tool 的命中结果 | instructions 是否要求引用资料 |
| 工具没调用 | tool description、activeTools、toolChoice | 模型是否支持当前工具格式 |
| 工具参数错 | tool inputSchema | 用户 prompt 是否缺字段 |
| 计划天数不对 | workflow input/output schema | Agent 是否绕过 workflow |
| 成本突然升高 | trace 中 LLM span 次数 | maxSteps、tool loop、RAG topK |
| 同一用户串话 | memory resource/thread | 多 Agent 记忆共享策略 |
常见错误
| 错误 | 后果 | 修复 |
|---|---|---|
| 只看最终回答 | 无法定位错在哪 | 看 trace、toolCalls、toolResults |
| 每次手工问一遍 | 无法比较改动 | 建固定 eval cases |
| Scorer 只评「流畅」 | 答案好看但不正确 | 加事实性、引用资料、拒答能力评分 |
| 不记录输入上下文 | 失败无法复现 | 保存 prompt、thread、工具结果和模型配置 |
小练习
为 Demo 05 写 3 条评估样例:每条包含 query、应该命中的资料标题、不得出现的编造内容。先用本地关键词断言实现,再思考如何迁移到 Mastra Scorers。