智能体工具构建器

agent-tool-builder
分类通用
作者Agentic Awesome Skills 社区
许可MIT
评分4.80/5
使用5.7K

Agent 工具构建师 (Agent Tool Builder)

工具是 AI Agent 与世界交互的方式。一个设计良好的工具,决定了 Agent 是能高效工作,还是会产生幻觉、静默失败,或者消耗比必要多 10 倍的 Token。

本技能涵盖了从 Schema 到错误处理的工具设计全过程。包括 JSON Schema 最佳实践、真正能帮助 LLM 的描述编写、验证机制,以及正成为 AI 工具通用语言的 MCP 标准。

核心洞察:工具描述比工具实现更重要。LLM 永远看不到你的代码——它只能看到 Schema 和描述。

原则

  • 为了提高 LLM 的准确率,描述质量 > 实现质量
  • 尽量将工具数量控制在 20 个以内——过多会导致混淆
  • 每个工具都需要明确的错误处理——静默失败会损害 Agent 的性能
  • 返回字符串而非对象——LLM 处理的是文本
  • 执行前设置验证关卡——拒绝、修复或升级,绝不静默失败
  • 使用 LLM 测试工具,而不仅仅是单元测试

能力

  • agent-tools (Agent 工具)
  • function-calling (函数调用)
  • tool-schema-design (工具 Schema 设计)
  • mcp-tools (MCP 工具)
  • tool-validation (工具验证)
  • tool-error-handling (工具错误处理)

范围

  • multi-agent-coordination $\rightarrow$ multi-agent-orchestration (多 Agent 协调 $\rightarrow$ 多 Agent 编排)
  • agent-memory $\rightarrow$ agent-memory-systems (Agent 记忆 $\rightarrow$ Agent 记忆系统)
  • api-design $\rightarrow$ api-designer (API 设计 $\rightarrow$ API 设计师)
  • llm-prompting $\rightarrow$ prompt-engineering (LLM 提示 $\rightarrow$ 提示工程)

工具链

标准

  • JSON Schema - 使用场景:所有工具定义。注:工具 Schema 的通用格式。
  • MCP (Model Context Protocol) - 使用场景:构建可复用的跨平台工具。注:Anthropic 推出的开放标准,已被广泛采用。

框架

  • Anthropic SDK - 使用场景:基于 Claude 的 Agent。注:Beta 版工具运行器处理了大部分复杂性。
  • OpenAI Functions - 使用场景:基于 OpenAI 的 Agent。注:使用 strict 模式以保证 Schema 的绝对合规。
  • Vercel AI SDK - 使用场景:多供应商工具处理。注:抽象了不同供应商之间的差异。
  • LangChain Tools - 使用场景:基于 LangChain 的 Agent。注:可将 MCP 工具转换为 LangChain 格式。

模式

工具 Schema 设计

为工具创建清晰、无歧义的 JSON Schema。

使用场景:为 Agent 定义任何新工具时。

工具 Schema 最佳实践:

1. 详细的描述(最重要)

""" 错误示例 - 太模糊: { "name": "get_stock_price", "description": "获取股票价格", "input_schema": { "type": "object", "properties": { "ticker": {"type": "string"} } } }

正确示例 - 全面详尽:
{
"name": "get_stock_price",
"description": "检索给定股票代码的当前股价。股票代码必须是 NYSE 或 NASDAQ 等美国主要证券交易所上市公司的有效代码。返回最新的美元交易价格。当用户询问当前或近期股价时使用。本工具不提供历史数据、公司信息或预测。",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "股票代码,例如苹果公司的 AAPL。"
}
},
"required": ["ticker"]
}
}
"""

2. 参数描述

""" 每个参数都需要包含:
  • 它是什么
  • 期望的格式
"""
  • 示例值
  • 边界情况/限制

