解密prompt系列. MCP - 工具演变 & MCP基础

解密prompt系列. MCP - 工具演变 & MCP基础

从"提示词"到"工具箱":LLM的能力边界焦虑如果你玩过早期的GPT-3,一定记得那种"纯文本进,纯文本出"的原始感。你费尽心思写prompt,它却连"今天天气"都答不上来,因为它没有实时数据。后来,开发者发明了函数调用(Function Calling) ,让模型输出一个JSON结构,由你的代码去执行外部API。这解决了"工具"问题,但随即暴露了新的痛点:每个工具都要你手动写OpenAPI schema、处理鉴权、管理协议 ,而且每换一个模型(GPT到Claude),工具格式就得重写一遍。这就像每个家电都要配一个专有的插座,居室乱成一团。MCP(Model Context Protocol,模型上下文协议) 的出现,就是为了终结这种"工具军阀混战"。MCP不是一个新的模型,也不是一个库,而是一个开放协议 。它定义了"模型"与"工具/数据源"之间如何发现、协商、调用。你可以把MCP理解为AI界的USB-C接口 ------任何支持MCP的客户端(如Claude Desktop、Cursor),都能即插即用地连接任何支持MCP的服务器(如GitHub、数据库、Slack)。### MCP的架构演变:从"硬编码"到"动态发现"早期工具调用的逻辑是这样的:python# 早期Function Calling的伪代码,工具定义硬编码在prompt里tools = [ { "type": "function", "function": { "name": "get_weather", "description": "获取天气", "parameters": { "type": "object", "properties": {"city": {"type": "string"}} } } }]# 每次新增工具,都需要修改这里的列表,并重新部署这种方式的致命缺陷是静态性 :工具列表在编译期就固定了。如果用户想临时接入一个私有API,客户端无法动态发现。MCP的核心演变在于引入了两阶段握手 :1. 发现阶段(Discovery) :客户端向MCP Server发送tools/list请求,服务器返回所有可用工具的完整描述(名称、输入schema、输出格式)。2. 调用阶段(Invocation) :客户端根据模型的理解,向MCP Server发送tools/call请求,附带工具名和参数。这彻底解耦了"模型"和"工具实现"。模型只需要知道"有一个工具叫get_weather,需要city参数",至于这个工具背后是调用气象局API还是读本地文件,模型完全不关心。MCP Server负责屏蔽底层复杂性。### 深入MCP协议:JSON-RPC 2.0与生命周期MCP基于JSON-RPC 2.0 规范,通过stdio(本地进程)或Streamable HTTP(远程服务)传输。其核心消息类型包括:- initialize:建立会话,协商协议版本- notifications/initialized:确认初始化完成- tools/list:获取工具目录- tools/call:执行工具- resources/list:获取数据资源(如文件、数据库表)- prompts/list:获取可复用的prompt模板下面我们写一个最小可运行的MCP服务器 ,用Python实现一个"计算器"工具,并通过stdio与客户端通信。python# server.py - 最小MCP服务器实现import jsonimport sysfrom typing import Anydef handle_request(request: dict) -> dict: """处理JSON-RPC请求""" method = request.get("method") request_id = request.get("id") if method == "initialize": # 协商协议版本和能力 return { "jsonrpc": "2.0", "id": request_id, "result": { "protocolVersion": "2024-11-05", "capabilities": {"tools": {}}, "serverInfo": {"name": "calc-server", "version": "0.1.0"} } } elif method == "tools/list": # 动态返回工具目录 return { "jsonrpc": "2.0", "id": request_id, "result": { "tools": [{ "name": "add", "description": "两个数字相加", "inputSchema": { "type": "object", "properties": { "a": {"type": "number"}, "b": {"type": "number"} }, "required": ["a", "b"] } }] } } elif method == "tools/call": # 执行工具 params = request.get("params", {}) name = params.get("name") args = params.get("arguments", {}) if name == "add": result = args["a"] + args["b"] return { "jsonrpc": "2.0", "id": request_id, "result": { "content": [{"type": "text", "text": str(result)}] } } elif method == "notifications/initialized": # 初始化完成通知,不需要响应 return None return {"jsonrpc": "2.0", "id": request_id, "error": {"code": -32601, "message": "Method not found"}}def main(): """从stdin读取JSON-RPC消息,处理并返回结果""" for line in sys.stdin: line = line.strip() if not line: continue try: request = json.loads(line) response = handle_request(request) if response: # 通知类消息无需响应 sys.stdout.write(json.dumps(response) + "\n") sys.stdout.flush() except Exception as e: error_resp = { "jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": f"Parse error: {str(e)}"} } sys.stdout.write(json.dumps(error_resp) + "\n") sys.stdout.flush()if __name__ == "__main__": main()运行这个服务器后,你可以用任意支持MCP的客户端连接它。例如,在Claude Desktop的配置文件中添加:json{ "mcpServers": { "calc": { "command": "python", "args": ["server.py"] } }}然后,你就能在对话中直接说"帮我计算12345+67890",模型会通过MCP协议自动调用add工具,并返回结果。### 从工具到资源:MCP的"上下文"野心MCP不只是工具调用,它还定义了resourcespromptsresources允许服务器暴露结构化数据(如数据库表、文件内容),客户端可以订阅这些资源的变更。这解决了另一个大问题:LLM的上下文窗口有限 ,MCP允许按需拉取数据,而不是把所有数据塞进prompt。下面是一个扩展的MCP服务器,增加了一个资源 (返回当前服务器时间),并演示了如何通过resources/read获取数据:python# server_resources.py - 带资源的MCP服务器import jsonimport sysfrom datetime import datetimedef handle_request(request: dict) -> dict: method = request.get("method") request_id = request.get("id") if method == "tools/list": # 注册两个工具:add 和 get_time return { "jsonrpc": "2.0", "id": request_id, "result": { "tools": [ { "name": "add", "description": "加法运算", "inputSchema": { "type": "object", "properties": { "a": {"type": "number"}, "b": {"type": "number"} }, "required": ["a", "b"] } }, { "name": "get_time", "description": "获取服务器当前时间", "inputSchema": {"type": "object", "properties": {}} } ] } } elif method == "tools/call": params = request.get("params", {}) name = params.get("name") args = params.get("arguments", {}) if name == "get_time": now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") return { "jsonrpc": "2.0", "id": request_id, "result": { "content": [{"type": "text", "text": f"当前时间: {now}"}] } } elif name == "add": result = args["a"] + args["b"] return { "jsonrpc": "2.0", "id": request_id, "result": { "content": [{"type": "text", "text": str(result)}] } } elif method == "resources/list": # 暴露一个静态资源:服务器UUID return { "jsonrpc": "2.0", "id": request_id, "result": { "resources": [{ "uri": "server://info", "name": "Server Info", "description": "服务器元数据", "mimeType": "text/plain" }] } } elif method == "resources/read": uri = request.get("params", {}).get("uri") if uri == "server://info": return { "jsonrpc": "2.0", "id": request_id, "result": { "contents": [{ "uri": uri, "mimeType": "text/plain", "text": "MCP Demo Server v1.0" }] } } return {"jsonrpc": "2.0", "id": request_id, "error": {"code": -32601, "message": "Method not found"}}def main(): for line in sys.stdin: line = line.strip() if not line: continue try: request = json.loads(line) response = handle_request(request) if response: sys.stdout.write(json.dumps(response) + "\n") sys.stdout.flush() except Exception as e: error_resp = {"jsonrpc": "2.0", "id": None, "error": {"code": -32700, "message": str(e)}} sys.stdout.write(json.dumps(error_resp) + "\n") sys.stdout.flush()if __name__ == "__main__": main()### MCP的深层价值:Agent的"即插即用"生态MCP的终极意义在于,它让AI Agent从"单机软件"变成了"操作系统" 。想象一下:- 你写了一个MCP Server连接公司的Jira,那么任何支持MCP的客户端(Claude、Cursor、甚至你自研的Agent)都能直接操作Jira。- 你写了一个MCP Server连接PostgreSQL,那么所有Agent都能安全地查询数据库,而不需要把数据库密码写在prompt里。更重要的是,MCP引入了权限控制审计日志 的概念。在MCP的规范中,客户端可以要求服务器声明其能力(capabilities),并限制某些工具只能在特定条件下调用。这比简单地把API Key塞进prompt安全得多。### 总结MCP是工具调用范式的"分水岭"。它从静态、硬编码、单模型绑定 的Function Calling,演变为动态发现、协议标准化、跨模型通用 的"AI外设总线"。MCP的核心贡献在于:1. 解耦模型与工具实现 :模型只需理解语义,工具只需实现功能,通过JSON-RPC桥接。2. 标准化生态 :一个MCP Server可被任何MCP客户端复用,打破模型垄断。3. 安全边界:通过资源级权限控制,避免Agent的"越权操作"。未来,MCP很可能成为AI Agent的"操作系统API",就像USB-C统一了硬件接口一样,MCP将统一AI的工具接口。对于开发者而言,掌握MCP不是"学一个新库",而是理解"如何为AI设计可插拔的能力层"。现在动手写一个自己的MCP Server,正是踏入这片新大陆的第一步。

