Mastra 开发(08):本地调试工作台

QuibblerAgentQuibblerAgent 2026-11-11 约 18 分钟 4 次阅读

第 2 篇搭环境时,我们在 pnpm dev 起的本地工作台里初见过 4111 端口:左侧选 Agent、右侧聊天、每轮回答带一条 Trace,当时只当它是"能看日志的聊天窗"。这篇把它正儿八经当调试工具讲透——因为它是 TS 栈对 Python 栈的一个实打实的差异化:LangChain 把可观测性外包给 LangSmith 云服务,Mastra 把调试台做进了框架本身。注册账号、配置 API Key、trace 上云,这些 LangSmith 的前置动作在 Mastra 里统统不存在;mastra dev 一条命令,调试闭环全在本机。

全文按"价值定位 → 启动导览 → Playground 交互 → Trace 解读 → 热重载循环 → REST 联调 → 评测联动 → CI 衔接"组织,示例延续第 2 篇的 timeAgent,界面分区与配置写法基于 2026 年 10 月官方文档逐一核实。


1、内置工作台的价值

调试 Agent 与调试普通函数最大的不同:问题常常不在"代码哪行错了",而在"模型为什么这么决定"。generate 只给你最终文本,中间的决策链——读了什么指令、调没调工具、传了什么参数、耗了多少 token——全在黑盒里。没有像样的观测工具,调 Agent 就只剩 print 大法。

两个生态的答案路数完全不同。Python 阵营的事实标准是 LangSmith:云端 SaaS,注册账号、拿 API Key、配环境变量,trace 上传到它的服务器再回来看。Mastra 的答案是内置:mastra dev 起本地服务,Playground、Trace、日志、评测面板全在 localhost。对比如下:

维度 LangSmith Mastra Dev 工作台
形态 云端 SaaS 本地内置,随框架安装
前置动作 注册账号、配 API Key 无,mastra dev 直起
数据驻留 上云 全在本机文件
费用 免费额度后按量计费 无
扩展 平台自身 可再导出至 Langfuse、Datadog

边界也要说清:本地优先不等于封闭。@mastra/observability 包提供一排 exporter,团队往后要接 Langfuse 或 Datadog,加一份配置就行(见官方可观测性文档)。但对单人开发与小团队,本机闭环已覆盖日常调试的绝大部分需求——这也是本篇展开的前提。

2、启动与界面导览

回到第 2 篇的工程,起服务只需一条命令:

pnpm dev

dev 脚本即 mastra dev,输出里的关键一行是地址:

➜ Local:  http://localhost:4111/

浏览器打开即进工作台。2026 年 10 月的界面按功能分了四组(区块随版本演进,以 Studio 官方文档为准),分区地图如下:

localhost:4111
├── Agents            # 对话调试:模型切换、参数滑杆、随行打分
├── Workflows         # 流程图可视化、逐步执行
├── Tools             # 绕过模型单独执行工具
├── MCP servers       # 查看已挂载的 MCP 服务与工具
├── Processors        # 输入输出处理器(guardrails 等)
├── Workspaces        # Agent 工作区文件与 Skills
├── Request context   # 运行时变量表单,跨对话保留
├── Evaluation
│   ├── Scorers       # 随行打分结果
│   ├── Datasets      # 数据集管理与导入
│   └── Experiments   # 实验对比
└── Observability     # Metrics / Traces / Logs 三视图

三句话导览。Agents 区是主战场,对话式调试都在这,第 3、4 节展开;Workflows 把流程画成图,可从任意输入逐步执行;Tools 区提供脱离模型的工具单独执行,排障时用来分层定位。Settings 里有两处值得知道:API prefix 默认 /api(第 6 节 curl 要用),自定义请求头则在联调带鉴权的服务时用得上。

端口与绑定地址在注册中心改,server 选项一行的事:

import { Mastra } from '@mastra/core'

export const mastra = new Mastra({
  agents: { timeAgent },
  server: { port: 4111, host: 'localhost' }, // 默认即 4111,按需覆盖
})

默认值就是 4111,通常不用动;端口被占或想多工程并跑时改这里。另外 mastra dev --https 会自动生成本地证书起 HTTPS 开发服务,调试要求安全上下文的接口时有用。

3、Playground 交互调试

Agents 区选中 timeAgent,中间是对话窗,右侧是参数面板。可调项有:模型(下拉切换,带供应商连接状态)、temperature、top-p,全是即调即生效的滑杆。旁边还有 Models 面板,把主模型与 fallback 链按优先级列出,可以临时停用某一级、调整顺序。

典型的调试循环长这样。同一句"现在几点了?这个月还剩几天?"先按默认参数发一遍,看工具调用是否发生;把 temperature 拉到 1 再发,对比两轮回答的措辞与工具触发是否稳定;最后改 instructions 加一条约束,保存后服务自动热重载,切回浏览器再发同一句。三分钟完成三轮对照实验——这是工作台相对于写脚本跑 generate 的真正效率差。

