VoltAgent 工具体系实战指南:从 createTool 到 Toolkit 的完整工具箱构建
人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆【免费下载链接】voltagentAI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework项目地址https://gitcode.com/gh_mirrors/vo/voltagent点击查看免费下载本篇技术指南以 VoltAgent 官方文档 Tools Toolkits 概览 为主体系统讲解如何通过voltagent/core为 AI Agent 定义单个工具createTool、在工具内访问操作上下文、启用输出 Schema 校验以及使用新一代Toolkit概念对相关工具进行分组管理与指令注入。读完本文你将能够独立编写可接入外部 API、数据库或任意自定义代码的工具并以 Toolkit 形式组织复杂 Agent 的工具集同时理解底层 ToolManager 与系统提示词组装机制。为什么需要 Tools 与 ToolkitsVoltAgent 允许你通过Tools扩展 AI Agent 的能力边界工具让 Agent 能够调用外部 API、执行计算、访问数据库或运行几乎任何自定义代码。而在实际工程中若干工具往往在逻辑上协同工作例如用于逐步推理的think、analyze或与同一 API 交互的一组工具为此 VoltAgent 引入了Toolkit概念来统一管理相关工具。整体 API 入口集中在 packages/core/src/tool/index.ts工具管理逻辑位于 packages/core/src/tool/manager。定义一个单一工具定义工具最基本的方式是使用createTool辅助函数也可以直接实例化Tool类。一个工具必须包含以下要素name工具的唯一名称LLM 通过它来调用工具。description对工具功能的清晰描述LLM 据此决定何时使用它。parameters定义工具输入参数的 Zod Schema。execute包含工具逻辑的异步函数接收校验后的参数作为输入。outputSchema可选定义预期输出格式的 Zod Schema提供后工具输出将按此校验。import { Agent, createTool } from voltagent/core; import { z } from zod; // Define a simple weather tool const getWeatherTool createTool({ name: get_weather, description: Fetches the current weather for a given location., parameters: z.object({ location: z.string().describe(The city and state, e.g., San Francisco, CA), }), execute: async ({ location }) { // In a real scenario, you would call a weather API here console.log(Fetching weather for ${location}...); if (location.toLowerCase().includes(tokyo)) { return { temperature: 15°C, condition: Cloudy }; } return { temperature: 22°C, condition: Sunny }; }, }); const agent new Agent({ name: WeatherAgent, instructions: An agent that can fetch weather information., model: openai/gpt-4o-mini, tools: [getWeatherTool], // Add the tool to the agent }); // Now the agent can use the get_weather tool when asked about weather.Tool 构造器的完整字段源码视角从源码 packages/core/src/tool/index.ts 可以看到createTool的底层ToolOptions除上述四个核心字段外还支持以下可选项id工具唯一标识符默认回退为name构造器中this.id options.id ?? options.name。tags用于组织或标注工具的用户自定义标签数组会写入 OpenTelemetry 的tool.tags属性。needsApproval是否需要在执行前获得审批设为函数时可针对每次调用动态决策其类型为boolean | ToolNeedsApprovalFunction。providerOptions透传给特定 Provider 的选项例如 Anthropic 的cacheControl: { type: ephemeral }缓存控制。mcp当工具通过voltagent/mcp-server暴露时使用的 MCP 注解与元数据如readOnlyHint、destructiveHint、idempotentHint等。toModelOutput将工具输出转换为多模态内容的函数Anthropic、OpenAI 支持可返回文本 图片等content类型结果。hooks工具生命周期钩子包括onStart与onEndonEnd可返回{ output }覆盖最终输出。构造器本身也有守护逻辑缺少name会直接抛出Tool name is required缺少parameters会抛出parameters schema is required缺少description时仅记录警告。Tool类还带有type user-defined判别字段源码 Tool 类定义供 ToolManager 在运行时可靠地区分 VoltAgent 自有工具与外部工具避免跨模块instanceof失效问题。另外execute字段是可选的——当不提供服务端execute时isClientSide()返回true表明该工具应在客户端侧执行。在工具中访问操作上下文工具可以通过execute的第二个参数访问操作元数据、用户上下文与控制机制import { Agent, createTool } from voltagent/core; import { z } from zod; // Tool that uses operation context const contextAwareWeatherTool createTool({ name: get_weather, description: Fetches weather with user preferences, parameters: z.object({ location: z.string().describe(The city name), }), execute: async ({ location }, options) { // Access user-defined context const units options?.context?.get(preferredUnits) || celsius; const userId options?.userId; // Use operation-scoped logger options?.logger?.info(Fetching weather for ${location} in ${units}); // Check abort signal if (options?.abortSignal?.aborted) { throw new Error(Request was cancelled); } // Call weather API with user preferences const response await fetch( https://api.weather.com/current?city${location}units${units}, { signal: options?.abortSignal } ); return await response.json(); }, }); // Use the tool with context const context new Map(); context.set(preferredUnits, fahrenheit); const agent new Agent({ name: WeatherAgent, instructions: An agent that respects user preferences, model: openai/gpt-4o-mini, tools: [contextAwareWeatherTool], }); const response await agent.generateText(Whats the weather in Paris?, { userId: user123, context, });options 参数的完整构成options参数即ToolExecuteOptions定义于 packages/core/src/agent/providers/base/types.ts是PartialOperationContext的扩展包含操作元数据operationId操作唯一标识、userId、conversationId用户上下文contextMapstring | symbol, unknown用于存放自定义数据控制机制abortController、abortSignal日志logger操作作用域 loggerAI SDK 数据toolCallId、messages二者封装在toolContext字段中另有name、abortSignal以及OperationContext中的resolvedMemory、workspace、requestHeaders、systemContext、isActive、parentAgentId、elicitation等字段见 packages/core/src/agent/types.ts注意abortController是向后兼容的冗余字段源码注释明确建议优先使用toolContext.abortSignal。当工具由 VoltAgent 的 Agent 内部调用时toolContext总是被填充见下文执行工厂实现而由外部调用方如 MCP Server调用时该字段是可选的。工具输出 Schema 校验VoltAgent 支持工具的可选输出 Schema 校验。这一特性确保工具输出符合预定义结构带来多重收益类型安全Type Safety工具输出基于 Schema 获得类型推断运行时校验Runtime Validation无效输出会被立即捕获错误恢复Error Recovery校验失败时 LLM 会收到错误信息并可用修正后的输出重试一致性Consistency所有工具响应遵循相同结构文档化Documentation输出 Schema 即 API 契约带输出 Schema 的示例import { createTool } from voltagent/core; import { z } from zod; // Define the output schema const weatherOutputSchema z.object({ location: z.string(), temperature: z.number(), condition: z.enum([sunny, cloudy, rainy, snowy]), humidity: z.number().min(0).max(100), forecast: z.object({ high: z.number(), low: z.number(), description: z.string(), }), }); // Create a tool with output validation const weatherTool createTool({ name: get_weather, description: Get current weather with forecast, parameters: z.object({ location: z.string().describe(City name), }), outputSchema: weatherOutputSchema, // Optional output schema execute: async ({ location }) { // This output will be validated against weatherOutputSchema return { location, temperature: 22, condition: sunny, humidity: 65, forecast: { high: 25, low: 18, description: Clear skies throughout the day, }, }; }, });校验机制的源码实现输出校验的底层实现在 packages/core/src/agent/agent.ts 的validateToolOutput方法中若工具提供了outputSchema执行结果会经过outputSchema.safeParse(result)校验校验失败时抛出带有validationErrorsZod 原始错误数组与actualOutput属性的 Error。该错误随后经 error-utils.ts 的 buildToolErrorResult 序列化为可回传给模型的可序列化错误对象。整体流程如下工具执行后若提供了outputSchema其输出即被校验。校验成功返回校验后的输出parseResult.data。校验失败向 LLM 返回错误对象{ error: true, message: Output validation failed: Expected number, received string, validationErrors: [...], actualOutput: {...} }LLM 可以看到校验错误并可能通过再次调用工具来修复问题。值得留意的是校验同样适用于异步生成器工具在 createToolExecutionFactory 中对于execute为 async generator 的工具其每个yield的中间值都会先经validateToolOutput校验再透传最后一个值作为最终结果。真实示例可参考 examples/with-tools/src/tools/weather.ts它使用z.discriminatedUnion(status, ...)定义了loading/success两种状态的输出 Schema并先用yield返回正在获取的初步更新再返回最终天气数据该工具还演示了needsApproval的注释用法。最佳实践为需要稳定响应格式的工具使用输出 Schema保持 Schema 聚焦避免过度复杂的嵌套结构在 Schema 中使用.describe()提供描述性错误信息考虑用.optional()让部分字段可选以增加灵活性输出 Schema 完全可选——不带它的工具行为与之前完全一致用 Toolkit 分组管理相关工具Toolkit允许你分组相关工具让工具管理保持组织化定义共享指令向 LLM 提供如何使用该 Toolkit 内全部工具的通用指导控制指令注入决定 Toolkit 的共享指令是否自动加入 Agent 的系统提示词定义一个 ToolkitToolkit是一个具有如下结构的对象createToolkit实现见 packages/core/src/tool/toolkit.tsimport { createTool, createToolkit, type Tool, type Toolkit } from voltagent/core; const myCalculatorToolkit createToolkit({ name: calculator_toolkit, description: Tools for performing basic arithmetic operations., // Optional instructions for the LLM instructions: Use these tools for calculations. Always use add for addition, subtract for subtraction., // Set to true to add the above instructions to the system prompt addInstructions: true, tools: [ createTool({ /* ... definition for add tool ... */ }), createTool({ /* ... definition for subtract tool ... */ }), // ... other calculator tools ], });Toolkit类型定义toolkit.ts 的 Toolkit 类型包含五个字段nameToolkit 的唯一标识名称用于管理与日志description可选Toolkit 作用或所含工具的简述默认空字符串instructions可选关于如何使用其中工具的共享指令addInstructions为true时才注入系统提示词addInstructions可选是否自动将instructions加入系统提示词默认为falsetools属于该 Toolkit 的Tool或 Vercel 工具数组ToolToolSchema, ToolSchema | undefined | VercelToolcreateToolkit同样有校验逻辑name缺失会抛错空tools数组会发出警告但不会阻止创建。类型定义中明确tools的数组元素类型为Tool | VercelTool说明 Toolkit 内既可以放 VoltAgent 自建工具也可以放 Provider 定义的工具。重要随着 Toolkit 的引入单个Tool实例不再拥有自己的instructions或addInstructions属性——指令统一在 Toolkit 层级管理。从源码看ToolOptions也确实没有这两个字段这一设计避免了指令在多个层级重复冗余。嵌套 Toolkit 的限制从 ToolkitManager 源码 可以确认Toolkit 内部不支持嵌套 Toolkit——ToolkitManager.addToolkit()是一个 no-op 实现调用时会记录警告 nested toolkits are not supported 并返回false因此Toolkit的tools数组只接受工具而非另一个 Toolkit。向 Agent 添加工具与 ToolkitAgent构造器的tools选项现在接受同时包含单个Tool对象与Toolkit对象的数组ToolManager会对两者进行无缝处理import { openai } from ai-sdk/openai; import { Agent, createTool, createToolkit, type Toolkit } from voltagent/core; // ... import other tools and toolkits ... const agent new Agent({ name: MultiToolAgent, instructions: An agent with various tools and toolkits., model: openai/gpt-4o-mini, tools: [ getWeatherTool, // Add an individual tool myCalculatorToolkit, // Add a toolkit openai.tools.webSearch(), // Add a provider-defined tool // ... other tools or toolkits ], });ToolManager 的底层行为ToolManagerpackages/core/src/tool/manager/ToolManager.ts继承自BaseToolManagerpackages/core/src/tool/manager/BaseToolManager.ts底层按三类容器管理工具baseTools用户自定义、可在服务端执行或仅客户端执行的工具providerTools由 Provider 外部管理的工具toolkitsToolkitManager实例内部再各自维护 baseTools 与 providerTools关键行为包括名称冲突检查addToolkit时若 Toolkit 内任一工具与现有独立工具或其他 Toolkit 内工具重名hasToolInAny检查会记录警告并跳过添加返回false同名 Toolkit 会被替换并发出警告。运行时类型判别isProviderTooltype provider、isBaseTooltype user-defined、isToolkit存在数组型tools属性三个类型守卫用于在addItems/addStandaloneTool中分派处理。扁平化视图getAllTools()、getAllBaseTools()、getAllProviderTools()、getAllToolNames()都会展开 Toolkit 内部工具形成 Agent 执行与 API 暴露getToolsForApi所需的统一视图prepareToolsForExecution会把parametersZod Schema转成 AI SDK 可消费的inputSchema同时透传needsApproval、providerOptions、toModelOutput与outputSchema。动态增删Agent 实例支持addTools运行时动态添加工具examples/with-tools/src/index.ts 演示了agent.addTools([weatherTool])的用法也支持removeTool、removeToolkit。自动指令注入机制Agent 初始化时其getSystemMessage方法会检查tools数组中提供的所有Toolkit。若某个 Toolkit 的addInstructions: true且定义了instructions字符串这些指令会被自动追加到 Agent 的基础描述之后构成发送给 LLM 的最终系统提示词。源码层面这一逻辑实现在 agent.ts 的 addToolkitInstructions它遍历this.toolManager.getToolkits()对每个addInstructions instructions的 Toolkit 以\n\n${toolkit.instructions}的形式拼接最终通过enrichInstructionsagent.ts L5588-L5619将其与markdown指令、检索上下文、工作记忆、子代理监督指令等合并为最终 system message。此外运行时通过generateText等调用传入的runtimeToolkits也会参与拼接同名时以运行时定义为优先并保持静态顺序。Provider 定义的工具部分 Provider 通过 Vercel AI SDK 暴露自己的工具它们可以作为独立工具存在也可以放入 Toolkit 中添加 Toolkit 时同样受名称冲突检查约束。它们不能通过通常的Tool.execute处理器在你的服务器上执行——执行由 Provider 管理。例如openai.tools.webSearch()就是典型的 Provider 工具它由 OpenAI 侧托管执行Agent 只负责把它传入工具列表见 examples/with-tools/src/index.ts。ProviderTool类型tool/index.ts L115-L121通过type: provider判别字段与id: \${string}.${string}模板类型如openai.webSearch加以标识在prepareToolsForExecution中Provider 工具会被原样透传给 AI SDKtools[tool.name] tool而不会包装execute。进阶内置的 reasoning_tools 推理工具 Toolkit文档 Reasoning Tools 给出了一个开箱即用的 Toolkit 实例。createReasoningTools实现见 packages/core/src/tool/reasoning/index.ts返回名为reasoning_tools的 Toolkit内含think内部思维草稿纸与analyze评估结果并决定continue/validate/final_answer两个工具并可通过addInstructions默认true、think、analyze、addFewShot、fewShotExamples选项定制默认指令要求 Agent 在任何工具调用或响应前先think并按Think - [Think - ...] - [Tool Calls] - [Analyze] - final_answer的迭代循环解题。这是理解相关工具 共享指令 自动注入三者如何协同的最佳范例——直接把一个 Toolkit 塞进tools数组Agent 即获得结构化推理能力。编写高质量工具的工程建议综合上述机制编写与组织工具时值得遵循以下原则命名与描述优先name是 LLM 的调用句柄description决定 LLM 的调用时机二者直接影响工具使用率缺失name/parameters会在构造时直接抛错。用 Zod Schema 约束边界parameters负责输入校验outputSchema负责输出契约借助describe()、.optional()、z.discriminatedUnion可以写出既严格又灵活的 Schema。善用操作上下文通过options读取用户偏好、使用操作级logger、监听abortSignal实现优雅取消并在长任务中通过 async generator 的yield推送初步进度参考 with-tools 示例。按领域组织 Toolkit把访问同一 API、或服务于同一业务流程的工具收进一个 Toolkit用共享instructions告诉 LLM 工具间的配合规则并仅在需要时开启addInstructions默认false避免系统提示词膨胀。留意命名冲突ToolManager 会在独立工具与 Toolkit 工具之间、以及 Toolkit 之间做名称冲突检查重名工具会被跳过或覆盖因此工具名应尽量全局唯一。区分执行边界自建工具的execute在你自己的服务器上运行Provider 工具的execute由 Provider 管理不要试图为其编写服务端处理器。赞分享人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆【免费下载链接】voltagentAI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework项目地址https://gitcode.com/gh_mirrors/vo/voltagent点击查看免费下载相关推荐VoltAgent 工具系统实战用 createTool 构建可插拔 AI Agent 工具链VoltAgent 工具系统实战用 createTool 构建可插拔 AI Agent 工具链 导读 本文以 VoltAgent 官方示例 examples/人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音VoltAgent 工具系统实战指南:用 createTool 为 Agent 添加自定义工具、动态工具与 Provider 内置工具VoltAgent 工具系统实战指南:用 createTool 为 Agent 添加自定义工具、动态工具与 Provider 内置工具 本文基于官方配方文档 T人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音PDFPatcher 使用教程批量合并、重命名、页面提取的输出与排障PDFPatcher 使用教程批量合并、重命名、页面提取的输出与排障 PDFPatcherPDF 补丁丁是一款免费、免安装的 Windows PDF 批量人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆Agent 工作流AI 评测MCP 服务MCP Clients语音上一篇在 TodoAppTs 示例中实战 WaspCLAUDE.md 指引下的全栈开发、验证与调试工作流下一篇SkillSpector contrib/batch_scan 测试设计深度解析如何用 164 个测试驯服并发池与 monkey-patch创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考