入力プロセッサ
入力プロセッサを使うと、メッセージが言語モデルに送信される前に、傍受・変更・検証・フィルタリングを行えます。これは、ガードレールの導入、コンテンツのモデレーション、メッセージ変換、セキュリティ制御の実装に役立ちます。
プロセッサは会話スレッド内のメッセージに対して動作します。内容の変更・フィルタリング・検証が可能で、条件に応じてリクエスト自体を中止することもできます。
組み込みプロセッサ
Mastra は一般的なユースケース向けに、いくつかの組み込みプロセッサを提供しています。
UnicodeNormalizer
このプロセッサは、Unicodeテキストを正規化して表記ゆれを防ぎ、問題になり得る文字を取り除きます。
import { Agent } from "@mastra/core/agent";
import { UnicodeNormalizer } from "@mastra/core/processors";
import { openai } from "@ai-sdk/openai";
const agent = new Agent({
name: 'normalized-agent',
instructions: 'You are a helpful assistant',
model: openai("gpt-4o"),
inputProcessors: [
new UnicodeNormalizer({
stripControlChars: true,
collapseWhitespace: true,
}),
],
});
利用可能なオプション:
stripControlChars
: 制御文字を削除(デフォルト: false)preserveEmojis
: 絵文字を保持(デフォルト: true)collapseWhitespace
: 連続するスペースや改行をまとめる(デフォルト: true)trim
: 先頭と末尾の空白を削除(デフォルト: true)
ModerationProcessor
このプロセッサは、LLM を用いて複数カテゴリにわたる不適切コンテンツを検出し、モデレーションを行います。
import { ModerationProcessor } from "@mastra/core/processors";
const agent = new Agent({
inputProcessors: [
new ModerationProcessor({
model: openai("gpt-4.1-nano"), // 高速かつコスト効率の高いモデルを使用
threshold: 0.7, // フラグ判定の信頼度しきい値
strategy: 'block', // フラグ判定されたコンテンツをブロック
categories: ['hate', 'harassment', 'violence'], // カスタムカテゴリ
}),
],
});
利用可能なオプション:
model
: モデレーション分析に用いる言語モデル(必須)categories
: チェックするカテゴリ配列(デフォルト: [‘hate’,‘hate/threatening’,‘harassment’,‘harassment/threatening’,‘self-harm’,‘self-harm/intent’,‘self-harm/instructions’,‘sexual’,‘sexual/minors’,‘violence’,‘violence/graphic’])threshold
: フラグ判定の信頼度しきい値(0〜1、デフォルト: 0.5)strategy
: コンテンツがフラグ判定された場合の動作(デフォルト: ‘block’)customInstructions
: モデレーションエージェントへのカスタム指示
利用可能な戦略:
block
: エラーでリクエストを拒否(デフォルト)warn
: 警告を記録しつつコンテンツを許可filter
: フラグ判定されたメッセージを除去し、処理を継続
PromptInjectionDetector
このプロセッサは、プロンプトインジェクション攻撃、ジェイルブレイク、システムの乗っ取り・改ざんの試みを検出して防止します。
import { PromptInjectionDetector } from "@mastra/core/processors";
const agent = new Agent({
inputProcessors: [
new PromptInjectionDetector({
model: openai("gpt-4.1-nano"),
threshold: 0.8, // 誤検知を減らすための高めのしきい値
strategy: 'rewrite', // 意図を保ちながら無害化を試みる
detectionTypes: ['injection', 'jailbreak', 'system-override'],
}),
],
});
利用可能なオプション:
model
: インジェクション検出に使用する言語モデル(必須)detectionTypes
: 検出対象のインジェクション種別の配列(デフォルト: [‘injection’, ‘jailbreak’, ‘system-override’])threshold
: フラグ付けのための信頼度しきい値(0〜1、デフォルト: 0.7)strategy
: インジェクション検出時の対応(デフォルト: ‘block’)instructions
: エージェント向けのカスタム検出指示includeScores
: ログに信頼度スコアを含めるかどうか(デフォルト: false)
利用可能な戦略:
block
: リクエストを拒否(デフォルト)warn
: 警告を記録するが処理は継続filter
: フラグ付けされたメッセージを除去rewrite
: 正当な意図を保ちつつインジェクションを無害化することを試みる
PIIDetector
このプロセッサは、メッセージ内の個人を特定できる情報(PII)を検出し、必要に応じてマスキング(秘匿化)します。
import { PIIDetector } from "@mastra/core/processors";
const agent = new Agent({
inputProcessors: [
new PIIDetector({
model: openai("gpt-4.1-nano"),
threshold: 0.6,
strategy: 'redact', // Automatically redact detected PII
detectionTypes: ['email', 'phone', 'credit-card', 'ssn', 'api-key', 'crypto-wallet', 'iban'],
redactionMethod: 'mask', // Preserve format while masking
preserveFormat: true, // Keep original structure in redacted values
includeDetections: true, // Log details for compliance auditing
}),
],
});
利用可能なオプション:
model
: PII 検出用の言語モデル(必須)detectionTypes
: 検出する PII 種別の配列(デフォルト: [‘email’, ‘phone’, ‘credit-card’, ‘ssn’, ‘api-key’, ‘ip-address’, ‘name’, ‘address’, ‘date-of-birth’, ‘url’, ‘uuid’, ‘crypto-wallet’, ‘iban’])threshold
: フラグ判定の信頼度しきい値(0〜1、デフォルト: 0.6)strategy
: PII 検出時の処理方針(デフォルト: ‘block’)redactionMethod
: PII の秘匿化方法(‘mask’, ‘hash’, ‘remove’, ‘placeholder’、デフォルト: ‘mask’)preserveFormat
: 秘匿化時に PII の形式を維持(デフォルト: true)includeDetections
: コンプライアンス監査向けに検出詳細をログへ含める(デフォルト: false)instructions
: エージェント向けのカスタム検出指示
利用可能な戦略:
block
: PII を含むリクエストを拒否(デフォルト)warn
: 警告を記録して許可filter
: PII を含むメッセージを除去redact
: PII をプレースホルダー値に置換
LanguageDetector
このプロセッサは受信メッセージの言語を検出し、ターゲット言語へ自動翻訳できます。
import { LanguageDetector } from "@mastra/core/processors";
const agent = new Agent({
inputProcessors: [
new LanguageDetector({
model: openai("gpt-4o-mini"),
targetLanguages: ['English', 'en'], // 英語コンテンツを許可
strategy: 'translate', // 非英語コンテンツを自動翻訳
threshold: 0.8, // 高い信頼度しきい値
}),
],
});
利用可能なオプション:
model
: 言語検出と翻訳に使用するモデル(必須)targetLanguages
: ターゲット言語の配列(言語名またはISOコード)threshold
: 言語検出の信頼度しきい値(0〜1、デフォルト: 0.7)strategy
: ターゲット外の言語が検出された場合の動作(デフォルト: ‘detect’)preserveOriginal
: 元のコンテンツをメタデータに保持(デフォルト: true)instructions
: エージェント用のカスタム検出指示
利用可能な戦略:
detect
: 言語のみ検出し、翻訳しない(デフォルト)translate
: 自動的にターゲット言語へ翻訳block
: ターゲット言語以外のコンテンツを拒否warn
: 警告を記録するがコンテンツは通過させる
複数のプロセッサを適用する
複数のプロセッサを連結できます。inputProcessors
配列に並んだ順に逐次実行され、あるプロセッサの出力は次のプロセッサの入力になります。
順序が重要です! 一般的には、最初にテキスト正規化、次にセキュリティチェック、最後にコンテンツの変更を行うのが推奨されます。
import { Agent } from "@mastra/core/agent";
import {
UnicodeNormalizer,
ModerationProcessor,
PromptInjectionDetector,
PIIDetector
} from "@mastra/core/processors";
const secureAgent = new Agent({
inputProcessors: [
// 1. まずテキストを正規化
new UnicodeNormalizer({ stripControlChars: true }),
// 2. セキュリティ上の脅威をチェック
new PromptInjectionDetector({ model: openai("gpt-4.1-nano") }),
// 3. コンテンツをモデレーション
new ModerationProcessor({ model: openai("gpt-4.1-nano") }),
// 4. 最後に個人情報(PII)を処理
new PIIDetector({ model: openai("gpt-4.1-nano"), strategy: 'redact' }),
],
});
カスタムプロセッサの作成
Processor
インターフェースを実装することで、カスタムプロセッサを作成できます。processInput
メソッドを実装すると、入力処理に使用できます。
import type { Processor } from "@mastra/core/processors";
import type { MastraMessageV2 } from "@mastra/core/agent/message-list";
import { TripWire } from "@mastra/core/agent";
class MessageLengthLimiter implements Processor {
readonly name = 'message-length-limiter';
constructor(private maxLength: number = 1000) {}
processInput({ messages, abort }: {
messages: MastraMessageV2[];
abort: (reason?: string) => never
}): MastraMessageV2[] {
// メッセージ全体の長さをチェック
try {
const totalLength = messages.reduce((sum, msg) => {
return sum + msg.content.parts
.filter(part => part.type === 'text')
.reduce((partSum, part) => partSum + (part as any).text.length, 0);
}, 0);
if (totalLength > this.maxLength) {
abort(`メッセージが長すぎます: ${totalLength} 文字(上限: ${this.maxLength})`); // TripWire エラーを投げる
}
} catch (error) {
if (error instanceof TripWire) {
throw error; // TripWire エラーは投げ直す
}
throw new Error(`長さの検証に失敗しました: ${error instanceof Error ? error.message : '不明なエラー'}`); // アプリケーションレベルでは標準のエラーを投げる
}
return messages;
}
}
// カスタムプロセッサを使用
const agent = new Agent({
inputProcessors: [
new MessageLengthLimiter(2000), // 2000 文字に制限
],
});
カスタムプロセッサを作成する際は、次の点に注意してください:
- 必ず
messages
配列を返すこと(必要に応じて変更されたもの) - 処理を早期終了するには
abort(reason)
を使用します。abort はメッセージのブロックをシミュレートするために使われ、abort
によって投げられるエラーは TripWire のインスタンスになります。コード/アプリケーションレベルのエラーには、標準のエラーを投げてください。 - 入力メッセージは直接変更し、メッセージの
parts
とcontent
の両方を必ず更新してください。 - プロセッサは単一責務に絞ること
- プロセッサ内でエージェントを使用する場合は、高速なモデルを用い、その応答サイズを可能な限り小さくし(トークンが増えるほど応答は指数関数的に遅くなります)、システムプロンプトはできるだけ簡潔にしてください。これらはいずれもレイテンシのボトルネックになります。
エージェントメソッドとの統合
Input processor は generate()
, stream()
, streamVNext()
メソッドで動作します。エージェントが応答の生成やストリーミングを開始する前に、すべての processor パイプラインが完了します。
// Processors run before generate()
const result = await agent.generate('Hello');
// Processors also run before streamVNext()
const stream = await agent.streamVNext('Hello');
for await (const chunk of stream) {
console.log(chunk);
}
いずれかの processor が abort()
を呼び出すと、リクエストは即座に終了し、以降の processor は実行されません。エージェントは、そのリクエストがブロックされた理由(result.tripwireReason
)の詳細とともに、200 のレスポンスを返します。
出力プロセッサ
入力プロセッサがユーザーのメッセージを言語モデルに届く前に処理するのに対し、出力プロセッサは、生成されたLLMの応答をユーザーに返す前に処理します。これは、応答の検証、コンテンツのフィルタリング、LLM生成コンテンツの安全対策に役立ちます。
LLMの応答処理の詳細は、Output Processors のドキュメントをご参照ください。