跳到主要内容

消息历史

消息历史是最基础也最重要的 Memory 形式。它让 LLM 能在上下文窗口中看到近期消息,使 Agent 可以引用先前的交流内容并连贯作答。

你也可以检索消息历史,在 UI 中显示过去的对话。

信息

每条消息都属于一个 Thread(对话)和一个 Resource(与其关联的用户或实体)。更多信息请参阅 Thread 与 Resource

注意

在客户端应用中使用 Memory 时,请从客户端仅发送新消息,而不是发送完整对话历史。

发送完整历史是多余的,因为 Mastra 会从 Storage 加载消息;而且当客户端时间戳与已存储时间戳冲突时,还可能导致消息排序错误。

有关 AI SDK 示例,请参阅使用 Mastra Memory

Thread 与 Resource
Thread 与 Resource的直接链接

Mastra 使用两个标识符来组织对话:

  • Thread:包含一系列消息的对话会话。
  • Resource:拥有该 Thread 的实体,例如应用中的用户、组织、项目或其他领域实体。

Studio 会自动为你生成 Thread ID 和 Resource ID。自行调用 stream()generate() 时,请显式提供这些标识符。

开始使用
开始使用的直接链接

安装 Mastra Memory 模块,以及适用于你所用数据库的 Storage Adapter。以下示例使用 @mastra/libsql,它会将数据存储在本地 mastra.db 文件中。

npm install @mastra/memory@latest @mastra/libsql@latest

消息历史需要 Storage Adapter 来持久化对话。如果尚未配置,请在 Mastra 实例上配置 Storage:

src/mastra/index.ts
import { Mastra } from '@mastra/core'
import { LibSQLStore } from '@mastra/libsql'

export const mastra = new Mastra({
storage: new LibSQLStore({
id: 'mastra-storage',
url: 'file:./mastra.db',
}),
})

在 Agent 中实例化一个 Memory 实例:

src/mastra/agents/test-agent.ts
import { Memory } from '@mastra/memory'
import { Agent } from '@mastra/core/agent'

export const agent = new Agent({
id: 'test-agent',
memory: new Memory({
options: {
lastMessages: 10,
},
}),
})

调用 Agent 时,消息会自动保存到数据库。你可以指定 threadIdresourceId 和可选的 metadata

await agent.generate('Hello', {
memory: {
thread: {
id: 'thread-123',
title: 'Support conversation',
metadata: { category: 'billing' },
},
resource: 'user-456',
},
})
信息

调用 agent.generate()agent.stream() 时,Thread 和消息会自动创建;你也可以使用 createThread()saveMessages() 手动创建。

你可以通过两种方式使用这些历史:

  • 自动包含:Mastra 会自动获取近期消息并将其包含在上下文窗口中。默认包含最近 10 条消息,让 Agent 始终以对话为依据。你可以通过 lastMessages 调整该数量,但多数情况下无需考虑它。
  • 手动查询:如需更精细的控制,请使用 recall() 函数直接查询 Thread 和消息。这样可以准确选择上下文窗口中要包含哪些 Memory,或者获取消息以在 UI 中渲染对话历史。
提示

启用 Memory 后,Studio 会使用消息历史在聊天侧边栏中显示过去的对话。

生成 Thread 标题
生成 Thread 标题的直接链接

启用 generateTitle 后,Mastra 可以根据对话记录自动生成具有描述性的 Thread 标题。当你构建的聊天界面需要在线程列表或侧边栏中渲染对话标题时,请使用此选项。

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support agent',
instructions: 'Answer customer support questions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
options: {
generateTitle: true,
},
}),
})

标题生成会在 Agent 响应后异步运行,不会影响响应时间。

若要优化成本或行为,请提供更小的 model 和自定义 instructions

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'Support agent',
instructions: 'Answer customer support questions.',
model: 'openai/gpt-5.6-sol',
memory: new Memory({
options: {
generateTitle: {
model: 'openai/gpt-5-mini',
instructions: 'Generate a one-word title.',
},
},
}),
})

访问 Memory
访问 Memory的直接链接

要访问用于查询、克隆或删除 Thread 和消息的 Memory 函数,请在 Agent 上调用 getMemory()

const agent = mastra.getAgentById('test-agent')
const memory = await agent.getMemory()

