> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # 搜索和索引 **加入版本:** `@mastra/core@1.1.0` 搜索功能让 Agent 能在已建立索引的 Workspace 文件中查找相关内容。当 Agent 需要回答问题或查找信息时,可以搜索索引内容,而不必读取每个文件。 ## 工作原理 Workspace 搜索分为索引和查询两个阶段。 ### 索引 内容必须先建立索引,之后才能搜索。为文档建立索引时: - 内容会被 token 化(拆分为可搜索的词项) - 对于 BM25:计算词频和文档统计信息 - 对于向量:使用 embedder 函数将内容转换为 embedding,并存储在 Vector Store 中 每个已建立索引的文档都有: - **id** - 唯一标识符(通常为文件路径) - **content** - 文本内容 - **metadata** - 随文档存储的可选键值数据 ### 查询 搜索时: 1. 使用与索引时相同的 token 化/embedding 方式处理查询 2. 根据文档与查询的相关度进行评分 3. 按评分排列结果,并返回匹配内容 Workspace 支持三种搜索模式:BM25 关键词搜索、向量语义搜索,以及结合二者的混合搜索。 ## BM25 关键词搜索 BM25 根据词频和文档长度对文档评分。它适合精确匹配和特定术语。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, }) ``` 自定义 BM25 参数时,`k1` 表示词频饱和度,`b` 表示文档长度归一化: ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: { k1: 1.5, b: 0.75, }, }) ``` ## 向量搜索 向量搜索使用 embedding 查找语义相似的内容,需要 Vector Store 和 embedder 函数。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embed } from 'ai' import { openai } from '@ai-sdk/openai' const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: async (text: string) => { const { embedding } = await embed({ model: openai.embedding('text-embedding-3-small'), value: text, }) return embedding }, }) ``` ### 批量 embedding 上述 embedder 每次处理一段文本。如果为包含数百个文件的 Workspace 建立索引,会调用 Provider 数百次,既慢又昂贵。 当 Provider 支持批处理(例如 OpenAI 的 `embedMany`)时,可以传入一个接受文本数组,并通过单次调用返回多个 embedding 的 embedder。若要选择启用,请在函数上设置 `batch: true` 属性。Mastra 会在运行时检查该属性并切换到批量路径。 以下示例将单文本 embedder 替换为批量 embedder。Embedder 函数接受数组,并按相同顺序返回 embedding 数组,同时包含两个额外属性: - `batch: true`:标记函数支持批处理。如果没有此属性,Mastra 会每次向其传入一段文本。 - `maxBatchSize`:Provider 单次调用接受的最大数组长度。Mastra 会将更大的请求拆分为该大小的 chunk,并并行发送。请将其设为 Provider 文档注明的限制(例如 OpenAI 为 2048、Cohere 为 96、Voyage 为 128)。省略时,会在一个请求中发送所有待处理文本。 ```typescript import { Workspace, LocalFilesystem } from '@mastra/core/workspace' import { PineconeVector } from '@mastra/pinecone' import { embedMany } from 'ai' import { openai } from '@ai-sdk/openai' const model = openai.embedding('text-embedding-3-small') const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), vectorStore: new PineconeVector({ apiKey: process.env.PINECONE_API_KEY, index: 'workspace-index', }), embedder: Object.assign( async (texts: string[]) => { const { embeddings } = await embedMany({ model, values: texts }) return embeddings }, { batch: true as const, maxBatchSize: 2048 }, ), }) ``` `Object.assign` 会将 `batch` 和 `maxBatchSize` 属性添加到 embedder 函数。Mastra 将其作为 metadata 读取,绝不会传给 Provider。 单文本 embedder 仍然可用。函数签名 `(text: string) => Promise` 没有变化,因此现有代码无需修改即可继续运行。 ## 混合搜索 同时配置 BM25 和向量搜索即可启用混合模式,结合关键词匹配与语义理解。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, vectorStore: pineconeVector, embedder: embedderFn, }) ``` ## 自定义索引名称 搜索索引名称默认根据 Workspace ID 生成。若要设置自定义名称,请使用 `searchIndexName`: ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, searchIndexName: 'my_workspace_vectors', }) ``` 索引名称必须是有效的 SQL 标识符:以字母或下划线开头,只包含字母、数字或下划线,长度不超过 63 个字符。 ## 为内容建立索引 ### 手动建立索引 使用 `workspace.index()` 以编程方式将内容添加到搜索索引。文件路径会成为文档 ID。还可以为每个文档传入 metadata。 ```typescript // Basic indexing await workspace.index('/docs/guide.md', 'Content of the guide...') // Index with metadata for filtering or context await workspace.index('/docs/api.md', apiDocContent, { metadata: { category: 'api', version: '2.0', }, }) ``` 手动建立索引适用于: - 为并非来自文件的内容建立索引(例如数据库记录、API 响应) - 希望在建立索引前预处理内容或将内容拆分为 chunk - 需要向文档添加自定义 metadata ### 自动建立索引 配置 `autoIndexPaths`,在 Workspace 初始化时自动为文件建立索引。每项可以是目录路径(递归建立索引),也可以是用于选择性索引的 glob 模式。 ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs', 'support/faq'], }) await workspace.init() ``` 调用 `init()` 时,所有匹配的文件都会被读取并建立搜索索引。文件路径会成为文档 ID。 使用 glob 模式可以为特定文件类型建立索引: ```typescript const workspace = new Workspace({ filesystem: new LocalFilesystem({ basePath: './workspace' }), bm25: true, autoIndexPaths: ['docs/**/*.md', 'support/**/*.txt'], }) ``` ## 搜索 使用 `workspace.search()` 查找相关内容。结果按相关度评分排序。 ```typescript const results = await workspace.search('password reset') for (const result of results) { console.log(`${result.id}: ${result.score}`) console.log(result.content) } ``` ### 搜索选项 可以通过选项定制搜索行为: ```typescript const results = await workspace.search('authentication flow', { topK: 10, mode: 'hybrid', minScore: 0.5, vectorWeight: 0.5, }) ``` | 选项 | 说明 | | -------------- | ------------------------------------------------------------ | | `topK` | 返回结果的最大数量。默认值:5 | | `mode` | 搜索模式:`'bm25'`、`'vector'` 或 `'hybrid'`。默认根据配置选择最佳可用模式。 | | `minScore` | 过滤低于该评分阈值(0-1)的结果。 | | `vectorWeight` | 在混合模式中,向量评分相对于 BM25 的权重。0 = 完全使用 BM25,1 = 完全使用向量,0.5 = 权重相等。 | ### 搜索结果 每项结果包含: ```typescript interface SearchResult { id: string // Document ID (typically file path) content: string // The matching content score: number // Relevance score (0-1) lineRange?: { // Lines where the match was found start: number end: number } metadata?: Record // Metadata stored with the document scoreDetails?: { // Score breakdown (hybrid mode only) vector?: number bm25?: number } } ``` **理解评分:** - 评分范围为 0 到 1,其中 1 表示完全匹配 - BM25 评分根据结果集中的最佳匹配进行归一化 - 向量评分表示查询与文档 embedding 之间的余弦相似度 - 在混合模式中,使用 `vectorWeight` 参数组合评分 ### 何时使用各种模式 | 模式 | 最适合 | 查询示例 | | -------- | ------------ | ----------------------------------------- | | `bm25` | 精确词项、技术查询、代码 | “useState hook”、“404 error”、“config.yaml” | | `vector` | 概念性查询、自然语言 | “如何处理用户身份验证”、“错误处理的最佳实践” | | `hybrid` | 通用搜索、未知查询类型 | 大多数 Agent 使用场景 | ## Agent Tool 在 Workspace 上配置搜索后,Agent 会获得用于搜索内容和建立索引的 Tool。有关详情,请参阅 [Workspace 类 Reference](https://mastra.zisheng.pro/reference/workspace/workspace-class)。 ## 相关内容 - [Workspace 概述](https://mastra.zisheng.pro/docs/workspace/overview) - [RAG 概述](https://mastra.zisheng.pro/guides/rag/overview) - [Workspace 类 Reference](https://mastra.zisheng.pro/reference/workspace/workspace-class)