Processeurs de mémoire
Les processeurs de mémoire transforment et filtrent les messages lorsqu'ils traversent un agent dont la mémoire est activée. Ils gèrent les limites de la fenêtre de contexte, suppriment le contenu superflu et optimisent les informations envoyées au modèle de langage.
Lorsque la mémoire est activée sur un agent, Mastra ajoute des processeurs de mémoire à son pipeline de processeurs. Ces processeurs récupèrent l'historique des messages, la mémoire de travail et les messages sémantiquement pertinents, puis conservent les nouveaux messages après la réponse du modèle.
Les processeurs de mémoire sont des processeurs qui agissent spécifiquement sur les messages et l'état liés à la mémoire.
Processeurs de mémoire intégrésLien direct vers Processeurs de mémoire intégrés
Mastra ajoute automatiquement les processeurs suivants lorsque la mémoire est activée :
MessageHistoryLien direct vers messagehistory
Récupère l'historique des messages et conserve les nouveaux messages.
Lorsque vous configurez :
memory: new Memory({
lastMessages: 10,
})
En interne, Mastra :
- Crée un processeur
MessageHistoryaveclimit: 10. - L'ajoute aux processeurs d'entrée de l'agent (exécution avant le LLM).
- L'ajoute aux processeurs de sortie de l'agent (exécution après le LLM).
Son rôle :
- Entrée : récupère les 10 derniers messages dans le stockage et les ajoute au début de la conversation.
- Sortie : conserve les nouveaux messages dans le stockage après la réponse du modèle.
Exemple :
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
}),
})
SemanticRecallLien direct vers semanticrecall
Récupère les messages sémantiquement pertinents en fonction de l'entrée actuelle et crée des embeddings pour les nouveaux messages.
Lorsque vous configurez :
memory: new Memory({
semanticRecall: { enabled: true },
vector: myVectorStore,
embedder: myEmbedder,
})
En interne, Mastra :
- Crée un processeur
SemanticRecall. - L'ajoute aux processeurs d'entrée de l'agent (exécution avant le LLM).
- L'ajoute aux processeurs de sortie de l'agent (exécution après le LLM).
- Nécessite la configuration d'un stockage vectoriel et d'un modèle d'embedding.
Son rôle :
- Entrée : effectue une recherche par similarité vectorielle afin de trouver les anciens messages pertinents et les ajoute au début de la conversation.
- Sortie : crée des embeddings pour les nouveaux messages et les enregistre dans le stockage vectoriel en vue d'une récupération ultérieure.
Exemple :
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
}),
})
WorkingMemoryLien direct vers workingmemory
Gère l'état de la mémoire de travail d'une conversation à l'autre.
Lorsque vous configurez :
memory: new Memory({
workingMemory: { enabled: true },
})
En interne, Mastra :
- Crée un processeur
WorkingMemory. - L'ajoute aux processeurs d'entrée de l'agent (exécution avant le LLM).
- Nécessite la configuration d'un adaptateur de stockage.
Son rôle :
- Entrée : récupère l'état de la mémoire de travail du thread actuel et l'ajoute au début de la conversation.
- Sortie : aucun traitement de sortie.
Exemple :
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
}),
})
Contrôle manuel et déduplicationLien direct vers Contrôle manuel et déduplication
Si vous ajoutez manuellement un processeur de mémoire à inputProcessors ou à outputProcessors, Mastra ne l'ajoutera pas automatiquement. Vous maîtrisez ainsi entièrement l'ordre des processeurs :
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
],
})
Ordre d'exécution des processeursLien direct vers Ordre d'exécution des processeurs
Il est important de comprendre l'ordre d'exécution lorsque vous associez des garde-fous à la mémoire :
Processeurs d'entréeLien direct vers Processeurs d'entrée
[Memory Processors] → [Your inputProcessors]
- Les processeurs de mémoire s'exécutent EN PREMIER :
WorkingMemory,MessageHistory,SemanticRecall. - Vos processeurs d'entrée s'exécutent ENSUITE : garde-fous, filtres et validateurs.
La mémoire charge donc l'historique des messages avant que vos processeurs puissent valider ou filtrer l'entrée.
Processeurs de sortieLien direct vers Processeurs de sortie
[Your outputProcessors] → [Memory Processors]
- Vos processeurs de sortie s'exécutent EN PREMIER : garde-fous, filtres et validateurs.
- Les processeurs de mémoire s'exécutent ENSUITE :
SemanticRecall(embeddings),MessageHistory(persistance).
Cet ordre est conçu pour être sûr par défaut : si votre garde-fou de sortie appelle abort(), les processeurs de mémoire ne s'exécutent jamais et aucun message n'est enregistré.
Garde-fous et mémoireLien direct vers Garde-fous et mémoire
L'ordre d'exécution par défaut garantit un comportement sûr des garde-fous :
Garde-fous de sortie (recommandé)Lien direct vers Garde-fous de sortie (recommandé)
Les garde-fous de sortie s'exécutent avant que les processeurs de mémoire n'enregistrent les messages. Si un garde-fou interrompt l'exécution :
- Le tripwire est déclenché.
- Les processeurs de mémoire sont ignorés.
- Aucun message n'est conservé dans le stockage.
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
}
Garde-fous d'entréeLien direct vers Garde-fous d'entrée
Les garde-fous d'entrée s'exécutent après que les processeurs de mémoire ont chargé l'historique. Si un garde-fou interrompt l'exécution :
- Le tripwire est déclenché.
- Le LLM n'est jamais appelé.
- Les processeurs de sortie, y compris la persistance en mémoire, sont ignorés.
- Aucun message n'est conservé dans le stockage.
// 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],
})
RécapitulatifLien direct vers Récapitulatif
| Type de garde-fou | Moment de l'exécution | En cas d'interruption |
|---|---|---|
| Entrée | Après le chargement de l'historique par la mémoire | Le LLM n'est pas appelé et rien n'est enregistré |
| Sortie | Avant l'enregistrement par la mémoire | Rien n'est enregistré dans le stockage |
Les deux scénarios sont sûrs : les garde-fous empêchent la conservation en mémoire de contenu inapproprié.
Gérer les pièces jointes volumineusesLien direct vers Gérer les pièces jointes volumineuses
Certains fournisseurs de stockage imposent des limites à la taille des enregistrements, que les pièces jointes encodées en base64 peuvent dépasser :
| Fournisseur | Taille maximale d'un enregistrement |
|---|---|
| DynamoDB | 400 KB |
| Convex | 1 MiB |
| Cloudflare D1 | 1 MiB |
PostgreSQL, MongoDB et libSQL ont des limites plus élevées et ne sont généralement pas concernés.
Utilisez un processeur d'entrée pour téléverser les pièces jointes vers un stockage externe, puis remplacez-les par des références URL avant la conservation des messages.
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')
}
}
Utilisez le processeur avec votre agent :
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()],
})
Documentation associéeLien direct vers Documentation associée
- Processeurs : concepts généraux relatifs aux processeurs et création de processeurs personnalisés
- Garde-fous : processeurs de sécurité et de validation
- Vue d'ensemble de la mémoire : types de mémoire et configuration
Lorsque vous créez des processeurs personnalisés, évitez de modifier directement le tableau d'entrée messages ou les objets qu'il contient.