相关推荐
砚凝霜1 小时前
软考网络工程师|第 4 章 WLAN MAC 机制、Ad Hoc、无线安全、WPAN 蓝牙 ZigBee 完整备考笔记
网络·笔记·安全
奈斯先生Vector2 小时前
不再手写 Prompt 链:用工作流编译器构建可验证的多模型 Agent 运行时
prompt
严谨的麻辣烫8 小时前
Linux sysctl 网络参数调优实战:高并发与长连接场景下的内核配置
linux·网络·php
IT小盘11 小时前
12-Prompt不等于一句话-System-User-Context三层结构
java·windows·prompt
爱研究的小梁15 小时前
多链路聚合通信:时延控制与网络波动对抗逻辑梳理
网络·人工智能·信息与通信
珠***格15 小时前
分布式光伏电站:四可装置如何实现 “可观、可测、可控、可调”
网络·人工智能·分布式·架构·能源
zbtlink15 小时前
给自动售货机配的那台WiFi6路由器,它用上了吗
网络·智能路由器
三言老师16 小时前
clear与history历史命令管理实操
linux·运维·服务器·网络·centos
上海云盾-小余16 小时前
CC 高频请求 + DDoS 流量攻击实战防御:全链路 WAF 流量清洗部署完整流程
网络·爬虫·安全·小程序·ddos