尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Agent Tool Builder 实战指南:为 AI Agent 构建高质量工具(Schema 设计、错误处理与 MCP 实现)
Agent Tool Builder 实战指南为 AI Agent 构建高质量工具Schema 设计、错误处理与 MCP 实现【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills本文是 AAS Coreagentic-awesome-skills仓库中agent-tool-builder技能Skill的深度实战指南。工具Tools / Function Calling是 AI Agent 与外部世界交互的唯一通道一个设计良好的工具是 Agent 稳定工作与幻觉、静默失败、浪费 10 倍 Token 之间的分水岭。读完本文你将掌握 JSON Schema 工具描述的编写规范、input_examples与错误处理最佳实践、基于 MCPModel Context Protocol的跨平台工具构建方法以及并行工具执行的完整调用链并可直接对照仓库中的校验规则清单自查自己的工具实现。本文主体内容来自 agent-tool-builder 详细指南即references/detailed-guide.md根技能定义见 SKILL.md该技能的元数据分类、风险等级、来源登记在 data/catalog.json 与 data/skills_index.json 中。一、核心原则描述质量高于实现质量agent-tool-builder的第一条原则也是最重要的心智模型描述质量 实现质量。原因在于LLM 永远不会看到你的工具内部代码——它只能看到工具暴露的name、description与input_schema。工具是否被正确调用、参数是否传对完全取决于这些可见面写得是否清楚。其余核心原则构成一套完整的工程约束工具数量控制在 20 个以内过多的工具会让 LLM 在选择时产生困惑降低调用准确率每个工具必须有显式错误处理静默失败会毒害Agent——它无法知道调用失败会基于错误假设继续推理返回字符串而非对象LLM 处理的是文本流工具结果应以字符串形式返回如json.dumps()/JSON.stringify()后的 JSON 文本执行前设置校验门槛对 LLM 提供的输入先校验遵循拒绝reject、修复fix或升级escalate三选一策略绝不静默失败用 LLM 实测工具单元测试只能证明代码正确无法证明描述对 LLM 足够清晰必须用真实的 LLM 调用验证工具可用性。该技能的能力域Capabilities覆盖agent-tools、function-calling、tool-schema-design、mcp-tools、tool-validation、tool-error-handling六个方向风险等级被标记为critical关键来源为vibeship-spawner-skills (Apache 2.0)见 data/catalog.json。二、技术选型标准与框架工具构建涉及两层技术栈分别解决如何描述工具与如何在代码中接入 Agent两个问题。标准Standards标准适用时机说明JSON Schema所有工具定义描述工具输入/输出结构的通用格式跨平台、跨模型MCPModel Context Protocol构建可复用、跨平台的工具Anthropic 提出的开放标准已被广泛采纳正成为 AI 工具的事实互操作层框架Frameworks框架适用场景要点Anthropic SDK基于 Claude 的 AgentBeta 版 Tool Runner 自动处理大部分调用循环复杂度OpenAI Functions基于 OpenAI 的 Agent使用 strict mode 保证 schema 严格合规Vercel AI SDK多厂商模型混用抽象不同厂商之间的工具调用差异LangChain Tools基于 LangChain 的 Agent可将 MCP 工具转换为 LangChain 工具格式选型原则面向单一模型生态优先使用官方 SDK需要跨平台复用则优先基于 MCP 构建多厂商混用场景用 Vercel AI SDK 这类抽象层。三、Tool Schema 设计JSON Schema 最佳实践工具 Schema 是 LLM 理解工具的说明书。detailed-guide.md给出了四层递进的最佳实践。3.1 详尽的描述最重要的一步描述要覆盖工具做什么、适用场景、参数格式、返回值语义、明确不做的事。对比以下反例与正例反例过于含糊LLM 难以判断何时调用{ name: get_stock_price, description: Gets stock price, input_schema: { type: object, properties: { ticker: {type: string} } } }正例完整描述使用边界与行为语义{ name: get_stock_price, description: Retrieves the current stock price for a given ticker symbol. The ticker symbol must be a valid symbol for a publicly traded company on a major US stock exchange like NYSE or NASDAQ. Returns the latest trade price in USD. Use when the user asks about current or recent stock prices. Does NOT provide historical data, company info, or predictions., input_schema: { type: object, properties: { ticker: { type: string, description: The stock ticker symbol, e.g. AAPL for Apple Inc. } }, required: [ticker] } }注意正例刻意用 Does NOT provide... 声明工具的否定边界这能显著减少 LLM 对工具的误用。3.2 每个参数都要有描述参数描述必须回答四个问题是什么、期望的格式、示例值、边界情况/限制。{ location: { type: string, description: City and state/country. Format: City, State for US (e.g., San Francisco, CA) or City, Country for international (e.g., Tokyo, Japan). Do not use ZIP codes or coordinates. }, unit: { type: string, enum: [celsius, fahrenheit], description: Temperature unit. Defaults to users locale if not specified. Use fahrenheit for US users, celsius for others. } }3.3 尽量使用枚举Enums枚举把 LLM 的自由文本输入约束到合法取值集合从源头消除非法值priority: { type: string, enum: [low, medium, high, critical], description: Task priority level }, action: { type: string, enum: [create, read, update, delete], description: The CRUD operation to perform }3.4 明确必填与可选字段使用required数组显式声明必填项并用additionalProperties: false开启严格模式防止 LLM 传入 schema 之外的意外字段{ type: object, properties: { query: {...}, limit: {...}, offset: {...} }, required: [query], additionalProperties: false }从技能范围Scope的定义看本技能同时引用了 api-designerAPI 设计与 prompt-engineering提示词工程等相邻技能Schema 设计与这两者的交集即用描述语言引导模型行为。四、工具输入示例input_examples让复杂调用不再靠猜对于包含嵌套对象或格式敏感输入的工具仅靠 Schema 无法表达调用范式。Anthropic SDK 的 Beta 功能input_examples可为每个工具附带 15 个真实调用示例官方数据表明在复杂操作上示例可将调用准确率从约 72% 提升到约 90%。{ name: create_calendar_event, description: Creates a calendar event with optional attendees and reminders, input_schema: { type: object, properties: { title: {type: string, description: Event title}, start_time: { type: string, description: ISO 8601 datetime, e.g. 2024-03-15T14:00:00Z }, duration_minutes: {type: integer, description: Event duration}, attendees: { type: array, items: {type: string}, description: Email addresses of attendees } }, required: [title, start_time, duration_minutes] }, input_examples: [ { title: Team Standup, start_time: 2024-03-15T09:00:00Z, duration_minutes: 30, attendees: [alicecompany.com, bobcompany.com] }, { title: Quick Chat, start_time: 2024-03-15T14:00:00Z, duration_minutes: 15 }, { title: Project Review, start_time: 2024-03-15T16:00:00-05:00, duration_minutes: 60, attendees: [teamcompany.com] } ] }示例设计原则EXAMPLE DESIGN PRINCIPLES使用真实感数据不要用占位符placeholder同时展示最小、部分字段、完整字段三种规格的调用每个工具保持 15 个示例克制精简优先覆盖歧义场景如带/不带attendees、不同时区偏移格式。五、工具错误处理返回能让 LLM 自我恢复的错误任何可能失败的工具都必须返回信息丰富的错误。错误是 Agent 推理循环的输入一个模糊的错误会迫使 LLM 盲目重试一个结构化的错误能让它直接修正参数。5.1 坏错误 vs 好错误// BAD没有可恢复信息 {error: Failed} {error: true} // GOOD包含类型、消息与建议 { error: true, error_type: not_found, message: Location Atlantis not found in weather database. Please provide a real city name like San Francisco, CA., suggestions: [San Francisco, CA, Los Angeles, CA] }对应到 Anthropic 的tool_result协议错误结果必须携带is_error: true{ type: tool_result, tool_use_id: toolu_01A09q90qw90lq917835lq9, content: Error: Location Atlantis not found in weather database. Please provide a real city name like San Francisco, CA., is_error: true }5.2 必须处理的四类错误输入校验错误缺少必填参数、格式非法、取值越界外部服务错误API 不可用、被限流rate limited、超时业务逻辑错误资源不存在、权限不足、冲突/重复内部错误未预期的异常、数据损坏。5.3 实现模式PythonToolResultdetailed-guide.md给出一个可直接落地的 Python 实现用统一的ToolResult数据结构封装成功/失败统一转换为tool_result协议格式。from dataclasses import dataclass from typing import Union dataclass class ToolResult: success: bool content: str error_type: str None suggestions: list[str] None def to_response(self) - dict: if self.success: return {content: self.content} return { content: fError ({self.error_type}): {self.content}, is_error: True } def get_weather(location: str) - ToolResult: # Validate input if not location or len(location) 2: return ToolResult( successFalse, contentLocation must be at least 2 characters, error_typevalidation_error ) try: data weather_api.fetch(location) return ToolResult( successTrue, contentfTemperature: {data.temp}°F, Conditions: {data.conditions} ) except LocationNotFound: return ToolResult( successFalse, contentfLocation {location} not found, error_typenot_found, suggestionsweather_api.suggest_locations(location) ) except RateLimitError: return ToolResult( successFalse, contentWeather service rate limit exceeded. Try again in 60 seconds., error_typerate_limit ) except Exception as e: return ToolResult( successFalse, contentfUnexpected error: {str(e)}, error_typeinternal_error )该模式的关键收益输入校验先行、异常按类型分类、错误信息中携带可操作的恢复提示如suggestions让 Agent 的下一轮推理有据可依。六、MCP 工具模式构建一次、处处复用MCPModel Context Protocol是 Anthropic 提出的开放标准用于把 AI Agent 连接到外部系统。核心价值是构建一次处处可用——工具与具体模型/厂商解耦。6.1 最小 TypeScript MCP Serverimport { Server } from modelcontextprotocol/sdk/server; import { StdioServerTransport } from modelcontextprotocol/sdk/server/stdio; const server new Server({ name: weather-server, version: 1.0.0 }); // Define tools server.setRequestHandler(tools/list, async () ({ tools: [ { name: get_weather, description: Get current weather for a location. Returns temperature, conditions, and humidity. Use for weather queries about specific cities., inputSchema: { type: object, properties: { location: { type: string, description: City and state, e.g. San Francisco, CA }, unit: { type: string, enum: [celsius, fahrenheit], default: fahrenheit } }, required: [location] } } ] })); // Handle tool calls server.setRequestHandler(tools/call, async (request) { const { name, arguments: args } request.params; if (name get_weather) { try { const weather await fetchWeather(args.location, args.unit); return { content: [ { type: text, text: JSON.stringify(weather) } ] }; } catch (error) { return { content: [ { type: text, text: Error: ${error.message} } ], isError: true }; } } throw new Error(Unknown tool: ${name}); }); // Start server const transport new StdioServerTransport(); await server.connect(transport);注意两个协议方法tools/list返回工具 Schema 清单tools/call执行具体调用错误时通过contentisError: true返回未知工具直接抛错。6.2 MCP 的收益跨 LLM 厂商的通用兼容性可复用的工具库资产支持流式与 SSE 传输内置可观测性提供工具访问控制。七、Tool Runner 模式用 SDK 自动接管调用循环如果不想手动管理模型调用 → 执行工具 → 回填结果的循环可以使用 Anthropic SDK 的 Beta Tool Runner。它会自动执行工具、管理会话状态、处理错误重试、提供流式输出。7.1 TypeScript Zod类型安全输入import { Anthropic } from anthropic-ai/sdk; import { betaZodTool } from anthropic-ai/sdk/helpers/beta/zod; import { z } from zod; const anthropic new Anthropic(); const getWeatherTool betaZodTool({ name: get_weather, description: Get the current weather in a given location, inputSchema: z.object({ location: z.string().describe(City and state, e.g. San Francisco, CA), unit: z.enum([celsius, fahrenheit]).default(fahrenheit) }), run: async (input) { // Type-safe input! return JSON.stringify({temperature: 72°F}); } }); const runner anthropic.beta.messages.toolRunner({ model: claude-sonnet-4-5, max_tokens: 1024, tools: [getWeatherTool], messages: [{ role: user, content: Whats the weather in Paris? }] }); for await (const message of runner) { console.log(message.content[0].text); }Zod 的优势在于inputSchema即运行时校验run回调中拿到的input是经过类型检查和默认值填充后的安全对象。7.2 Python 等价实现根技能 SKILL.md 中给出了 Python 版的beta_tool装饰器写法语义与 TypeScript 版完全对齐import anthropic from anthropic import beta_tool client anthropic.Anthropic() beta_tool def get_weather(location: str, unit: str fahrenheit) - str: Get the current weather in a given location. Args: location: The city and state, e.g. San Francisco, CA unit: Temperature unit, either celsius or fahrenheit # Implementation return json.dumps({temperature: 72°F, conditions: Sunny}) beta_tool def search_web(query: str) - str: Search the web for information. Args: query: The search query # Implementation return json.dumps({results: [...]}) # Tool runner handles the loop runner client.beta.messages.tool_runner( modelclaude-sonnet-4-5, max_tokens1024, tools[get_weather, search_web], messages[ {role: user, content: Whats the weather in Paris?} ] ) # Process each message for message in runner: print(message.content[0].text) # Or just get final result final runner.until_done()注意两个版本都遵守返回 JSON 字符串而非对象原则json.dumps/JSON.stringify。八、并行工具执行一次响应、多个工具默认情况下Claude 可以在同一次响应中调用多个工具这对相互独立的操作可以显著降低延迟。8.1 处理并行结果模型返回多个tool_use块# Claude returns multiple tool_use blocks: response.content [ {type: text, text: Ill check both locations...}, {type: tool_use, id: toolu_01, name: get_weather, input: {location: San Francisco, CA}}, {type: tool_use, id: toolu_02, name: get_weather, input: {location: New York, NY}}, {type: tool_use, id: toolu_03, name: get_time, input: {timezone: America/Los_Angeles}}, {type: tool_use, id: toolu_04, name: get_time, input: {timezone: America/New_York}} ] # Execute in parallel import asyncio async def execute_tools_parallel(tool_uses): tasks [execute_tool(t) for t in tool_uses] return await asyncio.gather(*tasks) results await execute_tools_parallel(tool_uses) # Return ALL results in SINGLE user message (critical!) tool_results [ {type: tool_result, tool_use_id: toolu_01, content: 72°F, Sunny}, {type: tool_result, tool_use_id: toolu_02, content: 45°F, Cloudy}, {type: tool_result, tool_use_id: toolu_03, content: 2:30 PM PST}, {type: tool_result, tool_use_id: toolu_04, content: 5:30 PM EST} ] # CORRECT: All results in one message messages.append({role: user, content: tool_results}) # WRONG: Separate messages (breaks parallel execution pattern) # messages.append({role: user, content: [tool_results[0]]}) # messages.append({role: user, content: [tool_results[1]]})关键陷阱所有并行工具的结果必须放在同一条 user 消息中一次性回填。拆分成多条消息会破坏并行模式导致模型丢失这些调用属于同一轮的上下文。8.2 鼓励并行写入系统提示For maximum efficiency, whenever you need to perform multiple independent operations, invoke all relevant tools simultaneously rather than sequentially.8.3 需要串行时的关闭开关response client.messages.create( modelclaude-sonnet-4-5, toolstools, tool_choice{type: auto, disable_parallel_tool_use: True}, messagesmessages )当工具之间存在依赖后者依赖前者的输出或共享可变状态时应显式禁用并行。九、校验检查清单发布工具前的 10 项自查detailed-guide.md以严重级别WARNING / INFO / ERROR列出了 10 条可操作的静态校验规则可直接作为 CI 或代码审查的检查项#检查项严重级别说明1Tool Description Must Be ComprehensiveWARNING描述至少 100 字符过短时补充何时使用、参数、返回值信息2Parameter Descriptions RequiredWARNING每个参数必须有描述说明其含义与期望格式3Schema Should Specify Required FieldsINFO显式定义必填字段补充required数组4Tool Implementation Needs Error HandlingERROR工具函数必须包含异常处理try/except 块5Error Results Need is_error FlagWARNING返回错误时必须设置is_error: true6Tools Should Return StringsWARNING返回 JSON 字符串而非 dict/对象用json.dumps()或JSON.stringify()7Tools Should Validate InputsWARNING执行前对 LLM 提供的输入做可见校验8SQL Queries Must Use ParameterizationERROR禁止字符串拼接用户输入进 SQL必须使用参数化查询9External Calls Need TimeoutsWARNINGHTTP 请求与外部调用必须设置超时参数10MCP Tools Must Have Input SchemaERROR所有 MCP 工具定义必须携带inputSchema其中第 8 条SQL 参数化是安全红线未参数化的 SQL 会让 LLM 生成的查询直接面临注入风险属于必须拒绝发布级别的 ERROR。第 4、10 条同为 ERROR 级别是工具可用性与协议合规性的底线。十、协作与委派何时把任务交给其他技能agent-tool-builder定义了明确的边界当任务超出单工具设计范畴时应委派给协作技能需要协调多个工具跨 Agent 编排 → multi-agent-orchestration跨 Agent 的工具编排需要工具调用之间的持久记忆 → agent-memory-systems工具状态管理构建语音 Agent 工具 → voice-agents音频/语音专属工具要求需要桌面控制类工具 → computer-use-agents桌面自动化工具需要测试所构建的工具 → agent-evaluation工具测试与评估。此外本技能与multi-agent-orchestration、api-designer、llm-architect、backend等技能搭配效果最佳。十一、适用范围与边界根据 SKILL.md 的 When to Use本技能适用于用户提及以下意图时agent tool、function calling、tool schema、tool design、mcp server / mcp tool、tool use、build tool for agent、define function、input_schema、tool_use、tool_result。同时必须遵守其 Limitations仅当任务与上述范围明确匹配时使用本技能本技能输出不能替代环境专属的验证、测试与专家审查当缺少必要的输入、权限、安全边界或成功标准时应停下并向用户澄清而非强行执行。总结构建高质量 Agent 工具的完整链路可以浓缩为四句话用详尽的 JSON Schema 描述让 LLM 准确调用用input_examples示范复杂输入范式用结构化的is_error错误返回让 Agent 自我恢复用 MCP 与 Tool Runner 让工具跨平台复用并免于手工维护调用循环。对照文末的 10 条校验清单逐项自查即可显著降低 Agent 幻觉、静默失败与 Token 浪费的发生概率。【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址: https://gitcode.com/GitHub_Trending/an/agentic-awesome-skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

