メモリプロセッサ
メモリプロセッサを使用すると、メモリから取得したメッセージの一覧を、エージェントのコンテキストウィンドウに追加して LLM に送信する前に変更できます。これは、コンテキストサイズの管理、コンテンツのフィルタリング、パフォーマンスの最適化に役立ちます。
プロセッサは、メモリ設定(例: lastMessages
、semanticRecall
)に基づいて取得されたメッセージに対して動作します。新規に受信したユーザーメッセージには影響しません。
組み込みプロセッサ
Mastra には組み込みのプロセッサが用意されています。
TokenLimiter
このプロセッサは、LLM のコンテキストウィンドウ上限超過によるエラーを防ぐために使用されます。取得したメモリ内のメッセージのトークン数を集計し、合計が指定した limit
を下回るまで最も古いメッセージから削除します。
import { Memory } from "@mastra/memory";
import { TokenLimiter } from "@mastra/memory/processors";
import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
const agent = new Agent({
model: openai("gpt-4o"),
memory: new Memory({
processors: [
// Ensure the total tokens from memory don't exceed ~127k
new TokenLimiter(127000),
],
}),
});
TokenLimiter
はデフォルトで o200k_base
エンコーディングを使用します(GPT-4o に適合)。モデルに応じて、必要に応じて別のエンコーディングを指定できます。
// Import the encoding you need (e.g., for older OpenAI models)
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
const memoryForOlderModel = new Memory({
processors: [
new TokenLimiter({
limit: 16000, // 16k コンテキストモデルの例
encoding: cl100k_base,
}),
],
});
エンコーディングの詳細は、OpenAI cookbook または js-tiktoken
リポジトリ を参照してください。
ToolCallFilter
このプロセッサは、LLM に送信されるメモリメッセージからツール呼び出しを取り除きます。コンテキストから冗長になりがちなツールのやり取りを除外することでトークンを節約でき、詳細が今後の対話で不要な場合に有用です。また、常にエージェントに特定のツールを再度呼び出させ、メモリ内の過去のツール結果に依存させたくない場合にも役立ちます。
import { Memory } from "@mastra/memory";
import { ToolCallFilter, TokenLimiter } from "@mastra/memory/processors";
const memoryFilteringTools = new Memory({
processors: [
// Example 1: Remove all tool calls/results
new ToolCallFilter(),
// Example 2: Remove only noisy image generation tool calls/results
new ToolCallFilter({ exclude: ["generateImageTool"] }),
// Always place TokenLimiter last
new TokenLimiter(127000),
],
});
複数のプロセッサの適用
複数のプロセッサをチェーンできます。processors
配列に記載された順に実行され、あるプロセッサの出力が次のプロセッサの入力になります。
順序が重要です! 一般的には、TokenLimiter
はチェーンの最後に配置するのがベストプラクティスです。これにより、他のフィルタリングの後、最終的なメッセージ集合に対して動作し、最も正確にトークン制限を適用できます。
import { Memory } from "@mastra/memory";
import { ToolCallFilter, TokenLimiter } from "@mastra/memory/processors";
// 仮の 'PIIFilter' カスタムプロセッサが存在すると仮定
// import { PIIFilter } from './custom-processors';
const memoryWithMultipleProcessors = new Memory({
processors: [
// 1. まず特定のツール呼び出しをフィルタ
new ToolCallFilter({ exclude: ["verboseDebugTool"] }),
// 2. カスタムフィルタを適用(例:仮の PII を削除 — 取り扱い注意)
// new PIIFilter(),
// 3. 最後のステップとしてトークン制限を適用
new TokenLimiter(127000),
],
});
カスタムプロセッサの作成
ベースの MemoryProcessor
クラスを拡張してカスタムロジックを実装できます。
import { Memory } from "@mastra/memory";
import { CoreMessage, MemoryProcessorOpts } from "@mastra/core";
import { MemoryProcessor } from "@mastra/core/memory";
class ConversationOnlyFilter extends MemoryProcessor {
constructor() {
// 必要に応じてデバッグを容易にするための名前を付与
super({ name: "ConversationOnlyFilter" });
}
process(
messages: CoreMessage[],
_opts: MemoryProcessorOpts = {}, // メモリ取得時に渡されるオプション。ここではほとんど不要
): CoreMessage[] {
// role に基づいてメッセージをフィルタリング
return messages.filter(
(msg) => msg.role === "user" || msg.role === "assistant",
);
}
}
// カスタムプロセッサを使用
const memoryWithCustomFilter = new Memory({
processors: [
new ConversationOnlyFilter(),
new TokenLimiter(127000), // トークン制限は引き続き適用
],
});
カスタムプロセッサを作成する際は、入力の messages
配列やその要素オブジェクトを直接変更(ミューテート)しないでください。