Function Calling 实战:让大模型调用外部工具的完整指南

什么是 Function Calling?

Function Calling(函数调用) 是大语言模型的一项关键能力,允许模型在对话过程中生成结构化的 JSON 输出,指示应用程序调用预定义的外部函数。

简单说:你告诉模型"你可以用这些工具",模型会在需要时自动决定调用哪个工具、传什么参数。

用户: "北京今天天气怎么样?"

模型思考: 我需要查询实时天气 → 调用 get_weather 函数

模型输出: {
  "function": "get_weather",
  "arguments": { "city": "北京" }
}

应用执行: get_weather("北京") → "晴,25°C"

模型最终回复: "北京今天天晴,气温 25°C,适合出行。"

核心流程

Function Calling 的完整流程分为 4 步

第 1 步:定义可用函数

使用 JSON Schema 描述函数的名称、功能和参数:

{
  "name": "get_weather",
  "description": "查询指定城市的实时天气信息",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称,如"北京""
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "温度单位,默认摄氏度"
      }
    },
    "required": ["city"]
  }
}

第 2 步:发送请求(附带函数定义)

from openai import OpenAI

client = OpenAI(
    api_key="your-key",
    base_url="https://api.your-relay.com/v1"
)

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "查询指定城市的实时天气",
        "parameters": {
            "type": "object",
            "properties": {
                "city": {"type": "string", "description": "城市名称"}
            },
            "required": ["city"]
        }
    }
}]

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "北京今天天气怎么样?"}],
    tools=tools,
    tool_choice="auto"
)

第 3 步:执行函数并回传结果

import json

message = response.choices[0].message

if message.tool_calls:
    tool_call = message.tool_calls[0]
    args = json.loads(tool_call.function.arguments)

    # 执行实际的外部函数
    weather_data = get_weather(args["city"])

    # 将结果作为 tool 消息回传
    follow_up = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "user", "content": "北京今天天气怎么样?"},
            message,  # 模型的 tool_call 消息
            {
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(weather_data)
            }
        ]
    )
    print(follow_up.choices[0].message.content)

第 4 步:模型基于结果生成最终回复

模型会结合函数返回的真实数据,生成自然语言的最终回答。

Node.js 实现

import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: 'your-key',
  baseURL: 'https://api.your-relay.com/v1'
})

const tools: OpenAI.Chat.ChatCompletionTool[] = [{
  type: 'function',
  function: {
    name: 'search_products',
    description: '在商品库中搜索商品',
    parameters: {
      type: 'object',
      properties: {
        keyword: { type: 'string', description: '搜索关键词' },
        max_price: { type: 'number', description: '最高价格' }
      },
      required: ['keyword']
    }
  }
}]

const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '帮我找 200 元以内的蓝牙耳机' }],
  tools,
  tool_choice: 'auto'
})

实际应用场景

场景函数示例说明
数据查询query_database查询订单、库存等结构化数据
信息获取search_web联网搜索最新资讯
任务执行send_email发送邮件、创建日程
文件操作read_file读取、分析用户上传的文件
计算工具calculate精确数学计算

并行调用与多轮调用

并行调用

现代模型支持在一次响应中同时调用多个函数

用户: "对比北京和上海的天气"
模型: [get_weather("北京"), get_weather("上海")]  // 并行两个调用

多轮调用

复杂任务可能需要多轮函数调用,模型会根据前一次的结果决定下一步操作。

哪些模型支持 Function Calling?

模型支持程度说明
GPT-4o / GPT-5⭐⭐⭐⭐⭐原生支持,最成熟
Claude Sonnet/Opus 4⭐⭐⭐⭐⭐Tool Use 协议
Gemini 2.5 Pro⭐⭐⭐⭐支持并行调用
DeepSeek-V3⭐⭐⭐基础支持
开源模型⭐⭐取决于微调质量

最佳实践

  1. 函数描述要精确:模型依靠描述来判断何时调用,含糊的描述会导致误判
  2. 参数用 enum 约束:能枚举的字段用 enum 而非 string,减少出错
  3. 做好错误处理:函数执行失败时,将错误信息返回给模型让它修正
  4. 控制工具数量:单次对话暴露 5-10 个工具最佳,太多会影响选择准确率
  5. 结合中转站:通过中转站使用 Function Calling,可以用更低的成本实现相同功能

💡 使用 APIS 费用计算器 估算 Function Calling 场景下的实际 Token 开销。