{
"location": {
"type": "string",
"description": "城市和州/国家。格式:美国请使用 'City, State'(例如 'San Francisco, CA'),国际请使用 'City, Country'(例如 'Tokyo, Japan')。请勿使用邮编或坐标。"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位。若未指定,则默认为用户所在地区的设置。美国用户使用 'fahrenheit',其他用户使用 'celsius'。"
}
}
"""

3. 尽可能使用 Enums

""" Enums 可将 LLM 限制在有效值范围内:

"priority": {
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"description": "任务优先级"
}

"action": {
"type": "string",
"enum": ["create", "read", "update", "delete"],
"description": "要执行的 CRUD 操作"
}
"""

4. 必填 vs 可选

""" 明确标注哪些是必填项:

{
"type": "object",
"properties": {
"query": {...}, // 必填
"limit": {...}, // 可选,带默认值
"offset": {...} // 可选
},
"required": ["query"],
"additionalProperties": false // 严格模式
}
"""

带有输入示例的工具

使用示例引导 LLM 调用工具

适用场景:包含嵌套对象或对格式敏感输入的复杂工具

工具使用示例 (Anthropic Beta 功能):

"""
示例向 Claude 展示了 Schema 无法表达的具体模式。
在复杂操作中,可将准确率从 72% 提升至 90%。
"""

{
"name": "create_calendar_event",
"description": "创建日历事件,支持可选的参会者和提醒",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string", "description": "事件标题"},
"start_time": {
"type": "string",
"description": "ISO 8601 日期时间,例如 2024-03-15T14:00:00Z"
},
"duration_minutes": {"type": "integer", "description": "事件时长(分钟)"},
"attendees": {
"type": "array",
"items": {"type": "string"},
"description": "参会者的电子邮件地址"
}
},
"required": ["title", "start_time", "duration_minutes"]
},
"input_examples": [
{
"title": "团队站会",
"start_time": "2024-03-15T09:00:00Z",
"duration_minutes": 30,
"attendees": ["[email protected]", "[email protected]"]
},
{
"title": "快速沟通",
"start_time": "2024-03-15T14:00:00Z",
"duration_minutes": 15
},
{
"title": "项目评审",
"start_time": "2024-03-15T16:00:00-05:00",
"duration_minutes": 60,
"attendees": ["[email protected]"]
}
]
}

示例设计原则:

- 使用真实数据,而非占位符

- 展示最小化、部分填充和完整定义的模式

- 保持简洁:每个工具提供 1-5 个示例

- 侧重于模糊场景

工具错误处理

返回有助于 LLM 恢复的错误信息

适用场景:任何可能失败的工具

错误处理最佳实践:

返回具有信息量的错误

""" 错误示例: {"error": "Failed"} {"error": true}

正确示例:
{
"error": true,
"error_type": "not_found",
"message": "在天气数据库中未找到地点 'Atlantis'。请提供真实的城市名称,例如 'San Francisco, CA'。",
"suggestions": ["San Francisco, CA", "Los Angeles, CA"]
}
"""

Anthropic 工具结果错误示例

""" { "type": "tool_result", "tool_use_id": "toolu_01A09q90qw90lq917835lq9", "content": "Error: Location 'Atlantis' not found 在天气数据库中。 请提供一个真实的城市名称,例如 'San Francisco, CA'。", "is_error": true } """

需要处理的错误类别

""" 1. 输入验证错误 - 缺失必要参数 - 格式无效 - 数值超出范围

2. 外部服务错误
- API 不可用
- 触发频率限制 (Rate limited)
- 请求超时

3. 业务逻辑错误
- 资源未找到
- 权限被拒绝
- 冲突/重复

4. 内部错误
- 未预料的异常
- 数据损坏
"""

实现模式

""" 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": f"Error ({self.error_type}): {self.content}",
"is_error": True
}

def get_weather(location: str) -> ToolResult:
# 验证输入
if not location or len(location) < 2:
return ToolResult(
success=False,
content="Location must be at least 2 characters",
error_type="validation_error"
)

