跳到主要内容

文档分块与嵌入

在处理内容之前,请先基于内容创建一个 MDocument 实例。你可以使用不同格式来初始化它:

const docFromText = MDocument.fromText('Your plain text content...')
const docFromHTML = MDocument.fromHTML('<html>Your HTML content...</html>')
const docFromMarkdown = MDocument.fromMarkdown('# Your Markdown content...')
const docFromJSON = MDocument.fromJSON(`{ "key": "value" }`)

文档处理
文档处理的直接链接

使用 chunk 将文档拆分为便于处理的数据块。Mastra 支持多种针对不同文档类型优化的分块策略:

  • recursive:根据内容结构智能拆分
  • character:基于字符的简单拆分
  • token:感知 token 的拆分
  • markdown:感知 Markdown 的拆分
  • semantic-markdown:根据相关标题组拆分 Markdown
  • html:感知 HTML 结构的拆分
  • json:感知 JSON 结构的拆分
  • latex:感知 LaTeX 结构的拆分
  • sentence:感知句子的拆分
备注

每种策略都接受针对其分块方式优化的不同参数。

下面是使用 recursive 策略的示例:

const chunks = await doc.chunk({
strategy: 'recursive',
maxSize: 512,
overlap: 50,
separators: ['\n'],
extract: {
metadata: true, // Optionally extract metadata
},
})

对于需要保留句子结构的文本,下面是使用 sentence 策略的示例:

const chunks = await doc.chunk({
strategy: 'sentence',
maxSize: 450,
minSize: 50,
overlap: 0,
sentenceEnders: ['.'],
})

对于需要保留章节间语义关系的 Markdown 文档,下面是使用 semantic-markdown 策略的示例:

const chunks = await doc.chunk({
strategy: 'semantic-markdown',
joinThreshold: 500,
modelName: 'gpt-3.5-turbo',
})
备注

提取元数据可能会调用 LLM,因此请确保已设置 API 密钥。

我们在 chunk() 参考文档中更深入地介绍了分块策略。

生成嵌入向量
生成嵌入向量的直接链接

使用你选择的 Provider 将数据块转换成嵌入向量。Mastra 通过模型路由器支持嵌入模型。

使用模型路由器
使用模型路由器的直接链接

最简单的方法是使用 Mastra 模型路由器,并传入 provider/model 字符串:

import { ModelRouterEmbeddingModel } from '@mastra/core/llm'
import { embedMany } from 'ai'

const { embeddings } = await embedMany({
model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
values: chunks.map(chunk => chunk.text),
})

Mastra 支持 OpenAI 和 Google 的嵌入模型。有关受支持嵌入模型的完整列表,请参阅嵌入参考文档

模型路由器会自动从环境变量中检测 API 密钥。

嵌入函数会返回向量,即表示文本语义的一组数字,可以直接用于向量数据库中的相似度搜索。

配置嵌入维度
配置嵌入维度的直接链接

嵌入模型通常会输出维度数固定的向量(例如,OpenAI 的 text-embedding-3-small 为 1536 维)。 某些模型支持降低维度,这有助于:

  • 减少向量数据库中的存储需求
  • 降低相似度搜索的计算成本

下面是一些受支持的模型:

OpenAI(text-embedding-3 模型):

import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const { embeddings } = await embedMany({
model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
options: {
dimensions: 256, // Only supported in text-embedding-3 and later
},
values: chunks.map(chunk => chunk.text),
})

Google(text-embedding-001):

const { embeddings } = await embedMany({
model: google('gemini-embedding-001', {
outputDimensionality: 256, // Truncates excessive values from the end
}),
values: chunks.map(chunk => chunk.text),
})
向量数据库兼容性

存储嵌入向量时,向量数据库索引的配置必须与嵌入模型的输出维度一致。如果维度不匹配,可能会出现错误或数据损坏。

示例:完整流程
示例:完整流程的直接链接

下面的示例展示了如何使用两个 Provider 进行文档处理和生成嵌入向量:

import { embedMany } from 'ai'

import { MDocument } from '@mastra/rag'

// Initialize document
const doc = MDocument.fromText(`
Climate change poses significant challenges to global agriculture.
Rising temperatures and changing precipitation patterns affect crop yields.
`)

// Create chunks
const chunks = await doc.chunk({
strategy: 'recursive',
maxSize: 256,
overlap: 50,
})

// Generate embeddings with OpenAI
import { ModelRouterEmbeddingModel } from '@mastra/core/llm'

const { embeddings } = await embedMany({
model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
values: chunks.map(chunk => chunk.text),
})

// OR

// Generate embeddings with Cohere
const { embeddings } = await embedMany({
model: 'cohere/embed-english-v3.0',
values: chunks.map(chunk => chunk.text),
})

// Store embeddings in your vector database
await vectorStore.upsert({
indexName: 'embeddings',
vectors: embeddings,
})

有关不同分块策略和嵌入配置的更多示例,请参阅:

有关向量数据库和嵌入的更多详情,请参阅: