函数调用是大模型的一种输出方式:模型不直接用文字回答,而是按事先约定好的格式,输出“要调用哪个外部函数、参数填什么”,再由程序真正去执行查询、计算或下单,最后把执行结果交回模型组织成自然语言。它让模型从只会说,变成能借别人的手做事——但请注意分工,动脑选工具的是模型,真正动手的从来不是模型本身。
先看一次完整的调用:订一间明天下午的会议室
假设你对助手说:明天下午三点,帮我订一间能坐 6 个人、带屏幕的会议室。没有函数调用时,模型只能回你一段建议,订没订成它说了不算。接好函数调用之后,流程会多出几步看不见的交接:
应用先把可用工具的清单告诉模型,每个工具都写清名字、用途和参数要求,比如订会议室这个函数需要日期、开始时间、人数和设备要求。模型对照你的话,选中这个函数,并把“明天下午三点”换算成具体日期和时间,人数填 6,设备填屏幕,输出一份结构化的调用请求。接下来轮到应用出场:它校验参数、真的去日历系统里查空闲并完成预订,再把“订成功,房间号 302”这样的结果回填给模型。模型最后才开口,用人话把结果告诉你。
整个过程里,模型输出的不是回答,而是一张填好的申请单。申请单格式对不对、该不该批、批完怎么执行,全是应用那一侧的事。
参数为什么必须写成 JSON Schema
模型选函数时最容易出错的地方,不是选哪个,而是参数怎么填:日期写成哪种格式、城市名用中文还是代码、人数是数字还是字符串,差一点执行就会失败。所以工具清单里对每个参数都要用 JSON Schema 这类格式规范写死类型、必填项和取值范围,模型照着模板填,应用再按同一份模板校验,不合规就打回重填或报错。
这也是函数调用和“让模型在回答里假装调用”的根本区别。提示词写得再详细,模型回一段像模像样的模拟结果,本质仍是编的;函数调用的返回结果来自真实系统,查到的航班就是真航班,订失败也会如实报错。判断一个产品是真能办事还是在演戏,看的就是结果有没有经过外部系统这一关。
和几个相近概念的边界
**和结构化输出的区别。**结构化输出只要求模型按固定字段交出 JSON,结果到此为止,没人拿去执行;函数调用是它的延伸,多了“执行并回填”这一段。把信息抽成表格是结构化输出,抽完直接拿去建日程,才是函数调用。
**和 MCP 的区别。**函数调用解决的是单个应用内部“模型怎么开口点名工具”,工具清单由这个应用自己维护;MCP 协议解决的是跨应用的统一接口,让同一批工具能被不同的模型和应用发现、复用。两者不在同一层,实际产品里经常叠在一起用:工具通过 MCP 接进来,模型仍靠函数调用的方式逐个点名。
**和智能体的区别。**函数调用是一次性的点名动作,本身不规划、不循环。智能体是把多次调用串起来的工作方式:先查航班、再比价格、然后下单、最后写进行程,中间还要根据每一步的结果决定下一步。没有函数调用这类机制,智能体就只剩空想;但只有函数调用、没有规划和纠错,也成不了智能体。
三个常见误解
**误解一:是模型自己在操作软件。**模型没有账号、没有权限,也碰不到你的日历和支付系统。它只负责提议,执行权始终在应用手里,应用完全可以拒绝一次不合规的调用。宣传里说得再神乎其神,落地时都要落到这条分工上。
**误解二:接上工具,它就不会出错了。**恰恰相反,函数调用把出错的方式变多了:函数会选错,城市会填错,同一件事可能重复执行两遍,工具返回的脏数据还可能把后面的回答带偏。它解决的是“能不能做”,不是“做得对不对”,校验、重试和兜底都得应用自己补上。
**误解三:工具越多,助手越强。**工具清单本身也要占上下文,几十个工具一股脑塞进去,模型反而容易挑花眼、选错行。做得好的产品会按场景筛选当前用得上的工具,而不是把工具箱整个倒出来。
能放心交给它做到哪一步
按风险给工具分级,是使用函数调用最重要的一条经验。查天气、查库存、算汇率这类只读操作,出错代价低,可以让模型直接调用;改数据、发消息、付款、下单这类会改变现实状态的操作,必须多一层确认:把函数名和关键参数明明白白摆给用户,点了确认才执行。权限也要按最小够用给,只查日程的工具就不该拿到删日程的权限。
还要留意一种新风险:工具返回的内容本身可能夹带指令。比如模型调用了一个网页读取工具,网页里藏着一句诱导它转账的话,它有可能当成命令照办。所以工具的返回结果只能当数据看,不能当指令听,这道防线要由应用在流程上守住,而不是指望模型自觉。
把这几条边界记住,再看各家发布的“模型能调用工具了”,就能分清哪些是真把执行链路打通了,哪些只是演示视频里跑得通。