通过 Memory 实例,你可以使用列出 Thread、召回消息、克隆对话等函数。

查询
查询的直接链接

使用以下方法获取 Thread 和消息,以便在 UI 中显示对话历史或实现自定义 Memory 检索逻辑。

注意

Memory 系统不会强制执行访问控制。运行任何查询之前,请在应用逻辑中验证当前用户有权访问被查询的 resourceId

Thread
Thread的直接链接

使用 listThreads() 检索某个 Resource 的 Thread:

const result = await memory.listThreads({
filter: { resourceId: 'user-123' },
perPage: false,
})

对 Thread 进行分页:

const result = await memory.listThreads({
filter: { resourceId: 'user-123' },
page: 0,
perPage: 10,
})

console.log(result.threads) // thread objects
console.log(result.hasMore) // more pages available?

你也可以按元数据筛选并控制排序顺序:

const result = await memory.listThreads({
filter: {
resourceId: 'user-123',
metadata: { status: 'active' },
},
orderBy: { field: 'createdAt', direction: 'DESC' },
})

要按 ID 获取单个 Thread,请使用 getThreadById()

const thread = await memory.getThreadById({ threadId: 'thread-123' })

消息
消息的直接链接

获得 Thread 后,使用 recall() 检索其中的消息。它支持分页、日期筛选和语义搜索

基本召回会返回 Thread 中的所有消息:

const { messages } = await memory.recall({
threadId: 'thread-123',
perPage: false,
})

对消息进行分页:

const { messages } = await memory.recall({
threadId: 'thread-123',
page: 0,
perPage: 50,
})

按日期范围筛选:

const { messages } = await memory.recall({
threadId: 'thread-123',
filter: {
dateRange: {
start: new Date('2025-01-01'),
end: new Date('2025-06-01'),
},
},
})

按浅层消息元数据筛选:

const { messages } = await memory.recall({
threadId: 'thread-123',
filter: {
metadata: {
category: 'billing',
escalated: true,
priority: 2,
archivedAt: null,
},
},
})

元数据筛选器仅匹配浅层标量值:string、有限 numberbooleannull

所有指定的元数据键都使用 AND 语义。null 筛选器只匹配显式的 null 值。缺少的元数据键不会匹配。

元数据键必须以字母或下划线开头,并且只能包含字母数字字符。长度不得超过 128 个字符,也不能使用 __proto__constructorprototype 等保留的原型键。

性能取决于 Storage 后端。部分后端可以将一部分筛选条件下推到数据库;另一些后端则会先应用 Thread、Resource 和日期约束,再扫描候选消息,最后进行分页。

按 ID 获取单条消息:

const { messages } = await memory.recall({
threadId: 'thread-123',
include: [{ id: 'msg-123' }],
})

按 ID 获取多条消息及其周围上下文:

const { messages } = await memory.recall({
threadId: 'thread-123',
include: [
{ id: 'msg-123' },
{
id: 'msg-456',
withPreviousMessages: 3,
withNextMessages: 1,
},
],
})

按含义搜索(设置方式请参阅 Semantic Recall):

const { messages } = await memory.recall({
threadId: 'thread-123',
vectorSearchString: 'project deadline discussion',
threadConfig: {
semanticRecall: true,
},
})

UI 格式
UI 格式的直接链接

消息查询返回 MastraDBMessage[] 格式。要在前端显示消息,你可能需要将它们转换为 UI 库期望的格式。例如,toAISdkV5Messages 会将消息转换为 AI SDK UI 格式。

克隆 Thread
克隆 Thread的直接链接

克隆 Thread 会创建现有 Thread 及其消息的副本。这适合为对话创建分支、在可能具有破坏性的操作前创建检查点,或者测试同一对话的不同变体。

const { thread, clonedMessages } = await memory.cloneThread({
sourceThreadId: 'thread-123',
title: 'Branched conversation',
})

你可以筛选要克隆的消息(按数量或日期范围)、指定自定义 Thread ID,并使用实用方法检查克隆关系。

有关完整 API,请参阅 cloneThread()克隆实用工具

删除消息
删除消息的直接链接

要从 Thread 中移除消息,请使用 deleteMessages()。你可以按消息 ID 删除,也可以清空 Thread 中的所有消息。