跳至主要內容

記憶處理器

記憶處理器會在訊息通過已啟用記憶功能的 Agent 時,對訊息進行轉換和篩選。它們會管理上下文視窗限制、移除不必要的內容,並最佳化傳送至語言模型的資訊。

在 Agent 上啟用記憶功能後,Mastra 會將記憶處理器加入 Agent 的處理器管線。這些處理器會擷取訊息記錄、工作記憶和語意相關的訊息,然後在模型回應後保存新訊息。

記憶處理器是專門處理記憶相關訊息和狀態的處理器

內置記憶處理器
內置記憶處理器 的直接連結

啟用記憶功能後,Mastra 會自動加入以下處理器:

MessageHistory
messagehistory 的直接連結

擷取訊息記錄並保存新訊息。

當你進行以下設定時:

memory: new Memory({
lastMessages: 10,
})

Mastra 內部會:

  1. 建立一個 MessageHistory 處理器,並設定 limit: 10
  2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行)
  3. 將它加入 Agent 的輸出處理器(在 LLM 之後執行)

作用:

  • 輸入:從儲存空間取得最近 10 則訊息,並將它們加到對話開頭
  • 輸出:模型回應後,將新訊息保存至儲存空間

範例:

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
semanticrecall 的直接連結

根據目前的輸入擷取語意相關的訊息,並為新訊息建立嵌入向量。

當你進行以下設定時:

memory: new Memory({
semanticRecall: { enabled: true },
vector: myVectorStore,
embedder: myEmbedder,
})

Mastra 內部會:

  1. 建立一個 SemanticRecall 處理器
  2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行)
  3. 將它加入 Agent 的輸出處理器(在 LLM 之後執行)
  4. 要求同時設定向量儲存空間和嵌入器

作用:

  • 輸入:執行向量相似度搜尋以找出相關的過往訊息,並將它們加到對話開頭
  • 輸出:為新訊息建立嵌入向量,並將它們存入向量儲存空間以供日後擷取

範例:

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
workingmemory 的直接連結

管理跨對話的工作記憶狀態。

當你進行以下設定時:

memory: new Memory({
workingMemory: { enabled: true },
})

Mastra 內部會:

  1. 建立一個 WorkingMemory 處理器
  2. 將它加入 Agent 的輸入處理器(在 LLM 之前執行)
  3. 要求設定儲存適配器

作用:

  • 輸入:擷取目前對話串的工作記憶狀態,並將它加到對話開頭
  • 輸出:不進行輸出處理

範例:

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
}),
})

手動控制與重複項目移除
手動控制與重複項目移除 的直接連結

如果你手動將記憶處理器加入 inputProcessorsoutputProcessors,Mastra 不會自動加入該處理器。這讓你可以完全控制處理器的執行次序:

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
],
})

處理器執行次序
處理器執行次序 的直接連結

結合防護機制與記憶功能時,了解執行次序十分重要:

輸入處理器
輸入處理器 的直接連結

[Memory Processors] → [Your inputProcessors]
  1. 記憶處理器會先執行WorkingMemoryMessageHistorySemanticRecall
  2. 你的輸入處理器會後執行:防護機制、篩選器、驗證器

因此,記憶功能會先載入訊息記錄,然後你的處理器才能驗證或篩選輸入。

輸出處理器
輸出處理器 的直接連結

[Your outputProcessors] → [Memory Processors]
  1. 你的輸出處理器會先執行:防護機制、篩選器、驗證器
  2. 記憶處理器會後執行SemanticRecall(嵌入向量)、MessageHistory(保存)

這個次序的設計宗旨是預設安全:如果你的輸出防護機制呼叫 abort(),記憶處理器便不會執行,而且不會儲存任何訊息

防護機制與記憶功能
防護機制與記憶功能 的直接連結

預設執行次序可提供安全的防護機制行為:

輸出防護機制會在記憶處理器儲存訊息之前執行。如果防護機制中止執行:

  • 觸發中止訊號
  • 跳過記憶處理器
  • 不會將任何訊息保存至儲存空間
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
  • 跳過輸出處理器(包括記憶保存處理器)
  • 不會將任何訊息保存至儲存空間
// 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記錄大小限制
DynamoDB400 KB
Convex1 MiB
Cloudflare D11 MiB

PostgreSQL、MongoDB 和 libSQL 的限制較高,通常不受影響。

使用輸入處理器將附件上載至外部儲存空間,然後在保存訊息前,以 URL 參照取代附件。

src/mastra/processors/attachment-uploader.ts
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<string> {
const base64 = dataUri.split(',')[1]
const buffer = Buffer.from(base64, 'base64')

throw new Error('Implement upload() with your storage provider')
}
}

在你的 Agent 中使用此處理器:

src/mastra/agents/support-agent.ts
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()],
})

建立自訂處理器時,應避免直接修改輸入的 messages 陣列或其中的物件。