Mastra MSSQL 存储适配器深度解析:@mastra/mssql 的能力演进、核心 API 与源码实现

发布时间:2026/9/15 18:28:25

Mastra MSSQL 存储适配器深度解析:@mastra/mssql 的能力演进、核心 API 与源码实现 Mastra MSSQL 存储适配器深度解析mastra/mssql 的能力演进、核心 API 与源码实现【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra导读本文基于 Mastra 开源仓库中 stores/mssql/CHANGELOG.md 及对应源码系统梳理mastra/mssql这一 Microsoft SQL Server 存储适配器的完整能力从基础配置、领域化存储架构到线程归属转移、工作流定义持久化、精确元数据过滤、分数溯源与多租户隔离等关键特性。读完本文你将掌握如何在 Mastra 项目中接入 SQL Server 作为 AI 应用与 Agent 的持久化后端理解各存储领域Memory、Workflows、Observability、Scores、Agents 等的调用方式并能从容应对 1.x 系列版本引入的行为变更与迁移要求。一、适配器概览SQL Server 作为 Mastra 的持久化底座mastra/mssql是 Mastra 面向 Microsoft SQL Server 的存储实现package.json 中描述为 MSSQL provider for Mastra - db storage capabilities提供通用存储能力、连接池管理与事务支持。它构建在 mssql。与同仓库的其他存储适配器pg、libsql、mysql、mongodb 等一致MSSQL 适配器采用领域化domain组合架构。核心类MSSQLStore继承自MastraCompositeStore在构造时自动装配以下领域实例见 stores/mssql/src/storage/index.ts领域类名用途scoresScoresMSSQL评估分数持久化与查询workflowsWorkflowsMSSQL工作流快照持久化工作流执行状态memoryMemoryMSSQL线程thread、消息message、资源resourceobservabilityObservabilityMSSQL追踪 span / trace 的观测数据backgroundTasksBackgroundTasksMSSQL后台任务状态存储agentsAgentsMSSQL通过 Agents API 创建与查询的 Agent 定义workflowDefinitionsWorkflowDefinitionsMSSQL声明式工作流定义的持久化import { MSSQLStore } from mastra/mssql; const storage new MSSQLStore({ id: mssql-storage, connectionString: Serverlocalhost,1433;Databasemastra;User Idsa;PasswordyourPassword;Encrypttrue;TrustServerCertificatetrue, }); // 通过 getStore() 访问各领域 const memory await storage.getStore(memory); await memory?.saveThread({ thread }); const workflows await storage.getStore(workflows); await workflows?.persistWorkflowSnapshot({ workflowName, runId, snapshot }); const observability await storage.getStore(observability); await observability?.createSpan(span);二、三种连接配置方式与初始化选项MSSQLConfigType定义于 stores/mssql/src/storage/index.ts支持三种互斥的连接方式加上若干初始化控制项。2.1 连接字符串推荐const store new MSSQLStore({ id: mssql-storage, connectionString: Serverlocalhost,1433;Databasemastra;User Idsa;PasswordyourPassword;Encrypttrue;TrustServerCertificatetrue, });2.2 服务器 / 端口 / 账号逐项配置const store new MSSQLStore({ id: mssql-storage, server: localhost, port: 1433, database: mastra, user: sa, password: yourPassword, options: { encrypt: true, trustServerCertificate: true }, // 可选默认即为此值 });2.3 注入预配置的连接池当需要在初始化前对连接池做定制例如注册connect监听器或设置连接级参数时可直接传入sql.ConnectionPool实例import sql from mssql; const pool new sql.ConnectionPool({ server: localhost, database: mydb, user: user, password: password, }); pool.on(connect, () console.log(Pool connected)); const store new MSSQLStore({ id: my-store, pool });三种方式在构造器内部统一归并为sql.ConnectionPoolstores/mssql/src/storage/index.ts因此后续所有领域类都共享同一个连接池。2.4 初始化行为控制项schemaName指定 SQL Server Schema默认为dbo。源码中this.schema config.schemaName || dbo且若指定了不存在的 SchemaMssqlDB.setupSchema()会自动执行CREATE SCHEMA需要 CREATE 权限见 stores/mssql/src/storage/db/index.ts。disableInit关闭自动建表/迁移。适合 CI/CD 场景——部署时显式调用storage.init()执行迁移运行时不再自动 DDL。skipDefaultIndexes跳过默认索引的创建默认false。默认索引失败只会记录 warning 而不会中断初始化因为索引属于性能优化而非功能正确性。indexes自定义索引数组按表名路由到对应领域const store new MSSQLStore({ id: mssql-storage, connectionString: ..., indexes: [ { name: my_threads_type_idx, table: mastra_threads, columns: [JSON_VALUE(metadata, \$.type\)] }, ], });2.5 本地起一个 SQL Server 实例仓库自带 stores/mssql/docker-compose.yaml使用mcr.microsoft.com/mssql/server:2025-CU3-ubuntu-24.04镜像并通过sqlcmd健康检查确保引擎真正就绪而非仅端口开放可配合npm test直接跑通适配器测试套件docker compose up -d --wait三、Memory 领域线程、消息与资源隔离Memory 领域MemoryMSSQL见 stores/mssql/src/storage/domains/memory/index.ts管理三张核心表mastra_threads、mastra_messages、mastra_resources并默认创建两条基于seq_id的复合索引threads 按(resourceId, seq_id DESC)messages 按(thread_id, seq_id DESC)。一个值得注意的源码细节MSSQL 默认索引刻意使用seq_id DESC而非createdAt DESC注释明确说明这是由于 SQL Server 毫秒精度限制。每张表都带有一个seq_id BIGINT IDENTITY(1,1)自增列作为稳定的时间序锚点stores/mssql/src/storage/db/index.ts。3.1 线程查询的资源隔离getThreadById支持可选的resourceId参数当线程不属于该资源时返回null1.3.0 起的行为避免跨资源读取const thread await memory.getThreadById({ threadId: my-thread-id, resourceId: my-user-id, }); // 若线程不属于 my-user-id返回 null分页列表listThreads同样支持resourceId过滤、按createdAt/updatedAt排序默认 DESC、page/perPage分页以及基于metadata的精确过滤。元数据过滤对 key 做了防 SQL 注入校验validateMetadataKeys值仅允许标量类型字符串、数字、布尔、null并通过JSON_VALUE(metadata, $.key)实现。3.2 消息读取的语义变更错误不再被吞掉1.7.0 引入了一个重要的行为变更#17910此前listThreads、listMessages、listMessagesByResourceId、listMessagesById会在后端失败时捕获异常、记录日志并返回空结果{ threads: [], total: 0, hasMore: false }。这导致短暂的数据库故障表锁、连接断开与确实没有数据无法区分——Agent 在故障窗口读取对话历史会误判为无历史而覆盖真实状态。升级后这些方法在真实后端故障时抛出MastraError。直接调用这些读方法而非经由 Agent时需要显式捕获try { const { threads } await storage.listThreads({ resourceId }); // ...use threads } catch (error) { // 真正的后端故障决定重试、上抛还是降级 // 空线程列表不再在这里被掩盖它只表示没有线程 }校验类USER 类别错误与确实为空的结果行为不变——前者直接透传以便调用方得到 400 响应后者仍然返回空分页结果源码中listThreads/listMessages对MastraError.category ErrorCategory.USER的错误直接 rethrow。3.3 线程更新的部分更新语义1.7.x 系列修复了生成的线程标题被覆盖问题#21041、#21257updateThread不再强制同时提供title和metadata两者相互独立、可省略其一省略的字段保持不变。MemoryMSSQL通过supportsPartialThreadUpdate true向更新的mastra/memory声明该能力stores/mssql/src/storage/domains/memory/index.ts同时保留对旧版本内存包的兼容——旧适配器场景下会自动回填已有标题。此外消息持久化也不再重写它刚读过的线程行。3.4 线程归属转移updateThreadResourceId最新版本1.8.0-alpha.0#23533新增线程归属转移能力可将既有线程连同其全部消息迁移到新的resourceId同时保留线程原始的createdAt时间戳。典型场景是把私有线程移入共享工作区无需再走先读后改的变通方案。服务端调用来自特权、非资源作用域上下文const thread await memory.updateThreadResourceId({ threadId: thread-123, resourceId: new-resource-456, });客户端调用const client new MastraClient({ baseUrl: http://localhost:4111 }); const thread client.getMemoryThread(thread-123, agent-id); await thread.transfer({ resourceId: new-resource-456 });配套能力包括mastra/core/mastra/memory新增Memory.updateThreadResourceId默认实现由MemoryStorage.updateThreadResourceId提供mastra/server新增受限路由POST /memory/threads/:threadId/transfer该端点拒绝带有已解析 resource scope 的请求mastra/client-js新增MemoryThread.transfer({ resourceId })。启用语义召回时消息向量会一并迁移到新resourceId保证按资源检索仍能命中被转移的线程。从源码可以看到 MSSQL 的实现细节stores/mssql/src/storage/domains/memory/index.ts整个转移过程在单个事务内完成先用SELECT ... WITH (UPDLOCK, HOLDLOCK)锁定线程行再串行更新线程与消息的resourceId从而避免同一线程的并发转移交错执行、产生归属分裂。若线程已属于目标资源则直接提交返回不产生冗余写入。四、WorkflowDefinitions 领域声明式工作流的持久化1.6.0#20471为包括 mssql 在内的所有主流后端实现了workflowDefinitions存储领域。此前POST /stored/workflows、Mastra.addStoredWorkflow只能依赖mastra/core的内存存储持久化适配器会从storage.getStore(workflowDefinitions)返回undefined。const workflowDefinitions await storage.getStore(workflowDefinitions); if (!workflowDefinitions) { throw new Error(This storage adapter does not support the workflowDefinitions domain); } await workflowDefinitions.upsert({ id: greeting-workflow, inputSchema: { type: object, properties: { name: { type: string } }, required: [name] }, outputSchema: { type: object, properties: { text: { type: string } }, required: [text] }, graph: [{ type: agent, id: greet, agentId: greeter-agent }], }); const { definitions, total } await workflowDefinitions.list({ status: active }); const definition await workflowDefinitions.get(greeting-workflow); await workflowDefinitions.delete(greeting-workflow);WorkflowDefinitionsMSSQL的实现要点见 stores/mssql/src/storage/domains/workflow-definitions/index.ts初始化时依据WORKFLOW_DEFINITIONS_SCHEMA创建共享表mastra_workflow_definitions并补充status默认索引与schedule列迁移alterTable。实现upsert/get/list/deletelist支持status与authorId过滤、按updatedAt降序。并发首写竞态安全两个调用方同时对同一个新 id 执行 upsert 时落败方的 insert 会命中重复键随后重新读取行并走部分更新路径而非直接失败stores/mssql/src/storage/domains/workflow-definitions/index.ts。JSON 列往返inputSchema、outputSchema、stateSchema、requestContextSchema、metadata、graph均经 JSON 序列化存取无论后端是哪个声明式工作流图都能原样还原损坏的持久化 JSON 会抛出带行号与列名的可操作错误而不是返回原始字符串parseJson见同文件第 20-33 行。部分 upsert 保留未指定字段含authorId更新与createdAt/updatedAt语义。MSSQLStore复合存储会自动装配该领域调用方无需手动构造——storage.getStore(workflowDefinitions)直接返回可用的句柄。五、Agents 领域与背景任务、观测能力5.1 Agents 存储领域1.3.0#16376为 MSSQL 适配器补齐了 agents 存储领域使 Studio 的 Agents 标签页与mastra.getEditor()可以在 MSSQL 后端正常工作import { MSSQLStore } from mastra/mssql; const store new MSSQLStore({ id: mssql-storage, connectionString: process.env.MSSQL_URL!, }); const agents await store.getStore(agents); const agent await agents?.getById(agent-id); const page await agents?.list({ status: published, perPage: 20 });5.2 后台任务与持久化 Agent1.2.1 起新增BackgroundTasksStorage领域实现使mastra/core的后台任务执行可依托任意存储适配器1.7.1 又为通过 Agents API 创建的 Agent 增加了durable选项让其无需部署代码即可获得持久化执行能力stores/mssql/CHANGELOG.mdawait mastraClient.createStoredAgent({ id: helper, name: Helper, instructions: You are a helpful assistant., model: { provider: openai, name: gpt-5 }, durable: true, // 传 true 用默认值或 { maxSteps, cleanupTimeoutMs } 调优 });缓存与 pubsub 继承自服务器的 Mastra 实例跨副本的持久化执行需要在服务端配置分布式后端自动恢复仍通过代码中的recovery.durableAgents配置。5.3 观测领域的迁移约束1.7.5 修复了作用域化 trace 删除——当遇到不支持的租户过滤器时直接拒绝删除而不是在无作用域的情况下清空数据#22553。1.2.0 为 spans 表新增requestContext列。另外spans 表要求(traceId, spanId)复合主键。初始化时若检测到历史数据中存在重复组合会抛出带结构化错误 IDMIGRATION_REQUIRED::DUPLICATE_SPANS的MastraError提示运行npx mastra migrate去重并添加唯一约束stores/mssql/src/storage/db/index.ts。迁移逻辑优先保留已完成的 spanendedAt IS NOT NULL、再按updatedAt、createdAt排序去重。六、Scores 领域分数溯源与多租户隔离1.4.1#18331为持久化分数增加了溯源字段与租户隔离字段scoreTrace()接受顶层batchId、datasetId、datasetItemId便于将一次基线评估的一组分数归并为一次评分批次并回联到其来源数据集条目await scoreTrace({ storage, scorer, target: { traceId }, batchId: baseline-batch-1, datasetId, datasetItemId, });分数可携带organizationId与projectIdlistScoresBy*系列方法支持filters选项按组织/项目范围过滤await storage.saveScore({ ...score, organizationId: org-a, projectId: proj-1 }); const result await storage.listScoresByScorerId({ scorerId, filters: { organizationId: org-a, projectId: proj-1 }, });projectId标识项目作用域与继续表示 Agent 记忆资源的resourceId相互独立。MSSQL 的分数存储会应用增量溯源迁移并保证持久化分数读取的顺序确定性。七、1.0.0 以来的 API 迁移要点升级必读1.0.0 大版本对存储 API 做了系统性收敛MSSQL 适配器同步落地。以下是 stores/mssql/CHANGELOG.md 明确记录的迁移要点7.1 用 listMessages 取代旧方法getMessages()与getMessagesPaginated()已移除统一改用带分页的listMessages()// Before const messages await storage.getMessages({ threadId: thread-1 }); // After const result await storage.listMessages({ threadId: thread-1, page: 0, perPage: 50, }); const messages result.messages; // 消息数组 console.log(result.total); // 总数 console.log(result.hasMore); // 是否还有下一页listMessages()默认按createdAt升序最旧在前需要倒序时const result await storage.listMessages({ threadId: thread-1, orderBy: { field: createdAt, direction: DESC }, });listMessages要求threadId非空且非纯空白字符串否则抛错而非返回空结果。7.2 分页参数从 offset/limit 改为 page/perPage所有存储与 Memory 分页 API 统一使用page从 0 开始与perPage// Before await memory.listThreadsByResourceId({ resourceId: user-123, offset: 20, limit: 10 }); // After await memory.listThreadsByResourceId({ resourceId: user-123, page: 2, perPage: 10 });同时为负page值增加了校验perPage的边界情况负值、0、false也做了统一处理。7.3 perPage: false 拉取全部记录listMessages()及分数查询listScoresBySpan()、listScoresByRunId()、listScoresByExecutionId()支持perPage: false以绕过分页上限HTTP 查询解析器接受?perPagefalse字符串。7.4 其他重命名与类型收敛getThreadsByResourceId/getThreadsByResourceIdPaginated→listThreadsByResourceIdoffset/limit改为嵌套orderBy: { field, direction }。getMessagesById({ messageIds, format })→listMessagesById({ messageIds })仅返回 V2 格式消息。client.getThreadMessages()→client.listThreadMessages()。MastraMessageV2更名为MastraDBMessage返回格式统一为{ messages: MastraDBMessage[] }可通过mastra/ai-sdk/ui的toAISdkV4/5Messages()转换。StorageGetMessagesArg→StorageListMessagesInput。运行时上下文RuntimeContext更名为RequestContextspans 表随之增加requestContext列。八、底层实现亮点类型映射、弹性列处理与索引约束MSSQL 适配器在源码层面对 SQL Server 特性做了大量针对性适配stores/mssql/src/storage/db/index.ts类型映射text→NVARCHAR(400)主键NVARCHAR(255)、复合索引列NVARCHAR(100)、大数据列NVARCHAR(MAX)timestamp→DATETIME2(7)uuid→UNIQUEIDENTIFIERjsonb→NVARCHAR(MAX)boolean→BIT等。其中NVARCHAR尺寸选择源于 SQL Server900 字节索引键上限NVARCHAR(100)200 字节允许复合索引最多 4 列NVARCHAR(400)800 字节支持单列索引。弹性列处理插入/更新前会查询INFORMATION_SCHEMA.COLUMNS并缓存实际列集合未知列静默丢弃而非报 SQL 错误——当更新的领域包新增字段而表尚未迁移时保证前向兼容1.2.0#14021。alterTable完成后会失效列缓存。事务化批量写入batchInsert在单事务内逐条插入失败整体回滚线程删除同样在事务中先删消息再删线程。线程 upsertsaveThread使用MERGE ... WITH (HOLDLOCK)实现原子化的插入或更新stores/mssql/src/storage/domains/memory/index.ts。截断回退清表优先TRUNCATE遇到外键约束错误错误号 4712自动回退为DELETE。九、版本适配与升级注意事项当前mastra/mssql版本为1.8.0-alpha.0见 stores/mssql/package.jsonpeer 依赖mastra/core范围为1.61.0-0 2.0.0-0CHANGELOG 中历史版本也对最低mastra/core版本做过修正#22564升级时请以实际发布版本的 peer 约束为准。1.7.4 起CHANGELOG.md不再随 npm 包分发以减小包体积需要版本历史时直接查看仓库中的 stores/mssql/CHANGELOG.md。升级到 1.7.0 后若直接调用listThreads/listMessages等读方法注意捕获MastraError以区分真实故障与空结果见 3.2 节。若曾通过旧版适配器写入数据且尚未运行 spans 去重迁移init()可能抛出MIGRATION_REQUIRED::DUPLICATE_SPANS按提示执行npx mastra migrate即可。结语mastra/mssql已从单一的记忆存储演进为覆盖 Memory、Workflows、Observability、Scores、BackgroundTasks、Agents、WorkflowDefinitions 七大领域的完整存储适配器并以seq_id时序锚点、MERGE/HOLDLOCK/UPDLOCK锁策略、弹性列过滤、自动建表与增量迁移等机制贴合 SQL Server 的平台特性。无论你是把 SQL Server 用作 Agent 记忆库、持久化工作流定义还是落地可追溯的评估分数体系都可以参照本文的能力清单与迁移指南结合仓库源码stores/mssql/src/storage快速完成接入与升级。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/15 18:23:24

