メインコンテンツへ移動

Memory Processor

Memory Processor は、Memory が有効な Agent をメッセージが通過するときに、メッセージを変換し、絞り込みます。コンテキストウィンドウの制限を管理して不要な内容を削除し、言語モデルへ送信する情報を最適化します。

Agent で Memory を有効にすると、Mastra は Agent の Processor パイプラインに Memory Processor を追加します。これらの Processor は、メッセージ履歴、ワーキングメモリ、意味的に関連するメッセージを取得し、モデルの応答後に新しいメッセージを永続化します。

Memory Processor は、Memory に関連するメッセージと状態を対象に動作する Processor です。

組み込みの Memory Processor
組み込みの Memory Processorへの直接リンク

Memory を有効にすると、Mastra は次の Processor を自動的に追加します。

MessageHistory
messagehistoryへの直接リンク

メッセージ履歴を取得し、新しいメッセージを永続化します。

次のように設定した場合:

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

Mastra の内部処理:

  1. limit: 10 を指定して MessageHistory 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への直接リンク

会話をまたいでワーキングメモリの状態を管理します。

次のように設定した場合:

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

Mastra の内部処理:

  1. WorkingMemory Processor を作成する
  2. Agent の入力 Processor に追加する(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
}),
})

手動制御と重複排除
手動制御と重複排除への直接リンク

Memory Processor を inputProcessors または outputProcessors に手動で追加した場合、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 の実行順序への直接リンク

ガードレールと Memory を組み合わせる場合は、実行順序を理解しておくことが重要です。

入力 Processor
入力 Processorへの直接リンク

[Memory Processors] → [Your inputProcessors]
  1. Memory Processor が最初に実行されるWorkingMemoryMessageHistorySemanticRecall
  2. 独自の入力 Processor が後に実行される:ガードレール、フィルター、バリデーター

そのため、Memory は独自の Processor が入力を検証または絞り込む前に、メッセージ履歴を読み込みます。

出力 Processor
出力 Processorへの直接リンク

[Your outputProcessors] → [Memory Processors]
  1. 独自の出力 Processor が最初に実行される:ガードレール、フィルター、バリデーター
  2. Memory Processor が後に実行されるSemanticRecall(埋め込み)、MessageHistory(永続化)

この順序は、デフォルトで安全になるよう設計されています。出力ガードレールが abort() を呼び出すと、Memory Processor は実行されず、メッセージは保存されません

ガードレールと Memory
ガードレールと Memoryへの直接リンク

デフォルトの実行順序により、ガードレールは安全に動作します。

出力ガードレールは、Memory Processor がメッセージを保存するに実行されます。ガードレールが中止した場合は、次のようになります。

  • トリップワイヤーが作動する
  • 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
}

入力ガードレール
入力ガードレールへの直接リンク

入力ガードレールは、Memory Processor が履歴を読み込んだに実行されます。ガードレールが中止した場合は、次のようになります。

  • トリップワイヤーが作動する
  • 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],
})

まとめ
まとめへの直接リンク

ガードレールの種類実行タイミング中止した場合
入力Memory が履歴を読み込んだ後LLM は呼び出されず、何も保存されない
出力Memory が保存する前ストレージに何も保存されない

どちらの場合も安全です。ガードレールにより、不適切な内容が 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')
}
}

この Processor を 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()],
})

カスタム Processor を作成するときは、入力の messages 配列やそのオブジェクトを直接変更しないでください。