MCP vs Function Calling:大模型工具调用,谁是未来?附完整实战代码
引言
随着大语言模型(LLM)从“对话引擎”演进为“智能代理”,工具调用(Tool Use) 已成为释放其生产力的关键能力。模型不仅能生成文字,还能调用外部API、查询数据库、操作文件,真正落地现实任务。
当前业界最主流的两种工具调用方案分别是:OpenAI带头推动的 Function Calling,以及Anthropic推出的开放协议 MCP(Model Context Protocol)。前者简单直观,但深度耦合于单次API调用;后者则希望成为连接模型与工具的“USB-C接口”,实现标准化、动态化的工具生态。
本文将深入对比两者的设计思想、使用方式与适用场景,并提供完整可运行的Python代码,让你边学边练,彻底搞懂它们的区别。
核心概念对比
1. Function Calling:函数即描述
Function Calling 的核心思路是把工具抽象为 函数的JSON Schema描述,在对话请求中随消息一起发送给模型。模型不会执行函数,而是返回它想要调用的函数名和参数,由开发者在本地执行后,再把结果回传给模型生成最终回复。
特点:
- 工具定义硬编码:每次请求都需要将函数列表完整塞进tools参数。
- 无状态:工具调用是一次性的,对话结束后不会保留工具信息。
- 紧耦合:函数实现、执行、结果格式化都由开发者手动控制。
- 模型负责决策:LLM只负责“选择函数+填参数”,执行权完全在外部。
2. MCP:协议即生态
MCP 将工具调用的概念抽象为 客户端-服务器协议。工具不再是一段描述文本,而是运行在独立服务器中的可发现资源。模型(通过MCP客户端)可以动态列出可用工具、调用工具,甚至订阅资源变化。
特点:
- 工具服务器化:工具实现在独立的MCP服务器中,可以被任何兼容的客户端复用。
- 动态发现:客户端启动后可以主动拉取服务器提供的工具清单,无需预先硬编码。
- 长连接与上下文:支持会话保持,工具调用可在对话上下文中持续复用。
- 开放标准:Anthropic、OpenAI、社区均参与建设,有望成为跨模型的通用工具层。
一句话总结:Function Calling 是“临时的斧子”,MCP 是“瑞士军刀工具箱”。
实战:天气查询工具
我们以一个最常见的场景——根据城市名获取天气——来分别实现两种方案,直观感受差异。
环境准备:Python 3.10+,安装依赖:
bash pip install openai mcp
运行OpenAI示例需要配置有效API Key:export OPENAI_API_KEY=sk-...
一、MCP 实现:协议化的工具服务
MCP 实现包含两部分:工具服务器 和 客户端。服务器声明并实现 get_weather 工具,客户端动态发现并调用它。
1. 编写 MCP 天气服务器(weather_server.py)
import asyncio
from mcp.server import Server
from mcp.server.stdio import stdio_server
# 创建MCP服务器实例
app = Server("weather-server")
@app.tool()
async def get_weather(city: str) -> str:
"""获取指定城市的天气情况(模拟)"""
# 实际项目中可接入真实天气API
city_weather = {
"北京": "晴天,25°C",
"上海": "多云,28°C",
"深圳": "雷阵雨,30°C"
}
return city_weather.get(city, "未知城市,暂无天气数据")
async def main():
# 使用标准输入输出作为传输通道
async with stdio_server() as (read_stream, write_stream):
await app.run(
read_stream,
write_stream,
app.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
2. 编写 MCP 客户端(mcp_client.py)
客户端通过启动子进程的方式连接上面的服务器,然后获取工具并调用。
import asyncio
from mcp import Client
from mcp.client.stdio import stdio_client, StdioServerParameters
async def main():
# 要连接的服务器的启动命令(相当于在终端执行 python weather_server.py)
server_params = StdioServerParameters(
command="python",
args=["weather_server.py"]
)
# 建立连接
async with stdio_client(server_params) as (read_stream, write_stream):
async with Client(read_stream, write_stream) as client:
# 初始化会话
await client.initialize()
# 动态获取服务器提供的工具列表
tools = await client.list_tools()
print("服务器提供的工具:", [tool.name for tool in tools])
# 调用工具,获取北京天气
result = await client.call_tool("get_weather", {"city": "北京"})
# 结果通常包含在 content 列表中
print("工具返回结果:", result.content[0].text)
if __name__ == "__main__":
asyncio.run(main())
运行方式:
1. 将以上两个文件放在同一目录下。
2. 先启动服务器:python weather_server.py(它会等待客户端连接,不必提前运行,客户端会自动启动)。
3. 运行客户端:python mcp_client.py,输出如下:
服务器提供的工具: ['get_weather']
工具返回结果: 北京晴天,25°C
亮点: 整个过程中,客户端从未硬编码工具的名称或参数,所有信息都是动态获取的。如果你想新增一个工具(例如 get_air_quality),只需
更多推荐



所有评论(0)