Automatisch 集成 Twitter:OAuth 1.0a 连接配置完全指南

Automatisch 集成 Twitter:OAuth 1.0a 连接配置完全指南 【免费下载链接】automatisch The open source Zapier alternative. Build workflow automation without spending time and money. 项目地址: https://gitcode.com/GitHub_Trending/au/automatisch 本…

2026/9/15 18:38:25

中文字体子集化:精准裁剪而非压缩的工程实践

1. 为什么中文字体子集化不是“压缩”而是“外科手术式裁剪”很多人第一次听说“中文字体子集化”,下意识就联想到 ZIP 压缩、图片 WebP 转换——这是最典型的认知偏差。我去年给一个面向海外用户的中文内容平台做性能优化时,也犯过这个错:直…

2026/9/15 18:38:25

ZZULIOJ刷题全攻略:从入门基础到算法进阶的题解整合与避坑指南

我记得第一次在新生群里看到“ZZULIOJ”这五个字母时,整个人是懵的。页面白底黑字,左侧一排深色菜单,点进去是一道道看着都认识的题,但提交后不是“编译错误”就是“答案错误”。后来我在这套OJ上从大一刷到大四,从被s…

2026/9/15 18:38:25

北京学会网站建设避坑指南:小白不踩雷实操手册

北京学会网站建设避坑指南:小白不踩雷实操手册 想在北京做个像样的网站,心里没底?自己不会代码,又怕被坑?别慌。 这三年我在北京海淀、朝阳跑遍了各大软件园,见过太多初创团队花大价钱做了个“四不像”网站,最后因为服务器卡顿、SEO做废、备案拖延…

