跳到主内容
AIHO 2026 全新改版上线
概念Function Calling工具调用Agent

Function Calling(函数调用)

让大模型根据用户意图自动选择并调用外部函数/API 的能力。是 AI Agent 的基础能力,让模型从对话进化到行动。

什么是 Function Calling

Function Calling(函数调用)是让大模型调用外部函数的能力。你告诉模型有哪些函数可用,模型根据用户意图决定调用哪个函数、传什么参数。

用户:"上海今天天气怎么样?"
  ↓
模型分析:需要查天气 → 调用 get_weather("上海")
  ↓
你的代码执行 get_weather("上海") → 返回 { temp: 28°C, condition: "多云" }
  ↓
模型基于返回结果生成回答:"上海今天 28°C,多云,适合出行。"

注意:模型自己不能执行函数。它只输出"我想调 get_weather('上海')"这条意图,真正的 HTTP 请求 / DB 查询是你的应用代码去跑。这是 Function Calling 最容易被误解的一点。

工作原理

1. 定义函数

你向模型提供函数的 JSON Schema 描述:

{
  "name": "get_weather",
  "description": "查询指定城市的天气",
  "parameters": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "城市名,如'上海'"
      }
    },
    "required": ["city"]
  }
}

2. 模型决定调用

模型根据用户输入,决定是否需要调用函数:

{
  "function_call": {
    "name": "get_weather",
    "arguments": "{\"city\": \"上海\"}"
  }
}

3. 你执行函数

你的代码执行实际函数调用,返回结果给模型:

result = get_weather("上海")  # { temp: 28, condition: "多云" }

4. 模型生成最终回答

模型基于函数返回结果生成自然语言回答。

Parallel Tool Calls:一次调多个

现代模型(GPT-4o+、Claude Sonnet 4+、Gemini 2.5+)支持单轮内发起多个工具调用。例如用户问"对比上海和北京的天气":

// 模型一次返回两个 tool_call
{
  "tool_calls": [
    { "id": "t1", "function": { "name": "get_weather", "arguments": "{\"city\":\"上海\"}" } },
    { "id": "t2", "function": { "name": "get_weather", "arguments": "{\"city\":\"北京\"}" } }
  ]
}

应用层可以并行执行这两个调用,把两个结果一起回给模型。能省一轮往返延迟。陷阱:

  • 不是所有 API 都默认开启,要看 parallel_tool_calls 参数
  • 并行的调用之间不能有依赖(B 的输入需要 A 的输出就不能并行)
  • 模型对"什么时候适合并行"判断不总是对——独立查询通常 OK,有顺序的操作(先建用户再发通知)会被错并行

Structured Outputs / JSON Mode

Function Calling 的近亲:让模型保证按指定 JSON Schema 输出。区别是不调函数、就要结构化数据本身。

平台机制
OpenAI Structured Outputsresponse_format: { type: "json_schema", strict: true },保证 100% 符合 schema
OpenAI JSON Moderesponse_format: { type: "json_object" },只保证是合法 JSON,结构不保证
Anthropic Tool Use用 tool definition 当 schema 模板,模型一定按 schema 填
Google GeminiresponseMimeType: "application/json" + responseSchema

用途:从非结构化文本提取结构化信息(PDF 解析、表单填写、分类打标),比 prompt 让模型"输出 JSON"稳定得多。

与 MCP 的关系

Function Calling 是模型层面的能力(模型决定调什么函数)。 MCP 是协议层面的标准(标准化函数发现和调用的方式)。

MCP 底层依赖 Function Calling,但提供了更完整的生态:

  • 动态发现 Server 能力
  • 标准化的工具/资源/提示词暴露方式
  • 跨工具复用

主流模型 FC 能力对比

模型ParallelStrict Schema工具数上限(实测稳定)
GPT-5 / GPT-4o✅ Structured Outputs100+
Claude Sonnet 4✅ Tool Use50-100
Gemini 2.5 Pro✅ responseSchema50+
DeepSeek V3部分30-50
GLM-5部分30-50
早期开源(Llama 3 等)⚠️ 部分10-20

经验:工具列表超过 20-30 个,所有模型的选择准确率都会下降。这是为什么 Agent 设计里常见"工具分组 / 分层路由"——先选一个工具组,再在组内选具体工具。

实际应用

AI 编程工具

Cursor / Claude Code 的 function calling:

{
  "name": "read_file",
  "description": "读取文件内容",
  "parameters": { "path": "string" }
}
{
  "name": "edit_file",
  "description": "编辑文件",
  "parameters": { "path": "string", "old": "string", "new": "string" }
}
{
  "name": "run_terminal",
  "description": "执行终端命令",
  "parameters": { "command": "string" }
}

Agent 平台

Coze / Dify 中的自定义工具就是 function calling:

  • 定义工具的输入输出
  • 模型自动编排调用顺序
  • 支持多步工具链

企业应用

  • 查询数据库(自然语言 → SQL → 结果)
  • 调用内部 API(ERP/CRM/OA)
  • 发送通知(邮件/钉钉/飞书)

最佳实践

1. 描述要清晰

// ❌ 模糊
{ "name": "search", "description": "搜索" }

// ✅ 清晰
{ "name": "search_docs", "description": "在企业知识库中全文搜索文档,返回最相关的 5 条结果" }

2. 参数类型要明确

// ❌ 不清楚枚举值
{ "unit": { "type": "string" } }

// ✅ 明确枚举
{ "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }

3. 提供错误处理

函数执行失败时,返回结构化错误让模型理解:

{ "error": "city_not_found", "message": "找不到城市'上海'" }

模型看到结构化错误能自己修正(比如把"上海"补成"上海市"再试一次);看到 HTTP 500 那种 stack trace 反而容易卡住。

4. 限制函数数量

一次提供太多函数会让模型困惑。建议:

  • 核心函数 5-10 个
  • 用 Agent 模式分步调用
  • 或用 MCP 动态发现

调试技巧

线上 FC 不稳定时,按顺序排查:

  1. 看模型是不是真选错了——把 tool_calls 完整 dump 出来。常见情况是模型选对了但参数错了。
  2. 降温到 0——把 temperature 设 0 让结果可复现,再调 prompt 和 schema。详见 Temperature 与 Top-P
  3. 加 description 到具体例子——"description": "查城市天气。例:city='上海' → 返回 {temp, condition}"。模型对例子比对类型描述敏感。
  4. 检查 strict mode——如果用了 strict: true 但 schema 写得不严(少 required、字段类型 union),模型会被卡住一直生成不合规的输出。
  5. 看模型有没有"幻觉调用"——明明没给的工具名也敢叫。这是 prompt 里历史轮里残留了不存在的工具描述,清掉。

延伸阅读

  • 协议层:MCP——把工具描述从应用搬到 Server
  • Agent 视角:AI Agent——FC 是 Agent 闭环里的「Action」环节
  • 控制随机性:Temperature 与 Top-P