两个进阶玩法。其一,对话支持流式中追发消息:上一轮还没生成完,你的补充已经排上队,适合模拟用户不耐烦补条件的真实场景。其二,Tools 区把 timeTool 单独拉出来执行:表单由 inputSchema 自动生成,填参数点运行,直接看 execute 的返回。这是分层排障的关键——工具单独跑就不对,问题在工具实现;工具对但 Agent 不调,问题在 description 或 instructions。

注意:Playground 里的参数改动只写进运行中服务的内存,重启即失效。它是试验田,验证有效的参数要回写到 Agent 定义代码里才算数。

4、Trace 逐层解读

Trace 是工作台最值钱的部分,看的位置有两处:Agents 对话里每轮响应自带的 trace 面板(第 2 篇见过),以及 Observability 页的 Traces 视图——后者聚合全部历史运行,配 Columns 开关可按 input、entity、duration、输入输出 token、预估成本等列排序筛选。

以 timeAgent 回答"现在几点了?"为例,一条典型 trace 从外到内四层:

  1. 根节点是这次 agent 运行,总耗时一目了然
  2. 第一次模型调用:输入含 instructions 与用户消息,输出工具调用决策
  3. 工具执行 span:get-current-time 的输入、输出时间串、毫秒级耗时
  4. 第二次模型调用:携带工具结果再次推理,产出最终文本

排障时四层各有用法:工具 span 耗时长,先查 execute(网络工具超时是常客);两次模型调用的 token 差异大,查 instructions 是否臃肿;带记忆的 Agent(第 5 篇)在模型调用输入里能看到注入的历史消息,轮次越多 promptTokens 越贵,这在 trace 里直接可读。Trace 面板头部有 Download trace JSON,导出的 trace-<id>.json 含全部 span 与输入输出,写评测或提 issue 时贴它比截图专业。

有个必知的坑:Observability 页默认是空的——trace 不落库。要持久化先装三个包:

pnpm add @mastra/observability @mastra/libsql @mastra/duckdb

再给 Mastra 实例配复合存储与导出器:

import { Mastra } from '@mastra/core/mastra'
import { LibSQLStore } from '@mastra/libsql'
import { DuckDBStore } from '@mastra/duckdb'
import { MastraCompositeStore } from '@mastra/core/storage'
import { Observability, MastraStorageExporter } from '@mastra/observability'

export const mastra = new Mastra({
  storage: new MastraCompositeStore({
    id: 'composite-storage',
    default: new LibSQLStore({ id: 'mastra-storage', url: 'file:./mastra.db' }),
    domains: { observability: await new DuckDBStore().getStore('observability') },
  }),
  observability: new Observability({
    configs: { default: { serviceName: 'mastra', exporters: [new MastraStorageExporter()] } },
  }),
  agents: { timeAgent },
})

两个要点。MastraCompositeStore 把存储分成两个域:业务数据(记忆、scorer 分数)走 LibSQL 文件库,观测数据走 DuckDB——DuckDB 不是洁癖,LibSQL 单独用时支撑不了 trace 查询与指标聚合,Traces 列表的高级筛选和 token 列就出不来。MastraStorageExporter 则把 trace、日志、指标写进存储。配完重启,Metrics、Traces、Logs 三视图就有数据,Logs 还支持全文检索,点一条日志能跳到关联 trace 的时间轴。

5、热重载开发循环

第 3 节的调试循环之所以快,底层是热重载:mastra dev 监视着 src/mastra/ 下的源码,保存即重新加载,Agent 定义、工具、工作流的改动下一秒生效,浏览器刷新即见。对比脚本式开发"改代码 → 重跑 → 等待 → 读输出",工作台把"重放同一条输入"的成本降到一次点击——而 Agent 调优恰恰是高频重放的活。

两个例外要记牢。其一,环境变量不热重载:.env.development 里加了 Key、换了供应商,必须重启 mastra dev,进程不会自动重读——第 2 篇的坑,在这里再踩一遍会浪费半小时。其二,重载会重置服务内存态,Playground 里没写回代码的临时参数随之丢失,又是"试验田"那句提醒的另一面。

6、REST API 测试台

工作台不只给浏览器用:mastra dev 起的同一个服务就是完整的 REST API,路径前缀默认 /api。这意味着前端或脚本可以直接把 localhost:4111 当联调后端,不需要先部署。全部端点在 http://localhost:4111/swagger-ui 的交互式文档里可查,服务端路由参考有完整清单。

先列注册过的 Agent:

curl http://localhost:4111/api/agents

返回是 Agent 元数据数组。再直接对 time-agent 发起一次 generate:

curl -X POST http://localhost:4111/api/agents/time-agent/generate \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"现在几点了?"}]}'

响应核心字段如下(token 数随实际变化):

{
  "text": "现在是 2026-10-27 14:32:05,星期二。",
  "finishReason": "stop",
  "usage": { "promptTokens": 312, "completionTokens": 28 }
}

