跳至主要內容

Memory processor

Memory processor 會在訊息通過已啟用 Memory 的 Agent 時轉換並篩選訊息。它們可管理 context window 上限、移除不必要的內容,並最佳化送往語言模型的資訊。

在 Agent 上啟用 Memory 後,Mastra 會將 Memory processor 加入 Agent 的 processor pipeline。這些 processor 會擷取訊息歷史、working memory 與語意相關的訊息,然後在模型回應後保存新訊息。

Memory processor 是專門處理 Memory 相關訊息與狀態的 processor

內建 Memory processor
「內建 Memory processor」的直接連結

啟用 Memory 後,Mastra 會自動加入下列 processor:

MessageHistory
「messagehistory」的直接連結

擷取訊息歷史並保存新訊息。

進行以下設定時:

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

Mastra 內部會:

  1. 建立 limit: 10MessageHistory processor
  2. 將它加入 Agent 的輸入 processor(在 LLM 前執行)
  3. 將它加入 Agent 的輸出 processor(在 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 processor
  2. 將它加入 Agent 的輸入 processor(在 LLM 前執行)
  3. 將它加入 Agent 的輸出 processor(在 LLM 後執行)
  4. 要求同時設定向量儲存與 embedder

執行內容:

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

範例:

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

管理跨對話的 working memory 狀態。

進行以下設定時:

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

Mastra 內部會:

  1. 建立 WorkingMemory processor
  2. 將它加入 Agent 的輸入 processor(在 LLM 前執行)
  3. 要求設定儲存 adapter

執行內容:

  • 輸入:擷取目前 thread 的 working memory 狀態,並放到對話前方
  • 輸出:不執行輸出處理

範例:

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

手動控制與去除重複項目
「手動控制與去除重複項目」的直接連結

若手動將 Memory processor 加入 inputProcessorsoutputProcessors,Mastra 不會再自動加入該 processor。你可以藉此完整控制 processor 的順序:

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

Processor 執行順序
「Processor 執行順序」的直接連結

將 guardrail 與 Memory 搭配使用時,瞭解執行順序相當重要:

輸入 processor
「輸入 processor」的直接連結

[Memory Processors] → [Your inputProcessors]
  1. Memory processor 最先執行WorkingMemoryMessageHistorySemanticRecall
  2. 你的輸入 processor 隨後執行:guardrail、篩選器、驗證器

因此,Memory 會在你的 processor 驗證或篩選輸入前載入訊息歷史。

輸出 processor
「輸出 processor」的直接連結

[Your outputProcessors] → [Memory Processors]
  1. 你的輸出 processor 最先執行:guardrail、篩選器、驗證器
  2. Memory processor 隨後執行SemanticRecall(嵌入向量)、MessageHistory(保存)

此順序的設計是為了確保預設安全:若輸出 guardrail 呼叫 abort(),Memory processor 便不會執行,且不會儲存任何訊息

Guardrail 與 Memory
「Guardrail 與 Memory」的直接連結

預設執行順序可提供安全的 guardrail 行為:

輸出 guardrail 會在 Memory processor 儲存訊息之前執行。若 guardrail 中止:

  • 觸發 tripwire
  • 跳過 Memory processor
  • 不會將任何訊息保存至儲存空間
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
}

輸入 guardrail
「輸入 guardrail」的直接連結

輸入 guardrail 會在 Memory processor 載入歷史之後執行。若 guardrail 中止:

  • 觸發 tripwire
  • 絕不呼叫 LLM
  • 跳過輸出 processor(包括 Memory 保存)
  • 不會將任何訊息保存至儲存空間
// 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],
})

摘要
「摘要」的直接連結

Guardrail 類型執行時間中止時的結果
輸入Memory 載入歷史後不呼叫 LLM,也不儲存內容
輸出Memory 儲存前不將任何內容儲存至儲存空間

兩種情境都很安全,guardrail 會防止不當內容保存至 Memory。

處理大型附件
「處理大型附件」的直接連結

部分儲存 Provider 會限制記錄大小,而 Base64 編碼的檔案附件可能超過該限制:

Provider記錄大小上限
DynamoDB400 KB
Convex1 MiB
Cloudflare D11 MiB

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

請使用輸入 processor 將附件上傳至外部儲存空間,接著以 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 中使用此 processor:

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

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