Linux文件描述符耗尽排查:从Too many open files到根因定位

Linux文件描述符耗尽排查:从Too many open files到根因定位

1. 从一次服务雪崩说起:文件句柄耗尽的真实面目凌晨两点,监控告警突然炸了。一台跑了半年多的业务服务器上,核心服务开始疯狂报错,日志里刷屏的就是那句让运维人血压飙升的话:Too many open files。更诡异的是&#xf…

📅 2026/10/21 3:35:52
无名杀:免费开源的网页版三国杀启动指南与武将自定义路径

无名杀:免费开源的网页版三国杀启动指南与武将自定义路径

无名杀:免费开源的网页版三国杀启动指南与武将自定义路径 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 无名杀(noname)是一款免费、开源的网页版三国杀卡牌游戏:浏览器打开即玩&…

📅 2026/10/21 3:35:52
Docker基础学习笔记:从镜像容器到常用命令与实战踩坑经验

Docker基础学习笔记:从镜像容器到常用命令与实战踩坑经验

1. 为什么我最终把Docker放进了日常工具箱1.1 从一次环境翻车说起最早接触Docker,我其实有点不以为然。那会儿我总觉得,部署不就是一个“代码拷过去,依赖装一遍,服务跑起来”的事情吗?直到有一次,某个后端同…

