跳至主要內容

工作記憶

訊息記錄語義回憶可協助 Agent 記住對話,而工作記憶則讓 Agent 能夠在多次互動之間保留用戶的持久資料。

工作記憶是 Agent 的即時記事區,用來隨時取用關於用戶或任務的重要資料。它可以在對話期間記住用戶的姓名、偏好或其他重要詳情。

這有助維持持續相關、並應隨時供 Agent 使用的狀態。

如果你使用 Observational MemoryobservationalMemory.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 SchemaZodValibotArkType 等)指定要追蹤的確切欄位和類型。使用 schema 時,Agent 會將工作記憶視為符合 schema 的 JSON 物件,並加以更新。

要求: 你必須指定 templateschema,但不可同時指定兩者。

範例:使用 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 的結構化、類型安全資料,請使用 schemaworkingMemory.schema 欄位接受任何兼容 PublicSchema 的 schema(包括 Zod v3、Zod v4、JSON Schema 或已符合標準的 schema)。Schema 採用合併語義:Agent 只提供要更新的欄位,現有欄位會獲保留。
  • 同一時間只能啟用一種模式:不支援同時設定 templateschema

範例:多步驟保留
範例:多步驟保留 的直接連結

以下簡要展示 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 現在可在之後的回覆中提及 SamBerlin,而毋須再次索取相關資料。

如果 Agent 未有按預期正確更新工作記憶,你可在 Agent 的 instructions 設定中加入系統指示,說明應_如何_及_何時_使用此範本。

設定初始工作記憶
設定初始工作記憶 的直接連結

雖然 Agent 通常會透過 updateWorkingMemory Tool 更新工作記憶,但你亦可在建立或更新執行緒時,以編程方式設定初始工作記憶。這適用於注入你希望 Agent 可隨時使用、而毋須在每次請求中傳入的用戶資料(例如姓名、偏好或其他資料)。

透過執行緒 metadata 設定工作記憶
透過執行緒 metadata 設定工作記憶 的直接連結

建立執行緒時,可透過 metadata 的 workingMemory key 提供初始工作記憶:

src/app/medical-consultation.ts
// 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+."

以編程方式更新工作記憶
以編程方式更新工作記憶 的直接連結

你亦可更新現有執行緒的工作記憶:

src/app/medical-consultation.ts
// 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 方法:

src/app/medical-consultation.ts
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' 的範本工作記憶。

範例
範例 的直接連結