跳到主要内容

Tool

Agent 使用 Tool 调用 API、查询数据库或运行代码库中的自定义函数。Tool 通过提供结构化的数据访问和执行定义明确的操作,为 Agent 增加语言生成之外的能力。你还可以从远程 MCP 服务器加载 Tool,扩展 Agent 的能力。

何时使用 Tool
何时使用 Tool的直接链接

当 Agent 需要来自远程资源的额外上下文或信息,或需要运行执行特定操作的代码时,请使用 Tool。这包括模型自身无法可靠处理的任务,例如获取实时数据,或返回一致且定义明确的输出。

快速开始
快速开始的直接链接

@mastra/core/tools 导入 createTool,并使用 iddescriptioninputSchemaoutputSchemaexecute 函数定义 Tool。

此示例创建一个从 API 获取天气数据的 Tool。execute 函数接收经过 inputSchema 验证的输入作为第一个参数,并接收可选的执行上下文作为第二个参数。你可以直接在函数签名中解构输入字段。

src/mastra/tools/weather-tool.ts
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 }, { abortSignal }) => {
const response = await fetch(`https://wttr.in/${location}?format=j1`, {
signal: abortSignal,
})
const data = await response.json()

return {
location,
temperatureCelsius: Number(data.current_condition[0].temp_C),
conditions: data.current_condition[0].weatherDesc[0].value,
}
},
})

创建 Tool 时,请保持描述简洁并聚焦于 Tool 的功能,突出其主要用例。描述清晰的 schema 名称也有助于指导 Agent 使用 Tool。有关可用属性、配置和示例的更多信息,请参阅 createTool 参考。

要让 Agent 可以使用 Tool,请将其添加到 Agent 类的 tools 属性。在 Agent 的系统提示词中说明可用 Tool 及其一般用途,有助于 Agent 判断何时应该调用 Tool、何时不应调用。

src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant.
Use the weatherTool to fetch current weather data.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})

定义 schema
定义 schema的直接链接

你可以使用任何支持 Standard JSON Schema 的库定义 Tool 的 inputSchemaoutputSchema,包括 ZodValibotArkType 等库。

src/mastra/tools/weather-tool.ts
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' }
},
})

多个 Tool
多个 Tool的直接链接

Agent 可以使用多个 Tool 处理更复杂的任务,将特定部分委派给各个 Tool。Agent 会根据用户消息、Agent 指令,以及 Tool 描述和 schema 来决定使用哪些 Tool。

