> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-TW/llms.txt # Working memory [訊息歷史](https://mastra.zisheng.pro/zh-TW/docs/memory/message-history)與[語意回憶](https://mastra.zisheng.pro/zh-TW/docs/memory/semantic-recall)可協助 Agent 記住對話,而 working memory 則能讓 Agent 在多次互動間持續保留使用者資訊。 Working memory 是 Agent 的主動暫存區:其中保存隨時可用的使用者或工作相關重要資訊。它可以在對話期間保留某人的名稱、偏好或其他重要細節。 對於維持持續存在、始終相關且應隨時提供給 Agent 的狀態,這項功能很實用。 若使用 [Observational Memory](https://mastra.zisheng.pro/zh-TW/docs/memory/observational-memory),`observationalMemory.observation.manageWorkingMemory` 可讓 OM 更新 Agent 的 working memory。 > **📹 觀看影片:** 觀看 [Mastra working memory](https://www.youtube.com/watch?v=UMy_JHLf1n8\&pp=ygUVbWFzdHJhIHdvcmtpbmcgbWVtb3J5),瞭解 Agent 如何在互動之間持續提供使用者脈絡。 Working memory 可保存於兩種不同的作用域: - **Resource 作用域**(預設):同一位使用者的所有對話 thread 都會保存 Memory - **Thread 作用域**:每個對話 thread 的 Memory 彼此隔離 \*\*必要條件:\*\*切換作用域後,Agent 不會看到另一個作用域中的 Memory。Thread 作用域 Memory 與 resource 作用域 Memory 完全分離。 ## 快速開始 以下是為 Agent 設定 working memory 的最小範例: ```typescript 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, }, }, }), }) ``` ## 運作方式 Working memory 是一段 Markdown 文字,Agent 可以持續更新,以儲存一直相關的資訊。 ## Memory 保存作用域 Working memory 可在兩種不同的作用域中運作,讓你選擇跨對話保存 Memory 的方式: ### Resource 作用域 Memory(預設) Working memory 預設會在同一位使用者(resourceId)的所有對話 thread 中保存,提供持久的使用者記憶: ```typescript 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 使用 使用 resource 作用域 Memory 時,請務必在 Memory 選項中傳入 `resource` 參數: ```typescript // Resource-scoped memory requires resource const response = await agent.generate('Hello!', { memory: { thread: 'conversation-123', resource: 'user-alice-456', // Same user across different threads }, }) ``` ### Thread 作用域 Memory Thread 作用域 Memory 會將 working memory 隔離至各個對話 thread。每個 thread 都維護自己獨立的 Memory: ```typescript const memory = new Memory({ storage, options: { workingMemory: { enabled: true, scope: 'thread', // Memory is isolated per thread template: `# User Profile - **Name**: - **Interests**: - **Current Goal**: `, }, }, }) ``` **使用情境:** - 分別討論不同主題的對話 - 暫時或工作階段專屬的資訊 - 每個 thread 都需要 working memory,但 thread 是暫時存在且彼此無關的 Workflow ## 儲存 adapter 支援 Resource 作用域 working memory 需要支援 `mastra_resources` 資料表的特定儲存 adapter: ### 支援的儲存 adapter - **libSQL**(`@mastra/libsql`) - **PostgreSQL**(`@mastra/pg`) - **OracleDB**(`@mastra/oracledb`) - **Upstash**(`@mastra/upstash`) - **MongoDB**(`@mastra/mongodb`) ## 自訂範本 範本可引導 Agent 判斷要在 working memory 中追蹤與更新哪些資訊。若未提供範本,Mastra 會使用預設範本。請依 Agent 的使用情境定義自訂範本,讓它記住最相關的資訊。若 thread 由多位使用者共用,請參閱[多使用者 thread](https://mastra.zisheng.pro/zh-TW/docs/memory/multi-user-threads)。 以下是自訂範本範例。在此範例中,只要使用者傳送包含任何相關資訊的訊息,Agent 就會立即儲存使用者的名稱、位置、時區等內容: ```typescript 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` 欄位中指示填寫或清除範本各部分的方式與時機。 ### 其他範本樣式 若只需要幾個項目,可以使用較短的單一區塊: ```typescript const basicMemory = new Memory({ options: { workingMemory: { enabled: true, template: `User Facts:\n- Name:\n- Favorite Color:\n- Current Topic:`, }, }, }) ``` 若偏好較具敘事性的樣式,也可以用簡短段落格式儲存重要事實: ```typescript 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).`, }, }, }) ``` ## 結構化 working memory Working memory 也可以使用結構化 schema 定義,不必使用 Markdown 範本。如此便能透過 [Standard JSON Schema](https://standardschema.dev/json-schema)([Zod](https://zod.dev/)、[Valibot](https://valibot.dev/)、[ArkType](https://arktype.io/) 等)指定要追蹤的確切欄位與型別。使用 schema 時,Agent 會以符合 schema 的 JSON 物件查看並更新 working memory。 \*\*必要條件:\*\*你必須指定 `template` 或 `schema`,但不能同時指定兩者。 ### 範例:以 schema 為基礎的 working memory ```typescript 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 物件接收 working memory。例如: ```json { "name": "Sam", "location": "Berlin", "timezone": "CET", "preferences": { "communicationStyle": "Formal", "projectGoal": "Launch MVP", "deadlines": ["2025-07-01"] } } ``` ### 以 schema 為基礎之 Memory 的合併語意 以 schema 為基礎的 working memory 使用**合併語意**,表示 Agent 只需包含要新增或更新的欄位。現有欄位會自動保留。 - \*\*物件欄位會深層合併:\*\*只更新提供的欄位,其他欄位維持不變 - \*\*將欄位設為 `null` 即可刪除:\*\*這會明確地從 Memory 移除該欄位 - \*\*陣列會整個取代:\*\*提供陣列欄位時,會取代現有陣列(不會逐項合併陣列) ## 選擇範本或 schema - 若希望 Agent 將 Memory 維護為自由格式的文字區塊,例如使用者個人資料或暫存區,請使用 **範本**(Markdown)。範本使用**取代語意**:Agent 每次更新都必須提供完整的 Memory 內容。 - 若需要可驗證、型別安全且能以程式存取的 JSON 結構化資料,請使用 **schema**。`workingMemory.schema` 欄位接受任何與 `PublicSchema` 相容的 schema(包括 Zod v3、Zod v4、JSON Schema 或已符合標準的 schema)。Schema 使用**合併語意**:Agent 只需提供要更新的欄位,現有欄位會繼續保留。 - 一次只能啟用一種模式:不支援同時設定 `template` 與 `schema`。 ## 範例:跨多步驟保留 以下簡化呈現 `User Profile` 範本在一小段使用者對話中的更新方式: ```nohighlight # 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`,而不必再次要求提供資訊,因為這些內容已儲存在 working memory 中。 若 Agent 未在預期時正確更新 working memory,你可以在 Agent 的 `instructions` 設定中加入系統 instruction,說明使用此範本的方式與時機。 ## 設定初始 working memory Agent 通常會透過 `updateWorkingMemory` Tool 更新 working memory,但你也可以在建立或更新 thread 時,以程式設定初始 working memory。若想將使用者資料(例如名稱、偏好或其他資訊)提供給 Agent,卻不想在每次要求中傳入,這項功能就很實用。 ### 透過 thread metadata 設定 working memory 建立 thread 時,可以透過 metadata 的 `workingMemory` key 提供初始 working memory: ```typescript // 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+." ``` ### 以程式更新 working memory 你也可以更新現有 thread 的 working memory: ```typescript // 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) `, }, }) ``` ### 直接更新 Memory 另一種方式是直接使用 `updateWorkingMemory` 方法: ```typescript await memory.updateWorkingMemory({ threadId: 'thread-123', resourceId: 'user-456', // Required for resource-scoped memory workingMemory: 'Updated memory content...', }) ``` ## 唯讀 working memory 在某些情境中,你可能想讓 Agent 存取 working memory 資料,但不允許修改。這適用於: - **路由 Agent**:需要脈絡,但不應更新使用者個人資料 - 多 Agent 系統中的**子 Agent**:應參照 Memory,但不應擁有它 若要啟用唯讀模式,請在 Memory 選項中設定 `readOnly: true`: ```typescript 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 }, }, }) ``` ## 選擇使用狀態訊號(實驗性) Working memory 預設會以系統訊息的一部分送達模型。你可以設定 `useStateSignals: true`,改以[狀態訊號](https://mastra.zisheng.pro/zh-TW/docs/long-running-agents/signals)傳送: ```typescript 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 }, }, }) ``` 變更內容: - \*\*儲存方式相同。\*\*讀寫的仍是相同 resource/thread `workingMemory` 欄位。 - \*\*Tool 具有相同結構,但以新名稱公開。\*\*寫入仍會流經相同的底層 Tool;在此路徑上會註冊為 `setWorkingMemory`(而非 `updateWorkingMemory`)。重新命名可避免舊版 strip filter 移除 Tool 呼叫部分,使其保留為一般稽核軌跡,而下一個模型步驟會自動取得新值。 - **只有傳送方式不同。**`Memory` 不會將內容併入系統提示,而會自動附加 `WorkingMemoryStateProcessor`,以 `stateId: 'working-memory'` 將目前 working memory 發出為 `state` 訊號。 你會繼承標準狀態訊號的優點:thread 作用域的追蹤 metadata、透過 `cacheKey` 去除重複內容(相同快照只會發出一次),以及較舊快照離開視窗後,透過 `contextWindow.hasSnapshot` 重新注入。 預設值(`useStateSignals: false`)會維持現有系統訊息行為不變。範本 working memory `version: 'vnext'` 不支援 `useStateSignals`。 ## 範例 - [搭配範本的 working memory](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-template) - [搭配 schema 的 working memory](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-schema) - [每個 resource 各自使用 working memory](https://github.com/mastra-ai/mastra/tree/main/examples/memory-per-resource-example):完整呈現 resource 作用域 Memory 保存方式的範例