> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # 工作記憶 [訊息記錄](https://mastra.zisheng.pro/zh-HK/docs/memory/message-history)和[語義回憶](https://mastra.zisheng.pro/zh-HK/docs/memory/semantic-recall)可協助 Agent 記住對話,而工作記憶則讓 Agent 能夠在多次互動之間保留用戶的持久資料。 工作記憶是 Agent 的即時記事區,用來隨時取用關於用戶或任務的重要資料。它可以在對話期間記住用戶的姓名、偏好或其他重要詳情。 這有助維持持續相關、並應隨時供 Agent 使用的狀態。 如果你使用 [Observational Memory](https://mastra.zisheng.pro/zh-HK/docs/memory/observational-memory),`observationalMemory.observation.manageWorkingMemory` 可讓 OM 為 Agent 更新工作記憶。 > **📹 觀看影片:** 觀看 [Mastra 工作記憶](https://www.youtube.com/watch?v=UMy_JHLf1n8\&pp=ygUVbWFzdHJhIHdvcmtpbmcgbWVtb3J5),了解 Agent 如何在多次互動之間持續取用用戶情境。 工作記憶可在兩種不同範圍內持久保存: - **資源範圍**(預設):同一用戶的所有對話執行緒都會共用持久記憶 - **執行緒範圍**:每個對話執行緒的記憶互相隔離 **要求:** 切換範圍後,Agent 將無法看到另一範圍的記憶——執行緒範圍記憶與資源範圍記憶完全分開。 ## 快速開始 以下是為 Agent 設定工作記憶的最簡範例: ```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, }, }, }), }) ``` ## 運作方式 工作記憶是一段 Markdown 文字,Agent 可隨時間更新,以儲存持續相關的資料。 ## 記憶持久保存範圍 工作記憶可在兩種不同範圍內運作,讓你選擇記憶如何跨對話持久保存: ### 資源範圍記憶(預設) 工作記憶預設會在同一用戶(resourceId)的所有對話執行緒之間持久保存,從而提供持久的用戶記憶: ```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` 參數: ```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 }, }) ``` ### 執行緒範圍記憶 執行緒範圍記憶會將工作記憶限制於個別對話執行緒。每個執行緒都會保留各自獨立的記憶: ```typescript 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 的使用情境定義自訂範本,讓它記住最相關的資料。如執行緒由多名用戶共用,請參閱[多用戶執行緒](https://mastra.zisheng.pro/zh-HK/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).`, }, }, }) ``` ## 結構化工作記憶 除了 Markdown 範本,亦可使用結構化 schema 定義工作記憶。這讓你可使用 [Standard JSON Schema](https://standardschema.dev/json-schema)([Zod](https://zod.dev/)、[Valibot](https://valibot.dev/)、[ArkType](https://arktype.io/) 等)指定要追蹤的確切欄位和類型。使用 schema 時,Agent 會將工作記憶視為符合 schema 的 JSON 物件,並加以更新。 **要求:** 你必須指定 `template` 或 `schema`,但不可同時指定兩者。 ### 範例:使用 schema 的工作記憶 ```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 物件形式接收工作記憶。例如: ```json { "name": "Sam", "location": "Berlin", "timezone": "CET", "preferences": { "communicationStyle": "Formal", "projectGoal": "Launch MVP", "deadlines": ["2025-07-01"] } } ``` ### 使用 schema 的記憶合併語義 使用 schema 的工作記憶採用**合併語義**,即 Agent 只需包含要新增或更新的欄位。現有欄位會自動保留。 - **物件欄位會深層合併:** 只更新所提供的欄位,其他欄位維持不變 - **將欄位設為 `null` 即可刪除:** 這會明確地從記憶中移除該欄位 - **陣列會整個取代:** 提供陣列欄位時,它會取代現有陣列(陣列不會逐項合併) ## 選擇範本或 schema - 如果希望 Agent 以自由格式的文字區塊(例如用戶資料或記事區)維護記憶,請使用 **範本**(Markdown)。範本採用**取代語義**:Agent 每次更新時都必須提供完整的記憶內容。 - 如果需要可驗證並以編程方式存取為 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`,而毋須再次索取相關資料。 如果 Agent 未有按預期正確更新工作記憶,你可在 Agent 的 `instructions` 設定中加入系統指示,說明應\_如何\_及\_何時\_使用此範本。 ## 設定初始工作記憶 雖然 Agent 通常會透過 `updateWorkingMemory` Tool 更新工作記憶,但你亦可在建立或更新執行緒時,以編程方式設定初始工作記憶。這適用於注入你希望 Agent 可隨時使用、而毋須在每次請求中傳入的用戶資料(例如姓名、偏好或其他資料)。 ### 透過執行緒 metadata 設定工作記憶 建立執行緒時,可透過 metadata 的 `workingMemory` key 提供初始工作記憶: ```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+." ``` ### 以編程方式更新工作記憶 你亦可更新現有執行緒的工作記憶: ```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) `, }, }) ``` ### 直接更新記憶 你亦可直接使用 `updateWorkingMemory` 方法: ```typescript await memory.updateWorkingMemory({ threadId: 'thread-123', resourceId: 'user-456', // Required for resource-scoped memory workingMemory: 'Updated memory content...', }) ``` ## 唯讀工作記憶 在某些情況下,你可能希望 Agent 可以存取工作記憶資料,但無法修改。這適用於: - 需要情境但不應更新用戶資料的**路由 Agent** - 多 Agent 系統中應參考但不擁有記憶的**子 Agent** 要啟用唯讀模式,請在記憶選項中設定 `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 }, }, }) ``` ## 選擇使用狀態訊號(實驗性功能) 工作記憶預設會成為系統訊息的一部分傳送至模型。你可設定 `useStateSignals: true`,選擇改為透過[狀態訊號](https://mastra.zisheng.pro/zh-HK/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 }, }, }) ``` 變更如下: - **儲存方式相同。** 系統會讀寫同一個資源/執行緒 `workingMemory` 欄位。 - **Tool 的結構相同,但會以新名稱公開。** 寫入操作仍會流經相同的底層 Tool;在此路徑上,它會註冊為 `setWorkingMemory`(而非 `updateWorkingMemory`)。更名可避免舊有的移除篩選器刪除 Tool 呼叫部分,讓它們作為一般審計記錄保留下來,而模型的下一步會自動取得新值。 - **只改變傳送方式。** `Memory` 不會將資料合併至系統提示,而是自動附加 `WorkingMemoryStateProcessor`,以 `state` 訊號(帶有 `stateId: 'working-memory'`)發出目前的工作記憶。 你會同時獲得標準狀態訊號的優點:執行緒範圍追蹤 metadata、透過 `cacheKey` 去除重複項目(相同快照只會發出一次),以及較舊快照移出情境視窗時透過 `contextWindow.hasSnapshot` 重新注入。 預設值(`useStateSignals: false`)會維持現有系統訊息行為不變。`useStateSignals` 不支援使用 `version: 'vnext'` 的範本工作記憶。 ## 範例 - [使用範本的工作記憶](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-template) - [使用 schema 的工作記憶](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-schema) - [按資源劃分的工作記憶](https://github.com/mastra-ai/mastra/tree/main/examples/memory-per-resource-example):完整展示資源範圍記憶持久保存的範例