工作内存
🌐 Working Memory
虽然消息历史和语义回忆帮助代理记住对话,但工作内存使他们能够在多次交互中保持关于用户的持续信息。
🌐 While message history and semantic recall help agents remember conversations, working memory allows them to maintain persistent information about users across interactions.
可以把它看作是代理的主动思维或草稿——他们保持可用的关于用户或任务的关键信息。这类似于一个人在交谈中自然记住某人的名字、偏好或重要细节的方式。
🌐 Think of it as the agent's active thoughts or scratchpad – the key information they keep available about the user or task. It's similar to how a person would naturally remember someone's name, preferences, or important details during a conversation.
这对于维护始终相关且始终应可供代理使用的持续状态非常有用。
🌐 This is useful for maintaining ongoing state that's always relevant and should always be available to the agent.
工作内存可以在两种不同的范围内持续存在:
🌐 Working memory can persist at two different scopes:
- 资源范围(默认):内存会在同一用户的所有对话线程中保持
- 线程范围:每个会话线程的内存是独立的
重要: 在作用域之间切换意味着代理无法看到其他作用域的内存——线程作用域的内存与资源作用域的内存是完全分开的。
快速开始Direct link to 快速开始
🌐 Quick Start
这是一个设置具有工作内存的代理的最小示例:
🌐 Here's a minimal example of setting up an agent with working memory:
import { Agent } from "@mastra/core/agent";
import { Memory } from "@mastra/memory";
// Create agent with working memory enabled
const agent = new Agent({
id: "personal-assistant",
name: "PersonalAssistant",
instructions: "You are a helpful personal assistant.",
model: "openai/gpt-5.1",
memory: new Memory({
options: {
workingMemory: {
enabled: true,
},
},
}),
});
工作原理Direct link to 工作原理
🌐 How it Works
工作内存是一个 Markdown 文本块,代理能够随着时间更新它,以存储持续相关的信息:
🌐 Working memory is a block of Markdown text that the agent is able to update over time to store continuously relevant information:
内存持久性范围Direct link to 内存持久性范围
🌐 Memory Persistence Scopes
工作内存可以在两种不同的范围内运作,让你选择内存在对话中的持续方式:
🌐 Working memory can operate in two different scopes, allowing you to choose how memory persists across conversations:
资源范围内内存(默认)Direct link to 资源范围内内存(默认)
🌐 Resource-Scoped Memory (Default)
默认情况下,工作内存会在同一用户(resourceId)的所有对话线程中持续存在,从而实现持久的用户内存:
🌐 By default, working memory persists across all conversation threads for the same user (resourceId), enabling persistent user memory:
const memory = new Memory({
storage,
options: {
workingMemory: {
enabled: true,
scope: "resource", // Memory persists across all user threads
template: `# User Profile
- **Name**:
- **Location**:
- **Interests**:
- **Preferences**:
- **Long-term Goals**:
`,
},
},
});
使用案例:
- 能记住用户偏好的个人助理
- 能够保持客户上下文的客服机器人
- 跟踪学生进展的教育应用
与代理商的使用Direct link to 与代理商的使用
🌐 Usage with Agents
使用资源范围内的内存时,确保在内存选项中传入 resource 参数:
🌐 When using resource-scoped memory, make sure to pass the resource parameter in the memory options:
// Resource-scoped memory requires resource
const response = await agent.generate("Hello!", {
memory: {
thread: "conversation-123",
resource: "user-alice-456", // Same user across different threads
},
});
线程范围内内存Direct link to 线程范围内内存
🌐 Thread-Scoped Memory
线程范围内的内存将工作内存隔离到各个对话线程。每个线程都维护自己隔离的内存:
🌐 Thread-scoped memory isolates working memory to individual conversation threads. Each thread maintains its own isolated memory:
const memory = new Memory({
storage,
options: {
workingMemory: {
enabled: true,
scope: "thread", // Memory is isolated per thread
template: `# User Profile
- **Name**:
- **Interests**:
- **Current Goal**:
`,
},
},
});
使用案例:
- 关于不同话题的不同对话
- 临时或会话特定信息
- 每个线程都需要工作内存,但线程是短暂的且彼此无关的工作流程
存储适配器支持Direct link to 存储适配器支持
🌐 Storage Adapter Support
资源范围的工作内存需要支持 mastra_resources 表的特定存储适配器:
🌐 Resource-scoped working memory requires specific storage adapters that support the mastra_resources table:
支持的存储适配器Direct link to 支持的存储适配器
🌐 Supported Storage Adapters
- libSQL (
@mastra/libsql) - PostgreSQL (
@mastra/pg) - Upstash (
@mastra/upstash) - MongoDB (
@mastra/mongodb)
自定义模板Direct link to 自定义模板
🌐 Custom Templates
模板指导代理在工作内存中跟踪和更新哪些信息。如果没有提供模板,将使用默认模板,但通常你会希望定义一个针对代理特定使用场景的自定义模板,以确保它记住最相关的信息。
🌐 Templates guide the agent on what information to track and update in working memory. While a default template is used if none is provided, you'll typically want to define a custom template tailored to your agent's specific use case to ensure it remembers the most relevant information.
这是一个自定义模板的示例。在这个示例中,只要用户发送包含任何相关信息的消息,代理就会存储用户的名称、位置、时区等信息:
🌐 Here's an example of a custom template. In this example the agent will store the users name, location, timezone, etc as soon as the user sends a message containing any of the info:
const memory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `
# User Profile
## Personal Info
- Name:
- Location:
- Timezone:
## Preferences
- Communication Style: [e.g., Formal, Casual]
- Project Goal:
- Key Deadlines:
- [Deadline 1]: [Date]
- [Deadline 2]: [Date]
## Session State
- Last Task Discussed:
- Open Questions:
- [Question 1]
- [Question 2]
`,
},
},
});
设计高效模板Direct link to 设计高效模板
🌐 Designing Effective Templates
一个结构良好的模板可以让客服代理更容易解析和更新信息。把模板当作一个简短的格式,让助手保持最新状态。
🌐 A well-structured template keeps the information easy for the agent to parse and update. Treat the template as a short form that you want the assistant to keep up to date.
- 简短、聚焦的标签。 避免使用段落或过长的标题。保持标签简短(例如
## Personal Info或- Name:),这样更新更易阅读,也不易被截断。 - 保持一致的大小写。 不一致的大小写(
Timezone:与timezone:)可能导致更新混乱。标题和项目符号标签应统一使用标题式大小写或小写。 - 保持占位符文本简单。 使用如
[e.g., Formal]或[Date]之类的提示来帮助大型语言模型填写正确的位置。 - 缩写非常长的数值。 如果你只需要短格式,请提供类似
- Name: [First name or nickname]或- Address (short):的指南,而不是完整的法律文本。 - 在
instructions中提及更新规则。 你可以直接在代理的instructions字段中说明如何以及何时填写或清除模板的各个部分。
替代模板样式Direct link to 替代模板样式
🌐 Alternative Template Styles
如果只需要几个项目,可以使用较短的单个块:
🌐 Use a shorter single block if you only need a few items:
const basicMemory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `User Facts:\n- Name:\n- Favorite Color:\n- Current Topic:`,
},
},
});
如果你更喜欢叙述风格,你也可以将关键事实以简短段落的形式存储:
🌐 You can also store the key facts in a short paragraph format if you prefer a more narrative style:
const paragraphMemory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `Important Details:\n\nKeep a short paragraph capturing the user's important facts (name, main goal, current task).`,
},
},
});
结构化工作内存Direct link to 结构化工作内存
🌐 Structured Working Memory
工作内存也可以使用结构化的模式来定义,而不是使用 Markdown 模板。这允许你使用 Zod 模式指定应跟踪的确切字段和类型。在使用模式时,代理将以与你的模式匹配的 JSON 对象的形式查看和更新工作内存。
🌐 Working memory can also be defined using a structured schema instead of a Markdown template. This allows you to specify the exact fields and types that should be tracked, using a Zod schema. When using a schema, the agent will see and update working memory as a JSON object matching your schema.
重要: 你必须指定 template 或 schema 中的一个,但不能同时指定两者。
示例:基于模式的工作内存Direct link to 示例:基于模式的工作内存
🌐 Example: Schema-Based Working Memory
import { z } from "zod";
import { Memory } from "@mastra/memory";
const userProfileSchema = z.object({
name: z.string().optional(),
location: z.string().optional(),
timezone: z.string().optional(),
preferences: z
.object({
communicationStyle: z.string().optional(),
projectGoal: z.string().optional(),
deadlines: z.array(z.string()).optional(),
})
.optional(),
});
const memory = new Memory({
options: {
workingMemory: {
enabled: true,
schema: userProfileSchema,
// template: ... (do not set)
},
},
});
当提供模式时,代理会以 JSON 对象的形式接收工作内存。例如:
🌐 When a schema is provided, the agent receives the working memory as a JSON object. For example:
{
"name": "Sam",
"location": "Berlin",
"timezone": "CET",
"preferences": {
"communicationStyle": "Formal",
"projectGoal": "Launch MVP",
"deadlines": ["2025-07-01"]
}
}
基于架构的内存语义合并Direct link to 基于架构的内存语义合并
🌐 Merge Semantics for Schema-Based Memory
基于模式的工作内存使用合并语义,这意味着代理只需要包含它想要添加或更新的字段。现有字段会自动保留。
🌐 Schema-based working memory uses merge semantics, meaning the agent only needs to include fields it wants to add or update. Existing fields are preserved automatically.
- 对象字段会深度合并: 仅更新提供的字段;其他字段保持不变
- 将字段设置为
null以删除它: 这会明确地从内存中移除该字段 - 数组会被完全替换: 当提供数组字段时,它会替换现有数组(数组不会逐元素合并)
在模板和模式之间进行选择Direct link to 在模板和模式之间进行选择
🌐 Choosing Between Template and Schema
- 如果你希望代理将内存保持为自由格式的文本块(例如用户档案或草稿),请使用模板(Markdown)。模板使用替换语义——代理在每次更新时必须提供完整的内存内容。
- 如果你需要可以验证并以 JSON 编程方式访问的结构化、类型安全的数据,请使用模式。模式使用合并语义——代理只提供要更新的字段,现有字段将被保留。
- 一次只能激活一种模式:不支持同时设置
template和schema。
示例:多步骤保留Direct link to 示例:多步骤保留
🌐 Example: Multi-step Retention
下面是一个简化视图,展示了 User Profile 模板在短用户对话中的更新情况:
🌐 Below is a simplified view of how the User Profile template updates across a short user
conversation:
# User Profile
## Personal Info
- Name:
- Location:
- Timezone:
--- After user says "My name is **Sam** and I'm from **Berlin**" ---
# User Profile
- Name: Sam
- Location: Berlin
- Timezone:
--- After user adds "By the way I'm normally in **CET**" ---
# User Profile
- Name: Sam
- Location: Berlin
- Timezone: CET
代理现在可以在后续回答中引用 Sam 或 Berlin,而无需再次请求这些信息,因为它们已被存储在工作内存中。
🌐 The agent can now refer to Sam or Berlin in later responses without requesting the information
again because it has been stored in working memory.
如果你的代理没有在你预期的时候正确更新工作内存,你可以在代理的 instructions 设置中添加关于 如何 和 何时 使用此模板的系统指令。
🌐 If your agent is not properly updating working memory when you expect it to, you can add system
instructions on how and when to use this template in your agent's instructions setting.
设置初始工作内存Direct link to 设置初始工作内存
🌐 Setting Initial Working Memory
虽然代理通常通过 updateWorkingMemory 工具更新工作内存,但你也可以在创建或更新线程时以编程方式设置初始工作内存。这对于注入用户数据(例如他们的名字、偏好或其他信息)非常有用,这样可以在不每次请求都传递这些信息的情况下,让代理使用这些数据。
🌐 While agents typically update working memory through the updateWorkingMemory tool, you can also set initial working memory programmatically when creating or updating threads. This is useful for injecting user data (like their name, preferences, or other info) that you want available to the agent without passing it in every request.
通过线程元数据设置工作内存Direct link to 通过线程元数据设置工作内存
🌐 Setting Working Memory via Thread Metadata
在创建线程时,你可以通过元数据的 workingMemory 键提供初始工作内存:
🌐 When creating a thread, you can provide initial working memory through the metadata's workingMemory key:
// Create a thread with initial working memory
const thread = await memory.createThread({
threadId: "thread-123",
resourceId: "user-456",
title: "Medical Consultation",
metadata: {
workingMemory: `# Patient Profile
- Name: John Doe
- Blood Type: O+
- Allergies: Penicillin
- Current Medications: None
- Medical History: Hypertension (controlled)
`,
},
});
// The agent will now have access to this information in all messages
await agent.generate("What's my blood type?", {
memory: {
thread: thread.id,
resource: "user-456",
},
});
// Response: "Your blood type is O+."
以编程方式更新工作内存Direct link to 以编程方式更新工作内存
🌐 Updating Working Memory Programmatically
你也可以更新现有线程的工作内存:
🌐 You can also update an existing thread's working memory:
// Update thread metadata to add/modify working memory
await memory.updateThread({
id: "thread-123",
title: thread.title,
metadata: {
...thread.metadata,
workingMemory: `# Patient Profile
- Name: John Doe
- Blood Type: O+
- Allergies: Penicillin, Ibuprofen // Updated
- Current Medications: Lisinopril 10mg daily // Added
- Medical History: Hypertension (controlled)
`,
},
});
直接内存更新Direct link to 直接内存更新
🌐 Direct Memory Update
或者,直接使用 updateWorkingMemory 方法:
🌐 Alternatively, use the updateWorkingMemory method directly:
await memory.updateWorkingMemory({
threadId: "thread-123",
resourceId: "user-456", // Required for resource-scoped memory
workingMemory: "Updated memory content...",
});
只读工作内存Direct link to 只读工作内存
🌐 Read-Only Working Memory
在某些情况下,你可能希望代理能够访问工作内存数据,但不能修改它。这在以下情况下很有用:
🌐 In some scenarios, you may want an agent to have access to working memory data without the ability to modify it. This is useful for:
- 需要上下文但不应更新用户资料的路由代理
- 子代理 在多代理系统中应该引用但不拥有内存
要启用只读模式,请在内存选项中设置 readOnly: true:
🌐 To enable read-only mode, set readOnly: true in the memory options:
const response = await agent.generate("What do you know about me?", {
memory: {
thread: "conversation-123",
resource: "user-alice-456",
options: {
readOnly: true, // Working memory is provided but cannot be updated
},
},
});
示例Direct link to 示例
🌐 Examples