src/mastra/agents/weather-agent.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'
import { hazardsTool } from '../tools/hazards-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: `
You are a helpful weather assistant.
Use the weatherTool to fetch current weather data.
Use the hazardsTool to provide information about potential weather hazards.`,
model: 'openai/gpt-5.6-sol',
tools: { weatherTool, hazardsTool },
})

将 Agent 用作 Tool
将 Agent 用作 Tool的直接链接

通过 agents 配置添加子 Agent,以创建 Supervisor。Mastra 会将每个子 Agent 转换为 agent-<key> Tool。请为每个子 Agent 添加 description,使 Supervisor 知道何时委派任务。

src/mastra/agents/supervisor.ts
import { Agent } from '@mastra/core/agent'

const writer = new Agent({
id: 'writer',
name: 'Writer',
description: 'Drafts and edits written content',
instructions: 'You are a skilled writer.',
model: 'openai/gpt-5.6-sol',
})

export const supervisor = new Agent({
id: 'supervisor',
name: 'Supervisor',
instructions: 'Coordinate the writer to produce content.',
model: 'openai/gpt-5.6-sol',
agents: { writer },
})

将 Workflow 用作 Tool
将 Workflow 用作 Tool的直接链接

通过 workflows 配置添加 Workflow。Mastra 会将每个 Workflow 转换为使用该 Workflow 的 inputSchemaoutputSchemaworkflow-<key> Tool。请为 Workflow 添加 description,使 Agent 知道何时触发它。

src/mastra/agents/research-agent.ts
import { Agent } from '@mastra/core/agent'
import { researchWorkflow } from '../workflows/research-workflow'

export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Agent',
instructions: 'You are a research assistant.',
model: 'openai/gpt-5.6-sol',
workflows: { researchWorkflow },
})

在多个 Agent 之间共享 Tool
在多个 Agent 之间共享 Tool的直接链接

当多个 Agent 使用同一 Tool 时,直接导入是最佳选择。每个 Agent 都会导入该 Tool,并将其添加到自己的 tools 记录中。这样依赖关系保持明确,每个 Agent 也可以独立使用。

src/mastra/tools/weather-tool.ts
import { createTool } from '@mastra/core/tools'

export const weatherTool = createTool({
id: 'weather-tool',
// Rest of the tool definition...
})
src/mastra/agents/weather-agents.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const weatherAgent = new Agent({
id: 'weather-agent',
name: 'Weather Agent',
instructions: 'Answer questions about current weather.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})
src/mastra/agents/travel-agents.ts
import { Agent } from '@mastra/core/agent'
import { weatherTool } from '../tools/weather-tool'

export const travelAgent = new Agent({
id: 'travel-agent',
name: 'Travel Agent',
instructions: 'Help users plan trips.',
model: 'openai/gpt-5.6-sol',
tools: { weatherTool },
})

如果需要从 Mastra 实例访问 Tool,请参阅 Mastra.getTool()Mastra.getToolById()Mastra.listTools()Agent 参考

为模型调整输出形状
为模型调整输出形状的直接链接

当 Tool 为应用返回丰富的结构化数据,但你希望模型接收更小或多模态的表示时,请使用 toModelOutput。这样既能让模型上下文保持聚焦,又能在应用中保留完整的 Tool 结果。

src/mastra/tools/weather-tool.ts
export const weatherTool = createTool({
execute: async ({ location }) => {
const response = await fetch(`https://wttr.in/${location}?format=j1`)
const data = await response.json()

return {
location,
temperatureCelsius: Number(data.current_condition[0].temp_C),
conditions: data.current_condition[0].weatherDesc[0].value,
weatherIconUrl: data.current_condition[0].weatherIconUrl[0].value,
source: data,
}
},
toModelOutput: output => {
return {
type: 'content',
value: [
{
type: 'text',
text: `${output.location}: ${output.temperatureCelsius}°C and ${output.conditions}`,
},
{ type: 'image-url', url: output.weatherIconUrl },
],
}
},
})

toModelOutput 也适用于通过 clientTools 传入的客户端 Tool。映射会在 Tool 执行后于客户端运行,转换后的输出会与原始结果一起发回服务器。

为 UI 和对话记录转换 Tool payload
为 UI 和对话记录转换 Tool payload的直接链接

当 Tool 返回应用所需的原始数据,但面向浏览器的流或用户可见的对话记录消息应接收更小或更安全的形状时,请使用 transformtransformtoModelOutput 相互独立:toModelOutput 调整发回模型的 payload,而 transform 则为 displaytranscript 目标调整 Tool 输入、输出、错误、批准 payload 和暂停 payload。

如果配置的转换失败,Mastra 不会为 display 或 transcript 目标回退到原始 payload。如果没有安全的 inputDelta 转换,输入增量将被抑制。

有关 transform 示例,请参阅 createTool() 参考。对于多个 Tool 之间的共享规则,请在 Agent 构造函数中配置 Agent 级 transform 策略。

在 Tool 调用前后运行逻辑
在 Tool 调用前后运行逻辑的直接链接

使用 hooks 在 Agent 每次调用 Tool 前后运行自定义逻辑。hook 适用于所有 Tool 来源:已分配 Tool、Memory Tool、Tool 集、客户端 Tool、Agent 和 Workflow Tool,以及 Workspace Tool。常见用途包括日志记录、审计、输入验证和阻止特定调用。

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'

