工具调用:从实验性功能到标准基础设施

2023年OpenAI推出Function Calling时,它被视为一个便捷的实验性功能。到2026年,工具调用已成为大模型应用的标准基础设施——每个Agent都需要调用工具,而调用方式的标准化程度直接决定了开发效率。

各厂商方案对比

OpenAI Function Calling

OpenAI的方案是最早的标准化工具调用格式:

{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "获取指定城市的天气",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {"type": "string", "description": "城市名"},
            "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
          },
          "required": ["city"]
        }
      }
    }
  ]
}

模型响应包含工具调用:

{
  "tool_calls": [
    {
      "id": "call_abc123",
      "function": {
        "name": "get_weather",
        "arguments": "{\"city\": \"北京\"}"
      }
    }
  ]
}

特点:参数以JSON字符串形式返回,需要二次解析。Parallel function calling支持一次调用多个工具。

Anthropic Tool Use

Anthropic的格式与OpenAI类似但在细节上有差异:

{
  "tools": [
    {
      "name": "get_weather",
      "description": "获取指定城市的天气",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": {"type": "string"}
        },
        "required": ["city"]
      }
    }
  ]
}

差异点:

  • input_schema替代parameters
  • 参数直接作为对象返回,不需要二次解析
  • 工具调用结果用tool_result消息类型返回

Google Gemini Function Calling

{
  "function_declarations": [
    {
      "name": "get_weather",
      "description": "获取指定城市的天气",
      "parameters": {
        "type": "object",
        "properties": {
          "city": {"type": "string"}
        }
      }
    }
  ]
}

差异点:用function_declarations替代tools,响应格式也略有不同。

差异带来的工程负担

# 适配不同厂商的工具调用格式
class ToolCallAdapter:
    def to_openai(self, tools):
        return [{"type": "function", "function": t} for t in tools]
    
    def to_anthropic(self, tools):
        return [{"name": t["name"], "input_schema": t["parameters"]} 
                for t in tools]
    
    def to_gemini(self, tools):
        return [{"function_declarations": tools}]
    
    def parse_response(self, response, provider):
        if provider == "openai":
            return self._parse_openai(response)
        elif provider == "anthropic":
            return self._parse_anthropic(response)
        elif provider == "gemini":
            return self._parse_gemini(response)

这种适配层增加了大量样板代码,且在厂商更新API时需要同步维护。

MCP:统一协议的曙光

MCP的工具定义

MCP通过标准化的JSON-RPC协议定义工具,与具体模型厂商无关:

// MCP Tool定义
interface Tool {
  name: string;
  description: string;
  inputSchema: {
    type: "object";
    properties: Record<string, JSONSchema>;
    required?: string[];
  };
}

MCP的工作流程

1. Client(Agent)连接到MCP Server
2. Client请求可用工具列表
3. MCP Server返回工具定义
4. LLM根据工具定义决定调用哪个工具
5. Client通过MCP协议向Server发送工具调用请求
6. Server执行工具并返回结果
7. Client将结果传给LLM继续推理

MCP vs 传统Function Calling

# 传统方式:工具定义嵌入在API请求中
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[...],
    tools=[
        {"type": "function", "function": {
            "name": "search",
            "parameters": {...}
        }}
    ]
)

# MCP方式:工具由独立Server提供,动态发现
mcp_client = MCPClient()
mcp_client.connect("filesystem-server")
mcp_client.connect("github-server")
mcp_client.connect("database-server")

tools = mcp_client.list_tools()  # 动态发现所有工具
# LLM使用这些工具,无需关心工具实现细节

MCP的核心优势

解耦:工具实现与模型厂商完全解耦。一次开发MCP Server,所有支持MCP的模型都能使用。

动态发现:Agent可以动态发现可用工具,而非硬编码在prompt中:

class MCPAgent:
    def __init__(self, mcp_client, llm):
        self.mcp = mcp_client
        self.llm = llm
    
    def run(self, task):
        # 动态获取工具
        tools = self.mcp.list_all_tools()
        
        # 根据任务筛选相关工具
        relevant_tools = self._select_tools(task, tools)
        
        # 构建工具调用prompt
        prompt = self._build_prompt(task, relevant_tools)
        response = self.llm.generate(prompt)
        
        # 执行工具调用
        if response.has_tool_call:
            result = self.mcp.call_tool(
                response.tool_name,
                response.tool_params
            )
            # 继续推理
            return self.llm.generate(prompt + str(result))
        
        return response

有状态会话:MCP支持有状态的工具会话,可以维护上下文:

# MCP支持有状态操作
# 例如:先打开文件,再读取,再关闭
mcp_client.call("file_open", {"path": "/data.csv"})
mcp_client.call("file_read", {"session_id": session_id})
mcp_client.call("file_close", {"session_id": session_id})

工具调用质量评估

参数生成准确率

模型生成的工具调用参数是否正确:

def evaluate_tool_calling(model, test_cases):
    results = []
    for case in test_cases:
        # 模型生成工具调用
        call = model.generate_tool_call(case["input"], case["available_tools"])
        
        # 评估
        name_correct = call["name"] == case["expected"]["name"]
        params_correct = True
        for key, expected_value in case["expected"]["params"].items():
            if key not in call["params"]:
                params_correct = False
            elif not is_equivalent(call["params"][key], expected_value):
                params_correct = False
        
        results.append({
            "name_correct": name_correct,
            "params_correct": params_correct,
            "overall": name_correct and params_correct
        })
    
    return {
        "name_accuracy": np.mean([r["name_correct"] for r in results]),
        "params_accuracy": np.mean([r["params_correct"] for r in results]),
        "overall_accuracy": np.mean([r["overall"] for r in results])
    }

各模型工具调用能力对比

模型工具选择准确率参数准确率并行调用支持复杂参数处理
GPT-4o95%92%优秀优秀
Claude-494%93%优秀优秀
Llama-4-70B89%85%良好良好
Qwen3-72B88%84%良好良好

常见错误模式

  1. 工具选择错误:选择功能相似但不完全匹配的工具
  2. 参数类型错误:字符串传为数字,数组传为字符串
  3. 必填参数遗漏:忽略required字段
  4. 枚举值错误:使用不在enum列表中的值
  5. 嵌套对象错误:复杂嵌套参数的生成质量较差

最佳实践

工具描述编写

好的工具描述对调用准确率至关重要:

{
  "name": "search_products",
  "description": "在商品数据库中搜索商品。支持按名称、类别、价格范围筛选。返回匹配的商品列表(最多50条)。如果需要查看商品详情,请调用get_product_detail。",
  "parameters": {
    "type": "object",
    "properties": {
      "query": {
        "type": "string",
        "description": "搜索关键词,如商品名称或描述中的词"
      },
      "category": {
        "type": "string",
        "enum": ["electronics", "clothing", "food", "books"],
        "description": "商品类别"
      },
      "min_price": {
        "type": "number",
        "description": "最低价格(单位:元)"
      },
      "max_price": {
        "type": "number",
        "description": "最高价格(单位:元)"
      }
    },
    "required": ["query"]
  }
}

关键原则:

  • 描述中包含使用场景和限制
  • 参数描述说明单位和格式
  • 枚举值列出所有选项
  • 在描述中提示相关的其他工具

结语

工具调用标准化是AI Agent生态成熟的关键标志。MCP协议正在扮演HTTP之于Web的角色——一个统一的协议层让工具开发者和模型开发者各司其职。当工具调用接口完全标准化后,竞争焦点将转向工具质量和Agent编排能力,而非接口适配。