链载Ai

标题: MCP协议详解:一文读懂跨时代的模型上下文协议 [打印本页]

作者: 链载Ai    时间: 5 小时前
标题: MCP协议详解:一文读懂跨时代的模型上下文协议

目录

1基本概念

2目标及优势
3示例 - 工具



本文主要介绍了 Anthropic 推出的开源协议 MCP(Model Context Protocol,模型上下文协议),能让你快速上手该协议,实现大型语言模型与外部数据源和工具的无缝集成。






ingFang SC";color: rgb(66, 66, 66);line-height: 40px;letter-spacing: 3px;-webkit-text-stroke: 3px rgb(66, 66, 66);visibility: visible;text-align: center;">01



基本概念


MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 推出的开源协议,旨在实现大型语言模型(LLM)与外部数据源和工具的无缝集成,用来在大模型和数据源之间建立安全双向的链接。


目标是成为 AI 领域的“HTTP 协议”,推动 LLM 应用的标准化和去中心化。


例如:AI 应用程序的 USB-C 端口。正如 USB-C 提供了一种将设备连接到各种外围设备和配件的标准化方式一样,MCP 也提供了一种将 AI 模型连接到不同数据源和工具的标准化方式。



ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 1.1 架构


MCP 遵循客户端-服务器架构,其中:

  1. 主机是发起连接的 LLM 应用程序(Claude for Desktop或其他 AI 工具)。

  2. 客户端在主机应用程序内部与服务器保持 1:1 连接,负责协议通信。

  3. 服务器供客户端访问,向客户提供上下文、工具和提示。同时由于 MCP Server 自己控制资源,不用把 API 密钥给 MCP Host,因此更加安全。



ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 1.2 资源


资源表示 MCP 服务器想要向客户端提供的任何类型的数据。这可以包括:文件内容、数据库记录、API 响应、实时系统数据、截图和图片、日志文件等更多内容。每个资源由唯一的 URI 标识,并且可以包含文本或二进制数据。


