MCP vs Function Calling:大模型工具调用,谁是未来?附完整实战代码
引言随着大语言模型LLM从“对话引擎”演进为“智能代理”工具调用Tool Use已成为释放其生产力的关键能力。模型不仅能生成文字还能调用外部API、查询数据库、操作文件真正落地现实任务。当前业界最主流的两种工具调用方案分别是OpenAI带头推动的Function Calling以及Anthropic推出的开放协议MCPModel 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 Keyexport OPENAI_API_KEYsk-...一、MCP 实现协议化的工具服务MCP 实现包含两部分工具服务器和客户端。服务器声明并实现get_weather工具客户端动态发现并调用它。1. 编写 MCP 天气服务器weather_server.pyimport 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( commandpython, 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只需