ToolSearchProcessor
ToolSearchProcessor は、実行時に定義された Tool の検出と読み込みを可能にする input processor です。すべての Tool を最初から Agent に渡す代わりに、2つのメタ Tool(search_tools と load_tool)を提供し、必要に応じて Tool を検索して読み込めるようにします。大規模な Tool ライブラリを扱う際のコンテキストトークン使用量を削減できます。
使用例使用例への直接リンク
import { ToolSearchProcessor } from '@mastra/core/processors'
const toolSearch = new ToolSearchProcessor({
tools: {
createIssue: githubTools.createIssue,
sendEmail: emailTools.send,
getWeather: weatherTools.forecast,
// ... many more tools
},
search: {
topK: 5,
minScore: 0.1,
},
})
コンストラクターパラメーターコンストラクターパラメーターへの直接リンク
options:
tools:
includeResolvedTools?:
search?:
search.topK?:
search.minScore?:
search.autoLoad?:
storage?:
ttl?:
filter?:
戻り値戻り値への直接リンク
id:
name:
processInputStep:
メソッドメソッドへの直接リンク
状態の確認(従来の 'in-memory' ストア)state-inspection-legacy-in-memory-storeへの直接リンク
これらのメソッドは、デフォルトの 'in-memory' ストアだけを操作します。状態をプロセス内のマップではなく会話メッセージに保持する 'context' ストアでは、何も行いません。
clearState(threadId)clearstatethreadidへの直接リンク
単一の thread について、読み込み済み Tool の状態を消去します。
processor.clearState('thread-123')
clearAllState()clearallstateへの直接リンク
すべての thread について、読み込み済み Tool の状態を消去します。
processor.clearAllState()
getStateStats()getstatestatsへの直接リンク
インメモリ使用量の増加をデバッグするため、追跡対象の thread 数と最も古いアクセス時刻を返します。
const { threadCount, oldestAccessTime } = processor.getStateStats()
戻り値: { threadCount: number; oldestAccessTime: number | null }
cleanupNow()cleanupnowへの直接リンク
スケジュールされた実行を待たず、TTL クリーンアップをすぐに実行します。
const cleaned = processor.cleanupNow()
戻り値: number: クリーンアップされた thread の数。
リクエスト対応のフィルタリングリクエスト対応のフィルタリングへの直接リンク
実行時定義の Tool にリクエスト固有のポリシーを適用するには、filter を使用します。フックは、解決された Tool ID を toolName として受け取るほか、Tool、request context、phase を受け取ります。toolName は search_tools が返す ID であり、tools オブジェクト内のキーとは異なる場合があります。
import { ToolSearchProcessor } from '@mastra/core/processors'
const toolSearch = new ToolSearchProcessor({
tools: allTools,
filter: ({ toolName, requestContext, phase }) => {
const plan = requestContext?.get('plan')
if (phase === 'search') {
return true
}
return plan === 'pro' || !toolName.startsWith('premium_')
},
})
phase の値は、フィルターが適用される場所を表します。
search:search_toolsが返す結果をフィルタリングします。load: 許可されていない Tool をload_toolが読み込むことを拒否します。active: 読み込み済みの Tool が許可されなくなった場合、現在のリクエストから隠します。
フックが例外をスローするか reject された場合、ToolSearchProcessor はそのリクエストで Tool を不許可として扱います。フックは一致する検索候補ごとに実行される可能性があるため、非同期のポリシーチェックは低コストにするかキャッシュしてください。search_tools メタ Tool は常に利用できます。load_tool は、search.autoLoad が有効でない限り利用できます。Agent または processInputStep を通じて直接渡された Tool は、ToolSearchProcessor の外部でフィルタリングするか includeResolvedTools を有効にしない限り、引き続き利用できます。
リクエストごとに解決された Tool を検索するリクエストごとに解決された Tool を検索するへの直接リンク
tools オプションは構築時に固定されるため、リクエストごとにのみ存在する Tool(呼び出し元の認証情報が必要な MCP Tool や、動的な tools 関数が返す Tool)を列挙できません。デフォルトでは、これらの Tool は検索を経由せず、毎ターンでプロンプト領域を占有します。
リクエスト用にインデックス化し、Agent が読み込むまでプロンプトから除外するには、includeResolvedTools: true を設定します。
import { Agent } from '@mastra/core/agent'
import { ToolSearchProcessor } from '@mastra/core/processors'
const toolSearch = new ToolSearchProcessor({
tools: staticTools,
includeResolvedTools: true,
})
const agent = new Agent({
id: 'mcp-agent',
name: 'mcp-agent',
instructions: 'Search for a tool when you need a capability you do not have.',
model: 'openai/gpt-5.6-sol',
// Resolved per request, then searchable alongside staticTools
tools: async ({ requestContext }) => mcpClient.getTools(requestContext.get('userToken')),
inputProcessors: [toolSearch],
})
各リクエストは個別にインデックス化されるため、ある呼び出し元が読み込んだ Tool が、別の呼び出し元にある同名 Tool のインスタンスとして解決されることはありません。
このオプションは、Memory、Workspace、Skill、ブラウザーの Tool を含め、リクエスト用に解決されるすべての Tool に適用されます。プロンプトに残るのは search_tools と load_tool のメタ Tool だけです。そのため、Agent が暗黙に依存する Tool も、呼び出す前に検索で見つける必要があります。
詳細な使用例詳細な使用例への直接リンク
import { Agent } from '@mastra/core/agent'
import { ToolSearchProcessor } from '@mastra/core/processors'
// Tools from various integrations
import { githubTools } from './tools/github'
import { slackTools } from './tools/slack'
import { dbTools } from './tools/database'
const toolSearch = new ToolSearchProcessor({
tools: {
...githubTools, // createIssue, listPRs, mergePR, ...
...slackTools, // sendMessage, createChannel, ...
...dbTools, // query, insert, update, ...
},
search: {
topK: 5,
minScore: 0.1,
},
})
const agent = new Agent({
id: 'dynamic-tools-agent',
name: 'dynamic-tools-agent',
instructions:
'You are a helpful assistant with access to many tools. Use search_tools to find relevant tools, then load_tool to make them available.',
model: 'openai/gpt-5.6-sol',
inputProcessors: [toolSearch],
})
Agent のワークフローは次のとおりです。
- Agent がユーザーメッセージを受け取る
- Agent がキーワード(例:「github issue」)を指定して
search_toolsを呼び出す - Agent が結果を確認し、Tool 名を指定して
load_toolを呼び出す - 読み込まれた Tool が次のターンから利用可能になる
- Agent が通常どおり読み込んだ Tool を使用する
autoLoad による1ステップの検出single-step-discovery-with-autoloadへの直接リンク
個別の読み込みステップを省略するには、search.autoLoad を true に設定します。search_tools が返した Tool はすぐに有効化され、load_tool メタ Tool は公開されません。検出ごとにモデルのターンが1回減るため、トークン使用量とレイテンシーが低下し、どの Provider でも同じように動作します。
const toolSearch = new ToolSearchProcessor({
tools: allTools,
search: {
topK: 3,
autoLoad: true,
},
})
autoLoad を使用したワークフローは次のようになります。
- Agent がユーザーメッセージを受け取る
- Agent がキーワードを指定して
search_toolsを呼び出す - 一致した Tool が自動的に有効化され、次のターンから利用可能になる
- Agent が通常どおり Tool を使用する
一致したすべての Tool が有効になるため、Agent が必要としない Tool の追加を避けるには、topK を小さく(たとえば 3 に)設定してください。有効化された Tool は既存の Tool の後に追加されるため、prompt caching をサポートする Provider では、キャッシュ済みプロンプトの prefix が安定します。
読み込み済み Tool のストレージ読み込み済み Tool のストレージへの直接リンク
storage オプションは、読み込み済み Tool のセットを追跡する場所を制御します。デフォルトは 'in-memory' です。'context' ストアはオプトインです。
'in-memory'(デフォルト)in-memory-defaultへの直接リンク
読み込み済み Tool は thread ごとのインメモリマップで追跡され、ttl オプション(デフォルトは1時間)に基づいてクリーンアップされます。これは従来の動作です。
- Memory の設定は不要です。
- プロセスを再起動すると状態は失われます。
- thread ID がないリクエストは単一の
'default'エントリを共有します。
このストアの確認やリセットには、clearState、clearAllState、getStateStats、cleanupNow を使用します。
'context'contextへの直接リンク
読み込み済み状態は会話メッセージから導出されます。Tool 名を含む search_tools または load_tool の結果がメッセージに残っている間、その Tool は読み込み済みになります。このモードには次の特性があります。
- Memory の設定は不要です。
- 再起動に耐えます。永続的な記録は、保存されたメッセージ履歴です。
- その結果がメッセージからなくなると、Tool は自動的にアンロードされます。
import { ToolSearchProcessor } from '@mastra/core/processors'
const toolSearch = new ToolSearchProcessor({
tools: allTools,
storage: 'context',
})
どちらのモードでも、Tool の読み込みはキャッシュと相性がよい処理です。読み込みは追加だけを行うため、prompt caching をサポートする Provider では、キャッシュ済みプロンプトの prefix が安定します。
Tool をアンロードするとモデルへ送る Tool 定義が変わるため、キャッシュ済み prefix がずれ、次のターンでは cache hit ではなく cache write が発生します。'in-memory' モードでは、thread の状態が ttl により削除されたときに発生します。'context' モードでは、Tool の検出結果がメッセージからなくなったとき(たとえば古いメッセージがトリミングされた場合)に発生します。Tool はアンロードされ、再利用する前にモデルがもう一度検索する必要があります。これは想定された動作です。使用していない Tool を削除することで、1回の cache write と引き換えに、以降のターンで prefix を短くできます。
他の processor との組み合わせ他の processor との組み合わせへの直接リンク
import { Agent } from '@mastra/core/agent'
import { ToolSearchProcessor, TokenLimiter } from '@mastra/core/processors'
const agent = new Agent({
id: 'my-agent',
name: 'my-agent',
model: 'openai/gpt-5.6-sol',
inputProcessors: [
new ToolSearchProcessor({
tools: allTools,
search: { topK: 5 },
}),
// Place TokenLimiter last to ensure context fits
new TokenLimiter(127000),
],
})