ToolSearchProcessor
ToolSearchProcessor 是一種輸入處理器,可探索並載入執行階段定義的 Tool。它不會預先將所有 Tool 提供給 Agent,而是提供兩個中繼 Tool(search_tools 和 load_tool),讓 Agent 能依需求尋找並載入 Tool。使用大型 Tool 程式庫時,這能減少情境 token 用量。
使用範例「使用範例」的直接連結
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」的直接連結
清除單一對話串的已載入 Tool 狀態。
processor.clearState('thread-123')
clearAllState()「clearallstate」的直接連結
清除所有對話串的已載入 Tool 狀態。
processor.clearAllState()
getStateStats()「getstatestats」的直接連結
回傳追蹤中的對話串數量與最早存取時間,供記憶體增長偵錯使用。
const { threadCount, oldestAccessTime } = processor.getStateStats()
回傳:{ threadCount: number; oldestAccessTime: number | null }
cleanupNow()「cleanupnow」的直接連結
立即執行 TTL 清除,不等待排定的掃描。
const cleaned = processor.cleanupNow()
回傳:number:已清除的對話串數量。
可感知請求的篩選「可感知請求的篩選」的直接連結
使用 filter 對執行階段定義的 Tool 套用請求專屬原則。掛鉤會接收解析後的 Tool ID(toolName)、Tool、請求情境和階段。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:阻止load_tool載入不允許的 Tool。active:若已載入的 Tool 不再獲得允許,針對目前請求將它隱藏。
如果掛鉤擲回錯誤或遭拒,ToolSearchProcessor 會將該 Tool 視為不允許用於此請求。掛鉤可能會為每個相符的搜尋候選項目執行,因此非同步原則檢查應保持輕量或使用快取。search_tools 中繼 Tool 一律可用。除非啟用 search.autoLoad,否則 load_tool 也可使用。直接透過 Agent 或 processInputStep 傳入的 Tool 仍可使用,除非在 ToolSearchProcessor 之外加以篩選,或啟用 includeResolvedTools。
搜尋為請求解析的 Tool「搜尋為請求解析的 Tool」的直接連結
tools 選項在建構時就會固定,因此無法列出僅存在於個別請求的 Tool(例如需要呼叫端憑證的 MCP Tool,或動態 tools 函式回傳的任何項目)。根據預設,這些 Tool 會略過搜尋,並在每一輪占用提示詞空間。
設定 includeResolvedTools: true,可為這些 Tool 建立該請求的索引,並在 Agent 載入前不將其放入提示詞:
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 的執行個體。
此選項會套用至為請求解析的每個 Tool,包括記憶體、Workspace、Skill 與瀏覽器 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 進行單步驟探索「single-step-discovery-with-autoload」的直接連結
將 search.autoLoad 設為 true,即可略過個別載入步驟。search_tools 回傳的 Tool 會立即啟用,而且不會公開 load_tool 中繼 Tool。每次探索可省去一輪模型互動,減少 token 用量與延遲,而且在不同 Provider 上的運作方式相同。
const toolSearch = new ToolSearchProcessor({
tools: allTools,
search: {
topK: 3,
autoLoad: true,
},
})
使用 autoLoad 時,作業流程如下:
- Agent 收到使用者訊息
- Agent 使用關鍵字呼叫
search_tools - 相符的 Tool 會自動啟用,並在下一輪可用
- Agent 以一般方式使用 Tool
每個相符項目都會啟用,因此 topK 應保持較小(例如 3),避免加入 Agent 不需要的 Tool。啟用的 Tool 會附加在現有 Tool 之後,讓支援提示詞快取的 Provider 能維持穩定的快取提示詞前綴。
已載入 Tool 的儲存方式「已載入 Tool 的儲存方式」的直接連結
storage 選項控制已載入 Tool 集合的追蹤位置。預設為 'in-memory',而 'context' 儲存區需選擇加入。
'in-memory'(預設)「in-memory-default」的直接連結
已載入的 Tool 會在記憶體內對應表中依對話串追蹤,並由 ttl 選項控制以 TTL 為基礎的清除(預設一小時)。這是原本的行為:
- 不需要記憶體設定。
- 處理程序重新啟動時,狀態會遺失。
- 沒有對話串 ID 的請求會共用單一
'default'項目。
使用 clearState、clearAllState、getStateStats 和 cleanupNow 檢查或重設此儲存區。
'context'「context」的直接連結
已載入狀態會從對話訊息衍生:只要訊息中仍有提及 Tool 名稱的 search_tools 或 load_tool 結果,該 Tool 就會保持載入。此模式:
- 不需要記憶體設定。
- 可承受重新啟動:保存的訊息歷史記錄就是持久記錄。
- 一旦該結果不再出現在訊息中,就會自動卸載 Tool。
import { ToolSearchProcessor } from '@mastra/core/processors'
const toolSearch = new ToolSearchProcessor({
tools: allTools,
storage: 'context',
})
兩種模式載入 Tool 時都適合使用快取:載入只會附加內容,因此支援提示詞快取的 Provider 能維持穩定的快取提示詞前綴。
卸載 Tool 會改變傳送給模型的 Tool 定義,使快取前綴發生位移,導致下一輪需要寫入快取,而非命中快取。在 'in-memory' 模式中,對話串狀態因 ttl 被逐出時會發生此情況。在 'context' 模式中,Tool 探索結果不再出現在訊息中時會發生此情況(例如刪減較舊訊息時)。Tool 會卸載,模型必須重新搜尋才能再次使用。這是預期行為:移除未使用的 Tool,是以一次快取寫入換取後續輪次較小的前綴。
與其他處理器搭配使用「與其他處理器搭配使用」的直接連結
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),
],
})