export const supportAgent = new Agent({
id: 'support-agent',
name: 'support-agent',
instructions: 'Help users with their questions.',
model: 'openai/gpt-5.6-sol',
hooks: {
beforeToolCall: ({ toolName, input }) => {
console.log(`Running ${toolName}`, input)
},
afterToolCall: ({ toolName, output, error }) => {
console.log(`Finished ${toolName}`, { output, error })
},
},
})

beforeToolCall 在 Tool 执行前运行,并接收 Tool 名称、输入和执行上下文。返回 { proceed: false, output } 可完全跳过 Tool 调用,Agent 会将 output 作为 Tool 结果接收:

const guardedAgent = new Agent({
id: 'guarded-agent',
name: 'guarded-agent',
instructions: 'Run shell commands for the user.',
model: 'openai/gpt-5.6-sol',
hooks: {
beforeToolCall: ({ toolName, input }) => {
const command = (input as { command?: string }).command ?? ''
if (toolName === 'execute_command' && command.includes('rm -rf')) {
return { proceed: false, output: 'Command blocked by policy.' }
}
},
},
})

无论 Tool 成功还是失败,afterToolCall 都会在 Tool 完成后运行。成功时接收 output;如果 Tool 抛出异常,则改为接收 error,并在 hook 运行后重新抛出该错误。

每次执行的 hook
每次执行的 hook的直接链接

.generate().stream() 传入 hooks,为单次执行设置 hook。每次执行的 hook 会覆盖匹配的 Agent 级 hook:

await supportAgent.generate('Look up the order status', {
hooks: {
beforeToolCall: ({ toolName }) => {
console.log(`This run only: ${toolName}`)
},
},
})

Agent 级 hook 和每次执行的 hook 按键合并:执行时仅传入 beforeToolCall,会保留 Agent 级 afterToolCall

流式传输
流式传输的直接链接

Tool 支持生命周期 hook,让你可以在流式传输期间监控 Tool 执行的不同阶段。这些 hook 特别适合日志记录或分析。

有关通用 writer API 用法,请参阅流式传输

可用 hook
可用 hook的直接链接

  • onInputStart:Tool 调用输入开始流式传输时调用
  • onInputDelta:输入流式到达时,对每个输入块调用
  • onInputAvailable:完整输入完成解析和验证时调用
  • onOutput:Tool 成功执行并产生输出后调用

有关所有生命周期 hook 的详细文档,请参阅 createTool() 参考

示例:使用 onInputAvailableonOutput
example-using-oninputavailable-and-onoutput的直接链接

import { createTool } from '@mastra/core/tools'
import { z } from 'zod'

export const weatherTool = createTool({
id: 'weather-tool',
description: 'Get weather information',
inputSchema: z.object({
location: z.string(),
}),
outputSchema: z.object({
location: z.string(),
temperatureCelsius: z.number(),
conditions: z.string(),
}),
// Called when the complete input is available
onInputAvailable: ({ input, toolCallId }) => {
console.log(`Weather requested for: ${input.location}`)
},
execute: async ({ location }) => {
const weather = await fetchWeather(location)
return weather
},
// Called after successful execution
onOutput: ({ output, toolName }) => {
console.log(`${toolName} result: ${output.temperatureCelsius}°C, ${output.conditions}`)
},
})

在 UI 中流式传输 Tool 输入
在 UI 中流式传输 Tool 输入的直接链接

模型生成 Tool 调用时,参数会在最终 tool-call 块之前,以 tool-call-delta 流块的形式增量到达。UI 可以监听相应的 tool_input_starttool_input_deltatool_input_end 事件,在 Tool 参数流式到达时进行渲染。例如,可以立即显示文件路径或命令,而无需等待完整的 Tool 调用。

对累积的 argsTextDelta 片段使用部分 JSON 解析器,可以在 JSON 完整之前提取可用的参数值。这样可以实现编辑 Tool 的实时 diff 预览、写入 Tool 的文件内容流式传输,以及即时显示搜索模式或文件路径等功能。