三个细节让这个端点适合做 A/B。请求体可放 instructions 临时覆盖系统指令,不改代码就能对比两版 prompt;threadId 与 resourceId 能串起多轮会话(配合第 5 篇的记忆);流式场景换 /stream 端点。响应的 toolCalls 字段带回工具调用记录,脚本断言它就能做最朴素的自动化验证——这是通往评测的桥。

7、评测面板联动

第 7 篇挂上去的 scorers,在工作台里有三个查看位置。Agents 对话里每条消息带 Scorers 标签,异步打分的分数与 judge 理由随消息可翻;Evaluation 组的 Datasets 管测试集,支持 CSV/JSON 导入导出与版本固定;Experiments 是最值得上手的一个:选数据集对 Agent 跑一轮实验,最多可把 2~10 个实验与基线并排对比,配日期过滤看指标走势。

这正好补上第 7 篇留的缺口。当时说"改完 instructions 立刻跑同一组输入对比分数"要写 vitest——现在工作台点两下就能完成:改 instructions → 保存热重载 → Experiments 重跑同一数据集 → 与上一轮实验对比。人工调优的短循环放在工作台,固化结论的长周期放进测试,各干各的。

8、与 CI 的衔接

工作台调优的终点不是"看起来不错",而是把结论固化成断言。衔接点就是第 7 篇第 5 节那个 vitest 文件:工作台里看到 timeAgent 稳定触发 get-current-time,就写成 checks.calledTool('get-current-time');看到幻觉分长期低于 0.2,就把 0.2 写进阈值断言。本地用工作台做探索,CI 用断言做守门——EDD 系列第 10 篇的硬门禁思想,在 TS 侧落地的最后一块拼图就在这里。

成本分层照搬第 7 篇的结论即可:checks.* 微秒级且可复现,放进每次提交都跑的常规用例;LLM judge 有轮次波动和真实开销,用环境变量分流到夜间流水线。工作台负责让你"看见差异",CI 负责"拦住退步",两条腿缺一不可。

9、总结

回顾全文:Mastra 把调试台做进框架,mastra dev 一条命令在 localhost:4111 起完整工作台——Agents 区对话式调参数,Tools 区分层排障,Observability 区逐层读 trace(记得配 DuckDB 复合存储才能落库),热重载撑起秒级迭代,REST API 让脚本与前端直接联调,Experiments 把第 7 篇的 scorer 变成免代码的对比实验。对从 LangChain 迁过来的工程师,最大体感是省掉 LangSmith 的注册与上云;对所有 Agent 开发者,最大收益是"改一行、重放一次"的调试节奏。

练习:回到第 2 篇的 timeAgent 做三组对照。第一组,temperature 取 0 与 1 各发同一句模糊提问(如"说说今天"),对比两轮 trace 里工具触发与措辞的差异;第二组,instructions 加一条"回答必须附带星期几",热重载后重发,看第一次模型调用的 token 变化;第三组,配好 Observability 落库后导出一份 trace JSON,数一数里面有几个 span。做完这三组,工作台对你就不神秘了。对于正在搭 TS Agent 项目的工程师,建议把 mastra dev 当成开发期的常驻进程——普通程序靠 IDE 断点,Agent 程序靠这块工作台。

相关推荐

获取系统SDK版本、判断手机ROM
精选Code

获取系统SDK版本、判断手机ROM

Build获取系统SDK版本Android中部分API的使用,需要在特定的SDK版本之后才能使用,因此在兼容老版本SDK的时候,经常需要判断API的版本。各种Android版本的对应关系参考《Android各版本对应的SDK版本》判断手机ROM有时候需要判断手机系统的ROM,检测ROM是MIUI、EMUI还是Flyme,可以使用getprop命令,去系统build.prop文件(关于build.p

4.2k
AndroidStudio中各种中文乱码问题
精选Code

AndroidStudio中各种中文乱码问题

AndroidStudio中各种中文乱码问题1、编译Java错误信息乱码在出现这个Annotation processors must be explicitly declared now...问题的时候,正好也发现AndroidStudio Build Output错误信息都乱码。经常遇到各种问题,习惯了,现在遇到的问题,都是以后的答案。 1.1、修改项目build.gradle(无效)在整个p

2.8k
Multi-Agent 详解:多智能体协作架构与实践
精选Agent

Multi-Agent 详解:多智能体协作架构与实践

一个智能体配上一套工具,已经能完成相当多任务。但让它同时“当产品经理、写后端、跑测试、做代码评审”,很快就会露馅:上下文里塞满了互相干扰的指令,十几件工具的清单来回切换,任务做到一半忘了开头。解法看起来很自然——像人类团队一样分工:让多个智能体各司其职,由一个协调者调度,这就是 Multi-Agent(多智能体)系统。它也是 2026 年智能体工程里讨论度最高、误用率也最高的架构。本文按“架构模式…

122