> Discover all available pages from the documentation index: https://mastra.zisheng.pro/ja/llms.txt # ToolSearchProcessor `ToolSearchProcessor` は、実行時に定義された Tool の検出と読み込みを可能にする **input processor** です。すべての Tool を最初から Agent に渡す代わりに、2つのメタ Tool(`search_tools` と `load_tool`)を提供し、必要に応じて Tool を検索して読み込めるようにします。大規模な Tool ライブラリを扱う際のコンテキストトークン使用量を削減できます。 ## 使用例 ```typescript 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** (`ToolSearchProcessorOptions`): Tool 検索 processor の設定オプション **options.tools** (`Record`): 動的に検索して読み込めるすべての Tool。これらの Tool は Agent がすぐに利用できるわけではなく、検索で検出し、必要に応じて読み込む必要があります。 **options.includeResolvedTools** (`boolean`): Agent がこのリクエスト用に解決した Tool(呼び出し元の認証情報が必要な MCP Tool や、動的な tools 関数が返す Tool)も検索対象にし、Agent が読み込むまでプロンプトに含めません。メタ Tool は除外されません。リクエストごとに解決される Tool はリクエスト単位でインデックス化されるため、各リクエストはそれぞれ固有の Tool インスタンスを検索して読み込みます。 **options.search** (`{ topK?: number; minScore?: number; autoLoad?: boolean }`): 検索動作の設定。 **options.search.topK** (`number`): 検索結果として返す Tool の最大数。 **options.search.minScore** (`number`): Tool を検索結果に含める最小関連度スコア(0~1)。 **options.search.autoLoad** (`boolean`): true の場合、search\_tools が返した Tool を検索処理の一部として即座に有効化します。load\_tool メタ Tool は公開されず、検索してから読み込む2段階のフローが1回の検索ステップにまとまります。検出された Tool は次のターンから利用できます。一致したすべての Tool が有効になるため、topK は控えめに設定してください。 **options.storage** (`'in-memory' | 'context'`): 読み込んだ Tool の状態を保持する場所。'in-memory'(デフォルト)は、thread ごとのインメモリマップで読み込み済み Tool を追跡し、TTL でクリーンアップします(ttl を参照)。再起動すると状態は失われ、匿名リクエストは 'default' エントリを共有します。'context' は会話メッセージから読み込み済み状態を導出します。Tool 名を含む search\_tools/load\_tool の結果がメッセージに残っている間、その Tool は読み込み済みになります。再起動に耐え、Memory を必要とせず、その結果がメッセージからなくなると自動的にアンロードされます。'context' ストアはオプトインです。 **options.ttl** (`number`): インメモリの thread 状態の有効期間(ミリ秒)。デフォルトの 'in-memory' ストアだけに適用され、この期間に操作がなければ thread の状態がクリーンアップされます。クリーンアップを無効にするには 0 を設定します。'context' ストアでは無視されます。 **options.filter** (`(args: ToolSearchFilterArgs) => boolean | Promise`): 検索結果から Tool を隠す、Tool の読み込みを拒否する、または現在のリクエストで読み込み済みの Tool を隠すための、リクエスト対応の任意フック。 ## 戻り値 **id** (`string`): 'tool-search' に設定された processor の識別子 **name** (`string`): 'Tool Search Processor' に設定された processor の表示名 **processInputStep** (`(args: ProcessInputStepArgs) => Promise`): 各ステップを処理し、検索/読み込み用のメタ Tool と、以前に読み込まれた Tool を Agent の Tool セットへ挿入します。 ## メソッド ### 状態の確認(従来の `'in-memory'` ストア) これらのメソッドは、デフォルトの `'in-memory'` ストアだけを操作します。状態をプロセス内のマップではなく会話メッセージに保持する `'context'` ストアでは、何も行いません。 #### `clearState(threadId)` 単一の thread について、読み込み済み Tool の状態を消去します。 ```typescript processor.clearState('thread-123') ``` #### `clearAllState()` すべての thread について、読み込み済み Tool の状態を消去します。 ```typescript processor.clearAllState() ``` #### `getStateStats()` インメモリ使用量の増加をデバッグするため、追跡対象の thread 数と最も古いアクセス時刻を返します。 ```typescript const { threadCount, oldestAccessTime } = processor.getStateStats() ``` 戻り値: `{ threadCount: number; oldestAccessTime: number | null }` #### `cleanupNow()` スケジュールされた実行を待たず、TTL クリーンアップをすぐに実行します。 ```typescript const cleaned = processor.cleanupNow() ``` 戻り値: `number`: クリーンアップされた thread の数。 ## リクエスト対応のフィルタリング 実行時定義の Tool にリクエスト固有のポリシーを適用するには、`filter` を使用します。フックは、解決された Tool ID を `toolName` として受け取るほか、Tool、request context、phase を受け取ります。`toolName` は `search_tools` が返す ID であり、`tools` オブジェクト内のキーとは異なる場合があります。 ```typescript 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 を検索する `tools` オプションは構築時に固定されるため、リクエストごとにのみ存在する Tool(呼び出し元の認証情報が必要な MCP Tool や、動的な `tools` 関数が返す Tool)を列挙できません。デフォルトでは、これらの Tool は検索を経由せず、毎ターンでプロンプト領域を占有します。 リクエスト用にインデックス化し、Agent が読み込むまでプロンプトから除外するには、`includeResolvedTools: true` を設定します。 ```typescript 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 も、呼び出す前に検索で見つける必要があります。 ## 詳細な使用例 ```typescript 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 のワークフローは次のとおりです。 1. Agent がユーザーメッセージを受け取る 2. Agent がキーワード(例:「github issue」)を指定して `search_tools` を呼び出す 3. Agent が結果を確認し、Tool 名を指定して `load_tool` を呼び出す 4. 読み込まれた Tool が次のターンから利用可能になる 5. Agent が通常どおり読み込んだ Tool を使用する ## `autoLoad` による1ステップの検出 個別の読み込みステップを省略するには、`search.autoLoad` を `true` に設定します。`search_tools` が返した Tool はすぐに有効化され、`load_tool` メタ Tool は公開されません。検出ごとにモデルのターンが1回減るため、トークン使用量とレイテンシーが低下し、どの Provider でも同じように動作します。 ```typescript const toolSearch = new ToolSearchProcessor({ tools: allTools, search: { topK: 3, autoLoad: true, }, }) ``` `autoLoad` を使用したワークフローは次のようになります。 1. Agent がユーザーメッセージを受け取る 2. Agent がキーワードを指定して `search_tools` を呼び出す 3. 一致した Tool が自動的に有効化され、次のターンから利用可能になる 4. Agent が通常どおり Tool を使用する 一致したすべての Tool が有効になるため、Agent が必要としない Tool の追加を避けるには、`topK` を小さく(たとえば `3` に)設定してください。有効化された Tool は既存の Tool の後に追加されるため、prompt caching をサポートする Provider では、キャッシュ済みプロンプトの prefix が安定します。 ## 読み込み済み Tool のストレージ `storage` オプションは、読み込み済み Tool のセットを追跡する場所を制御します。デフォルトは `'in-memory'` です。`'context'` ストアはオプトインです。 ### `'in-memory'`(デフォルト) 読み込み済み Tool は thread ごとのインメモリマップで追跡され、`ttl` オプション(デフォルトは1時間)に基づいてクリーンアップされます。これは従来の動作です。 - Memory の設定は不要です。 - プロセスを再起動すると状態は失われます。 - thread ID がないリクエストは単一の `'default'` エントリを共有します。 このストアの確認やリセットには、`clearState`、`clearAllState`、`getStateStats`、`cleanupNow` を使用します。 ### `'context'` 読み込み済み状態は会話メッセージから導出されます。Tool 名を含む `search_tools` または `load_tool` の結果がメッセージに残っている間、その Tool は読み込み済みになります。このモードには次の特性があります。 - Memory の設定は不要です。 - 再起動に耐えます。永続的な記録は、保存されたメッセージ履歴です。 - その結果がメッセージからなくなると、Tool は自動的にアンロードされます。 ```typescript 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 との組み合わせ ```typescript 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), ], }) ``` ## 関連情報 - [Processors](https://mastra.zisheng.pro/ja/docs/agents/processors) - [Tool の使用](https://mastra.zisheng.pro/ja/docs/agents/using-tools)