2026/9/15 4:54:30

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/15 0:01:16

AI英语单词APP开发:自适应学习算法与移动端优化实践

1. 项目概述 作为一名在移动应用开发领域摸爬滚打多年的老手,我最近完成了一个AI英语单词APP的开发项目。这个项目将传统单词记忆方法与现代AI技术相结合,打造了一款能够智能适应不同用户学习习惯的英语学习工具。 市面上大多数单词APP都存在一个通病&a…

2026/9/15 0:01:16

Flutter与OpenHarmony结合开发手语学习APP实战

1. 项目背景与核心价值作为一名同时接触过Flutter和OpenHarmony的开发者,最近我完成了一个基于Flutter for OpenHarmony的手语学习APP实战项目。这个项目最大的特点在于实现了跨平台框架与国产操作系统深度结合的创新实践——用Flutter开发的应用能完美运行在OpenHa…

2026/9/15 0:01:16

六个月成为机器人工程师:从ROS2到SLAM的实战路径

1. 六个月的紧迫感从哪来:先搞清楚你要成为哪种机器人工程师说实话,六个月的期限并不是一个宽松的时间线。市面上任何一本正经的机器人学教材都超过五百页,ROS2的官方文档可以翻到你怀疑人生,再加上ABB、KUKA这些工业机器人厂家动…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/14 13:53:59

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码