> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # createTool() `createTool()` 函數用於定義 Mastra Agent 可執行的自訂 Tool。Tool 可讓 Agent 與外部系統互動或進行計算,從而擴展其功能。Tool 亦可存取特定資料。 ## 使用範例 ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Get the current weather for a location', inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny', } }, }) ``` 第一個 `execute` 參數是經 `inputSchema` 驗證的值。請直接在函數簽名中解構 schema 欄位,如 `{ location }` 所示。可選的第二個參數包含執行 context。 ## 參數 **id** (`string`): Tool 的唯一識別符。 **description** (`string`): 說明 Tool 的用途。Agent 會據此決定何時使用該 Tool。 **inputSchema** (`StandardJSONSchemaV1`): 定義 Tool 的 execute 函數預期輸入參數的 Standard JSON Schema。 **outputSchema** (`StandardJSONSchemaV1`): 定義 Tool 的 execute 函數預期輸出結構的 Standard JSON Schema。 **strict** (`boolean`): 設為 true 時,Mastra 會在支援此功能的模型 adapter 上啟用嚴格 Tool 輸入產生。這有助支援的 Provider 傳回更符合 Tool schema 的引數。 **toModelOutput** (`(output: TSchemaOut) => unknown`): 可選函數,用於在 Tool 的 execute 輸出傳回模型前進行轉換。使用此函數可向模型傳回 text、json 或 content 形式的輸出(包括圖片/檔案等多模態部分),同時在應用程式碼中保留完整的原始輸出。 **transform** (`ToolPayloadTransform`): 可選的目標感知轉換,在 Tool payload 離開 runtime 並送往顯示 stream 或使用者可見的 transcript 訊息前套用。可為 input、inputDelta、output、error、approval、suspend 及 resume 等階段設定 display 和 transcript 轉換。 **suspendSchema** (`StandardJSONSchemaV1`): 定義傳遞至 suspend() 的 payload 結構的 Standard JSON Schema。Tool 暫停執行時,此 payload 會傳回 client。 **resumeSchema** (`StandardJSONSchemaV1`): 定義 Tool 恢復執行時 resumeData 預期結構的 Standard JSON Schema。啟用 autoResumeSuspendedTools 時,Agent 會用它從使用者訊息擷取資料。 **requireApproval** (`boolean`): 設為 true 時,Tool 執行前需要明確批准。Agent 會發出 tool-call-approval chunk,並暫停直至獲批准或被拒絕。 **mcp** (`MCPToolProperties`): 透過 Model Context Protocol 公開的 Tool 所使用的 MCP 專屬屬性。包括 annotations(例如 title、readOnlyHint、destructiveHint、idempotentHint、openWorldHint 等 Tool 行為提示)及 \_meta(原樣傳遞至 MCP client 的任意 metadata)。 **requestContextSchema** (`StandardJSONSchemaV1`): 用於驗證 request context 值的 Standard JSON Schema。提供此項時,系統會在 execute() 執行前驗證 context;若驗證失敗,便會傳回錯誤物件。 **providerOptions** (`Record>`): 使用此 Tool 時傳遞至模型的 Provider 專屬選項。key 是 Provider 名稱,例如 anthropic 或 openai;value 則是該 Provider 專屬的設定物件。 **inputExamples** (`Array<{ input: Record }>`): 有效 Tool 輸入的範例,支援的模型 Provider 可將其用作輸入範例。 **background** (`ToolBackgroundConfig`): 此 Tool 的背景工作設定。啟用後,Tool 可在 Agent 對話繼續期間於背景執行。 **execute** (`function`): 包含 Tool 邏輯的函數。一般自訂 Tool 通常會提供 execute,但對於在其他地方執行或調整的 Tool 定義,此類型允許省略該函數。它接收兩個參數:根據 inputSchema 驗證的輸入資料(第一個參數),以及包含 requestContext、abortSignal 和其他執行 metadata 的執行 context 物件(第二個參數)。 **execute.input** (`z.infer`): 根據 inputSchema 驗證的輸入資料 **execute.context** (`ToolExecutionContext`): 包含 metadata 的可選執行 context **execute.context.requestContext** (`RequestContext`): 用於存取共享狀態及相依項目的 Request Context **execute.context.abortSignal** (`AbortSignal`): 用於中止 Tool 執行的 signal **execute.context.agent** (`AgentToolExecutionContext`): Agent 專屬 context,在 Tool 由 Agent 執行時可用。 **execute.context.workflow** (`WorkflowToolExecutionContext`): Workflow 專屬 context(state、setState、suspend 等) **execute.context.mcp** (`MCPToolExecutionContext`): MCP 專屬 context(elicitation 等) **execute.context.observe** (`ToolObserve`): 用於從 Tool 的 execute 函數內記錄子 span 及結構化 log 的 observability helper。系統必定提供此項;沒有啟用 tracing context 時,span 會直接執行函數,而 log 則不會執行任何操作。 **onInputStart** (`function`): Tool 呼叫的輸入串流開始時觸發的可選 callback。簽名:(options: ToolCallOptions) => void | PromiseLike\。 **onInputDelta** (`function`): 輸入文字串流傳入時,針對每個增量 chunk 觸發的可選 callback。簽名:({ inputTextDelta, ...options }: { inputTextDelta: string } & ToolCallOptions) => void | PromiseLike\。 **onInputAvailable** (`function`): 完整 Tool 輸入可用並已完成解析時觸發的可選 callback。簽名:({ input, ...options }: { input: TSchemaIn } & ToolCallOptions) => void | PromiseLike\。 **onOutput** (`function`): Tool 成功執行並傳回輸出後觸發的可選 callback。簽名:({ output, toolName, ...options }: { output: TSchemaOut; toolName: string } & Omit\) => void | PromiseLike\。 原始碼類型中會出現 `mastra` 和 `mcpMetadata` 等由 runtime 填入的欄位,但這些欄位由 Mastra 或 MCP adapter 設定。一般使用 `createTool()` 時毋須設定。 ## 傳回值 `createTool()` 函數會傳回 `Tool` 物件。 **Tool** (`object`): 代表已定義 Tool 的物件,可隨時加入 Agent。 ## 定義 schema 你可以使用任何支援 [Standard JSON Schema](https://standardschema.dev/json-schema) 的程式庫,定義 Tool 的 `inputSchema` 和 `outputSchema`。這包括 [Zod](https://zod.dev/)、[Valibot](https://valibot.dev/) 和 [ArkType](https://arktype.io/) 等程式庫。 **Zod**: ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Fetches weather for a location', inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny' } }, }) ``` **Valibot**: ```typescript import { createTool } from '@mastra/core/tools' import * as v from 'valibot' import { toStandardJsonSchema } from '@valibot/to-json-schema' export const weatherTool = createTool({ id: 'weather-tool', description: 'Fetches weather for a location', inputSchema: toStandardJsonSchema( v.object({ location: v.string(), }), ), outputSchema: toStandardJsonSchema( v.object({ location: v.string(), temperatureCelsius: v.number(), conditions: v.string(), }), ), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny' } }, }) ``` **ArkType**: ```typescript import { createTool } from '@mastra/core/tools' import { type } from 'arktype' export const weatherTool = createTool({ id: 'weather-tool', description: 'Fetches weather for a location', inputSchema: type({ location: 'string', }), outputSchema: type({ location: 'string', temperatureCelsius: 'number', conditions: 'string', }), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny' } }, }) ``` ## 嚴格 Tool 輸入範例 如要 Mastra 要求支援的模型 Provider 產生與 Tool schema 完全相符的引數,請設定 `strict: true`。 ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Get the current weather for a location', strict: true, inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny', } }, }) ``` Mastra 會將 `strict: true` 傳遞至支援嚴格 Tool 呼叫的模型 adapter。對於不支援嚴格 Tool 呼叫的 adapter,Mastra 會忽略此選項。 ## `toModelOutput` 範例 如果 Tool 應向應用程式傳回豐富的內部資料,但模型只應接收簡化值或多模態內容,請使用 `toModelOutput`。 ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Get the current weather for a location', inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), radarImageUrl: z.string().url(), }), execute: async ({ location }) => ({ location, temperatureCelsius: 21, conditions: 'sunny', radarImageUrl: 'https://example.com/radar/seattle.png', }), toModelOutput: output => { return { type: 'content', value: [ { type: 'text', text: `${output.location}: ${output.temperatureCelsius}°C and ${output.conditions}`, }, { type: 'image-url', url: output.radarImageUrl }, ], } }, }) ``` Tool 仍會向應用程式傳回完整的 `execute` 結果,而模型會接收經轉換的 `toModelOutput` 值。 `toModelOutput` 可傳回: - `type: 'text'` - `type: 'json'` - `type: 'content'` with parts like `text`, `image-url`, `image-data`, `file-url`, `file-data`, `file-id`, `image-file-id`, or `custom` ## `transform` 範例 如果 Tool 應為 runtime 行為保留原始輸入或輸出,但顯示 stream 或 transcript 訊息應接收更精簡或安全的結構,請使用 `transform`。 ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const customerTool = createTool({ id: 'lookup-customer', description: 'Looks up a customer', inputSchema: z.object({ customerId: z.string(), internalPath: z.string(), }), outputSchema: z.object({ displayName: z.string(), apiKey: z.string(), debugScore: z.number(), }), execute: async () => { return { displayName: 'Acme', apiKey: 'secret-value', debugScore: 0.97, } }, transform: { display: { input: ({ input }) => ({ customerId: input?.customerId }), output: ({ output }) => ({ displayName: output?.displayName }), error: () => ({ message: 'Customer lookup failed' }), }, transcript: { input: ({ input }) => ({ customerId: input?.customerId }), output: ({ output }) => ({ displayName: output?.displayName }), error: () => ({ message: 'Customer lookup failed' }), }, }, }) ``` Tool 仍會接收原始 `inputSchema` 值並傳回原始 `execute` 結果。Mastra 會將 `display` 轉換套用至串流 UI payload,並將 `transcript` 轉換套用至使用者可見的 transcript 訊息。 ## MCP annotation 範例 透過 MCP (Model Context Protocol) 公開 Tool 時,你可以加入 annotation 以說明 Tool 行為,並自訂 client 顯示 Tool 的方式。這些 MCP 專屬屬性歸入 `mcp` 屬性: ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Get the current weather for a location', inputSchema: z.object({ location: z.string().describe('City name or coordinates'), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), // MCP-specific properties mcp: { // Annotations for client behavior hints annotations: { title: 'Weather Lookup', // Human-readable display name readOnlyHint: true, // Tool doesn't modify environment destructiveHint: false, // Tool doesn't perform destructive updates idempotentHint: true, // Same args = same result openWorldHint: true, // Interacts with external API }, // Custom metadata for client-specific functionality _meta: { version: '1.0.0', category: 'weather', }, }, execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny', } }, }) ``` ## Tool 生命週期 hook Tool 支援生命週期 hook,讓你監察 Tool 執行的不同階段並作出回應。這些 hook 尤其適合用於 logging、analytics、驗證,以及串流期間的即時更新。 以下範例示範已設定所有生命週期 hook 的 Tool: ```typescript import { createTool } from '@mastra/core/tools' import { z } from 'zod' export const weatherTool = createTool({ id: 'weather-tool', description: 'Get the current weather for a location', inputSchema: z.object({ location: z.string(), }), outputSchema: z.object({ location: z.string(), temperatureCelsius: z.number(), conditions: z.string(), }), execute: async ({ location }) => { return { location, temperatureCelsius: 21, conditions: 'sunny', } }, onInputStart: ({ toolCallId }) => { console.log(`Tool call ${toolCallId} input started`) }, onInputDelta: ({ inputTextDelta, toolCallId }) => { console.log(`Tool call ${toolCallId} received input chunk: ${inputTextDelta}`) }, onInputAvailable: ({ input, toolCallId }) => { console.log(`Tool call ${toolCallId} received location: ${input.location}`) }, onOutput: ({ output, toolCallId, toolName }) => { console.log(`Tool ${toolName} call ${toolCallId} returned conditions: ${output.conditions}`) }, }) ``` ### 可用的 hook #### `onInputStart` 在 Tool 呼叫的輸入串流開始時、接收任何輸入資料前呼叫。 ```typescript export const tool = createTool({ id: 'example-tool', description: 'Example tool with hooks', onInputStart: ({ toolCallId, messages, abortSignal }) => { console.log(`Tool ${toolCallId} input streaming started`) }, }) ``` #### `onInputDelta` 輸入文字串流傳入時,會針對每個增量 chunk 呼叫。適合用於顯示即時進度或解析部分 JSON。 ```typescript export const tool = createTool({ id: 'example-tool', description: 'Example tool with hooks', onInputDelta: ({ inputTextDelta, toolCallId, messages, abortSignal }) => { console.log(`Received input chunk: ${inputTextDelta}`) }, }) ``` #### `onInputAvailable` 完整 Tool 輸入可用,並已根據 `inputSchema` 完成解析及驗證時呼叫。 ```typescript export const tool = createTool({ id: 'example-tool', description: 'Example tool with hooks', inputSchema: z.object({ location: z.string(), }), onInputAvailable: ({ input, toolCallId, messages, abortSignal }) => { console.log(`Tool received complete input:`, input) // input is fully typed based on inputSchema }, }) ``` #### `onOutput` Tool 成功執行並傳回輸出後呼叫。適合用於記錄結果、觸發後續動作或 analytics。 ```typescript export const tool = createTool({ id: 'example-tool', description: 'Example tool with hooks', outputSchema: z.object({ result: z.string(), }), execute: async input => { return { result: 'Success' } }, onOutput: ({ output, toolCallId, toolName, abortSignal }) => { console.log(`${toolName} execution completed:`, output) // output is fully typed based on outputSchema }, }) ``` ### Hook 執行次序 一般串流 Tool 呼叫會按以下次序觸發 hook: 1. **onInputStart**: 輸入串流開始 2. **onInputDelta**: 在 chunk 傳入時呼叫多次 3. **onInputAvailable**: 完整輸入已完成解析及驗證 4. Tool 的 **execute** 函數執行 5. **onOutput**: Tool 已成功完成 ### Hook 參數 Hook callback 會接收以下由原始碼定義的參數結構: - `onInputStart`: 接收 `ToolCallOptions`,包括 `toolCallId`、`messages` 及 `abortSignal` 等欄位。 - `onInputDelta`: 接收 `{ inputTextDelta: string } & ToolCallOptions`。 - `onInputAvailable`: 接收 `{ input: TSchemaIn } & ToolCallOptions`,其中 `input` 的類型來自 `inputSchema`。 - `onOutput`: 接收 `{ output: TSchemaOut; toolName: string } & Omit`,其中 `output` 的類型來自 `outputSchema`。此 hook 不會接收 `messages`。 ### 錯誤處理 Hook 錯誤會被自動捕捉並記錄,但不會阻止 Tool 繼續執行。如果 hook 拋出錯誤,系統會將其記錄至 console,但不會令 Tool 呼叫失敗。 ## MCP Tool annotation 透過 Model Context Protocol (MCP) 公開 Tool 時,你可以提供說明 Tool 行為的 annotation。這些 annotation 可協助 OpenAI Apps SDK 等 MCP client 了解如何呈現及處理你的 Tool。 MCP 專屬屬性歸入 `mcp` 屬性,其中包括 `annotations` 和 `_meta`: ```typescript mcp: { annotations: { /* behavior hints */ }, _meta: { /* custom metadata */ }, } ``` ### `ToolAnnotations` 屬性 **title** (`string`): Tool 的人類可讀標題,用於 UI component 中的顯示用途。 **readOnlyHint** (`boolean`): 設為 true 時,Tool 不會修改其環境。此提示表示 Tool 只會讀取資料,而且沒有副作用。預設為 false。 **destructiveHint** (`boolean`): 設為 true 時,Tool 可能會對其環境進行破壞性更新。設為 false 時,Tool 只會進行增量更新。此提示協助 client 判斷是否需要確認。預設為 true。 **idempotentHint** (`boolean`): 設為 true 時,以相同引數重複呼叫 Tool 不會對其環境產生額外影響。此提示表示冪等行為。預設為 false。 **openWorldHint** (`boolean`): 設為 true 時,此 Tool 可與外部實體的「開放世界」互動(例如網頁搜尋、外部 API)。設為 false 時,Tool 的作用域是封閉且已完整定義。預設為 true。 這些 annotation 遵循 [MCP 規範](https://spec.modelcontextprotocol.io/specification/2025-03-26/server/tools/#tool-annotations),並會在透過 MCP 列出 Tool 時原樣傳遞。 ## 相關內容 - [MCP 概覽](https://mastra.zisheng.pro/zh-HK/docs/mcp/overview) - [在 Agent 中使用 Tool](https://mastra.zisheng.pro/zh-HK/docs/agents/using-tools) - [Agent 批准](https://mastra.zisheng.pro/zh-HK/docs/agents/agent-approval) - [Tool 串流](https://mastra.zisheng.pro/zh-HK/docs/agents/using-tools) - [Request Context](https://mastra.zisheng.pro/zh-HK/docs/server/request-context)