工作記憶
訊息記錄和語義回憶可協助 Agent 記住對話,而工作記憶則讓 Agent 能夠在多次互動之間保留用戶的持久資料。
工作記憶是 Agent 的即時記事區,用來隨時取用關於用戶或任務的重要資料。它可以在對話期間記住用戶的姓名、偏好或其他重要詳情。
這有助維持持續相關、並應隨時供 Agent 使用的狀態。
如果你使用 Observational Memory,observationalMemory.observation.manageWorkingMemory 可讓 OM 為 Agent 更新工作記憶。
觀看 Mastra 工作記憶,了解 Agent 如何在多次互動之間持續取用用戶情境。
工作記憶可在兩種不同範圍內持久保存:
- 資源範圍(預設):同一用戶的所有對話執行緒都會共用持久記憶
- 執行緒範圍:每個對話執行緒的記憶互相隔離
要求: 切換範圍後,Agent 將無法看到另一範圍的記憶——執行緒範圍記憶與資源範圍記憶完全分開。
快速開始快速開始 的直接連結
以下是為 Agent 設定工作記憶的最簡範例:
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.6-sol',
memory: new Memory({
options: {
workingMemory: {
enabled: true,
},
},
}),
})
運作方式運作方式 的直接連結
工作記憶是一段 Markdown 文字,Agent 可隨時間更新,以儲存持續相關的資料。
記憶持久保存範圍記憶持久保存範圍 的直接連結
工作記憶可在兩種不同範圍內運作,讓你選擇記憶如何跨對話持久保存:
資源範圍記憶(預設)資源範圍記憶(預設) 的直接連結
工作記憶預設會在同一用戶(resourceId)的所有對話執行緒之間持久保存,從而提供持久的用戶記憶:
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**:
`,
},
},
})
使用情境:
- 能記住用戶偏好的個人助理
- 能保留客戶情境的客戶服務聊天機械人
- 能追蹤學生進度的教育應用程式
與 Agent 配合使用與 Agent 配合使用 的直接連結
使用資源範圍記憶時,請確保在記憶選項中傳入 resource 參數:
// Resource-scoped memory requires resource
const response = await agent.generate('Hello!', {
memory: {
thread: 'conversation-123',
resource: 'user-alice-456', // Same user across different threads
},
})
執行緒範圍記憶執行緒範圍記憶 的直接連結
執行緒範圍記憶會將工作記憶限制於個別對話執行緒。每個執行緒都會保留各自獨立的記憶:
const memory = new Memory({
storage,
options: {
workingMemory: {
enabled: true,
scope: 'thread', // Memory is isolated per thread
template: `# User Profile
- **Name**:
- **Interests**:
- **Current Goal**:
`,
},
},
})
使用情境:
- 分別討論不同主題的對話
- 臨時或只適用於工作階段的資料
- 每個執行緒都需要工作記憶,但執行緒屬臨時性質且彼此無關的 Workflow
儲存適配器支援儲存適配器支援 的直接連結
資源範圍工作記憶需要支援 mastra_resources 資料表的特定儲存適配器:
支援的儲存適配器支援的儲存適配器 的直接連結
- libSQL (
@mastra/libsql) - PostgreSQL (
@mastra/pg) - OracleDB (
@mastra/oracledb) - Upstash (
@mastra/upstash) - MongoDB (
@mastra/mongodb)
自訂範本自訂範本 的直接連結
範本會引導 Agent 在工作記憶中追蹤和更新哪些資料。未有提供範本時,Mastra 會使用預設範本。請為 Agent 的使用情境定義自訂範本,讓它記住最相關的資料。如執行緒由多名用戶共用,請參閱多用戶執行緒。
以下是自訂範本的範例。在此範例中,用戶傳送的訊息一旦包含任何相關資料,Agent 就會儲存用戶的姓名、位置、時區等資料:
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]
`,
},
},
})
設計有效的範本設計有效的範本 的直接連結
結構清晰的範本,可讓 Agent 直接解析和更新資料。你可將範本視為一份希望助手持續更新的簡短表格。
- 使用簡短而明確的標籤。 避免段落或過長的標題。標籤應保持精簡(例如
## Personal Info或- Name:),讓更新內容容易閱讀,並降低被截斷的機會。 - 統一大小寫。 大小寫不一致(
Timezone:與timezone:)可能令更新內容雜亂。標題和項目符號標籤應統一使用標題式大小寫或小寫。 - 盡量縮短佔位文字。 使用
[e.g., Formal]或[Date]等提示,協助 LLM 填寫正確位置。 - 縮短非常長的值。 如果只需要簡短形式,請加入
- Name: [First name or nickname]或- Address (short):等指引,而非完整的法律文字。 - 在
instructions中說明更新規則。 你可直接在 Agent 的instructions欄位中指示應如何及何時填寫或清除範本的各部分。
其他範本樣式其他範本樣式 的直接連結
如果只需要幾個項目,可使用較短的單一區塊:
const basicMemory = new Memory({
options: {
workingMemory: {
enabled: true,
template: `User Facts:\n- Name:\n- Favorite Color:\n- Current Topic:`,
},
},
})
如果偏好較具敘事性的風格,也可以簡短段落格式儲存重要資料:
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).`,
},
},
})
結構化工作記憶結構化工作記憶 的直接連結
除了 Markdown 範本,亦可使用結構化 schema 定義工作記憶。這讓你可使用 Standard JSON Schema(Zod、Valibot、ArkType 等)指定要追蹤的確切欄位和類型。使用 schema 時,Agent 會將工作記憶視為符合 schema 的 JSON 物件,並加以更新。
要求: 你必須指定 template 或 schema,但不可同時指定兩者。
範例:使用 schema 的工作記憶範例:使用 schema 的工作記憶 的直接連結
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)
},
},
})
提供 schema 後,Agent 會以 JSON 物件形式接收工作記憶。例如:
{
"name": "Sam",
"location": "Berlin",
"timezone": "CET",
"preferences": {
"communicationStyle": "Formal",
"projectGoal": "Launch MVP",
"deadlines": ["2025-07-01"]
}
}
使用 schema 的記憶合併語義使用 schema 的記憶合併語義 的直接連結
使用 schema 的工作記憶採用合併語義,即 Agent 只需包含要新增或更新的欄位。現有欄位會自動保留。
- 物件欄位會深層合併: 只更新所提供的欄位,其他欄位維持不變
- 將欄位設為
null即可刪除: 這會明確地從記憶中移除該欄位 - 陣列會整個取代: 提供陣列欄位時,它會取代現有陣列(陣列不會逐項合併)
選擇範本或 schema選擇範本或 schema 的直接連結
- 如果希望 Agent 以自由格式的文字區塊(例如用戶資料或記事區)維護記憶,請使用 範本(Markdown)。範本採用取代語義:Agent 每次更新時都必須提供完整的記憶內容。
- 如果需要可驗證並以編程方式存取為 JSON 的結構化、類型安全資料,請使用 schema。
workingMemory.schema欄位接受任何兼容PublicSchema的 schema(包括 Zod v3、Zod v4、JSON Schema 或已符合標準的 schema)。Schema 採用合併語義:Agent 只提供要更新的欄位,現有欄位會獲保留。 - 同一時間只能啟用一種模式:不支援同時設定
template和schema。
範例:多步驟保留範例:多步驟保留 的直接連結
以下簡要展示 User Profile 範本如何在一段簡短的用戶對話中更新:
# 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
由於資料已儲存在工作記憶中,Agent 現在可在之後的回覆中提及 Sam 或 Berlin,而毋須再次索取相關資料。
如果 Agent 未有按預期正確更新工作記憶,你可在 Agent 的 instructions 設定中加入系統指示,說明應_如何_及_何時_使用此範本。
設定初始工作記憶設定初始工作記憶 的直接連結
雖然 Agent 通常會透過 updateWorkingMemory Tool 更新工作記憶,但你亦可在建立或更新執行緒時,以編程方式設定初始工作記憶。這適用於注入你希望 Agent 可隨時使用、而毋須在每次請求中傳入的用戶資料(例如姓名、偏好或其他資料)。
透過執行緒 metadata 設定工作記憶透過執行緒 metadata 設定工作記憶 的直接連結
建立執行緒時,可透過 metadata 的 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+."
以編程方式更新工作記憶以編程方式更新工作記憶 的直接連結
你亦可更新現有執行緒的工作記憶:
// 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)
`,
},
})
直接更新記憶直接更新記憶 的直接連結
你亦可直接使用 updateWorkingMemory 方法:
await memory.updateWorkingMemory({
threadId: 'thread-123',
resourceId: 'user-456', // Required for resource-scoped memory
workingMemory: 'Updated memory content...',
})
唯讀工作記憶唯讀工作記憶 的直接連結
在某些情況下,你可能希望 Agent 可以存取工作記憶資料,但無法修改。這適用於:
- 需要情境但不應更新用戶資料的路由 Agent
- 多 Agent 系統中應參考但不擁有記憶的子 Agent
要啟用唯讀模式,請在記憶選項中設定 readOnly: true:
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
},
},
})
選擇使用狀態訊號(實驗性功能)選擇使用狀態訊號(實驗性功能) 的直接連結
工作記憶預設會成為系統訊息的一部分傳送至模型。你可設定 useStateSignals: true,選擇改為透過狀態訊號傳送:
const memory = new Memory({
storage: new LibSQLStore({ id: 'mastra-storage', url: 'file:./mastra.db' }),
options: {
workingMemory: {
enabled: true,
template: '# User\n- name:\n- location:',
useStateSignals: true, // experimental: deliver as state signal
},
},
})
變更如下:
- 儲存方式相同。 系統會讀寫同一個資源/執行緒
workingMemory欄位。 - Tool 的結構相同,但會以新名稱公開。 寫入操作仍會流經相同的底層 Tool;在此路徑上,它會註冊為
setWorkingMemory(而非updateWorkingMemory)。更名可避免舊有的移除篩選器刪除 Tool 呼叫部分,讓它們作為一般審計記錄保留下來,而模型的下一步會自動取得新值。 - 只改變傳送方式。
Memory不會將資料合併至系統提示,而是自動附加WorkingMemoryStateProcessor,以state訊號(帶有stateId: 'working-memory')發出目前的工作記憶。
你會同時獲得標準狀態訊號的優點:執行緒範圍追蹤 metadata、透過 cacheKey 去除重複項目(相同快照只會發出一次),以及較舊快照移出情境視窗時透過 contextWindow.hasSnapshot 重新注入。
預設值(useStateSignals: false)會維持現有系統訊息行為不變。useStateSignals 不支援使用 version: 'vnext' 的範本工作記憶。
範例範例 的直接連結
- 使用範本的工作記憶
- 使用 schema 的工作記憶
- 按資源劃分的工作記憶:完整展示資源範圍記憶持久保存的範例