{uri:string;//Uniqueidentifierfortheresourcename:string;//Human-readablenamedescription?:string;//OptionaldescriptionmimeType?:string;//OptionalMIMEtype}


ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 1.3 提示


MCP 中的提示是预定义的模板,可以:接受动态参数、上下文、链接多个交互 、指导特定工作流程、表面作为 UI 元素(如斜线命令)。


{name:string;//Uniqueidentifierforthepromptdescription?:string;//Human-readabledescriptionarguments?:[//Optionallistofarguments{name:string;//Argumentidentifierdescription?:string;//Argumentdescriptionrequired?:boolean;//Whetherargumentisrequired}]}


ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 1.4 工具


MCP 中的工具允许服务器公开可由客户端调用并由 LLM 用来执行操作的可执行函数。工具的关键方面包括:

  1. 发现 tools/list:客户端可以通过端点列出可用的工具

  2. 调用:使用端点调用工具 tools/call,服务器执行请求的操作并返回结果

  3. 灵活性:工具范围从简单的计算到复杂的 API 交互


与资源一样,工具也由唯一名称标识,并可以包含说明来指导其使用。但是,与资源不同的是,工具表示可以修改状态或与外部系统交互的动态操作。


{name:string;//Uniqueidentifierforthetooldescription?:string;//Human-readabledescriptioninputSchema:{//JSONSchemaforthetool'sparameterstype:"object",properties:{...}//Tool-specificparameters}}


ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 1.5 采样


采样是 MCP 的一项强大功能,允许服务器通过客户端请求 LLM 完成,从而实现复杂的代理行为,同时保持安全性和隐私性。这种人机交互设计确保用户可以控制 LLM 所看到和生成的内容。采样流程遵循以下步骤:

  1. sampling/createMessage 服务器向客户端发送请求。

  2. 客户审核请求并可以修改。

  3. 来自 LLM 的客户样本。

  4. 客户检查完成情况。

  5. 客户端将结果返回给服务器。


{messages: [{role: "user" | "assistant",content: {type: "text" | "image",
// For text:text?: string,
// For images:data?: string, // base64 encodedmimeType?: string}}],modelPreferences?: {hints?: [{name?: string// Suggested model name/family}],costPriority?: number, // 0-1, importance of minimizing costspeedPriority?: number,// 0-1, importance of low latencyintelligencePriority?: number// 0-1, importance of capabilities},systemPrompt?: string,includeContext?: "none" | "thisServer" | "allServers",temperature?: number,maxTokens: number,stopSequences?: string[],metadata?: Record<string, unknown>}




ingFang SC";color: rgb(66, 66, 66);line-height: 40px;letter-spacing: 3px;-webkit-text-stroke: 3px rgb(66, 66, 66);visibility: visible;text-align: center;">02



目标及优势


由于 LLM 难以直接访问实时数据源(如企业内部数据库、实时文档、在线服务等),开发者通常需要为每个应用场景定制专用的适配器或插件,这既耗时费力,又缺乏可扩展性。




ingFang SC";color: rgb(66, 66, 66);line-height: 40px;letter-spacing: 3px;-webkit-text-stroke: 3px rgb(66, 66, 66);visibility: visible;text-align: center;">03



示例 - 工具


MCP工具调用流程如下:


用户发送问题 -> LLM 分析可用工具 -> 客户端通过 MCP 服务器来执行所选工具 -> 将结果发送回 LLM -> LLM根据工具返回结果和用户问题进行回答。


(流程有点像检索增强生成,把检索的部分替换成了调用工具)。


这里示例包含两个,一个是结合我们当前业务初步实现的工具以及官网 github 给出的示例。


ingFang SC", system-ui, -apple-system, BlinkMacSystemFont, "Helvetica Neue", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);line-height: 1.6em;text-align: left;"> 3.1 通过 mcp 构建一个获取 Path of Exile 2 游戏最新版本的工具


我们发现简单的使用 RAG 往往无法获取实时信息,因此按照官网流程初步构建了一个结合爬虫的 MCP 工具。


客户端:


1、首先导入对应的 FastMCP 类(使用 字符串自动生成工具定义,从而轻松创建和维护 MCP 工具,这里的效果后面会展示)以及我们需要获取实时信息的网址(这里是 PoE2 的官网)。


fromtypingimportAnyfrommcp.server.fastmcpimportFastMCP#InitializeFastMCPservermcp=FastMCP("athofExile2hotfix")target_url="https://www.pathofexile.com/forum/view-forum/2212"


2、工具的核心功能函数 - helper 函数(实际上这里就是想要实现的功能,下面只是一个简单的爬虫函数用于示例)。


asyncdefpoe2_hotfix(url:str):headers={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/58.0.3029.110Safari/537.3'}response=requests.get(url,headers=headers)asyncwithhttpx.AsyncClient()asclient:try:response=awaitclient.get(url,headers=headers,timeout=30.0)soup=BeautifulSoup(response.text,'html.parser')#查找包含帖子内容的表格table=soup.find('table')result_text=""iftable:forrowintable.find_all('tr'):cells=row.find_all('td')ifcells:forcellincells:result_text+=cell.get_text(strip=True)+'\n'result_text+='-'*50+'\n'#分隔线else:print('未找到表格元素')returnresult_textexceptException:returnNone


3、添加 mcp 类中的工具函数(执行处理程序,负责实际执行每个工具的逻辑),每个工具函数对应一个特定的工具。

@mcp.tool()asyncdeffind_poe2_hotfix()->str:hotfix_data=awaitpoe2_hotfix(target_url)ifnothotfix_data:return"Unabletofindanyhotfixinoffice"returnhotfix_data


4、最后初始化并运行服务器,到这里就可以 server 端的工作就算完成了。


if__name__=="__main__":#Initializeandruntheservermcp.run(transport='stdio')


5、通过 MCP host 进行测试,这里采用的是官方文档中构建 LLM client 的方法(也可以选择 Clauder for Desktop,只需要将之前的服务器添加到 key 中,相当于告诉 host 这里有一个用于 PoE2 补丁版本查询的 MCP 服务器)。


Quickstart - For Client Developers(https://modelcontextprotocol.io/quickstart/client)


实现了客户端初始化,服务器连接, 查询处理,交互式界面以及资源管理。


6、测试


安装 MCP 依赖后可以在命令行使用 MCP Inspector 对其进行测试:


pipinstallmcpmcpdevserver.py


在 MCP Inspector 里面的工具页面就可以看到新建立的工具,运行工具后可以看到工具返回的结果。



7、效果展示


在命令行将客户端连接到对应的工具


uvrunclient.pypoe2hotfix.py






8、思考


优化 prompt 以及添加更多工具来实现更复杂的功能,比如使用更优的爬虫工具,以及通过深度爬虫爬取对应补丁的帖子,这样在回答的最新补丁版本号的同时返回具体内容。


3.2 构建一个简单的chatbot - 官方示例


完整代码详见:https://github.com/modelcontextprotocol/python-sdk/tree/main/examples/clients/simple-chatbot


逻辑流程


1、工具集成:

a.从MCP服务器动态发现工具b.工具描述自动包含在系统提示中c.工具执行通过标准化MCP协议处理


2、运行时流程:

a.收到用户输入b.输入与可用工具的上下文一起发送到LLMc.LLM响应解析:如果是工具调用→执行工具并返回结果如果是直接响应→返回给用户d.工具结果发送回LLM进行解释e.最终响应呈现给用户


服务器侧工具发现:服务器侧调用 list_tools 函数。


all_tools=[]forserverinself.servers:tools=awaitserver.list_tools()all_tools.extend(tools)


工具函数定义:


def format_for_llm(self) -> str:"""Format tool information for LLM.
Returns:A formatted string describing the tool."""args_desc = []if "properties" in self.input_schema:for param_name, param_info in self.input_schema["properties"].items():arg_desc = (f"- {param_name}: {param_info.get('description', 'No description')}")if param_name in self.input_schema.get("required", []):arg_desc += " (required)"args_desc.append(arg_desc)
return f"""Tool: {self.name}Description: {self.description}Arguments:{chr(10).join(args_desc)}"""


chatbot prompt:


system_message=("Youareahelpfulassistantwithaccesstothesetools:\n\n"f"{tools_description}\n""Choosetheappropriatetoolbasedontheuser'squestion.""Ifnotoolisneeded,replydirectly.\n\n""IMPORTANT:Whenyouneedtouseatool,youmustONLYrespondwith""theexactJSONobjectformatbelow,nothingelse:\n""{\n"'"tool":"tool-name",\n''"arguments":{\n''"argument-name":"value"\n'"}\n""}\n\n""Afterreceivingatool'sresponse:\n""1.Transformtherawdataintoanatural,conversationalresponse\n""2.Keepresponsesconcisebutinformative\n""3.Focusonthemostrelevantinformation\n""4.Useappropriatecontextfromtheuser'squestion\n""5.Avoidsimplyrepeatingtherawdata\n\n""Pleaseuseonlythetoolsthatareexplicitlydefinedabove.")


-End-
原创作者|王文清






欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5