Function Call、Tool、MCP:大模型工具调用三件事

📅 2026/7/23 8:58:15 👁️ 阅读次数 📝 编程学习
Function Call、Tool、MCP:大模型工具调用三件事

Function Call、Tool、MCP:大模型工具调用三件事

    • 一、大模型缺什么
    • 二、Function Call:让大模型学会“下命令”
    • 三、Tool:自带描述和干活逻辑的方法
    • 四、完整流程:本地 Tool
    • 五、为什么执行完还要回传大模型
    • 六、Tool 多了的麻烦
    • 七、MCP:让第三方自己提供 Tool
      • 7.1 核心思路
      • 7.2 两方各自做什么
      • 7.3 SDK 是什么,在哪用
      • 7.4 我们怎么写代码:两种方式
    • 八、MCP 配置实战
      • 8.1 配置文件
      • 8.2 框架启动时自动做了什么
      • 8.3 大模型该怎么调还怎么调
      • 8.4 调用流程
    • 九、有无 MCP 对比
    • 十、演变总结
    • 十一、速记卡

一、大模型缺什么

大模型能做的大模型不能做的
回答学过的东西查实时天气
理解你给的文章调你的 API
翻译、润色操作你的文件

它缺“手”和“眼”,需要工具帮忙。


二、Function Call:让大模型学会“下命令”

大模型不直接说人话,而是输出一段 JSON,告诉程序:“我要调用哪个函数,参数是什么”。

普通对话Function Call
“您可以打开天气 App 看北京天气”{"function":"get_weather","city":"北京"}

格式谁定的:大模型厂商内置好的,你不用教它。

填什么内容:大模型根据你给的“工具菜单”和用户的话,自己匹配工具、提取参数。


三、Tool:自带描述和干活逻辑的方法

Tool 就是一个方法,包含两部分:

Tool 里有什么作用给谁看
描述部分(名称、功能描述、参数定义)告诉大模型“我能干嘛、需要什么参数”大模型
执行逻辑(方法体里的代码)真正干活的代码,调 API、跑脚本程序自己

用 Java 写一个本地 Tool:

@Tool(name="get_weather",description="查询指定城市的实时天气")publicStringgetWeather(@ToolParam(description="城市名称")Stringcity){return天气API.query(city);// 执行逻辑}
组成部分代码里写的作用
名称get_weather大模型在 JSON 里填这个名字
描述“查询指定城市的实时天气”大模型据此判断能不能用
参数city,城市名称大模型知道要传什么
执行逻辑调天气 API大模型不关心,程序自己跑

四、完整流程:本地 Tool

天气API大模型应用程序用户天气API大模型应用程序用户1. 发送工具列表(Tool 描述)2. “查北京天气”3. 转发用户的话4. 匹配 get_weather5. {“function”:“get_weather”,“city”:“北京”}6. 解析,执行 get_weather7. 调 API8. {“temp”:25,“weather”:“晴”}9. 回传原始数据10. 润色11. “北京今天晴天,25度”12. 展示

一句话:大模型点菜(JSON),程序炒菜(执行方法),大模型上菜(润色)。


五、为什么执行完还要回传大模型

程序拿到的是原始数据,不会“说人话”。

原始数据用户期待的回复
{"temp":25,"weather":"晴"}“北京今天晴天,25度,体感舒适。”
角色负责
Tool 执行逻辑动手拿数据
大模型动脑判断 + 动嘴润色

六、Tool 多了的麻烦

早期每接一个第三方服务,都要手写一个 Tool。

服务开发者要做什么
天气手写 Tool 封装 API
GitHub手写 Tool
地图手写 Tool

本质问题:我们在替服务方写 Tool。


七、MCP:让第三方自己提供 Tool

7.1 核心思路

第三方服务按统一标准封装接口,我们直接连,不用替它写 Tool。

类比:

  • MCP 之前:买电器送裸线,自己接插头
  • MCP 之后:电器出厂自带标准插头,直接插

7.2 两方各自做什么

角色做什么用什么
第三方服务方把自己的 API 封装成 MCP 服务MCP 官方提供的 SDK
我们配置连接地址,直接调用配置文件里写 URL

7.3 SDK 是什么,在哪用

SDK(软件开发工具包)是 MCP 官方提供的一套现成工具包,给第三方服务方用的。第三方用这个 SDK,可以把自己的服务(比如 GitHub API)快速变成一个标准的 MCP 服务端,暴露一个 URL 出来。

SDK 是第三方用的,不是我们用的。我们的 Java 程序不需要引入 MCP SDK,只需要配一个 URL。

7.4 我们怎么写代码:两种方式

方式做法适用场景
本地手动封装自己写@Tool方法,方法体里调第三方 API第三方没提供 MCP 接口
MCP 配置连接在配置文件里写 URL,框架自动拉取第三方提供了 MCP 服务端

如果第三方提供了 MCP 服务,我们选第二种,零代码。


八、MCP 配置实战

8.1 配置文件

假设有三个第三方服务都提供了 MCP 接口:

spring:ai:mcp:client:connections:github:type:STREAMABLE_HTTPurl:https://github-mcp.example.com/mcpweather:type:STREAMABLE_HTTPurl:https://weather-mcp.example.com/mcpemail:type:STREAMABLE_HTTPurl:https://email-mcp.example.com/mcp

有多少个 MCP 工具,就配多少个connections节点。不需要为每个工具写 Java 类。

8.2 框架启动时自动做了什么

1. 读取配置文件里的 MCP 连接列表 2. 逐个连接 MCP 服务端 3. 从每个服务端拉取它提供的工具描述 4. 把这些工具描述合并到本地 Tool 列表中 5. 把完整的工具列表发给大模型

你不需要手动写任何代码去拉取、合并、发送。框架全自动完成。

8.3 大模型该怎么调还怎么调

大模型眼里,所有工具都一样,不区分是本地的还是 MCP 远程的。它照样输出 Function Call:

{"function":"github_search","arguments":{"query":"AI agent"}}

框架收到后自动判断:这个工具来自 MCP,走 MCP 协议远程调用,拿到结果回传大模型润色。

8.4 调用流程

MCP服务端(第三方)大模型应用程序用户MCP服务端(第三方)大模型应用程序用户1. 启动时自动拉取 MCP 工具,合并到工具列表,发给大模型2. “搜索 GitHub AI 项目”3. 转发4. {“function”:“github_search”,“query”:“AI agent”}5. 框架自动走 MCP 协议请求远端6. 返回结果7. 回传润色8. 最终回复9. 展示

九、有无 MCP 对比

对比项没有 MCP有 MCP
接一个工具要写多少代码一个完整的@Tool一行 YAML 配置
接十个工具十个@Tool十段 YAML 配置
工具更新维护改代码,重新部署第三方自己更新,我们不用动
工具列表发给大模型手动收集框架自动合并本地 Tool + MCP 工具
调用逻辑框架自动框架自动(跟本地 Tool 一样)

十、演变总结

阶段核心
起点大模型没手没脚
Function Call大模型能下命令(输出 JSON)
Tool方法含描述和执行逻辑,描述给大模型看,逻辑自己跑
MCP第三方自己封装,我们配置 URL 直接用

十一、速记卡

Function Call = 大模型下命令的语法 Tool = 描述(给大模型看)+ 执行逻辑(自己跑) MCP = 第三方用官方 SDK 封装服务,我们配 URL 直接连 本地 Tool 和 MCP 工具的关系: 大模型眼里都一样 框架自动合并,一起发给大模型 调用流程不变 SDK 给谁用: 第三方服务方用,用来封装 MCP 服务端 我们不用,我们只配 URL