try:
data = weather_api.fetch(location)
return ToolResult(
success=True,
content=f"Temperature: {data.temp}°F, Conditions: {data.conditions}"
)
except LocationNotFound:
return ToolResult(
success=False,
content=f"Location '{location}' not found",
error_type="not_found",
suggestions=weather_api.suggest_locations(location)
)
except RateLimitError:
return ToolResult(
success=False,
content="Weather service rate limit exceeded. Try again in 60 seconds.",
error_type="rate_limit"
)
except Exception as e:
return ToolResult(
success=False,
content=f"Unexpected error: {str(e)}",
error_type="internal_error"
)
"""

MCP 工具模式

使用 Model Context Protocol 构建工具

适用场景:创建可复用的跨平台工具

MCP 工具实现:

"""
MCP (Model Context Protocol) 是 Anthropic 推出的开放标准,用于
将 AI 智能体连接到外部系统。一次构建,随处使用。
"""

基础 MCP 服务器 (TypeScript)

""" import { Server } from "@modelcontextprotocol/sdk/server"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio";

const server = new Server({
name: "weather-server",
version: "1.0.0"
});

// 定义工具
server.setRequestHandler("tools/list", async () => ({
tools: [
{
name: "get_weather",
description: "获取指定地点的当前天气。返回
温度、天气状况和湿度。适用于关于特定城市的
天气查询。",
inputSchema: {
type: "object",
properties: {
location: {
type: "string",
description: "城市和州/省,例如 'San Francisco, CA'"
},
unit: {
type: "string",
enum: ["celsius", "fahrenheit"],
default: "fahrenheit"
}
},
required: ["location"]
}
}
]
}));

