资讯详情

资讯详情

从 Function Calling 到 MCP:大模型的“工具调用”到底是怎么回事

这篇讲什么模型能写诗、能改代码却不知道你的数据库里有什么。工具调用Tool Calling就是给它装上“手”的那一环。本文沿一条主线讲清两件事——Function Calling 到底是什么MCP 又为什么非出现不可。适合谁刚接触 Agent 开发、被 Function Calling / Tool Calling / MCP 几个词绕晕的同学想把大模型接进 Java 后端项目的开发者。一、先看问题模型被关在一个房间里大模型最擅长的事情是语言听懂你说了什么然后组织出一段像样的回答。但它的世界到“文字”就为止了——它读不到你库里那三百万条订单打不开你本地的配置文件也调不动你写了半年的下单接口。打个比方它像一个被关在房间里、知识极其渊博的顾问。你隔着门缝问它问题它能给你非常漂亮的建议但它没法自己下楼去档案室取资料也没法替你签字盖章。要让它真正办事就必须有人替它跑腿。这个“跑腿的人”就是我们自己写的后端代码。而“模型怎么告诉代码该跑哪一趟”正是工具调用要解决的问题。围绕这件事行业里有两个词经常被混着用Function Calling 和 MCP。它们不在同一个层面上——一个属于模型能力一个属于通信协议。下面逐个拆开。二、Function Calling让模型“开口要东西”一句话Function Calling 是大模型的一项能力——在需要外部数据时它不再输出自然语言而是输出一段结构化 JSON告诉程序“我要调哪个工具、传什么参数”。2.1 它到底是一段什么样的输出平时我们让模型回答它吐出来的是人话。但如果你在提问之前先告诉它“你手上有这些工具”它就有可能换成另一种输出一段结构化的 JSON内容是“我要调 get_weather城市传武汉”。这段 JSON就是我们常说的tool_call工具调用指令。这里顺手说清两个会反复出现的词JSON是一种用“键 值”描述数据的文本格式机器读起来毫不费力JSON Schema则是用 JSON 写的一份“参数说明书”用来告诉模型这个工具需要哪些参数、各是什么类型、哪些必填。2.2 关键认知模型只“点单”不下厨这是初学阶段最容易搞错的一点值得单独强调。模型不执行任何代码。它只输出“我要调什么、参数是什么”这段意图。真正去查数据库、跑业务逻辑、把结果拿回来的永远是你后端的代码。用餐厅打比方模型是坐在桌边的客人它负责看菜单、点菜你的代码是后厨负责真刀真枪做出来。客人说得再清楚菜也不会自己出现。2.3 一次工具调用的完整五步把链路摊开看其实非常朴素先交底提前把工具名单交给模型每个工具带上名字、用途描述和参数 Schema。提问用户问“武汉今天多少度”模型判断——这个我编不出来得去查。下单模型输出 tool_call指名道姓说调哪个工具、传什么参数。办事后端捕获这段结构解析出工具名和参数执行对应的业务代码。回话把执行结果放回对话上下文模型据此组织成最终回答。注意第 2、3、5 步是模型在做第 1、4 步是你的代码在做。这个分工是后面所有概念的骨架——MCP 也是在这套骨架上做加法。2.4 从 Function Calling 改名叫 Tool Calling这项能力最早由 OpenAI 推出当时叫 Function Calling因为它确实就是调“函数”。后来能调的东西越来越多搜索引擎、数据库、文件系统、HTTP 接口……“函数”这个词兜不住了行业便慢慢改口叫Tool Calling。名字换了思想没变让模型用一种结构化的方式表达“我要用某个外部能力”。三、原生 Function Calling 的痛点每家厂商一套方言一句话Function Calling 只有“能力”没有“标准”。tool_call 长什么样各家模型自己定——字段名、嵌套层级、参数类型全都不一样。3.1 两家最典型的写法同样是“查武汉天气”OpenAI 和 Claude 返回的结构是这样的{ tool_calls: [ { id: call_123, type: function, function: { name: get_weather, arguments: {\city\:\武汉\} } } ] }特点是顶层是tool_calls 数组函数信息被包在function 对象里而arguments 是一个JSON字符串——你得自己再反序列化一次才能真正用。{ content: [ { type: tool_use, id: tu-123, name: get_weather, input: {city: 武汉} } ] }Claude 这边压根没有 tool_calls 字段调用块混在content 数组里类型标记为tool_use参数字段叫input而且直接就是 JSON 对象。3.2 三个要命的差异差异点OpenAI 风格Claude 风格对代码的影响顶层容器tool_calls 数组content 数组里的 tool_use 块去哪里找调用块写法不同参数载体arguments 是 JSON 字符串input 直接是 JSON 对象一个要二次反序列化一个拿来就用类型标识type: functiontype: tool_use判断分支的条件不同3.3 代价M × N 的适配地狱如果你手写解析那这套逻辑只认一家。项目要换模型、或者要同时接多家就得写多套分支——M 个模型 × N 个工具代码里长满 if-else每加一家都要把回归测试重跑一遍。有人会说“国产模型不都兼容 OpenAI 吗”这是厂商主动做的兼容不是标准。一旦碰上不兼容的比如 Claude问题立刻现形。这类差异通常由应用层自己消化——写一层归一化或者交给框架。但那属于实现细节。真正更难的是另一个问题工具本身散落在各处每个应用都要重新接一遍。四、MCP给工具定一个通用插座一句话MCPModel Context Protocol模型上下文协议是一份「方法名 参数结构」的约定跑在 JSON-RPC 上。它管工具怎么暴露、怎么被发现、怎么被调用不管模型怎么理解。4.1 它到底是一份什么约定全部动作只有三类。用途方法干什么握手initialize交换协议版本各自声明支持哪些能力发现tools/list返回工具清单名字、描述、参数 Schema调用tools/call传工具名和参数返回执行结果加上 resources 和 prompts 的同构版本就是它的全部。协议本体薄到一个下午能读完——它不是框架不含调度循环、不含重试、不含上下文管理。4.2 它不是什么把常见的误认一次排掉对照着记更牢容易误认成实际是Function Calling 的新版本模型侧完全没变还是输出 tool_call一个框架一纸约定加各语言 SDK没有运行时一种传输协议底下是管道或 HTTP它只管消息长什么样必须联网的服务stdio 模式就是本机两个进程走管道4.3 为什么需要它N × M 变成 N M没有统一协议时每个 AI 应用都要为每个工具单独写一套对接逻辑N 个应用 × M 个工具就是 N × M 份代码。有了 MCP工具方写一次 Server应用方写一次 Client中间用协议对接复杂度降到 N M。这个套路程序员很熟——LSP 就是这么解决「N 个编辑器 × M 门语言」的语言方提供一个服务所有编辑器都能接。MCP 想做的是同一件事只是把语言换成了工具。4.4 三个角色角色是什么职责HostAI 应用本身对接模型、管权限哪些工具可调、调到什么程度MCP ClientHost 内部的通信层和 Server 收发 JSON-RPC 消息MCP Server独立进程或远程服务暴露能力本地走 stdio远程走 HTTP4.5 能暴露什么三类原语MCP 的能力边界比「工具调用」更宽它定义了三类核心原语原语含义典型场景由谁发起Tools带副作用的操作写文件、发请求、改数据模型决定调用Resources只读的上下文资源本地 Markdown、数据库表结构Host 直接注入上下文Prompts可参数化的提示模板预制好的分析或总结模板Host 主动拉取最实际的区别在中间那行Resources 不需要模型申请。Host 觉得有用就直接读出来塞进上下文模型看到的是「已经摆在桌上的材料」而不是「还要去要的材料」。省 token、控延迟都靠这个。4.6 跑一次六步只有第 4 步归协议管——把调用送出去、把结果拿回来。第 3 步是模型自己完成的MCP 一步都没碰。它只是把「工具住在哪里、由谁来执行」抽了出去变成独立服务。收益也就很直接工具改一次所有 Host 立刻可用新工具上线拉一下 tools/list 就发现不用改代码发版。4.7 和 Function Calling 的分工解决什么属于Function Calling模型怎么表达「我要调工具」模型能力MCP工具怎么暴露、怎么被发现、怎么被复用通信协议一句话记住Function Calling 是模型的表达能力MCP 是工具的接入方式。两者配合不是替代。五、两者关系一张图收尾两层的分工可以一句话概括MCP决定工具从哪来Function Calling 决定模型怎么选。缺了上层工具进不来缺了下层模型不会自己开口。落到实际选型判断标准很简单你的情况该做什么只有一个应用工具都是自己写的手写 Function Calling 就够不必上 MCP工具要给多个应用、多个团队复用做成 MCP Server一次开发、多处接入要同时接多家模型自己写一层归一化或用现成框架与 MCP 无关六、写在最后工具调用是 Agent 开发最核心的基础能力而整个生态正在从“各家私有、零散实现”慢慢走向标准化。这个进程里两层分工已经相当清晰Function Calling管“模型怎么表达”——能力层由模型厂商定义MCP管“工具怎么接入”——协议层由生态共同维护。至于“各家格式怎么消化”MCP 管不到模型厂商也不会替你管。它通常落在应用层——写一层归一化或者交给框架。但那是实现细节不改变上面这两层的分工。把这两层看清之后再去看任何一份工具接入文档、任何一个 Agent 项目你都能很快定位它在解决哪一段问题——而不是继续把 Function Calling、Tool Calling、MCP 混成一团。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →