Mastra 集成 Turbopuffer 向量存储指南:从接入配置到过滤查询的完整实战
Mastra 集成 Turbopuffer 向量存储指南从接入配置到过滤查询的完整实战【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastraTurbopuffer 是一款以高吞吐、低延迟为特点的托管向量数据库其服务运行在内存之上适合对检索性能敏感的 AI 应用。mastra/turbopuffer是 Mastra 官方提供的 Turbopuffer 向量存储适配层它基于官方turbopuffer/turbopufferSDK 实现并额外融入了 Mastra 的遥测telemetry支持使 Turbopuffer 可以无缝接入 Mastra 的 Agent、Memory 与 RAG 工作流。本文将以 stores/turbopuffer/README.md 为骨架结合仓库中的源码与测试用例带你掌握该适配器的安装、初始化、建索引、写入向量、相似度查询、元数据过滤、向量更新与删除等全部能力并深入理解其底层实现原理。安装与依赖前提在项目中安装适配器npm install mastra/turbopuffer根据 package.json 的声明该包的运行环境要求如下Node.js22.13.0engines字段核心依赖turbopuffer/turbopuffer^0.10.18负责与 Turbopuffer API 通信peerDependenciesmastra/core1.0.0-0 2.0.0-0即需要与 Mastra 核心包配合使用包以 ESM 为主同时提供 CommonJS 构建产物dist/index.cjs通过exports字段区分import与require入口在 Mastra 的 monorepo 结构中该包位于 stores/turbopuffer源码结构为src/index.ts包入口导出./vector/indexsrc/vector/index.tsTurbopufferVector核心类实现src/vector/filter.tsMastra 过滤器到 Turbopuffer 过滤器的翻译器src/vector/index.test.ts 与 filter.test.ts集成测试与翻译器单元测试快速上手初始化、建索引、写入与查询README 给出了最核心的使用流程下面结合源码对其中的每一步做详细拆解。1. 实例化 TurbopufferVectorimport { TurbopufferVector } from mastra/turbopuffer; const vectorStore new TurbopufferVector({ id: my-turbopuffer-vector, apiKey: your-api-key, baseUrl: https://gcp-us-central1.turbopuffer.com, });构造参数TurbopufferVectorOptions定义于 src/vector/index.ts参数类型默认值说明idstring必填存储实例的唯一标识用于遥测与日志关联apiKeystring必填Turbopuffer API KeybaseUrlstringhttps://api.turbopuffer.comAPI 基础地址可按区域指定如https://gcp-us-central1.turbopuffer.comconnectTimeoutnumber10_000ms建立连接的超时时间仅 Node 与 Deno 环境生效connectionIdleTimeoutnumber60_000ms连接空闲超时仅 Node 与 Deno 环境生效warmConnectionsnumber0创建客户端时预先建立的连接数compressionbooleantrue是否压缩请求并接受压缩响应consistencystrong \| eventualstrong实例级别的查询一致性级别可被单次查询覆盖schemaConfigForIndex(indexName: string) { dimensions; schema }无按索引名返回显式 schema 配置的回调用于为指定索引声明维度与可过滤字段其中consistency的语义源码注释src/vector/index.tsstrong默认查询能看到查询发起之前写入的所有数据延迟更高eventual延迟更低但最近写入的数据可能尚未可见。该选项在 v1.2.0 中加入见 CHANGELOG.md并且测试用例明确验证了三级覆盖关系实例默认strong→ 实例级eventual→ 单次查询覆盖实例配置见 index.test.ts 中TurbopufferVector consistency option测试块。2. 创建索引createIndexawait vectorStore.createIndex({ indexName: my-index, dimension: 3, metric: cosine });这里有一个值得注意的实现细节Turbopuffer 本身没有显式的创建索引操作。源码中通过createIndexCache一个Map在本地登记createIndex()的调用记录并校验后续 upsert 是否与已创建的索引一致src/vector/index.ts 的注释与实现。createIndex的核心逻辑src/vector/index.tsmetric缺省时默认为cosine指标到 Turbopuffer 距离度量的映射cosine→cosine_distanceeuclidean→euclidean_squareddotproduct→不支持会抛出错误dimension 0会被拒绝Dimension must be a positive integer若同一indexName被重复调用且参数不一致会抛出错误提示维度或度量冲突参数一致则直接返回不产生额外开销幂等校验失败时会包装为MastraError错误 id 形如createVectorErrorId(TURBOPUFFER, CREATE_INDEX, INVALID_ARGS)域为STORAGE类别为USER。测试用例验证了重复创建相同参数不抛错、查询未创建索引会报createIndex() not called、维度不符会报错等行为index.test.ts。3. 写入向量upsertconst vectors [ [0.1, 0.2, 0.3], [0.3, 0.4, 0.5], ]; const metadata [{ text: doc1 }, { text: doc2 }]; const ids await vectorStore.upsert({ indexName: my-index, vectors, metadata });upsert的实现要点src/vector/index.ts前置校验vectors为空会报错索引必须已通过createIndex()登记否则报错ID 生成不传ids时自动使用crypto.randomUUID()为每个向量生成 ID元数据合并每条记录形如{ id, vector, ...metadata[i] }将metadata数组按序展开到行记录中批量写入Turbopuffer 单次 upsert 请求体上限为 256 MB官方 limits 文档因此实现按batchSize 100分批写入schema 校验若提供了schemaConfigForIndex回调会校验vectors[0].length是否与声明的dimensions一致不一致则报错失败时包装为类别为THIRD_PARTY的MastraError。测试中有一处实用提醒index.test.tsid是 Turbopuffer 的保留属性若想把自增序号写入元数据应使用类似item_id的字段名。4. 相似度查询queryconst results await vectorStore.query({ indexName: my-index, queryVector: [0.1, 0.2, 0.3], topK: 10, filter: { text: { $eq: doc1 } }, includeVector: false, });query的实现要点src/vector/index.tsqueryVector是必填项与部分向量库不同该适配器不支持纯元数据查询未传queryVector会抛出带明确提示的MastraErrorMISSING_VECTOR底层调用namespace.query参数包含distance_metric从createIndexCache中取出建索引时映射好的距离度量rank_by: [vector, ANN, queryVector]按 ANN 向量相似度排序top_k返回条数filters经过翻译器转换后的过滤器见下文vector_encoding: includeVector ? float : undefined仅在includeVector: true时回传向量默认不返回以节省带宽include_attributes: true始终返回元数据属性consistency取查询级 consistency ?? 实例级 opts.consistency ?? strong结果映射每条结果去掉id、vector、$dist等内部字段剩余字段作为metadatascore取自$dist并仅当includeVector时附带vector。返回结构符合 Mastra 核心的 QueryResult 约定id、score、metadata、可选vector。元数据过滤Mastra 过滤器到 Turbopuffer 的翻译Mastra 提供了一套跨存储统一的过滤器 DSLmastra/turbopuffer通过TurbopufferFilterTranslatorsrc/vector/filter.ts将其转换为 Turbopuffer 的原生三元组过滤格式Mastra 过滤器: { field: { $gt: 10 } } Turbopuffer 过滤器: [And, [[field, Gt, 10]]]支持的运算符翻译器在getSupportedOperators()中声明了能力边界filter.ts类别支持的运算符说明比较$eq、$ne、$gt、$gte、$lt、$lte映射为Eq、NotEq、Gt、Gte、Lt、Lte数组$in、$nin、$all映射为In、NotIn$all用多个In条件做 AND 模拟逻辑$and、$or映射为And、Or元素$existstrue→NotEq nullfalse→Eq null正则无$regex等会抛出 Unsupported operator自定义无关键翻译规则结合 filter.test.ts 的单元测试翻译器的行为非常清晰隐式相等{ field: value }→[And, [[field, Eq, value]]]{ age: 30 }、{ active: true }同理顶层多字段隐式 AND{ field1: value1, field2: value2 }→ 两个Eq条件的And同字段多运算符{ price: { $gt: 100, $lt: 200 } }→And两个条件数组值{ tags: [tag1, tag2] }与{ tags: { $in: [...] } }都翻译为In条件$all则展开为逐元素的InAND 组合逻辑嵌套$or内嵌$and等深层结构可递归翻译$exists{ field: { $exists: true } }→[field, NotEq, null]false反之嵌套对象拍平为点号路径{ user: { profile: { age: { $gt: 25 } } } }→[user.profile.age, Gt, 25]多级嵌套如user.profile.settings.theme同样支持Date 规范化Date值会被normalizeValue转为 ISO 字符串空过滤器{}、undefined、null均翻译为undefined表示不加过滤条件错误场景$regex、空$all数组等会被明确拒绝。在查询中使用过滤器的实战示例以集成测试中的商品数据为例index.test.ts// 比较运算符价格大于 500 filter: { price: { $gt: 500 } } // 数组运算符分类属于电子或书籍 filter: { category: { $in: [electronics, books] } } // $all标签同时包含 premium 与 new filter: { tags: { $all: [premium, new] } } // 逻辑组合 filter: { $or: [ { price: { $gt: 900 } }, { tags: { $all: [bestseller] } }, ], } // 深层嵌套 filter: { $and: [ { $or: [{ category: electronics }, { category: books }] }, { price: { $lt: 100 } }, { inStock: true }, ], }其他核心操作更新、删除与索引管理更新向量updateVectorupdateVector支持按 ID 或按过滤器两种方式定位目标src/vector/index.ts并做了严格的参数校验id与filter互斥同时传入或都不传都会抛MastraErrorupdate中vector与metadata至少提供一个按filter更新时先用一个单位化哑向量1/sqrt(dimension)填充对匹配记录做 ANN 查询top_k: 10000拿到全部目标 ID再执行写入若只更新其中一部分如仅元数据会先读出已有向量再回写避免覆盖丢失数据批量回写按batchSize 1000分批执行没有任何匹配时会记录 info 日志并直接返回。删除向量deleteVector / deleteVectorsdeleteVector({ indexName, id })按单个 ID 删除底层为namespace.write({ deletes: [id] })src/vector/index.tsdeleteVectors({ indexName, filter?, ids? })支持按 ID 数组或过滤器批量删除src/vector/index.tsids与filter互斥且ids不能为空数组、filter不能为空对象按filter删除时同样先通过哑向量查询拿到匹配 IDinclude_attributes: []只取 IDTurbopuffer SDK 单次 delete 请求上限为 1000 个 ID实现按batchSize 1000分批提交。索引管理listIndexes()调用client.namespaces({})返回所有命名空间 IDsrc/vector/index.tsdescribeIndex({ indexName })返回{ dimension, count, metric }结构的IndexStatsIndexStats。其中dimension与metric来自本地createIndexCache登记值count取自 Turbopuffer 命名空间元数据中的approx_row_count近似行数因此它反映的是已登记索引的配置与近似向量数src/vector/index.tsdeleteIndex({ indexName })调用namespace.deleteAll()清空命名空间并从本地缓存中移除登记记录src/vector/index.ts。集成到 MastraMemory 与 Agent 场景TurbopufferVector继承自 Mastra 核心的抽象基类MastraVectorpackages/core/src/vector/vector.ts因此它天然符合 Mastra 对向量存储的通用契约可直接用于Agent 记忆Mastra Memory 使用向量存储实现语义检索将对话历史向量化后按相关性召回。源码中schemaConfigForIndex的文档示例正是为记忆索引声明 schema 的场景src/vector/index.ts示例中memory_messages_384索引对应 Mastra 默认 embedding 模型 384 维输出并声明thread_id为可过滤的 string 字段RAG 知识库文档切片 → embedding →upsert入库查询时通过query 元数据过滤做精确召回工具集成该适配器自带遥测支持操作过程可被 Mastra 观测体系追踪。schemaConfigForIndex的典型用法const vectorStore new TurbopufferVector({ id: my-turbopuffer-vector, apiKey: process.env.TURBOPUFFER_API_KEY!, schemaConfigForIndex: (indexName: string) { if (indexName memory_messages_384) { return { dimensions: 384, schema: { thread_id: { type: string, filterable: true }, }, }; } throw new Error(TODO: add schema for index: ${indexName}); }, });声明 schema 后upsert与query都会校验向量维度与声明一致从而在写入前发现 embedding 维度不匹配的问题。一致性、限制与注意事项一致性权衡默认strong一致性确保查询立即可见写入数据但会增加延迟对检索延迟敏感、可容忍短暂不可见的场景可设为eventual。集成测试中waitUntilVectorsIndexed也印证了 Turbopuffer 写入到可查询之间存在索引延迟测试会轮询describeIndex直到向量数达到预期index.test.ts。dotproduct不受支持建索引时选用该度量会直接报错请改用cosine默认或euclidean。查询必须携带queryVector不支持纯元数据查询。id是保留字段写入元数据时避免使用名为id的键。批量限制upsert 单请求体上限 256 MB实现以 100 条为一批delete 单请求上限 1000 个 ID实现自动分批。过滤器能力边界Turbopuffer 不支持$regex、$options、$elemMatch、$nor、$not翻译器会拒绝这些运算符filter.ts比较运算要求数值类型合法测试验证了非数值参与$gt等运算会被拒绝index.test.ts。错误处理规范所有操作失败都会包装为带错误 ID、域STORAGE与类别USER/THIRD_PARTY的MastraError便于统一捕获与观测。运行集成测试仓库中附带完整的集成测试src/vector/index.test.ts与翻译器单元测试src/vector/filter.test.ts。集成测试读取环境变量TURBOPUFFER_API_KEY后自动执行覆盖了增删改查、元数据过滤、批量写入、并发查询、性能与错误处理等场景未配置 API Key 时相关测试会被跳过。翻译器单元测试则不依赖网络可直接运行cd stores/turbopuffer npm test如需在自己项目中验证可通过环境变量注入 Key 后运行测试会使用带时间戳的唯一索引名如test-index-timestamp并在结束后清理。总结mastra/turbopuffer将 Turbopuffer 的内存级高性能检索能力以标准MastraVector契约的形式接入 Mastra 生态。通过本文你可以看到它在官方 SDK 之上补齐了索引登记与一致性校验、自动 ID 生成与批量写入、统一过滤 DSL 的翻译、按 ID/过滤器的更新删除、以及规范化的MastraError错误模型。无论你是为 Agent 接入语义记忆还是构建 RAG 知识库都可以按安装 → 实例化 → createIndex → upsert → query这条主线快速落地并在需要时通过consistency、schemaConfigForIndex等选项做进一步调优。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考