Function Calling 与 MCP 学习笔记
这两个概念经常一起出现,但属于不同层次。Function Calling 是 LLM 的底层能力,MCP 是工具的连接协议。两者不是替代关系,而是配合关系。
一、Function Calling 是什么
定义
Function Calling(函数调用)是 LLM 的一种能力:模型能根据用户意图,输出一个结构化的「调用某函数」请求(函数名 + 参数,JSON 格式),而不是自然语言文本。
它解决了什么
早期的 LLM 只会「说话」——你问它天气,它只能基于训练数据编一个,没法拿实时数据。Function Calling 让 LLM 从「只会说话」变成「能喊你去做事」:
没有 function calling:
用户: 北京今天天气?
LLM: 北京今天晴,25度...(编的,可能是训练时的旧数据)
有 function calling:
用户: 北京今天天气?
LLM: tool_calls=[{name: "get_weather", args: {city: "Beijing"}}] ← 输出结构化调用请求
你的代码: 执行 get_weather("Beijing") → "多云,18度"
LLM: 北京今天多云,18度(基于真实数据)
工作流程(5 步)
1. 你告诉 LLM 有哪些函数可用
tools = [{name, description, parameters}] ← 函数的 schema
2. LLM 收到用户问题,判断该不该调函数
3. 该调 → LLM 输出 tool_calls = [{name, args}] ← 结构化 JSON,不是文本
4. 你的代码执行这个函数,拿到结果
5. 把结果返回给 LLM,LLM 基于结果生成最终回答
关键认知:LLM 不执行,只声明
LLM 自己不会执行任何函数,它只会「说」要调哪个、传什么参数(输出 tool_calls)。真正执行函数的是你的代码。
这是初学者最常误解的点:以为「LLM 调用了工具」是 LLM 在执行。其实 LLM 只发了个「调用请求」,执行在代码侧。
和之前笔记的关联
前面「工具选择机制实验」验证的就是 function calling 的行为:LLM 收到工具 schema + 用户问题,输出 tool_calls。改 name/description/args 影响的就是 LLM 判断「该不该调、调哪个」。@tool、bind_tools 这些 API 都是利用 function calling——它们把工具转成 schema 发给 LLM,LLM 用 function calling 输出调用请求。
二、MCP 是什么
定义
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 提出的开放协议,标准化「LLM 应用」与「外部工具/数据源」之间的连接方式。
注意:MCP 是一个协议/标准,不是某个 LLM 的能力,也不是某个框架。
它解决了什么
在 MCP 之前,工具接入是「每个框架各自为政」:
LangChain: 工具用 @tool 写,只能在 LangChain 用
LlamaIndex: 工具用自己的格式,只能在 LlamaIndex 用
某个厂商 SDK: 又一套格式
问题:工具与框架强耦合。你给 LangChain 写的工具,换到别的框架就用不了。工具没法独立复用。
MCP 的解法:把工具做成独立的服务(MCP Server),通过标准协议暴露能力。任何支持 MCP 的客户端都能连进来用,不用管工具内部用什么框架实现。
类比:USB 协议
USB 协议: U盘 / 鼠标 / 摄像头(设备) ←→ 电脑(主机)
不管设备内部怎么造,只要符合 USB 接口就能用
MCP 协议: 工具服务(MCP Server) ←→ Agent 应用(MCP Client)
不管工具用什么框架写,只要符合 MCP 协议就能接入
架构
MCP Server(工具提供方) MCP Client(Agent 侧)
- 用任意框架实现 - 连接 Server,发现工具
- 暴露工具(名字、描述、参数) - 把工具转成 LLM 能用的 schema
- 执行工具调用,返回结果 - 把 LLM 的调用请求转给 Server
↑ ↑
└──────── MCP 协议(标准通信)────────┘
三、两者的关系
不同层次,不是替代
| Function Calling | MCP | |
|---|---|---|
| 是什么 | LLM 的能力 | 连接协议 |
| 解决什么 | LLM 怎么决定调哪个工具、传什么参数 | 工具怎么被发现、被连接、与 Agent 解耦 |
| 作用层 | LLM 层 | 工具接入层 |
| 谁定义 | LLM 厂商(OpenAI/Anthropic/...) | Anthropic 提出的开放标准 |
配合关系
MCP 工具最终也要通过 function calling 被 LLM 调用。完整链路:
1. MCP Server 暴露工具(用任意框架实现)
2. MCP Client 连接 Server,发现工具列表
3. Client 把工具转成 LLM 能理解的 schema(name + description + args)
4. LLM 用 function calling 判断该不该调、调哪个、传什么参数 → 输出 tool_calls
5. Client 把 tool_calls 转成 MCP 协议消息,发给 Server
6. Server 执行工具,返回结果
7. Client 把结果回传给 LLM,LLM 生成最终回答
分工:
- MCP 负责「工具怎么连进来」——工具独立部署、标准协议接入、跨框架复用
- Function Calling 负责「LLM 怎么决定调」——看 schema、判断意图、输出结构化调用
层级图
LLM(用 function calling 决定调工具)
↑ 需要 schema(name + description + args)
Agent 框架 / MCP Client(把工具转成 schema 给 LLM)
↑ MCP 协议(标准化连接)
MCP Server(工具的实际实现,可用任意框架)
四、一句话区分
- Function Calling:LLM 能输出「调这个函数、传这些参数」的结构化请求。是 LLM 用工具的前提能力。
- MCP:让工具作为独立服务、通过标准协议被任何 Agent 接入。是工具连接的标准化方案。
MCP 不依赖某个 LLM 的 function calling(任何能调工具的 LLM 都能用 MCP 工具);function calling 也不依赖 MCP(本地工具直接用 function calling 也能调)。但当工具需要跨框架复用、独立部署时,MCP + function calling 配合是最干净的方案。
五、实践中的对照
在一个典型的 Agent 项目里,常常两种工具并存:
| 工具来源 | 接入方式 | 例子 |
|---|---|---|
| 本地工具 | 框架装饰器(如 @tool)直接变 Tool |
查时间、查数据库等简单内部工具 |
| 远程工具 | MCP Server + Client adapter 转 Tool | 第三方监控、日志、外部 API 等 |
两者最终都变成 LLM 能 bind 的 Tool 类型,LLM 用 function calling 统一调用。对 LLM 来说,工具是本地的还是 MCP 的,没有区别——它只看 schema,输出 tool_calls。
这也是 MCP 的价值所在:工具实现与 Agent 框架解耦后,你可以把任意 MCP 工具接入任意 Agent,不用改 Agent 代码,也不用重写工具。
六、关键认知清单
- Function Calling 是 LLM 的能力:模型能输出结构化的函数调用请求(name + args),而不是只会生成文本。
- LLM 不执行函数,只声明调用:真正执行在代码侧。这是最常见的误解点。
- MCP 是协议,不是能力:标准化工具与 Agent 的连接,让工具可独立部署、跨框架复用。
- 两者不同层次:Function Calling 在 LLM 层(怎么决定调),MCP 在接入层(怎么连进来)。
- 两者配合:MCP 工具通过 adapter 转成 schema,LLM 用 function calling 调用,调用经 MCP 协议转给 Server 执行。
- 对 LLM 而言工具无差别:本地工具和 MCP 工具最终都是 schema,LLM 统一用 function calling 调用。
- MCP 解决的是工程问题(解耦、复用、独立部署),不是 LLM 能力问题。
- 不是所有工具都需要 MCP:简单本地工具直接
@tool就够;需要跨框架/远程/第三方复用时才上 MCP。
评论区