📅 2026/10/21 3:35:52
MORE NEWS

更多资讯

📰

C# WinForms CAN上位机通讯DEMO:从报文收发到协议调试

简介:面向汽车电子、工业自动化及嵌入式开发者的CAN总线通讯上位机DEMO,通过一个完整可运行的例程,演示上位机程序如何完成CAN报文的构建、收发、解析与界面联动。压缩包共47个文件,以C#源码(cs、resx、Designer&#…

📰

语义分割实战:如何让弹幕自动避开视频关键区域

弹幕防遮挡这东西,我当初在B站看番的时候就有想法了。视频里正播到关键剧情,人物表情都没看清,满屏“前方高能”直接糊脸,这体验确实说不上好。后来做毕设,导师丢给我一个方向:能不能用深度学习把视频里“重…

📰

Linux LVM空间调整:安全将home分区容量转移至根目录

1. 项目概述:为什么“Linux分配home容量给根目录”是运维现场高频痛点“Linux分配home容量给根目录”这个标题,乍看像一句操作指令,实则直击Linux系统管理中最常被低估、却最容易引发生产事故的核心矛盾——磁盘空间的静态规划与动态使用的根…

📰

NEU-DET数据集实战指南:钢材表面缺陷检测全流程解析

NEU-DET数据集这几年在工业视觉圈子里几乎成了“入门必刷”的基准,我做表面缺陷检测项目这两三年,前前后后在它上面折腾了不少时间,从最早拿YOLOv5跑着玩,到后来做数据增强对比实验,再到给产线项目做可行性预研&#x…

📰

rea不是拼写错误:三字符压缩命名在前端、CLI与低代码中的工程实践

项目标题: "rea"这个标题乍一看像拼写错误,也像某个缩写,又像随手打出来的半截词——但恰恰是这种极简、模糊、甚至带点“故障感”的命名,在当下内容生态里反而成了高频信号。我接触过不少类似命名的项目:有的是某次内部…

📰

知识工作插件集:自动化知识管理、摘要与关联的全流程方案

"knowledge-work-plugins"这套插件合集,是我在过去一年里围绕知识工作场景陆续攒出来的。起因很简单:我平时要处理大量技术文档、读书笔记、会议纪要和项目复盘,常用的笔记工具和知识库软件功能都不差,但总在某个环节卡…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