> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # 記憶處理器 記憶處理器會在訊息通過已啟用記憶功能的 Agent 時,對訊息進行轉換和篩選。它們會管理上下文視窗限制、移除不必要的內容,並最佳化傳送至語言模型的資訊。 在 Agent 上啟用記憶功能後,Mastra 會將記憶處理器加入 Agent 的處理器管線。這些處理器會擷取訊息記錄、工作記憶和語意相關的訊息,然後在模型回應後保存新訊息。 記憶處理器是專門處理記憶相關訊息和狀態的[處理器](https://mastra.zisheng.pro/zh-HK/docs/agents/processors)。 ## 內置記憶處理器 啟用記憶功能後,Mastra 會自動加入以下處理器: ### `MessageHistory` 擷取訊息記錄並保存新訊息。 **當你進行以下設定時:** ```typescript memory: new Memory({ lastMessages: 10, }) ``` **Mastra 內部會:** 1. 建立一個 `MessageHistory` 處理器,並設定 `limit: 10` 2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行) 3. 將它加入 Agent 的輸出處理器(在 LLM 之後執行) **作用:** - **輸入**:從儲存空間取得最近 10 則訊息,並將它們加到對話開頭 - **輸出**:模型回應後,將新訊息保存至儲存空間 **範例:** ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { LibSQLStore } from '@mastra/libsql' import { openai } from '@ai-sdk/openai' const agent = new Agent({ id: 'test-agent', name: 'Test Agent', instructions: 'You are a helpful assistant', model: 'openai/gpt-5.6-sol', memory: new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:memory.db', }), lastMessages: 10, // MessageHistory processor automatically added }), }) ``` ### `SemanticRecall` 根據目前的輸入擷取語意相關的訊息,並為新訊息建立嵌入向量。 **當你進行以下設定時:** ```typescript memory: new Memory({ semanticRecall: { enabled: true }, vector: myVectorStore, embedder: myEmbedder, }) ``` **Mastra 內部會:** 1. 建立一個 `SemanticRecall` 處理器 2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行) 3. 將它加入 Agent 的輸出處理器(在 LLM 之後執行) 4. 要求同時設定向量儲存空間和嵌入器 **作用:** - **輸入**:執行向量相似度搜尋以找出相關的過往訊息,並將它們加到對話開頭 - **輸出**:為新訊息建立嵌入向量,並將它們存入向量儲存空間以供日後擷取 **範例:** ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { LibSQLStore } from '@mastra/libsql' import { PineconeVector } from '@mastra/pinecone' import { OpenAIEmbedder } from '@mastra/openai' import { openai } from '@ai-sdk/openai' const agent = new Agent({ name: 'semantic-agent', instructions: 'You are a helpful assistant with semantic memory', model: 'openai/gpt-5.6-sol', memory: new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:memory.db', }), vector: new PineconeVector({ id: 'memory-vector', apiKey: process.env.PINECONE_API_KEY!, }), embedder: new OpenAIEmbedder({ model: 'text-embedding-3-small', apiKey: process.env.OPENAI_API_KEY!, }), semanticRecall: { enabled: true }, // SemanticRecall processor automatically added }), }) ``` ### `WorkingMemory` 管理跨對話的工作記憶狀態。 **當你進行以下設定時:** ```typescript memory: new Memory({ workingMemory: { enabled: true }, }) ``` **Mastra 內部會:** 1. 建立一個 `WorkingMemory` 處理器 2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行) 3. 要求設定儲存適配器 **作用:** - **輸入**:擷取目前對話串的工作記憶狀態,並將它加到對話開頭 - **輸出**:不進行輸出處理 **範例:** ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { LibSQLStore } from '@mastra/libsql' import { openai } from '@ai-sdk/openai' const agent = new Agent({ name: 'working-memory-agent', instructions: 'You are an assistant with working memory', model: 'openai/gpt-5.6-sol', memory: new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:memory.db', }), workingMemory: { enabled: true }, // WorkingMemory processor automatically added }), }) ``` ## 手動控制與重複項目移除 如果你手動將記憶處理器加入 `inputProcessors` 或 `outputProcessors`,Mastra **不會**自動加入該處理器。這讓你可以完全控制處理器的執行次序: ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { MessageHistory } from '@mastra/core/processors' import { TokenLimiter } from '@mastra/core/processors' import { LibSQLStore } from '@mastra/libsql' import { openai } from '@ai-sdk/openai' // Custom MessageHistory with different configuration const customMessageHistory = new MessageHistory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:memory.db' }), lastMessages: 20, }) const agent = new Agent({ name: 'custom-memory-agent', instructions: 'You are a helpful assistant', model: 'openai/gpt-5.6-sol', memory: new Memory({ storage: new LibSQLStore({ id: 'memory-store', url: 'file:memory.db' }), lastMessages: 10, // This would normally add MessageHistory(10) }), inputProcessors: [ customMessageHistory, // Your custom one is used instead new TokenLimiter({ limit: 4000 }), // Runs after your custom MessageHistory ], }) ``` ## 處理器執行次序 結合防護機制與記憶功能時,了解執行次序十分重要: ### 輸入處理器 ```text [Memory Processors] → [Your inputProcessors] ``` 1. **記憶處理器會先執行**:`WorkingMemory`、`MessageHistory`、`SemanticRecall` 2. **你的輸入處理器會後執行**:防護機制、篩選器、驗證器 因此,記憶功能會先載入訊息記錄,然後你的處理器才能驗證或篩選輸入。 ### 輸出處理器 ```text [Your outputProcessors] → [Memory Processors] ``` 1. **你的輸出處理器會先執行**:防護機制、篩選器、驗證器 2. **記憶處理器會後執行**:`SemanticRecall`(嵌入向量)、`MessageHistory`(保存) 這個次序的設計宗旨是**預設安全**:如果你的輸出防護機制呼叫 `abort()`,記憶處理器便不會執行,而且**不會儲存任何訊息**。 ## 防護機制與記憶功能 預設執行次序可提供安全的防護機制行為: ### 輸出防護機制(建議) 輸出防護機制會在記憶處理器儲存訊息**之前**執行。如果防護機制中止執行: - 觸發中止訊號 - 跳過記憶處理器 - **不會將任何訊息保存至儲存空間** ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { openai } from '@ai-sdk/openai' // Output guardrail that blocks inappropriate content const contentBlocker = { id: 'content-blocker', processOutputResult: async ({ messages, abort }) => { const hasInappropriateContent = messages.some(msg => containsBadContent(msg)) if (hasInappropriateContent) { abort('Content blocked by guardrail') } return messages }, } const agent = new Agent({ id: 'safe-agent', name: 'safe-agent', instructions: 'You are a helpful assistant', model: 'openai/gpt-5.6-sol', memory: new Memory({ lastMessages: 10 }), // Your guardrail runs BEFORE memory saves outputProcessors: [contentBlocker], }) // If the guardrail aborts, nothing is saved to memory const result = await agent.generate('Hello') if (result.tripwire) { console.log('Blocked:', result.tripwire.reason) // Memory is empty - no messages were persisted } ``` ### 輸入防護機制 輸入防護機制會在記憶處理器載入記錄**之後**執行。如果防護機制中止執行: - 觸發中止訊號 - 永不呼叫 LLM - 跳過輸出處理器(包括記憶保存處理器) - **不會將任何訊息保存至儲存空間** ```typescript // Input guardrail that validates user input const inputValidator = { id: 'input-validator', processInput: async ({ messages, abort }) => { const lastUserMessage = messages.findLast(m => m.role === 'user') if (isInvalidInput(lastUserMessage)) { abort('Invalid input detected') } return messages }, } const agent = new Agent({ id: 'validated-agent', name: 'validated-agent', instructions: 'You are a helpful assistant', model: 'openai/gpt-5.6-sol', memory: new Memory({ lastMessages: 10 }), // Your guardrail runs AFTER memory loads history inputProcessors: [inputValidator], }) ``` ### 摘要 | 防護機制類型 | 執行時間 | 中止執行的結果 | | ------ | --------- | ------------------ | | 輸入 | 記憶功能載入記錄後 | 不會呼叫 LLM,亦不會儲存任何內容 | | 輸出 | 記憶功能儲存內容前 | 不會將任何內容儲存至儲存空間 | 這兩種情況都很安全——防護機制會防止將不適當的內容保存至記憶。 ## 處理大型附件 部分儲存 Provider 會限制記錄大小,而經 base64 編碼的檔案附件可能超出限制: | Provider | 記錄大小限制 | | --------------------------------------------------------------------------------- | ------ | | [DynamoDB](https://mastra.zisheng.pro/zh-HK/reference/storage/dynamodb) | 400 KB | | [Convex](https://mastra.zisheng.pro/zh-HK/reference/storage/convex) | 1 MiB | | [Cloudflare D1](https://mastra.zisheng.pro/zh-HK/reference/storage/cloudflare-d1) | 1 MiB | PostgreSQL、MongoDB 和 libSQL 的限制較高,通常不受影響。 使用輸入處理器將附件上載至外部儲存空間,然後在保存訊息前,以 URL 參照取代附件。 ```typescript import type { Processor } from '@mastra/core/processors' import type { MastraDBMessage } from '@mastra/core/memory' export class AttachmentUploader implements Processor { id = 'attachment-uploader' async processInput({ messages }: { messages: MastraDBMessage[] }) { return Promise.all(messages.map(message => this.processMessage(message))) } async processMessage(message: MastraDBMessage) { const attachments = message.content.experimental_attachments if (!attachments?.length) return message const uploaded = await Promise.all( attachments.map(async attachment => { if (!attachment.url?.startsWith('data:')) return attachment const url = await this.upload(attachment.url, attachment.contentType) return { ...attachment, url } }), ) return { ...message, content: { ...message.content, experimental_attachments: uploaded } } } async upload(dataUri: string, contentType?: string): Promise { const base64 = dataUri.split(',')[1] const buffer = Buffer.from(base64, 'base64') throw new Error('Implement upload() with your storage provider') } } ``` 在你的 Agent 中使用此處理器: ```typescript import { Agent } from '@mastra/core/agent' import { Memory } from '@mastra/memory' import { AttachmentUploader } from '../processors/attachment-uploader' export const supportAgent = new Agent({ id: 'support-agent', name: 'Support agent', instructions: 'Answer customer support questions.', model: 'openai/gpt-5.6-sol', memory: new Memory({ lastMessages: 10 }), inputProcessors: [new AttachmentUploader()], }) ``` ## 相關文件 - [處理器](https://mastra.zisheng.pro/zh-HK/docs/agents/processors):一般處理器概念及自訂處理器的建立方式 - [防護機制](https://mastra.zisheng.pro/zh-HK/docs/agents/guardrails):安全與驗證處理器 - [記憶概覽](https://mastra.zisheng.pro/zh-HK/docs/memory/overview):記憶類型與設定 建立自訂處理器時,應避免直接修改輸入的 `messages` 陣列或其中的物件。