控制 Tool 选择
控制 Tool 选择的直接链接

.generate().stream() 传入 toolChoiceactiveTools,控制 Agent 在运行时使用哪些 Tool。

await agent.generate('Check the forecast', {
toolChoice: 'required',
activeTools: ['weatherTool'],
})

有关包括 toolsetsclientToolsprepareStep 在内的所有运行时选项,请参阅 Agent.generate() 参考

控制流响应中的 toolName
control-toolname-in-stream-responses的直接链接

流响应中的 toolName 由你使用的对象键决定,而不是 Tool、Agent 或 Workflow 的 id 属性。

export const weatherTool = createTool({
id: 'weather-tool',
})

// Using the variable name as the key
tools: { weatherTool }
// Stream returns: toolName: "weatherTool"

// Using the tool's id as the key
tools: { [weatherTool.id]: weatherTool }
// Stream returns: toolName: "weather-tool"

// Using a custom key
tools: { "my-custom-name": weatherTool }
// Stream returns: toolName: "my-custom-name"

这样可以指定 Tool 在流中的标识方式。如果希望 toolName 与 Tool 的 id 一致,请使用 Tool 的 id 作为对象键。

将子 Agent 和 Workflow 用作 Tool
将子 Agent 和 Workflow 用作 Tool的直接链接

子 Agent 和 Workflow 遵循相同模式。它们会被转换为以相应前缀加对象键命名的 Tool:

属性前缀示例键toolName
agentsagent-weatheragent-weather
workflowsworkflow-researchworkflow-research
const orchestrator = new Agent({
id: 'orchestrator',
agents: {
weather: weatherAgent, // toolName: "agent-weather"
},
workflows: {
research: researchWorkflow, // toolName: "workflow-research"
},
})

请注意,对于子 Agent,流响应中会出现两个不同的标识符:

  • Tool 调用事件中的 toolName: "agent-weather":生成的 Tool 包装器名称
  • data-tool-agent 块中的 id: "weather-agent":子 Agent 实际的 id 属性

内置 Tool
内置 Tool的直接链接

Mastra 在 @mastra/core/tools 中提供与具体 Agent 无关的内置 Tool,可为任何 Agent 添加交互和组织能力。

Tool用途
ask_user向用户提问并等待回答
submit_plan提交计划文件以供用户批准
task_write创建或替换结构化任务列表
task_update按 ID 更新一项跟踪任务
task_complete将一项跟踪任务标记为已完成
task_check检查任务列表完成状态
webSearchTool使用当前模型运行 Provider 原生网页搜索
webFetchTool按 URL 获取网页并返回其文本内容

希望模型 Provider 运行其原生网页搜索 Tool 时,请从 @mastra/core/tools 导入 webSearchTool。Mastra 会在运行时根据当前模型解析它,然后将由 Provider 管理的 Tool 传递给模型。

src/mastra/agents/research-agent.ts
import { Agent } from '@mastra/core/agent'
import { webSearchTool } from '@mastra/core/tools'

export const researchAgent = new Agent({
id: 'research-agent',
name: 'Research Agent',
instructions: 'Use web search when you need current information.',
model: 'openai/gpt-5.6-sol',
tools: {
search: webSearchTool,
},
})

webSearchTool 支持 OpenAI、Anthropic、Google Gemini 和 xAI 模型。如果 Mastra 无法从当前模型推断出这些 Provider 之一,Agent 运行会失败并抛出 MastraError

search 键只是 Agent 本地的 Tool 名称,可以使用任意键。webSearchTool 值会告诉 Mastra 使用 Provider 网页搜索。

获取网页
获取网页的直接链接

当 Agent 需要读取特定 URL 时,请从 @mastra/core/tools 导入 webFetchTool。该 Tool 通过 HTTP 或 HTTPS 请求页面,并返回文本内容和响应元数据。

