Mastra 本地开发环境搭建与 Smoke Test 实战从端口排查到可观测性配置【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra导读本文是 Mastra 框架本地开发--env local环境的完整实战指南覆盖开发服务器启动、LLM 环境变量配置、僵尸进程排查、本地可观测性Observability搭建与故障排查以及自定义 API 路由和浏览器 Agent 的本地验证方法。读完本文你将掌握一套可直接复用的本地 Smoke Test 流程从零启动一个可测试的 Mastra 项目验证其 API、Studio、Traces 与浏览器 Agent 各项能力并学会阅读 Mastra 源码来定位问题根源。本文基于 Mastra 官方 Smoke Test Skill 中的 local-setup.md 展开并结合 Mastra 仓库 的源码实现进行纵深讲解。一、环境准备与前置条件本地 Smoke Test 的运行前提十分精简但每一项都直接影响后续步骤能否顺利执行。1.1 启用浏览器工具Mastra 的 Smoke Test 既包含 API/curl 级验证也包含 Studio 界面的浏览器级验证。进行浏览器验证前必须确保浏览器工具已启用通过/browser on启用浏览器工具若浏览器工具不可用运行/browser进行配置浏览器工具支持两种底层 ProviderStagehandAI 驱动的浏览器操作与AgentBrowser确定性浏览器操作。说明本地完整 Smoke Test 要求同时进行 API/curl 检查和 Studio 浏览器遍历除非显式传入--skip-browser。API 检查证明运行时端点可用浏览器检查证明 Playground/Studio UI 能加载、提交表单并展示结果。详见 SKILL.md。1.2 LLM Provider 环境变量根据所选 LLM Provider确保对应的 API Key 已可用Provider环境变量openaiOPENAI_API_KEYanthropicANTHROPIC_API_KEYgroqGROQ_API_KEYgoogleGOOGLE_GENERATIVE_AI_API_KEYcerebrasCEREBRAS_API_KEYmistralMISTRAL_API_KEY检查顺序重要全局环境变量echo $ENV_VAR_NAME项目.env文件若前两者均未找到才向用户询问补充说明来自 environment-variables.mdMASTRA_PLATFORM_API_URL用于区分 staging 与 production 目标需在mastra auth login之前设置而MASTRA_CLOUD_ACCESS_TOKEN、MASTRA_CLOUD_TRACES_ENDPOINT由平台在部署时自动注入本地开发无需设置——这也是本地环境不应该看到MASTRA_CLOUD_ACCESS_TOKEN not set提示的原因。二、启动本地开发服务器端口 41112.1 第一步检查 4111 端口上的僵尸进程这是本地 Smoke Test 最容易踩坑、也最容易被忽略的一步。mastra dev在:4111已被占用时会自动递增端口如:4112、:4113。如果你没注意到这一点后续所有 curl 请求都会打到错误的项目上——尤其是上一次测试会话遗留的旧项目仍在运行的情况。启动前务必检查lsof -i :4111 # 如果有 node 进程在监听先杀掉再启动 kill $(lsof -ti :4111) 2/dev/null从源码角度佐证默认端口 4111 与开发服务器锁文件记录pid、host、port机制在 packages/cli/src 的命令实现与测试中被大量使用例如 guard-live-dev-server.test.ts 中正是通过读取锁文件中的{ pid, host: localhost, port: 4111 }来判断是否存在正在运行的开发服务器从而决定mastra build是否被拦截。理解这一机制有助于你判断端口被占的本质可能不是普通进程冲突而是有意的开发服务器锁仍在生效。2.2 第二步启动开发服务器cd 项目目录 pnpm|npm|yarn|bun run dev服务器启动在http://localhost:4111。启动后等待输出中出现 Mastra API running 字样并确认打印出的实际 URL再运行测试curl -s -o /dev/null -w HTTP %{http_code}\n http://localhost:4111/api/agents # HTTP 200 → 开发服务器已就绪关键判断点如果开发服务器打印的是url: http://localhost:4112/api而非:4111说明 4111 已被占用。此时应停止进程、杀掉僵尸进程后重启若环境支持也可显式传入--port 4111。否则测试参考文档中所有基于 4111 的 curl 示例都会打到错误的服务器上。2.3 验证开发服务器存活浏览器验证前同样需要先确认端口存活curl -s -o /dev/null -w %{http_code}\n http://localhost:4111 lsof -i :4111 || true若进程已死从生成的测试项目中重启并等待就绪带超时轮询cd $SMOKE_DIR/smoke-project pnpm run dev $SMOKE_DIR/logs/dev-server-browser.log 21 for i in {1..60}; do code$(curl -s -o /dev/null -w %{http_code} http://localhost:4111 || true) [ $code 200 ] break sleep 1 done三、本地可观测性Observability设置本地 Smoke Test 验证 Traces 之前必须先确认可观测性已正确配置。新版create-mastra脚手架默认使用PinoLoggerObservability而非旧版的createLogger/OtelConfig并借助MastraCompositeStore组合一个默认 LibSQL 存储 面向observability域的 DuckDB 存储。3.1 检查src/mastra/index.ts标准配置模板如下import { Mastra } from mastra/core/mastra; import { PinoLogger } from mastra/loggers; import { LibSQLStore } from mastra/libsql; import { DuckDBStore } from mastra/duckdb; import { MastraCompositeStore } from mastra/core/storage; import { Observability, MastraStorageExporter, MastraPlatformExporter, SensitiveDataFilter, } from mastra/observability; export const mastra new Mastra({ // ... agents, workflows, scorers storage: new MastraCompositeStore({ id: composite-storage, default: new LibSQLStore({ id: mastra-storage, url: file:./mastra.db }), domains: { observability: await new DuckDBStore().getStore(observability), }, }), logger: new PinoLogger({ name: Mastra, level: info }), observability: new Observability({ configs: { default: { serviceName: mastra, exporters: [new MastraStorageExporter(), new MastraPlatformExporter()], spanOutputProcessors: [new SensitiveDataFilter()], }, }, }), });从源码理解MastraCompositeStoreMastraCompositeStore的实现位于 packages/core/src/storage/base.ts。从其构造函数可以看出几个关键设计组合优先级domains editor default即domains中的覆盖项优先false覆盖表示显式禁用该域线程状态域内置回退threadState域默认会被接上一个内存存储InMemoryThreadStateStorage保证内置任务工具开箱即用只有显式false覆盖才会完全禁用该域初始化委托组合存储保留了父存储引用init()会委托给父存储自身的init()逻辑pragma、有序 DDL、初始化合并等避免组合存储并行遍历内部域时产生SQLITE_BUSY/ no such table 竞态问题构造校验id必填且不能为空必须至少提供一个存储来源default、editor 或 domain 覆盖之一否则直接抛出错误。上述模板正是利用了default 存储 domains 覆盖的模式常规数据落在 LibSQLfile:./mastra.db而observability域的 Trace 数据落在独立的 DuckDB 存储中。从源码理解SensitiveDataFilterSensitiveDataFilter实现于 observability/mastra/src/span_processors/sensitive-data-filter.ts它作为SpanOutputProcessor在 span 输出前对敏感字段进行脱敏默认敏感字段password、token、secret、key、apikey、auth、authorization、bearer、bearertoken、jwt、credential、clientsecret、privatekey、refresh、ssn。匹配不区分大小写并归一化分隔符api-key、api_key、Api Key都会匹配apikey三种脱敏风格full替换为脱敏令牌默认[REDACTED]、partial保留首尾各 3 个字符、中间打码、indexed对每个唯一值分配稳定的[LABEL_N]令牌同一 trace 内相同值映射到相同令牌保持可关联性的同时不暴露原始值状态按 trace 作用域缓存最多追踪 1000 个最近使用的 trace每个 trace 最多 1000 个唯一值超限回退到完整脱敏令牌处理范围span 的 attributes、metadata、input、output、errorInfo、requestContext 等字段都会被处理JSON 字符串中的敏感字段也会被解析后脱敏若脱敏失败字段会被替换为{ error: { processor: sensitive-data-filter } }。从源码理解两个 ExporterMastraStorageExporter见 observability/mastra/src/exporters/mastra-storage.ts存储型导出器将可观测性事件缓冲后按批次刷新到配置的 ObservabilityStorage 后端并带重试支持——这正是本地 Trace 数据能落到 DuckDB 的底层通道MastraPlatformExporter见 observability/mastra/src/exporters/mastra-platform.ts平台型导出器将 Trace 上报到 Mastra 平台云端场景使用。3.2 检查依赖确认package.json包含mastra/observabilitymastra/loggersmastra/libsql默认存储和mastra/duckdbobservability 域3.3 检查开发服务器输出启动开发服务器时观察版本横幅与 Studio URL例如mastra 1.13.0-alpha.4 ready in … Studio at http://localhost:4111 API at http://localhost:4111/api不应看到MASTRA_CLOUD_ACCESS_TOKEN not set——该提示仅属于云端场景本地开发不需要平台注入的 JWT。3.4 本地 Trace 故障排查若 Trace 缺失按以下顺序排查核对 telemetry 配置——确认 Mastra 实例中已配置telemetry重启开发服务器——配置变更必须重启才能生效检查浏览器控制台——查看是否有 OTel 导出错误检查依赖——确保mastra/observability已安装。本地 Trace 的存储特性重要本地 Trace 默认存储在内存中Trace 仅在开发服务器运行期间保留如需持久化 Trace需配置存储后端如上面模板中的 DuckDB observability 域。四、自定义 API 路由的本地验证添加自定义路由后详见 SKILL.md 主流程本地验证方式如下curl http://localhost:4111/hello # 期望输出{message:Hello from custom route!}若 404请回到路由注册处检查两个高频错误点源自 references/tests/setup.md属性名必须是apiRoutes而非routes——server.routes会静默失效不报任何错误修改配置后务必运行类型检查——pnpm tsc --noEmit能捕获routesvsapiRoutes、timeout: 30vstimeout: 30这类mastra build会静默忽略的配置错误。五、浏览器 Agent 的本地测试Browserception在本地测试浏览器 Agent 时你会体验到一种浏览器套娃browserception现象你的 MastraCode 浏览器正在观看项目的 Agent 浏览器——即测试工具层的浏览器在观察被测试项目里 Stagehand 启动的浏览器。需要明确的本地运行事实Stagehand 启动的是机器上已安装的本地 Chromium 系浏览器如 Google Chrome启动前确认机器上有可用的浏览器即可无需单独安装 Playwright 浏览器。浏览器 Agent 还有一个运行时硬性要求给 Agent 传入browser: new StagehandBrowser(...)会自动附加BrowserContextProcessor输入处理器该处理器通过 Mastra memory 读写浏览器状态因此每次调用浏览器 Agent 都必须同时提供 thread 与 resource id否则处理器会抛出类似错误[Processor:browser-context] computeStateSignal requires Mastra memory with an active resourceId and threadId正确的调用姿势是使用memory: { thread, resource }载荷顶层的threadId/resourceId会被静默丢弃curl -s -X POST http://localhost:4111/api/agents/browser-agent/generate \ -H Content-Type: application/json \ -d { messages:[{role:user,content:Navigate to https://example.com and tell me the page title.}], memory:{thread:tid,resource:rid} }Studio 聊天界面无需显式传 ID因为聊天 UI 会自动分配它们。六、本地 Smoke Test 的完整执行框架理解 local-setup 之后将其放入 Smoke Test 的全局流程中见 SKILL.mdsmoke test --env local --existing-project ~/my-app # 完整本地测试 smoke test --env local --existing-project ~/my-app --test agents,traces # 部分测试--env local下本地即pnpm dev→localhost:4111无部署配置无论完整还是部分测试Setup第 1 步始终必须运行--test指定的测试按顺序执行其余跳过浏览器验证后将结果以独立章节追加到$SMOKE_DIR/smoke-report.md逐项记录 Area、Result 与 Evidence如Agent 聊天返回了东京天气并展示 tool call。七、总结与常见问题速查本地开发环境的 Smoke Test 链路可以概括为一条主线环境变量就绪 → 清理 4111 端口僵尸进程 → 启动 dev 服务器并确认 URL → 验证可观测性配置CompositeStore Observability DuckDB→ curl 验证 API → 浏览器验证 Studio → 逐项记录报告。问题排查方向curl 打到错误项目4111 被占用导致端口自动递增先lsof -i :4111查僵尸url: ...:4112而非 4111杀掉占用进程重启或显式--port 4111Trace 缺失依次检查 telemetry 配置、重启服务器、浏览器控制台 OTel 错误、mastra/observability依赖出现MASTRA_CLOUD_ACCESS_TOKEN not set该提示属于云端本地不应出现检查是否误用了云端部署配置自定义路由 404确认使用server.apiRoutes而非server.routes并运行tsc --noEmit浏览器 Agent 调用报错确认每次调用都携带memory: { thread, resource }本地 Trace 重启后消失属正常现象——默认内存存储需配置持久化后端如需更深入的背景可继续阅读同目录下的 SKILL.md、environment-variables.md 与 tests/setup.md或直接查看 core 存储实现 与 observability 包 的源码。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考