Function Calling · 工具调用

函数调用:让大模型从「会聊」变成「会干」

大模型天生只会「说话」,不会「做事」。Function Calling(函数调用 / 工具使用)就是把一句自然语言,翻译成一次真正的动作——查天气、读数据库、发邮件、跑代码。本文用时间线、对比图和一段真实故事,把它的来龙去脉讲清楚。

01开场:从「陪聊」到「办事」

想象你雇了一个记忆力超群、读过万卷书的助手。你问他「明天北京会下雨吗」,他微笑着说:「根据我训练时看到的规律,北京在夏秋交界时常有阵雨。」——听起来有道理,但他根本没看明天的天气预报。

问题不在他聪不聪明,而在于他被关在一个只有文字的房间里:能说,不能查;能猜,不能算;能编,不能做。Function Calling 就是给这间屋子开了一扇门——门外是真实世界,是工具,是能真正改变状态的操作。

一句话定位:Function Calling 让模型输出「我要调哪个函数、参数是什么」的结构化指令,由外部程序去执行,再把结果喂回模型。模型从「答案的生产者」变成「行动的决策者」。

02背景:LLM 的三个天生短板

为什么非得有 Function Calling?因为它补的是大模型出厂自带的硬伤。下面这段对话很典型:

🧑 你
帮我查下现在上海的温度,顺便算 12345 × 67890 等于多少。
🤖 旧式 LLM
上海大概在 20~28 度之间吧。乘法的话……大约是 8.3 亿左右。其实我不太确定,建议你自己查一下。

⏱知识会过期

训练数据有截止日期,之后的事(实时股价、今天天气、刚上的新闻)一概不知,只能「编造一个像样的」。

🧮算不准

语言模型本质是「预测下一个词」,不是计算器。大数乘除、精确统计、复杂推理容易出错,还特别自信。

🔒碰不到现实

不能读数据库、不能调 API、不能发消息、不能下单。它的世界只有输入过的那几段文本。

这三道墙,靠「把模型训得更大」也跨不过去——因为有些信息根本不在训练数据里,有些动作根本不该由模型自己完成。唯一的办法是:让模型学会「我不知道 / 我算不了 / 我办不到时,去叫工具」。

这正是 Function Calling 出现的历史必然性:不是锦上添花,而是把「会聊的天」变成「能用的助手」的必经之路。

03历史:Function Calling 是怎么来的

它不是某天突然冒出来的,而是「想让 AI 用工具」这件事,从土办法一步步走到原生能力的进化史。

2020前 规则 Bot Siri/插件 2020–22 Prompt 里塞 JSON few-shot 约定 2023.06 OpenAI 原生 function calling 2024 并行/结构化 MCP 标准化 2025+ Agent 基础设施 默认能力 智能靠规则,工具靠 硬编码;没有「理解」 的自然语言入口 GPT-3 后靠提示词让 模型「吐 JSON」;脆弱、 常格式崩坏 模型被专门训练成 「输出合法调用」;可靠、 成为一等公民 一次返回多个调用; MCP 让工具「即插即 用」标准化 FC 成为 Agent 的 底座;框架自动编排 「思考-行动」

关键转折:从「约定」到「原生」

早期(2020–2022)大家靠 prompt 工程:在提示里写「请只返回 JSON {"tool":"...","args":{...}}」,再用代码去解析。这能跑,但模型经常不守规矩——多了个逗号、加了句解释、漏了字段,解析就崩。本质是把「结构化输出」这种硬工程问题,甩给了本来就爱自由的生成模型。

2023 年 6 月,OpenAI 在 API 里加入 tools / functions 参数:模型被专门训练去识别「什么时候该调用、调哪个、参数怎么填」,并且输出被约束成机器可校验的 JSON。从「求模型配合」变成「模型天生就会」。之后 Claude、Gemini 等纷纷推出等价的 tool use / function declarations,能力成为行业标配。

里程碑意义:Function Calling 把「用工具」从 hack 变成了模型的内置能力,是今天所有 AI Agent、AI 搜索、AI 办公的起点。

04它解决了什么:把「语言」变成「动作」

用一张图看 Function Calling 前后,同一个问题发生了什么变化。

没有 Function Calling 用户:北京明天天气怎么样? 模型:根据经验,北京初秋多晴,气温约 18~26℃。 (猜测,未查实) 结果:一个「看起来合理」的幻觉答案, 无法行动,也无法验证。 有了 Function Calling 用户:北京明天天气怎么样? 模型:调用 get_weather(city="北京", date="明天") → 系统执行 → 回填实况 结果:真实温度 22℃、多云;模型据此 给出可执行的建议(带伞/穿衣)。 质变

🔌打通真实世界

模型能查询实时数据、调用业务系统,回答不再是「训练记忆里的回声」,而是「此刻的事实」。

⚙️把计算外包

精确运算、检索、统计交给专门的程序,模型只负责「决策用哪个工具」,准确率与可靠性大幅提升。

🤝从「答」到「办」

能发邮件、下单、写库——AI 第一次具备「改变外部状态」的能力,从参谋变成执行者。

🧠承认「不知道」

模型学会在不确定时求助工具,反而更可信;幻觉被「查证回路」天然抑制。

05原理:一次调用长什么样

核心就三步:你告诉模型有哪些工具 → 模型决定调哪个、填什么参数 → 你执行并把结果还回去。工具用 JSON Schema 描述,模型生成的就是一份合规的「调用申请」。

① 描述工具(Tool Schema)

{
  "name": "get_weather",
  "description": "查询指定城市、指定日期的天气",
  "parameters": {
    "type": "object",
    "properties": {
      "city":  {"type": "string", "description": "城市名,如 北京"},
      "date":  {"type": "string", "description": "日期,如 明天 / 2026-09-08"}
    },
    "required": ["city"]
  }
}