// 处理工具调用
server.setRequestHandler("tools/call", async (request) => {
const { name, arguments: args } = request.params;

if (name === "get_weather") {
try {
const weather = a
wait 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);
"""

MCP 优势

"""
  • 跨 LLM 供应商的通用兼容性
  • 可复用的工具库
  • 支持 Streaming 和 SSE 传输
  • 内置的可观测性
  • 工具访问控制
"""

Tool Runner 模式

使用 SDK tool runners 进行自动处理

适用场景:构建无需手动管理的工具循环

TOOL RUNNER (Anthropic SDK Beta):

"""
Tool runner 自动处理工具调用循环:

  • 当 Claude 调用工具时执行该工具

  • 管理对话状态

  • 处理错误重试

  • 提供流式传输支持

"""

Python 示例

""" import anthropic from anthropic import beta_tool

client = anthropic.Anthropic()

@beta_tool
def get_weather(location: str, unit: str = "fahrenheit") -> str:
'''获取指定地点的当前天气。

Args:
location: 城市和州,例如 San Francisco, CA
unit: 温度单位,'celsius' 或 'fahrenheit'
'''
# 实现代码
return json.dumps({"temperature": "72°F", "conditions": "Sunny"})

@beta_tool
def search_web(query: str) -> str:
'''在网络上搜索信息。

Args:
query: 搜索查询词
'''
# 实现代码
return json.dumps({"results": [...]})

Tool runner 处理循环

runner = client.beta.messages.tool_runner( model="claude-sonnet-4-5", max_tokens=1024, tools=[get_weather, search_web], messages=[ {"role": "user", "content": "What's the weather in Paris?"} ] )

处理每条消息

for message in runner: print(message.content[0].text)

或直接获取最终结果

final = runner.until_done() """

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) => {
// 类型安全的输入!
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: "What's the weather in Paris?" }]
});

for await (const message of runner) {
console.log(message.content[0].text);
}
"""

并行工具执行

同时运行多个工具

适用场景:可以并行运行的独立工具调用

PARALLEL TOOL EXECUTION:

"""
默认情况下,Claude 可以在一次响应中调用多个工具。
这大大降低了独立操作的延迟。
"""

处理并行结果

"""

Claude 返回多个 tool_use 块:

response.content = [ {"type": "text", "text": "I'll 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"}} ]

并行执行

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)

在单个用户消息中返回所有结果(至关重要!)

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"} ]

正确:所有结果在一条消息中

messages.append({"role": "user", "content": tool_results})

错误:分多条消息发送(会破坏并行执行模式)

messages.append({"role": "user", "content": [tool_results[0]]})

messages.append({"role": "user", "content": [tool_results[1]]})

"""

鼓励并行工具调用

""" 在系统提示词中添加: "为了最大限度提高效率,每当你需要执行多个独立操作时,请同时调用所有相关工具,而非顺序调用。" """

禁用并行调用(必要时)

""" response = client.messages.create( model="claude-sonnet-4-5", tools=tools, tool_choice={"type": "auto", "disable_parallel_tool_use": True}, messages=messages ) """

验证检查

工具描述必须详尽

严重程度:WARNING

工具描述应至少 100 个字符

消息:工具描述太短。请添加关于使用场景、参数和返回值的详细信息。

必须提供参数描述

严重程度:WARNING

每个参数都应有描述

消息:参数缺失描述。请描述其含义及预期格式。

Schema 应指定必填字段

严重程度:INFO

明确定义哪些字段是必填的

消息:Schema 未指定必填字段。请添加 'required' 数组。

工具实现需要错误处理

严重程度:ERROR

工具函数应处理异常

消息:工具函数缺少 try/except 块。请添加错误处理。

错误结果需要 is_error 标志

严重程度:WARNING

返回错误时,将 is_error 设置为 true

消息:错误结果缺少 is_error 标志。请添加 'is_error': true。

工具应返回字符串

严重程度:WARNING

返回 JSON 字符串,而非字典/对象

消息:返回了字典而非字符串。请使用 json.dumps() 或 JSON.stringify()。

工具应验证输入

严重程度:WARNING

在执行前验证 LLM 提供的输入

消息:工具函数没有可见的输入验证。请在执行前进行验证。

SQL 查询必须使用参数化

严重程度:ERROR

绝不要将用户输入直接拼接进 SQL

消息:SQL 查询似乎使用了字符串拼接。请使用参数化查询。

外部调用需要超时设置

严重程度:WARNING

HTTP 请求和外部调用应设置超时时间

消息:外部 API 调用缺少超时设置。请添加 timeout 参数。

MCP T

工具必须包含输入模式 (Input Schema)

严重程度:错误 (ERROR)

所有 MCP 工具都需要 inputSchema

消息:MCP 工具定义缺失 inputSchema。

协作

委派触发条件

  • 用户需要协调多个工具 -> multi-agent-orchestration (跨智能体的工具编排)
  • 用户需要在工具调用之间保持持久化记忆 -> agent-memory-systems (工具状态管理)
  • 用户正在构建语音智能体工具 -> voice-agents (音频/语音特定工具要求)
  • 用户需要计算机控制工具 -> computer-use-agents (桌面自动化工具)
  • 用户想要测试其工具 -> agent-evaluation (工具测试与评估)

相关技能

可与以下技能协同工作:multi-agent-orchestration, api-designer, llm-architect, backend

使用场景

  • 用户提到或暗示:智能体工具 (agent tool)
  • 用户提到或暗示:函数调用 (function calling)
  • 用户提到或暗示:工具模式 (tool schema)
  • 用户提到或暗示:工具设计 (tool design)
  • 用户提到或暗示:MCP 服务器 (mcp server)
  • 用户提到或暗示:MCP 工具 (mcp tool)
  • 用户提到或暗示:工具使用 (tool use)
  • 用户提到或暗示:为智能体构建工具 (build tool for agent)
  • 用户提到或暗示:定义函数 (define function)
  • 用户提到或暗示:input_schema
  • 用户提到或暗示:tool_use
  • 用户提到或暗示:tool_result

局限性

  • 仅在任务明确符合上述范围时使用此技能。
  • 不要将输出视为环境特定验证、测试或专家评审的替代方案。
  • 如果缺失必要的输入、权限、安全边界或成功标准,请停止并请求澄清。