Mastra RAG 实战指南用 mastra/rag 完成文档切分、重排序与图检索【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra导读mastra/rag是 Mastra 面向检索增强生成Retrieval-Augmented Generation场景的 TypeScript 工具包封装了 RAG 管线的三个核心环节文档切分chunking、相关性重排序reranking与基于图的检索graph-based retrieval。本文将以 packages/rag/README.md 为主线结合仓库源码逐层讲解如何用MDocument准备语料、用多策略切分器控制分块粒度、用元数据提取器增强上下文以及如何用重排序与 GraphRAG 在生成前筛选出最相关的上下文帮助你在 Mastra Agent 或 Workflow 中搭建一套可落地的 RAG 知识库检索链路。一、包概览与安装1.1 包定位mastra/rag的核心职责是在 Agent 生成响应之前准备好语料并筛选最相关的上下文。它提供的三大能力与源码目录一一对应见 packages/rag/src/index.ts文档切分MDocument类及若干 Transformersrc/document/重排序rerank、rerankWithScorer函数与相关性打分器src/rerank/图检索GraphRAG类src/graph-rag/。此外src/tools/还提供了可直接接入 Agent 的检索工具例如createVectorQueryTool与createDocumentChunkerTool让 RAG 能力可以像普通工具一样被 Agent 调用。1.2 安装npm install mastra/rag从 packages/rag/package.json 可以看到该包的运行时依赖包括big.js重排序权重计算、js-tiktokentoken 级切分、node-html-better-parserHTML 解析等peer 依赖为mastra/core与zodNode 版本要求22.13.0。包同时提供 ESM 与 CJS 产物可在 CommonJS 项目中直接require使用。二、文档对象 MDocumentRAG 管线的起点2.1 四种文档构造入口MDocument提供了四种静态工厂方法document.ts分别对应不同的源材料类型并在内部记录type字段用于后续自动选择默认切分策略import { MDocument } from mastra/rag; const textDoc MDocument.fromText(纯文本内容, { source: notes.txt }); const htmlDoc MDocument.fromHTML(htmlbodypHTML 内容/p/body/html); const mdDoc MDocument.fromMarkdown(# 标题\n\nMarkdown 正文); const jsonDoc MDocument.fromJSON({key: value});每个文档都可以附带metadata元数据元数据会随切分后的 chunk 一起保留成为后续向量检索过滤filter与来源追溯source的基础。2.2 基于文档类型的默认策略当调用chunk()而未显式指定策略时defaultStrategy()document.ts会根据文档类型自动推断文档类型默认切分策略htmlhtmlmarkdownmarkdownjsonjsonlatexlatex其他含 textrecursive也就是说MDocument.fromMarkdown(...).chunk()与显式传入strategy: markdown等价这让最简单的调用方式也能获得与内容结构匹配的切分效果。三、文档切分九种策略与参数详解3.1 策略总览chunk()方法的完整签名定义在 document/types.ts共支持 9 种切分策略type ChunkStrategy | recursive | character | token | markdown | html | json | latex | sentence | semantic-markdown;每种策略的可用参数由StrategyOptions联合类型约束document/types.tsTypeScript 会在编译期阻止传入非法组合。所有策略共享的通用参数BaseChunkOptions如下参数类型说明maxSizenumber单个 chunk 的最大长度长度单位由lengthFunction决定默认按字符计数overlapnumber相邻 chunk 之间的重叠长度用于保持上下文连贯、避免关键信息被切断lengthFunction(text: string) number自定义长度计算函数例如按 token 数而非字符数计数separatorPositionstart \| end分隔符保留在 chunk 的起始还是末尾character/recursive策略有效addStartIndexboolean是否为每个 chunk 记录起始字符索引stripWhitespaceboolean是否去除 chunk 首尾空白3.2 recursive通用首选支持 26 种编程语言递归切分按从大到小的分隔符优先级逐级拆分默认分隔符序列为[\n\n, \n, , ]见 character.ts。它会先用段落分隔段落过长再按换行、空格逐级细分最后兜底到单字符因此对混合结构的自然语言文本效果最好。该策略的独特能力是language参数通过Language枚举document/types.ts指定代码语言后RecursiveCharacterTransformer.fromLanguage()会加载该语言专属的分隔符列表character.ts从而在class、function、interface等语法边界处切分避免把代码块拦腰截断import { MDocument, Language } from mastra/rag; const code MDocument.fromText( class UserService { async findById(id: string) { ... } } ); const chunks await code.chunk({ strategy: recursive, language: Language.TS, // 按 TypeScript 语法边界切分 maxSize: 512, overlap: 50, });Language枚举覆盖了 TS/JS、Python、Go、Rust、Java、C/C、Kotlin、Swift、PHP、Ruby、Lua、Perl、Haskell、Elixir、PowerShell、Scala、COBOL、Solidity、Protobuf、Markdown、LaTeX、HTML 等 26 种语言。此外还支持separators自定义分隔符序列与isSeparatorRegex指定分隔符为正则表达式。实现上CharacterTransformer还专门处理了 Unicode 代理对surrogate pair边界问题切分时会先记录完整码点边界确保 chunk 永远不会从一个 emoji 或生僻字的中间切开character.ts对中文等多字节文本同样安全。3.3 character按固定分隔符切分适用于分隔符明确、结构规整的文本如日志、CSV 风格的记录。默认分隔符为\n\n支持separator与isSeparatorRegex参数若某个片段仍超过maxSize会自动带 overlap 二次细分const chunks await doc.chunk({ strategy: character, separator: \n, // 按行切分 maxSize: 512, overlap: 50, });3.4 token以 token 为单位的精确切分基于js-tiktoken实现document.ts适合对上下文窗口预算敏感的场景如把内容切进固定 token 上限的 prompt。支持encodingNametiktoken 编码名如cl100k_base或modelName按模型自动选择对应编码两种指定方式以及allowedSpecial/disallowedSpecial控制特殊 tokenconst chunks await doc.chunk({ strategy: token, modelName: gpt-4o, // 或 encodingName: cl100k_base maxSize: 512, // 按 token 数而非字符数 overlap: 50, });3.5 markdown保留文档结构的切分Markdown 文档优先按标题层级切分传入headers标题级别与分隔符的映射数组即可使用MarkdownHeaderTransformer每个标题及其下内容成为一个 chunkstripHeaders可控制是否剥离标题行、returnEachLine可让每一行单独成块document.tsconst chunks await mdDoc.chunk({ strategy: markdown, headers: [ [#, Header 1], [##, Header 2], ], maxSize: 512, overlap: 50, });3.6 html按标题或区块切分HTML 切分要求必须显式提供headers标签名与语义名映射或sections标签对与区块名映射二者之一否则会抛出HTML chunking requires either headers or sections to be specifieddocument.ts。按区块切分后再用RecursiveCharacterTransformer兜底控制maxSizeconst chunks await htmlDoc.chunk({ strategy: html, headers: [ [h1, Header 1], [h2, Header 2], ], maxSize: 512, });3.7 json结构化数据的递归切分JSON 必须显式指定maxSize。RecursiveJsonTransformer会沿 JSON 的嵌套结构递归切分尽量保持每个 chunk 是完整的 JSON 片段并提供minSize、ensureAscii转义非 ASCII 字符、convertLists数组转文本列表等控制项document.tsconst chunks await jsonDoc.chunk({ strategy: json, maxSize: 512, minSize: 64, ensureAscii: false, convertLists: true, });3.8 latex 与 sentencelatex按\section、\subsection、\begin{...}等 LaTeX 结构边界切分LatexTransformersentence按句子边界切分maxSize为必填参数支持minSize、targetSize、sentenceEnders自定义句末标点、fallbackToWords句子过长时退回按词切分、fallbackToCharacters再退回按字符切分等document.ts。3.9 semantic-markdown语义级智能切分SemanticMarkdownTransformer同样基于 tiktoken在 Markdown 结构基础上引入joinThresholdtoken 阈值低于该阈值时相邻小节会合并成一个 chunk从而避免产生大量内容稀疏的碎片化小节适合模型输出或 LLM 生成的文档document.tsconst chunks await mdDoc.chunk({ strategy: semantic-markdown, joinThreshold: 512, modelName: gpt-4o, maxSize: 1024, });3.10 一次调用同时完成元数据提取chunk()支持可选的extract参数document.ts在切分后立刻对每个 chunk 执行 LLM 元数据提取一次调用得到已切分 已增强的结果。提取器共五种均定义在 src/document/extractors/提取器参数要点提取内容titlenodes、nodeTemplate、combineTemplate为每个 chunk 生成标题并建立指向原文档的SOURCE关系summarysummaries预置摘要列表、promptTemplate生成 chunk 摘要questionsquestions生成数量、embeddingOnly生成该 chunk 可能回答的问题keywordskeywords关键词数量、promptTemplate提取关键词schemaschemaZod Schema、instructions、metadataKey按 Zod Schema 抽取结构化字段写入元数据const chunks await doc.chunk({ strategy: recursive, maxSize: 512, overlap: 50, extract: { title: true, summary: { summaries: [本段讨论 RAG 的切分策略] }, keywords: { keywords: 5 }, questions: { questions: 3 }, schema: z.object({ topic: z.string() }), }, });从 extractors/types.ts 可见提取器默认使用openai(gpt-4o)读取OPENAI_API_KEY环境变量也可通过每个提取器的llm字段传入自定义的 Mastra 语言模型。注意schema提取器无布尔形式必须显式传入 Zod Schematitle为true时会为带docId元数据的 chunk 建立SOURCE关系链document.ts。提取出的内容会合并写回对应 chunk 的metadata如title、summary、questions、keywords、自定义 key这些元数据随后可直接用于向量检索的过滤与重排序。3.11 切分结果访问chunk()返回Chunk[]内部结构定义见 src/document/schema/也可以通过三个便捷方法读取document.tsconst chunks await document.chunk({ strategy: recursive, maxSize: 512, overlap: 50 }); document.getDocs(); // Chunk[]含 text 与 metadata document.getText(); // string[]纯文本列表 document.getMetadata(); // Recordstring, any[]元数据列表四、重排序让最相关的上下文排到最前4.1 为什么需要重排序向量检索返回的前 K 条结果不一定与用户问题语义最贴合——向量相似度可能被主题相似但未正面回答问题的文本干扰。重排序阶段用一个更强的打分器对候选结果逐条评估再按综合得分取 Top-K能显著提升送入 Agent 的上下文质量。4.2 三因子加权打分模型rerank的实现位于 src/rerank/index.ts每个候选结果的综合得分由三个因子加权求和finalScore weights.semantic * semanticScore weights.vector * vectorScore weights.position * positionScore因子来源说明semanticLLM / 专用重排模型打分对 query 与 chunk 文本的相关性评分0~1vector向量库返回的相似度候选结果在向量检索阶段的原始得分position候选在原始列表中的位置1 - position / totalChunks保留向量检索的初始排序信号默认权重为semantic: 0.4、vector: 0.4、position: 0.2index.ts可通过weights自定义但三项权重之和必须严格等于 1否则会抛出Weights must add up to 1异常使用big.js做精确浮点校验。若提供了queryEmbedding还会对查询向量的模长与主特征做微调adjustScores提升对长查询的敏感度。topK默认取 3控制最终返回的结果数。4.3 两种重排序入口入口一rerank—— 基于语言模型自动选择打分器index.tsimport { rerank } from mastra/rag; import { createOpenAI } from ai-sdk/openai; const openai createOpenAI({ apiKey: process.env.OPENAI_API_KEY }); const model openai(gpt-4o); const ranked await rerank(vectorResults, queryText, model, { topK: 5, weights: { semantic: 0.5, vector: 0.3, position: 0.2 }, });rerank会根据模型 ID 自动选择语义打分器modelId rerank-v3.5时使用CohereRelevanceScorer调用 Cohere Rerank API否则使用MastraAgentRelevanceScorer用传入的语言模型包装一个专门的相关性打分 Agent。入口二rerankWithScorer—— 显式传入打分器index.tsimport { rerankWithScorer, CohereRelevanceScorer } from mastra/rag; const cohereScorer new CohereRelevanceScorer(rerank-v3.5, process.env.COHERE_API_KEY); const ranked await rerankWithScorer({ results: vectorResults, query: queryText, scorer: cohereScorer, options: { topK: 5 }, });4.4 三种语义打分器打分器统一实现RelevanceScoreProvider接口来自mastra/core/relevance位于 src/rerank/relevance/MastraAgentRelevanceScorermastra-agent/index.ts将传入的 Mastra 语言模型包装成relevance-scorer-nameAgent指令要求它仅输出 0~1 之间的一个数字parseRelevanceScore会严格校验返回值必须在[0, 1]内非法输出直接抛错。这是开箱即用、无需额外 API Key 的默认方案。CohereRelevanceScorercohere/index.ts调用api.cohere.com/v2/rerankAPI Key 通过构造参数或COHERE_API_KEY环境变量提供适合需要专用重排模型、追求更高相关性的场景。ZeroEntropyzeroentropy/index.ts基于 ZeroEntropy 的语义打分实现。rerank()返回RerankResult[]每项包含result原始向量结果、score综合得分以及detailssemantic/vector/position 各因子得分便于调试分析。该函数还支持传入observabilityContext切分与重排序过程都会以rag rerank、rag chunk等 span 的形式写入 Mastra 的可观测性追踪index.ts。五、GraphRAG基于图的检索与关联挖掘5.1 图结构的建立GraphRAG类src/graph-rag/index.ts以语义相似即连边的方式把 chunk 组织成图构造时指定dimensionembedding 维度默认 1536与threshold连边相似度阈值默认 0.7。createGraph(chunks, embeddings)会为每个 chunk 创建一个节点并对任意两节点计算余弦相似度超过阈值则建立一条semantic类型的无向边自动补上反向边边的权重即为相似度index.tsimport { GraphRAG } from mastra/rag; const graph new GraphRAG({ dimension: 1536, threshold: 0.7 }); graph.createGraph(chunkList, embeddingList); // 两数组长度必须一致5.2 混合检索稠密检索 随机游走重排query()采用稠密检索 随机游走重排Random Walk with Restart的混合策略index.ts先用余弦相似度从图中筛出与查询向量最相似的 Top-K 候选节点对每个候选节点执行带重启的随机游走默认 100 步、重启概率 0.15按边的权重概率游走到邻居节点统计访问频次并归一化将稠密相似度 × 游走得分叠加作为最终分排序后返回 Top-K 的RankedNode[]含id、content、metadata、score。const results graph.query({ query: queryEmbedding, // number[]维度必须与 dimension 一致 topK: 10, randomWalkSteps: 100, // 游走步数 restartProb: 0.15, // 重启概率须在 (0, 1) 之间 filter: { category: health }, // 可选的严格元数据过滤 });随机游走的价值在于即使某节点与查询的直接相似度不高只要它被多个高相关节点高频引用处于图的枢纽位置其最终得分也会被抬升——这正是图检索区别于纯向量检索、擅长挖掘关联与模式的地方。query()的参数有严格校验查询向量维度必须匹配、topK 1、randomWalkSteps 1、restartProb必须落在(0, 1)违规都会抛出明确错误。filter提供严格等值匹配的元数据过滤且过滤时随机游走只会发生在被过滤后的节点子集内。5.3 图的生命周期管理GraphRAG还提供完整的管理 APIindex.tsaddNode/addEdge手动增补节点与边节点必须携带与dimension匹配的 embeddinggetNodes/getEdges/getEdgesByType遍历图结构updateNodeContent更新节点内容clear清空整个图serialize()/GraphRAG.deserialize()图的 JSON 快照持久化与恢复。快照带有版本号当前为 1恢复时校验版本、节点 embedding 维度与边引用的节点完整性。源码注释提示由于快照会包含每个节点的完整 embedding大图的 JSON 快照可能达到数 MB持久化时需注意体积index.ts。从源码中的 TODO 注释可以推断当前仅支持semantic一种边类型后续计划扩展 sequential、hierarchical、citation 等更多边类型与自定义边index.ts。六、开箱即用的 RAG 工具mastra/rag在 src/tools/ 提供了可直接注册给 Agent 的工具6.1 createDocumentChunkerTool把文档切分封装成 Agent 可调用工具document-chunker.ts默认参数为recursive策略、maxSize: 512、overlap: 50可在创建时覆盖import { createDocumentChunkerTool, MDocument } from mastra/rag; const doc MDocument.fromText(longText); const chunkerTool createDocumentChunkerTool({ doc, params: { strategy: recursive, maxSize: 512, overlap: 50 }, });6.2 createVectorQueryTool把向量检索 重排序封装成 Agent 工具vector-query.ts内部完成解析queryText/topK/filter→ 从向量库检索 → 使用配置的reranker模型或打分器对结果重排序 → 返回relevantContext与sources。工具描述与参数说明集中在 utils/default-settings.ts其中对 Agent 的提示词明确了queryText不可为空、topK默认 10、filter必须是合法 JSON 等约束确保 Agent 生成的工具调用参数符合预期。该工具还支持通过requestContext在运行时覆盖indexName、vectorStoreName、model、reranker等配置并内置了向量库缺失时的优雅降级返回空结果而非报错。除此之外src/tools/bedrock-knowledge-base.ts 还提供了 AWS Bedrock 托管知识库Managed KB的接入工具使用说明见 tools/BEDROCK_MANAGED_KB.md适合已有 Bedrock 知识库资产、想在 Mastra Agent 中直接复用的团队。七、把三件套串成一条完整 RAG 管线综合上述能力一条典型的 Mastra RAG 检索链路可以这样组织import { MDocument, GraphRAG, rerank, createVectorQueryTool } from mastra/rag; import { createOpenAI } from ai-sdk/openai; // 1. 语料准备切分 元数据提取 const doc MDocument.fromMarkdown(rawMarkdown, { docId: guide-001 }); const chunks await doc.chunk({ strategy: markdown, maxSize: 512, overlap: 50, extract: { title: true, summary: true, keywords: { keywords: 5 } }, }); // 2. 生成 embedding 并写入向量库示意具体取决于所选向量库 // await vectorStore.upsert(chunks.map(c ({ id: c.id, vector: embed(c.text), metadata: c.metadata }))); // 3. 可选构建图索引用于关联检索 const graph new GraphRAG({ dimension: 1536, threshold: 0.7 }); graph.createGraph(chunks, await Promise.all(chunks.map(c embed(c.text)))); // 4. 检索 重排序在 Agent 生成前筛选最相关上下文 const openai createOpenAI({ apiKey: process.env.OPENAI_API_KEY }); const results await rerank(rawVectorResults, userQuestion, openai(gpt-4o), { topK: 5, weights: { semantic: 0.4, vector: 0.4, position: 0.2 }, });八、总结与延伸阅读mastra/rag用一套简洁的 TypeScript API 覆盖了 RAG 从语料准备到上下文筛选的完整闭环MDocument 9 种切分策略解决怎么切从通用递归切分、token 精确切分到 Markdown/HTML/JSON/LaTeX 的结构感知切分再到 26 种编程语言的语法边界切分五种 LLM 元数据提取器解决怎么增强标题、摘要、问题、关键词、结构化 Schema 在切分时一次提取三因子重排序解决怎么选语义 向量 位置加权配合 Cohere / Mastra Agent / ZeroEntropy 三种打分器GraphRAG解决怎么关联语义图 随机游走挖掘跨 chunk 的关联与模式内置工具让 Agent 直接获得切分与检索能力并全程接入 Mastra 可观测性。仓库中还提供了完整的测试用例可作进一步参考例如切分行为的测试在 document.test.ts 与各 transformers/ 目录下的测试文件重排序测试在 rerank/index.test.ts图检索测试在 graph-rag/index.test.ts如果你使用 Docker 开发环境packages/rag/docker-compose.yaml 可用于启动测试所需的依赖服务。版本历史与发布说明见 packages/rag/CHANGELOG.md。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
