
1. 引言大模型LLM的能力边界正在被快速拓展。从最初只能“聊天”到如今能够调用外部工具、访问实时数据、操作业务系统模型正在从“对话引擎”进化为“行动引擎”。而推动这一转变的两大关键技术正是Function Calling函数调用与MCPModel Context Protocol模型上下文协议。Function Calling 让模型能够按照结构化格式输出调用意图从而触发外部 APIMCP 则进一步标准化了模型与工具、数据源之间的连接方式让工具接入从“点对点定制”走向“标准化互联”。本文将从实践角度出发先讲清楚 Function Calling 的原理与落地方式再深入 MCP 的架构与生态最后通过一个完整的实战案例展示如何将两者结合构建一个可扩展的智能体应用。2. Function Calling 基础2.1 什么是 Function CallingFunction Calling 是 LLM 的一种能力模型在生成回复时不再仅仅输出自然语言而是可以输出一个结构化的“函数调用请求”包含函数名和参数。应用层收到这个请求后执行对应的函数再把结果返回给模型模型据此生成最终回复。它本质上解决的是让模型能够“使用工具”。2.2 工作原理Function Calling 的工作流程通常分为以下几步开发者定义一组函数描述其名称、参数结构JSON Schema和用途。在请求中将这些函数定义随用户消息一起发送给模型。模型判断需要调用某个函数时输出一个结构化的函数调用对象。应用执行该函数获取结果。将结果作为新的消息回传给模型模型生成最终回复。fromopenaiimportOpenAI clientOpenAI()tools[{type:function,function:{name:get_weather,description:获取指定城市的当前天气,parameters:{type:object,properties:{city:{type:string,description:城市名称}},required:[city]}}}]responseclient.chat.completions.create(modelgpt-4o,messages[{role:user,content:北京今天天气怎么样}],toolstools)print(response.choices[0].message.tool_calls)2.3 核心价值实时数据访问模型可以查询数据库、调用 API获取训练数据之外的最新信息。业务系统集成模型可以代表用户操作业务系统如创建工单、查询订单。减少幻觉通过工具返回的真实数据替代模型“编造”的答案。复杂任务拆解模型可以将复杂任务拆解为多个函数调用逐步完成。3. MCP 协议详解3.1 什么是 MCPMCPModel Context Protocol是由 Anthropic 于 2024 年底提出的开放协议旨在标准化 LLM 应用与外部数据源、工具之间的连接方式。你可以把它理解为 AI 领域的“USB-C 接口”统一的连接标准让任何模型都能方便地接入各种工具和数据源。3.2 MCP 的核心架构MCP 采用客户端-服务器架构包含三个核心角色MCP Host运行 LLM 的应用程序如 Claude Desktop、IDE 插件等。MCP ClientHost 内部的协议客户端负责与 Server 建立连接。MCP Server暴露工具、资源和提示词的轻量级服务可以是本地进程也可以是远程服务。JSON-RPC 2.0MCP Host (LLM 应用)MCP ClientMCP Server本地文件系统远程 API数据库3.3 MCP 的核心能力MCP Server 主要暴露三类能力Tools工具可被模型调用的函数类似 Function Calling 中的函数定义。Resources资源可被读取的数据如文件内容、数据库记录。Prompts提示词模板可复用的提示词帮助模型理解特定任务的执行方式。3.4 传输方式MCP 支持两种主要传输方式stdio通过标准输入输出进行通信适合本地进程。HTTP SSE通过 HTTP 进行通信适合远程服务。# 一个简单的 MCP Server 示例使用 FastMCPfrommcp.server.fastmcpimportFastMCP mcpFastMCP(weather-server)mcp.tool()defget_weather(city:str)-str:获取指定城市的当前天气# 这里调用真实的天气 APIreturnf{city}当前天气晴25°Cif__name____main__:mcp.run()4. Function Calling 与 MCP 的关系4.1 两者的定位差异Function Calling 是一种模型能力解决的是“模型如何表达调用意图”MCP 是一种连接协议解决的是“应用如何标准化地接入工具”。简单来说Function Calling 是“模型会说我要用什么工具”。MCP 是“工具如何被统一地发现、连接和调用”。4.2 两者如何协同在实际的智能体应用中两者往往是配合使用的MCP Server 将工具标准化暴露出来。应用通过 MCP Client 发现并获取工具定义。工具定义被转换为 Function Calling 格式随请求发送给模型。模型输出函数调用请求。应用通过 MCP 执行对应的工具返回结果。MCP Server 暴露工具MCP Client 发现工具转换为 Function Calling 格式LLM 生成调用意图通过 MCP 执行工具结果返回 LLM生成最终回复4.3 为什么需要 MCP在没有 MCP 之前每接入一个工具开发者都需要为模型定制一套函数定义和调用逻辑。工具多了之后维护成本急剧上升。MCP 的出现让工具接入变得标准化、可复用大幅降低了智能体应用的开发成本。5. 实战构建一个 MCP Function Calling 的智能体5.1 场景设计我们构建一个“智能运维助手”它能够查询服务器状态获取应用日志根据日志内容给出处理建议5.2 定义 MCP Server# server.pyfrommcp.server.fastmcpimportFastMCP mcpFastMCP(ops-assistant)mcp.tool()defget_server_status(server_id:str)-str:查询指定服务器的运行状态# 模拟查询returnf服务器{server_id}状态运行中CPU 45%内存 62%mcp.tool()defget_app_logs(app_name:str,lines:int50)-str:获取指定应用的最新日志# 模拟日志returnf[INFO]{app_name}启动成功\n[INFO] 请求处理正常\n[ERROR] 连接池超时if__name____main__:mcp.run()5.3 在应用中接入 MCP Client# client.pyimportasynciofrommcpimportClientSession,StdioServerParametersfrommcp.client.stdioimportstdio_clientasyncdefmain():server_paramsStdioServerParameters(commandpython,args[server.py])asyncwithstdio_client(server_params)as(read,write):asyncwithClientSession(read,write)assession:awaitsession.initialize()# 列出所有可用工具toolsawaitsession.list_tools()fortoolintools.tools:print(f工具{tool.name}-{tool.description})asyncio.run(main())5.4 将 MCP 工具接入 LLM# agent.pyimportjsonimportasynciofromopenaiimportOpenAIfrommcpimportClientSession,StdioServerParametersfrommcp.client.stdioimportstdio_client clientOpenAI()asyncdefrun_agent():server_paramsStdioServerParameters(commandpython,args[server.py])asyncwithstdio_client(server_params)as(read,write):asyncwithClientSession(read,write)assession:awaitsession.initialize()# 获取 MCP 工具列表mcp_toolsawaitsession.list_tools()# 转换为 Function Calling 格式tools[]fortoolinmcp_tools.tools:tools.append({type:function,function:{name:tool.name,description:tool.description,parameters:tool.inputSchema}})messages[{role:user,content:帮我检查一下 order-service 的日志看看有没有异常}]# 第一轮模型决定是否调用工具responseclient.chat.completions.create(modelgpt-4o,messagesmessages,toolstools)msgresponse.choices[0].message# 如果模型要求调用工具ifmsg.tool_calls:fortool_callinmsg.tool_calls:fn_nametool_call.function.name fn_argsjson.loads(tool_call.function.arguments)# 通过 MCP 执行工具resultawaitsession.call_tool(fn_name,fn_args)print(f工具返回{result.content[0].text})# 将结果回传给模型messages.append(msg)messages.append({role:tool,tool_call_id:tool_call.id,content:result.content[0].text})# 第二轮模型生成最终回复finalclient.chat.completions.create(modelgpt-4o,messagesmessages,toolstools)print(f助手{final.choices[0].message.content})asyncio.run(run_agent())5.5 运行效果当用户提问“帮我检查一下 order-service 的日志”时智能体的工作流程如下模型识别需要调用get_app_logs工具。应用通过 MCP 执行该工具获取日志。日志中包含[ERROR] 连接池超时。模型基于日志内容生成处理建议。6. 最佳实践与注意事项6.1 工具设计原则单一职责每个工具只做一件事职责清晰。参数精简参数越少越好降低模型误调用的概率。描述清晰工具描述要说明“何时使用”和“做什么”帮助模型正确选择。错误处理工具内部要做好异常捕获返回友好的错误信息。6.2 安全与权限最小权限给工具分配最小必要的权限。敏感操作确认涉及删除、修改等敏感操作应增加人工确认环节。输入校验对模型传入的参数进行严格校验防止注入攻击。审计日志记录所有工具调用便于追溯。6.3 性能优化工具数量控制一次请求中传入的工具不宜过多避免模型选择困难。结果截断工具返回结果过大时应截断或摘要后再回传模型。缓存策略对高频查询类工具可考虑结果缓存。7. 总结与展望Function Calling 与 MCP 分别从“模型能力”和“连接标准”两个维度共同推动了智能体应用的落地。Function Calling 让模型具备了使用工具的能力而 MCP 则让工具的接入变得标准化、生态化。展望未来随着 MCP 生态的不断丰富我们可以预见工具接入将像安装应用一样简单。智能体将能够跨系统、跨平台地协同工作。模型与真实世界的连接将更加紧密。对于开发者而言尽早掌握 Function Calling 与 MCP 的实践方法将在智能体应用开发中占据先机。