📞 Function Calling 原理与实战

Function Calling(函数调用)是 LLM 与外部世界交互的核心机制。模型不再只生成文本,而是输出结构化的函数调用请求,由应用程序执行后将结果返回模型,形成感知—决策—执行的闭环。

🔄 工作流程

Function Calling 完整生命周期
用户消息 → 模型判断 → 输出工具调用 → 执行 → 返回结果 → 最终回复
1
用户输入 + 可用工具列表(含 Schema)发送给 LLM
2
LLM 决策:判断是否需要调用工具,如需则输出 tool_calls(含函数名 + 参数 JSON)
3
应用程序执行:解析 LLM 输出,调用对应的本地函数 / API
4
结果回传:将函数执行结果以 tool role 消息追加到对话上下文
5
LLM 整合:基于工具返回结果生成最终自然语言回复

📋 工具定义规范

不同模型厂商的 Function Calling 格式存在差异,但核心概念一致:名称、描述、参数 Schema

OpenAI vs Anthropic 格式对比

🤖 OpenAI (GPT-4o)
{
  "type": "function",
  "function": {
    "name": "get_weather",
    "description": "获取指定城市的天气",
    "parameters": {
      "type": "object",
      "properties": {
        "city": {
          "type": "string",
          "description": "城市名称"
        },
        "unit": {
          "type": "string",
          "enum": ["celsius", "fahrenheit"],
          "description": "温度单位"
        }
      },
      "required": ["city"]
    }
  }
}
🧠 Anthropic (Claude)
{
  "name": "get_weather",
  "description": "获取指定城市的天气",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名称"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "温度单位"
      }
    },
    "required": ["city"]
  }
}
特性OpenAIAnthropic
工具定义键type: "function" + function直接 name + input_schema
参数 Schema 键parametersinput_schema
多工具支持tools 数组tools 数组
并行调用✅ 原生支持✅ 原生支持
强制调用tool_choice: "required"通过 system prompt 约束
流式输出✅ 增量 tool_calls✅ 增量 content blocks

📐 参数 Schema 最佳实践

1
描述要清晰具体

描述不仅仅是给人看的,模型也依赖描述来理解工具的用途。避免模糊描述,给出使用场景和约束条件。

2
使用 enum 约束可选值

对有限选项的参数使用 enum,减少模型的幻觉和格式错误。

3
合理设置 required

只将真正必需的参数标记为 required。过多的必需参数会降低调用成功率,过少则可能导致关键信息缺失。

4
遵循 JSON Schema 规范

使用标准 JSON Schema (Draft 7+),支持 oneOfanyOf、嵌套对象等高级结构。避免使用不兼容的自定义扩展。

5
控制工具数量

每次请求的工具数量建议控制在 10-20 个以内。工具过多会增加模型选择错误的风险,可采用分步路由策略。

🎯 工具选择策略

策略原理适用场景优缺点
全量注册将所有工具一次性发给模型工具数 < 20✅ 简单直接
⚠️ 工具多时性能下降
分类路由先让模型选择工具类别,再下发该类工具工具数 20-100✅ 减少上下文消耗
⚠️ 需要额外的分类步骤
语义检索用 embedding 匹配用户意图最相关的 top-K 工具工具数 > 100✅ 可扩展性强
⚠️ 检索质量依赖 embedding
混合策略语义检索 + LLM 筛选大规模工具库✅ 兼顾精度与效率
⚠️ 系统复杂度高

🛡️ 错误处理与重试

常见错误类型

错误类型表现处理方式
参数格式错误JSON 解析失败、类型不匹配将错误信息反馈给 LLM,让其修正后重试
必填参数缺失缺少 required 字段提示 LLM 缺少哪个参数,请求补全
函数执行异常运行时错误、超时返回友好错误消息给 LLM,让其换用其他工具或降级处理
幻觉调用调用了不存在的工具或参数校验工具名称和参数 Schema,拒绝执行并提示
无限循环LLM 反复调用同一工具无进展设置最大调用轮次(通常 5-10 轮)

推荐重试策略

1
解析重试

参数 JSON 解析失败 → 将原始输出 + 错误信息反馈 LLM,最多重试 2 次

2
执行重试

函数执行超时或临时故障 → 指数退避重试(1s, 2s, 4s),最多 3 次

3
降级策略

重试全部失败 → 告知用户当前无法完成该操作,并提供替代方案

📊 主流模型 Function Calling 能力对比

模型FC 支持并行调用强制调用流式 FC严格模式多轮对话典型准确率
GPT-4o ✅ 原生 ✅ strict 模式~95%
GPT-4.1 ✅ 原生 ✅ strict 模式~96%
Claude 3.5 / 4 ✅ 原生 ⚠️ system prompt~93%
Gemini 2.5 Pro ✅ 原生 ~91%
DeepSeek-V3 ✅ 原生 ⚠️ prompt 引导~90%
Qwen-Max ✅ 原生 ⚠️ prompt 引导~88%
LLaMA 4 ✅ 原生 ⚠️ prompt 引导⚠️ 部分支持~87%

* 准确率为综合评测估算值,实际表现因具体场景和 prompt 设计而异。建议针对自身业务场景做专项评测。

💡 实战建议 从 GPT-4o 或 Claude 开始验证 FC 可行性,然后根据需要适配多模型。使用统一的工具定义中间层(如 LangChain 的 Tool 接口),便于在不同模型间切换。