注意 description 极重要:模型靠它判断「该不该调、怎么填」。写得含糊,模型就乱调。

② 模型决策 → 执行 → 回填(循环)

① 用户问题+ 工具清单 ② 模型决策选工具+填参数 ③ 你来执行函数/API ④ 结果回填作为新上下文 ⑤ 最终回答不再调用 若还需查别的信息,回到 ② 继续循环
模型不会自己执行函数——它只产出「调用意图」。真正跑代码、查数据库的是你的后端。控制权始终在你手里,这也是安全的来源。

06怎么用:一个最小实战架子

下面是一段「伪代码」,展示最常见的 ReAct 循环(思考—行动—观察)。真实 SDK(OpenAI / Anthropic / 通义等)接口细节不同,但骨架一致。

messages = [用户问题]
tools = [get_weather, search_web, calc]   # 你的工具 schema 列表

while True:
    resp = llm.chat(messages, tools=tools)   # 把工具清单交给模型
    if not resp.tool_calls:                  # 模型说「不用工具了」
        print(resp.text)                     # → 这就是最终回答
        break

    for call in resp.tool_calls:            # 可能一次多个(并行)
        args = json.loads(call.arguments)    # 模型填的参数
        result = run_tool(call.name, args)   # 你来执行(校验后再跑!)
        messages.append({                    # 把结果回填进上下文
            "role": "tool",
            "tool_call_id": call.id,
            "content": result
        })
三道防线:① 执行前校验参数(类型/范围/是否在白名单);② 写操作(发邮件/删数据)加权限与确认;③ 防提示注入——工具返回的内容可能夹带「恶意指令」,别让它直接控制流程。

并行调用

当多个工具互不依赖(同时查天气和汇率),模型一次返回多个 tool_call,你并发执行,省掉往返延迟。这是 2024 年后主流模型都支持的能力。

07应用场景:AI 的工具箱

凡是「模型干不好、但程序很擅长」的事,都适合交给 Function Calling。下面是几类高频场景:

🌐实时信息

天气、股价、汇率、航班、新闻——补足知识截止的短板。

📚检索与知识

查数据库、搜内部文档、RAG 召回——让回答有依据。

🧮精确计算

计算器、日历排期、单位换算——把算不准的活外包。

💻代码执行

跑 Python 分析数据、画图表——让模型「动手算」而非「嘴上算」。

✉️执行动作

发邮件、建工单、下单、写库——AI 第一次能改变现实状态。

🔗外部 API

调支付、地图、CRM——把 SaaS 世界连进对话。

一句话记忆:「查、算、搜、做」四类动作,几乎覆盖了今天所有「能用的 AI 助手」。

08一个完整故事:订机票 + 查天气

把前面所有概念串起来。用户只说了一句话,背后却跑了好几轮 Function Calling:

🧑 你
「帮我看看这周五从上海飞北京的机票,再告诉我北京那天天气,合适的话直接帮我订最便宜的那班。」
模型拆解任务:需要先查航班、查天气,再决定订哪班。它先调用 search_flights(from="上海",to="北京",date="这周五")。
你执行并回填:后端查航班 API,返回 3 个班次与价格。模型看到结果,留下「最便宜班次」候选。
模型继续调用:get_weather(city="北京",date="这周五")。回填:多云、22℃。
模型综合判断:天气无碍,选最便宜班次,调用 book_flight(flight_id="...")。写操作触发确认环节,你弹窗让用户二次确认。
最终回答:模型不再调用工具,输出「已为您预订周五 CA18xx,北京多云 22℃ 无需带伞,登机口稍后通知」。任务闭环。

整个过程里,模型始终是指挥官,工具是手脚,而「确认订票」这种危险动作由你的代码把关。这就是 Function Calling 最动人的样子:自然语言进,真实结果出。

09发展:并行、结构化、MCP、Agent

⚡并行调用

一次返回多个独立调用,并发执行,大幅降低多工具任务的延迟。

📐结构化输出

从「调工具」延伸到「按 schema 出 JSON」,用于抽取、分类、表单填充。

🔌MCP 协议

2024 年提出的工具「标准化接入协议」:工具如何被发现、调用、返回有了统一规范,模型与工具解耦,即插即用。

🤖Agent 编排

把「调用工具」放进自主循环,加规划、记忆、反思,FC 成为 Agent 的能力底座。

三者层次:Function Calling 是能力(模型会不会调),MCP 是标准(工具怎么接),Agent 是用法的编排(调起来干什么)。常被一起考,别混为一谈。

10常见坑

参数非法

模型可能生成 schema 外的字段/类型,必须服务端校验再执行,别直接 eval。

幻觉调用

编造不存在的工具或参数,需约束可调用集合、校验 name 是否真的是你注册的工具。

副作用失控

写操作要权限、确认或沙箱;警惕工具返回内容里的「提示注入」。

流式解析

流式输出下要能增量拼出完整 JSON 再执行,解析失败要有重试与兜底。

陷入死循环

模型反复调用却不给终态,要设最大轮数(max_turns)强制收口。

成本与延迟

每轮都把工具结果塞回上下文,长链路会撑爆 token、拖慢响应,注意裁剪。

11一图总结

自然语言 用户的请求 Function Calling 模型决策+填参 真实工具 执行+回填 真实结果 可行动 语言 → 动作 → 事实

Function Calling 不是某个花哨功能,而是大模型「落地成人手」的那块基石:它把会聊的天,变成了会干的活。理解了它,也就理解了今天所有 AI Agent、AI 搜索、AI 办公产品的共同起点。

想看面试速记版(协议细节 / schema 设计 / 与 MCP·Agent 关系 / 速记卡)?→ 函数调用与工具使用(面试版)