src/mastra/agents/reader-agent.ts
import { Agent } from '@mastra/core/agent'
import { webFetchTool } from '@mastra/core/tools'

export const readerAgent = new Agent({
id: 'reader-agent',
name: 'Reader Agent',
instructions: 'Fetch the page the user links to before answering.',
model: 'openai/gpt-5.6-sol',
tools: {
fetch: webFetchTool,
},
})

该 Tool 接受单个 url 输入,并返回 contenttruncatedstatusstatusTextcontentTypeurlok。它应用以下限制:

  • 只允许 http:https: URL。
  • 阻止对 localhost 以及私有或保留 IP 地址的请求,包括 DNS 解析返回的地址。
  • 响应会在 100,000 个字符处截断,结果中会包含 truncated: true
  • 请求最多跟随 5 次重定向,并在 15 秒后超时。

失败不会抛出异常。该 Tool 会返回 isError: true,并在 content 中提供原因,使 Agent 能够重试或解释问题。

向用户提问
向用户提问的直接链接

导入 askUserTool,并将其添加到 Agent 的 Tool 集。

该 Tool 会暂停运行,并发出包含问题的 tool-call-suspended 事件。当你使用用户答案调用 resumeStream() 时,运行将恢复。

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { askUserTool } from '@mastra/core/tools'

const agent = new Agent({
id: 'assistant',
name: 'Assistant',
instructions: 'Ask the user for clarification when the request is ambiguous.',
model,
tools: { askUserTool },
})

流式运行 Agent 并监听 tool-call-suspended 块。suspendPayload 包含问题和可选的结构化选项:

src/run.ts
const stream = await agent.stream('Summarize my project')

for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended') {
const { question, options } = chunk.payload.suspendPayload
console.log(question)
const answer = await getUserAnswer() // your UI logic
const resumed = await agent.resumeStream(answer, { runId: stream.runId })
for await (const c of resumed.textStream) process.stdout.write(c)
}
}

askUserTool 支持自由文本、单选(options 数组)和多选(selectionMode: 'multi_select')提示。将其与 autoResumeSuspendedTools 搭配使用,可让 Agent 根据用户的下一条聊天消息自动恢复。有关详细信息,请参阅 Tool 自动恢复

提交计划以供审查
提交计划以供审查的直接链接

导入 submitPlanTool,让 Agent 将计划写入文件并提交给用户审查。该 Tool 会暂停运行,直到用户批准或拒绝:

src/run.ts
for await (const chunk of stream.fullStream) {
if (chunk.type === 'tool-call-suspended' && chunk.payload.toolName === 'submit_plan') {
const { path } = chunk.payload.suspendPayload
// Read and display the plan file, then resume:
const resumed = await agent.resumeStream({ action: 'approved' }, { runId: stream.runId })
for await (const c of resumed.textStream) process.stdout.write(c)
}
}

任务跟踪
任务跟踪的直接链接

任务 Tool 为 Agent 运行管理结构化、持久的任务列表。它们需要 Memory,以便将列表持久化到线程作用域的存储中。

通过 TaskSignalProvider 添加任务跟踪,它将全部四个 Tool 和 TaskStateProcessor 捆绑在一次注册中:

src/mastra/agents/index.ts
import { Agent } from '@mastra/core/agent'
import { Memory } from '@mastra/memory'
import { TaskSignalProvider } from '@mastra/core/signals'

const agent = new Agent({
id: 'coder',
name: 'Coder',
instructions: 'Track your progress with the task tools.',
model,
memory: new Memory(),
signals: [new TaskSignalProvider()],
})

同一时间只能有一个任务处于 in_progress 状态。列表存储在线程作用域的 threadState 存储域中,并投影到 Agent 的 state-signal 通道,因此在观察 Memory 截断后仍会保留。有关完整 schema,请参阅任务 Tool 参考

AgentController 在每种模式下都会自动包含所有内置 Tool,无需手动添加。有关 AgentController 专用行为,请参阅 Tool 批准