Input Processors
Input Processorsを使用すると、メッセージが言語モデルに送信される_前に_、メッセージを傍受、変更、検証、またはフィルタリングできます。これは、ガードレール、コンテンツモデレーション、メッセージ変換、およびセキュリティ制御の実装に役立ちます。
Processorsは会話スレッド内のメッセージに対して動作します。コンテンツを変更、フィルタリング、または検証でき、特定の条件が満たされた場合はリクエストを完全に中止することもできます。
組み込みプロセッサ
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
このプロセッサは、プロンプトインジェクション攻撃、jailbreak、システム操作の試みを検出・防止します。
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', // 検出された PII を自動的に編集
detectionTypes: ['email', 'phone', 'credit-card', 'ssn', 'api-key', 'crypto-wallet', 'iban'],
redactionMethod: 'mask', // 形式を維持しつつマスク
preserveFormat: true, // マスク後も元の構造を保持
includeDetections: true, // コンプライアンス監査用に詳細を記録
}),
],
});
利用可能なオプション:
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
メソッドを実装している場合、Processor は入力処理に使用できます。
import type { Processor, MastraMessageV2, TripWire } from "@mastra/core/processors";
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(`Message too long: ${totalLength} characters (max: ${this.maxLength})`); // TripWire エラーを送出
}
} catch (error) {
if (error instanceof TripWire) {
throw error; // TripWire エラーは再送出
}
throw new Error(`Length validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`); // アプリケーションレベルでは標準的なエラーを送出
}
return messages;
}
}
// カスタムプロセッサを使用する
const agent = new Agent({
inputProcessors: [
new MessageLengthLimiter(2000), // 2000 文字に制限
],
});
カスタムプロセッサを作成する際のポイント:
- 常に
messages
配列(必要に応じて変更後のもの)を返す - 早期終了には
abort(reason)
を使用する。Abort はメッセージのブロックを模擬するために使われ、abort
で送出されるエラーは TripWire のインスタンスになる。コード/アプリケーションレベルのエラーは標準的なエラーを送出する。 - 入力メッセージを直接変更する。メッセージの parts と content の両方を必ず更新する。
- プロセッサは単一責務に絞る
- プロセッサ内でエージェントを使用する場合は、高速なモデルを使い、その応答サイズを可能な限り小さく抑え(トークンが増えるほど応答は指数関数的に遅くなる)、system プロンプトはできるだけ簡潔にする。これらはいずれもレイテンシのボトルネックとなる。
エージェントメソッドとの統合
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 のドキュメントをご覧ください。