版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
PAGE6博学谷——让IT教学更简单,让IT学习更有效PAGE12《智能体构建与应用开发》教学设计课程名称:授课年级:授课学期:教师姓名:年月课题名称项目5构建Agent智能体与工具系统任务5-1智能体调用工具计划课时3课时教学引入在成功为AI助手赋予记忆能力,使其能连贯处理多轮对话后,技术主管要求王亮探索LangChain框架的智能体模块,学习创建工具、构建智能体,实现一个能“听懂要求、选择工具、执行操作、返回结果”的智能工作流,让AI不仅能对话,还能像专家一样执行具体任务。教学目标【知识目标】(1)掌握工具的基本概念。(2)掌握广义智能体和狭义智能体的概念区别。(3)了解大语言模型工具调用能力的发展历程。【技能目标】(1)能够使用@tool装饰器创建自定义功能工具。(2)能够使用create_agent方法构建智能体,并为其装配可用工具列表。(3)能够通过自然语言指令驱动智能体,正确调用工具并解析返回结果。【素养目标】(1)通过将复杂任务分解为工具调用序列,培养学生“化整为零、分而治之”的系统工程思维。(2)通过调试智能体的工具选择与参数传递,培养学生的工程实践能力。教学重点分清广义与狭义智能体概念,掌握@tool自定义工具、agent搭建及自然语言驱动工具调用的实操流程。教学难点理解智能体自主决策工具选择逻辑,调试工具参数传递与调用结果解析异常问题。教学方式课堂教学以PPT讲授为主,并结合多媒体进行教学教学过程任务5-1智能体调用工具※通过直接引入的方式导入新课在运行Web应用时,数据库起着至关重要的作用,它不仅存储和管理应用的核心数据,还能够确保数据的一致性和完整性,随着用户量的增加,数据库的性能和高可用性变得尤为重要,技术主管要求王亮部署Mariadb数据库,存储用户访问数据,同时部署Redis缓存数据库,将高频访问、变更不频繁的数据加载到内存中,减轻Mariadb数据库的查询压力。※新课讲解一、教师通过PPT的方式讲解1.工具的基本概念工具是智能体实现具体功能的核心执行单元,它为智能体提供超越纯文本对话的“专业能力延伸”。每个工具本质上是一个封装了特定操作(如数据查询、数学计算、API调用或系统操作)的标准化功能模块,其输入输出接口被严格定义,以便智能体准确调用并解析结果。通过将AI的通用推理能力与工具的专用功能相结合,智能体能够像人类专家一样,在理解需求后自主选择并操作合适的工具,逐步完成从信息检索到复杂流程执行的多样化任务。2.广义智能体和狭义智能体的概念区别(1)广义智能体(2)狭义智能体3.大语言模型调用工具能力的发展历程(1)工程化探索期(2020-2022年)最早,大语言模型自身并不具备直接操作外部工具(如计算器、数据库)的能力。为了让模型能完成这类任务,开发者主要使用以下2种间接实现方法。①提示词约定与格式解析②生成并执行代码(2)接口标准化期(2023年)2023年6月,OpenAI在ChatGPT中推出了FunctionCall(函数调用)功能,开发者只需要用标准格式告诉模型:“这里有这些工具能用,每个工具叫什么、能干什么、需要什么参数”。当用户提问时,模型会判断是否需要工具。如果需要,它就输出一个标准格式的结构化调用请求(JSON字符串),即“工具调用单”。例如:json{"name":"get_weather","arguments":"{"city":"北京"}"}这个“调用单”就像一张填写好的、机器可读的申请表,系统收到后可以准确解析出工具名(get_weather)和参数字符串({"city":"北京"}),然后将其转换为具体参数并执行对应工具。整个过程精准、可靠,无需人工干预。FunctionCall标准接口有两个好处,一是完全标准化,所有工具都用同一种格式;二是安全可控,模型只负责“申请”工具,实际执行权在开发者手中。这种方式很快成为行业标准,让AI调用工具变得简单可靠。(3)智能化协作期(2023年至今)有了FunctionCall这个标准接口,AI调用工具变得简单可靠,但这还只是单次对话、单次调用。要让AI真正处理多步骤复杂任务,关键在于引入了一套新的系统架构——智能体架构(狭义智能体),这套架构的核心是一个自主工作流引擎。它将大模型的规划能力、工具的调用能力以及任务的状态管理封装为一个可自动运行的闭环系统。在此架构下,AI系统得以“自己思考步骤、自己调用工具、自己检查进度、自己调整计划”。比如用户说“帮我查天气然后推荐穿搭”,AI会自动执行以下步骤。①思考(“需要先查天气,再根据天气推荐衣服”);②调用天气查询Function;③根据气温结果调用穿搭推荐Function;④整理最终答案,返回给用户。AI能组合多个工具完成复杂工作,从查资料、算数据到发邮件、生成报表,真正成为能主动解决问题的智能助手。二、构建工具1.新建项目打开PyCharm,按照创建项目4的方法创建项目5,打开项目5的本地终端窗口,导入LangChain的核心依赖,如下所示。(.venv)PSD:\langchain\project5>pipinstalllangchainlangchain-openailangchain-communitypython-dotenv安装完成后,拷贝project4中的.env文件和model.py文件到项目5根目录下,如图5-2所示。图5-2任务5-1初始化项目5基础环境2.创建2个工具(1)创建省会查询工具在project5项目中再建立一个名称为tool_basic.py的文件,输入以下代码。fromlangchain.toolsimporttool#============创建工具1:省会查询工具============@tooldefget_province_capital(location:str)->str:"""获取省会城市功能:根据省份名称查询对应的省会城市参数:location-省份名称,如"辽宁省"、"广东"返回:省会城市名称或错误信息示例:get_province_capital("辽宁")→"沈阳"get_province_capital("广东省")→"广州""""#省份-省会映射数据province_data={"辽宁省":"沈阳","广东省":"广州","江苏省":"南京","浙江省":"杭州","山东省":"济南"}#增强输入处理:如果用户输入"辽宁",自动转为"辽宁省"ifnotlocation.endswith("省"):location=location+"省"#返回结果或错误信息iflocationinprovince_data:returnf"{location}的省会是:{province_data[location]}"else:returnf"未找到{location}的省会信息"以上代码使用LangChain的@tool装饰器将一个普通Python函数转化为AI可调用的智能工具,首先从langchain.tools导入tool装饰器,这是创建工具的基础,然后通过@tool装饰器标记get_province_capital函数,这个装饰器会自动为函数添加元数据,使其能被大型语言模型识别和调用。函数上方有三引号包裹的文档字符串,文档字符串相当于工具的"说明书",用于解释函数、类或模块功能的一种特殊注释,常见的标准格式包括Google风格、NumPy风格和reStructuredText风格,无论采用哪种格式,优秀的文档字符串都应包含功能描述、参数说明、返回值解释和使用示例,以确保代码的可读性和可维护性,同时帮助AI工具准确理解和使用该函数。以上代码中,使用三引号包裹的文档字符串说明了工具的功能(查询省会城市)、参数要求(省份名称)、返回值、提供了调用示例,AI模型完全依赖它来理解何时以及如何调用这个工具。函数内部实际功能:定义省份数据字典,对用户输入进行标准化处理(自动添加"省"后缀),然后查询并返回结果。(2)创建数学计算工具在省会查询工具之后,编写数学计算工具,输入以下代码。#============创建工具2:数学计算工具============@tooldefcalculator(expression:str)->str:"""计算数学表达式功能:计算基本的数学表达式参数:expression-数学表达式,如"15*3"、"(10+5)*2"返回:计算结果或错误信息"""try:result=eval(expression)returnf"{expression}={result}"exceptZeroDivisionError:return"计算错误:除数不能为零"exceptSyntaxError:returnf"计算错误:表达式'{expression}'格式不正确"exceptExceptionase:returnf"计算错误:{str(e)}"#============导出工具============#将所有工具放在一个列表中,方便导入使用all_tools=[get_province_capital,calculator]以上代码创建了一个数学计算工具并将其与之前的省会查询工具打包成工具集,首先通过@tool装饰器将calculator函数转换为AI可调用的工具,其文档字符串清晰地说明了工具功能:计算数学表达式。工具接受字符串参数expression(如"15*3"),返回格式化的计算结果或错误信息函数实际功能:使用eval()进行数学计算,通过try-except结构实现了完整的错误处理机制,能够识别除零错误、语法错误等多种异常情况。通过all_tools=[get_province_capital,calculator]将两个功能独立的工具(查询省会类和计算类)整合到一个列表中,这种模块化的组织方式便于后续的统一管理和调用。(3)测试2个工具在数学计算工具的下方,输入以下代码,测试2个工具的具体功能。#测试工具功能if__name__=="__main__":print("测试工具功能:")#测试省会查询工具print("1.测试省会查询工具:")print(get_province_capital.invoke({"location":"辽宁省"}))print(get_province_capital.invoke({"location":"广东省的省会"}))#测试计算工具print("2.测试数学计算工具:")print(calculator.invoke({"expression":"15*3"}))print(calculator.invoke({"expression":"10加上5等于几"}))print("工具创建完成!")以上代码是工具的功能测试模块,用于验证两个工具的实际运行效果,通过if__name__=="__main__":条件判断,确保只有在直接运行该脚本时才会执行测试代码,而不会被其他模块导入时意外运行。测试分为两个部分:首先测试省会查询工具,分别传入规范格式"辽宁省"和自然语言格式"广东省的省会";然后测试数学计算工具,传入标准表达式"15*3"和非标准输入"10加上5等于几"。所有测试都使用.invoke()方法并传入字典参数。运行tool_basic.py,两个工具测试结果如图5-3所示。图5-3任务5-1测试2个工具从结果中发现,当使用get_province_capital工具并传入“辽宁省”这样的规范参数时,工具能够正确返回“沈阳”;同样,calculator工具在传入“15*3”这样的标准数学表达式时也能正确计算。当输入“广东省的省会”时,由于工具尚未连接到大语言模型(LLM),它无法理解自然语言的意图,无法解析问题并传递正确参数给工具,导致程序尝试查找“广东省的省会省”这样的错误数据,最终返回找不到信息,同理,当向计算器输入“10加上5等于几”这样的自然语言时,工具无法解析其数学含义,直接将其作为表达式传递给eval()函数,导致语法错误。三、构建智能体并调用工具1.创建智能体在project5项目中,创建名称为agent_basic.py的文件,输入以下代码。frommodelimportllm#导入大语言模型实例fromlangchain.agentsimportcreate_agent#导入创建智能体的函数fromtool_basicimportall_tools#导入之前定义的工具(省会查询工具和计算器工具)importjson#导入json模块用于格式化输出#创建智能体(Agent)agent=create_agent(model=llm,tools=all_tools,system_prompt="你是智能工具调用助手")以上代码通过create_agent函数创建一个具有工具调用能力的智能体(agent)。该智能体将大语言模型的推理能力与外部工具的执行能力有机结合,构建出一个能够理解自然语言、自主决策何时调用工具、并正确传递参数,成为用户与大语言模型、工具集之间的智能协调者,实现了从"用户提问"到"工具执行"再到"结果返回"的完整智能流程。其中create_agent函数常用的参数如表5-1所示。表5-1create_agent函数常用参数参数名类型是否必需默认值说明modelLLM实例是无已初始化的LLM实例toolsList[Tool]是无智能体可调用的工具列表,每个工具都是@tool装饰的函数system_promptstr或SystemMessage否None系统提示词,指导智能体行为2.调用工具并返回结果(1)编写代码在创建agent智能体之后,在智能体下方添加以下代码,实现智能体调用工具后,返回结果并显示调用过程。defshow_process(messages):"""显示调用过程和最终答案"""#第一步:初始化空列表,存储所有工具调用记录tools_used=[]formsginmessages:#遍历智能体处理过程中的所有消息记录ifhasattr(msg,'tool_calls')andmsg.tool_calls:#消息包含工具调用属性且不为空fortcinmsg.tool_calls:#遍历该消息中的每一个工具调用对象tools_used.append({#将工具调用信息结构化为字典并添加到列表中"name":tc.get('name'),#获取调用的工具函数名称"args":tc.get('args')#获取传递给该工具的参数})#第二步:格式化显示工具调用记录iftools_used:#如果有工具被调用print("调用工具的JSON格式:")#显示调用的JSON格式字符串print(json.dumps(tools_used,ensure_ascii=False,indent=2))print("调用的工具和参数:")#显示调用的工具和参数fortoolintools_used:print(f"-{tool['name']}:{tool['args']}")#第三步:从消息中提取最终答案answer=""#初始化答案变量formsginmessages:#再次遍历所有消息ifhasattr(msg,'type')andmsg.type=="ai"andhasattr(msg,'content'):#查找AI生成的消息answer=msg.content.strip()#提取消息内容并去除空白字符ifanswer:#如果找到非空答案break#找到答案后停止搜索#第四步:显示最终答案ifanswer:print(f"答案:{answer}")#输出智能体生成的最终答案if__name__=="__main__":print("调用工具回答用户问题")#程序启动提示print("="*40)#分隔线#进入交互式问答循环whileTrue:qution=input("请提问:").strip()#获取用户输入并去除首尾空格#检查退出条件:用户输入退出关键词ifqutionin['退出','exit','quit']:print("再见")break#退出循环#处理非空提问ifqution:try:#调用智能体处理用户问题result=agent.invoke({"messages":[{"role":"user","content":qution}]#问题包装成消息})show_process(result["messages"])#解析并显示智能体的执行过程exceptExceptionase:print(f"错误:{e}")#捕获并显示异常信息以上代码实现了一个包含过程可视化的智能体交互系统。系统接收用户问题后,由智能体进行处理,其执行过程中产生的完整消息流被show_process函数解析,以结构化格式展示智能体的内部操作,具体流程如下。①用户交互层通过交互式while循环构建命令行问答界面,持续接收用户的自然语言问题输入,并提供退出机制。②智能体执行层通过agent.invoke()方法将用户问题封装为标准消息格式,触发智能体的完整推理-执行工作流,首先由大语言模型进行思维链推理,分析问题意图并制定解决策略,然后基于推理结果自主决策是否调用外部工具,如需调用则选择合适的工具并生成结构化参数,智能体执行工具调用后,将工具返回的结果反馈给大语言模型,最后由大语言模型整合所有信息,生成符合用户需求的自然语言答案。③过程可视化层show_process函数深度解析智能体返回的完整消息流,捕获并提取所有工具调用记录(包括工具名称和传递参数),通过双重格式(标准JSON和易读文本)结构化展示智能体从问题理解、工具选择、参数传递到答案生成的完整决策链路,实现智能体内部操作过程的可视化。测试结果运行agent_basic.py程序,输入问题“辽宁省的省会在哪里”,结果如图5-4所示。图5-4任务5-1提问省会问题从结果中发现,当提问“辽宁省的省会在哪里”时,大模型能够分析用户问题,调用名称为get_provinec_capital的工具,并且传递了正确参数“辽宁省”,查询结果后,返回给用户,其中json字符串显示了大模型返回的调用工具名称和参数信息。提问“5乘以3等于几”时,大模型同样能够分析用户问题,调用名称为calculator的工具,并且传递了正确参数“5*3”,工具结果返回给大模型,由大模型回复用户正确结果,如图5-5所示。图5-5任务5-1提问数学计算问题课题名称项目5构建Agent智能体与工具系统任务5-2智能体调用MCP服务计划课时5课时教学引入王亮在开发一个具备天气和地理查询功能的智能体后,无法获取真实的天气和地理数据,技术主管要求他为该智能体集成高德地图的MCP服务能力,实现从申请开发者密钥、运行MCP服务器、开发MCP客户端到最终智能体集成的完整链路,确保智能体能够理解用户自然语言中的查询需求,调用高德地图API并返回精准结果。教学目标【知识目标】(1)掌握MCP协议的核心功能。(2)掌握MCP架构的核心组件。【技能目标】(1)能够开发运行高德MCP服务端的程序。(2)能够开发高德MCP客户端程序。(3)能够开发高德MCP客户端程序。【素养目标】(1)通过智能体集成MCP服务,培养学生构建标准化、可复用智能体工具的架构与集成能力。(2)通过遵循MCP协议标准进行开发,培养学生理解和使用接口规范的职业习惯。教学重点掌握MCP协议功能与架构组件,完成高德MCP服务端、客户端开发并集成至智能体实现地理数据查询。教学难点理解MCP标准化接口通信逻辑,打通密钥鉴权、服务交互、智能体调用的完整业务链路调试。教学方式任务驱动,案例教学教学过程任务5-2智能体调用MCP服务※通过直接引入的方式导入新课王亮在开发一个具备天气和地理查询功能的智能体后,无法获取真实的天气和地理数据,技术主管要求他为该智能体集成高德地图的MCP服务能力,实现从申请开发者密钥、运行MCP服务器、开发MCP客户端到最终智能体集成的完整链路,确保智能体能够理解用户自然语言中的查询需求,调用高德地图API并返回精准结果。-※新课讲解教师通过PPT的方式讲解。1.MCP协议的核心功能MCP(ModelContextProtocol)是一个开放、通用的协议标准,旨在为大语言模型提供统一的外部资源访问接口,使其能够动态调用工具和获取实时数据,而无需为每个应用场景开发专门的接口。MCP作为一种标准协议,就像为AI大模型提供了一个“万能接口”,使得AI模型能够与多种数据源和工具进行无缝连接。它类似于USB接口,通过标准化的方法将AI模型与各类工具和数据源进行对接,提供统一且可靠的方式来访问所需数据。MCP的核心目标是替代传统的碎片化Agent代码集成,从而提升AI系统的可靠性与效率。通过引入通用标准,服务提供商可以基于这一协议推出自己的AI服务能力,帮助开发者更快速地构建强大的AI应用,传统的智能应用在集成外部应用时,采用的架构如图5-6所示。图5-6传统智能应用调用外部应用架构从图5-6可以看出,每个智能应用在调用外部应用时,都需要进行代码对接,非常繁琐,引入了MCP协议之后,智能应用调用外部应用的架构如图5-7所示。图5-7传统智能应用调用外部应用架构从图5-7可以看出,在引入了MCP协议之后,大模型智能应用再对接外部应用就方便很多了,只需要大模型应用和外部应用都遵守MCP协议就可以了。2.MCP架构的核心组件MCP采用“客户端-服务器”模式进行工作,包括以下5个部分组成。(1)MCP主机(MCPHost)(2)MCP客户端(MCPClients)(3)MCP服务器(MCPServers)(4)本地资源(LocalResources)(5)远程资源(RemoteResources)通过网络访问的外部数据,指MCP服务器通过API或网络协议访问的远程服务,如第三方WebAPI(天气、股票、地图)、云端数据库等。各个组件之间的调用关系如图5-8所示。图5-8各组件之间的调用关系如图5-8所示,用户使用接口(如问题对话框)访问大语言模型,大语言模型借助MCP客户端访问MCP服务端,通过MCP服务端操作本地或者远程资源操作,进而扩展大语言模型的功能。二、在高德开放平台上申请开发密钥在本任务中,首先在在高德开放平台申请开发密钥,然后编程程序,在本地运行高德MCP服务器端(软件包已提供),接下来开发高德MCP客户端,获取MCP服务器的工具,最后在智能体中集成MCP客户端。1.登录高德开放平台高德MCP服务器需要使用高德开放平台上的API服务功能,为客户端提供工具,所以首先登录高德开放平台,申请API开发密钥,然后在本地运行高德MCP服务器。使用浏览器打开高德开放平台,地址为/,打开后返回页面如图5-9所示。图5-9高德开放平台首页单击右侧“登录”按钮,返回页面如图5-10所示。图5-10登录高德开放平台在图中使用“短信登录”或者手机扫描“二维码登录”方式进行登录,可以省去注册账号环节,首次登录时,按照提示使用支付宝和邮箱进行实名验证,登录成功后,单击“控制台”链接,如图5-11所示。图5-11进入控制台2.申请开发密钥进入到控制台后,选择左侧“应用管理”下的“我的应用”,单击右侧“创建新应用”按钮,如图5-12所示。图5-12创建新应用在“新建应用”对话框中,输入应用名称为MCP(任意),选择应用类型为“旅游”,如图5-13所示。图5-13创建名称为MCP,类型出行应用单击“新建”按钮,成功创建名称为MCP的应用,完成后,在MCP应用中,选择“添加Key”链接,如图5-14所示。图5-14选择“添加Key”链接在弹出的对话框中,输入Key名称为MCP_Agent,选择服务平台为Web服务,勾选“阅读并同意高德开放平台服务协议和高德开放平台隐私权政策”如图5-15所示。图5-15编辑Key的内容单击“提交”按钮,在langchain_agent应用下成功创建Key开发密钥,如图5-16所示。图5-16成功创建Key在图5-16中,可以选择右侧“查看配额”链接,高德开放平台为认证用户提供了免费的调用服务,足够学习使用。三、本地运行MCP服务器1.查询高德MCP服务器软件包(1)安装node.js软件使用浏览器访问node.js官网下载地址/zh-cn/download,结果如图5-17所示。图5-16成功创建Key单击图5-16中“Windows安装程序(.msi)”,下载node.js软件到本地,(也可以从教材资源中下载),下载完成后,启动安装程序,如图5-17所示。图5-16启动node.js安装程序单击“Next”按钮,进入到最终用户许可协议对话框,如图5-17所示。图5-17同意用户协议勾选接收协议条款后,单击“Next”按钮,进入到选择安装目录对话框,如图5-18所示。图5-18选择安装目录采用默认的安装目录,单击“Next”按钮,进入到“选择您想要的功能安装方式”,如图5-19所示。图5-19选择安装功能采用默认的功能,单击“Next”按钮,进入到“原生模块工具”对话框,如图5-20所示。图5-20原生模块工具采用默认设置(不勾选图中复选框),单击“Next”按钮,进入到准备安装Node.js对话框,如图5-21所示。图5-21准备安装Node.js单击“Instatll”按钮,等待一会后,成功安装了Node.js软件,如图5-22所示。图5-22成功安装Node.js(2)查询高德MCP服务软件包Node.js是JavaScript的运行环境,npm是Node.js的包管理器,启动Pycharm软件,打开命令行终端窗口,输入npm--version,查看npm包管理工具的版本信息,结果如图5-23所示。图5-23查看npm包管理工具的版本从结果中可以发现,npm包管理工具正确安装了,版本是11.6.2,使用npmconfiggetregistry命令查看npm包管理工具的默认仓库地址,如图5-24所示。图5-24查看npm包管理工具的默认仓库地址从结果中可以发现,npm包管理工具的仓库地址是/,使用npm查询包含amap(高德地图的官方英文标识)的软件包,结果如图5-25所示。图5-25通过npm查询包含amap的软件包从结果的框中发现高德MCP服务器的软件包,名称为@amap/amap-maps-mcp-server,其中@amap表示命名空间,是高德官方认证的包,MCPserverforusingtheAMapMapsAPI表示此软件包用于访问高德地图API的MCP服务器,后续编写代码,运行该软件包。2.编写运行高德MCP服务器代码MCP服务端和客户端的通信通常包括stdio、Socket、SSE等方式,stdio是MCP最简单的本地进程间通信方式,适合个人开发和简单集成,Socket提供全双工网络通信,支持多客户端和远程访问,适合生产环境与团队协作,SSE是基于HTTP的单向服务器推送,擅长实时通知和事件流,本任务采用Socket通信方式。(1)导入和定义类在project5项目中创建一个名称为mcp_server.py的文件,输入以下代码。importsubprocessimportosimporttimeimportsocketimportthreadingclassMCPServerTCP:"""TCP方式的MCP服务器"""def__init__(self,api_key:str,host='',port=8765):self.api_key=api_key#高德API密钥self.host=host#服务器监听地址self.port=port#服务器监听端口cess=None#MCP子进程self.server_socket=None#TCP服务器套接字self.clients=[]#已连接的客户端列表以上代码导入了五个Python标准库,构成了MCP代理服务器的技术基础。subprocess负责启动和管理外部MCP服务器进程;os用于安全传递API密钥等环境配置;time提供进程启动的时序控制;socket建立TCP网络通信服务端;threading实现多客户端并发处理能力。MCPServerTCP类定义了一个TCP到MCP的协议转换网关。初始化方法接收三个参数:高德API密钥用于服务认证,主机地址控制访问范围(默认本地),端口号指定服务入口。类内部维护三个关键属性:process将存储子进程控制器,server_socket作为网络监听器,clients列表用于管理所有活跃客户端连接,实现网络请求到本地进程通信的桥接转换。(2)主启动函数在以上代码的下边,继续编写主启动函数,如下所示。defstart(self):"""启动TCP服务器"""print("启动MCP服务器(TCP)...")#启动MCP进程env=os.environ.copy()env["AMAP_MAPS_API_KEY"]=self.api_key#设置环境变量#启动高德MCP服务器进程(Node.js包)cess=subprocess.Popen(["npx","-y","@amap/amap-maps-mcp-server"],env=env,stdin=subprocess.PIPE,#标准输入管道(接收数据)stdout=subprocess.PIPE,#标准输出管道(发送数据)stderr=subprocess.PIPE,#标准错误管道text=True,encoding='utf-8',bufsize=1,shell=True#Windows需要shell=True)time.sleep(2)#等待进程启动ifcess.poll()isnotNone:#检查进程是否已退出print("MCP进程启动失败")returnFalseprint("MCP进程启动成功")#启动TCP服务器self.server_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建TCP套接字self.server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#设置地址重用self.server_socket.bind((self.host,self.port))#绑定地址和端口self.server_socket.listen(5)#开始监听,最大连接数5print(f"TCP服务器监听:{self.host}:{self.port}")print("服务器启动成功")#启动客户端连接处理线程(接受新连接)accept_thread=threading.Thread(target=self._accept_clients,daemon=True)accept_thread.start()#启动MCP输出转发线程(将MCP输出转发给客户端)output_thread=threading.Thread(target=self._forward_output,daemon=True)output_thread.start()returnTrue以上代码主要完成启动MCP服务进程、建立TCP网络服务、启动工作线程等三个主要功能。①启动MCP服务进程②建立TCP网络服务。③启动工作线程(4)客户端连接管理在以上代码下方,输入客户端连接管理的代码,如下所示。def_accept_clients(self):"""接受客户端连接"""whilecessandcess.poll()isNone:#MCP进程运行时循环client_socket,addr=self.server_socket.accept()#接受客户端连接print(f"客户端连接:{addr}")#为每个客户端创建处理线程client_thread=threading.Thread(target=self._handle_client,args=(client_socket,addr),daemon=True#守护线程,主程序退出时自动结束)client_thread.start()self.clients.append(client_socket)#添加到客户端列表以上代码完成持续监听客户端连接和多客户端并发处理的功能。①持续监听客户端连接②多客户端并发处理(4)客户端数据处理在以上代码下方,输入客户端数据处理的代码,如下所示。def_accept_clients(self):"""接受客户端连接"""whilecessandcess.poll()isNone:#MCP进程运行时循环client_socket,addr=self.server_socket.accept()#接受客户端连接print(f"客户端连接:{addr}")#为每个客户端创建处理线程client_thread=threading.Thread(target=self._handle_client,args=(client_socket,addr),daemon=True#守护线程,主程序退出时自动结束)client_thread.start()self.clients.append(client_socket)#添加到客户端列表①连接接收循环机制②并发处理与连接管理(5)MCP输出转发在以上代码下方,输入MCP输出转发的代码,如下所示。def_forward_output(self):"""将MCP进程的stdout转发给客户端"""whilecessandcess.poll()isNone:#从MCP进程读取输出(逐行读取)line=cess.stdout.readline()ifline:print(f"MCP输出:{line[:100]}...")#转发给所有连接的客户端forclientinself.clients[:]:#创建副本遍历client.send(line.encode('utf-8'))#发送给客户端以上代码完成持续监听MCP进程输出、广播机制、数据流与编码转换功能。①持续监听MCP进程输出②广播机制③数据流与编码转换(6)主程序入口在以上代码下方,输入主程序入口的代码,如下所示。if__name__=="__main__":#创建MCP服务器实例server=MCPServerTCP(api_key="***********",#自己在高德开放平台申请的API密钥host='',#本地回环地址port=8765#监听端口)ifserver.start():#启动服务器print("服务器运行中,客户端可以连接")#保持程序运行(主线程休眠)whileTrue:time.sleep(1)以上代码是程序的主入口和启动控制部分。首先创建MCPServerTCP服务器实例,传入自己在高德开放平台申请德API密钥、本地主机地址和端口号。然后调用server.start()方法启动服务器,如果启动成功则打印运行提示,并通过whileTrue:time.sleep(1)让主线程无限休眠,保持程序持续运行,确保后台的TCP服务器线程和MCP进程能正常工作。运行mcp_server.py程序,结果如图5-26所示。图5-26MCP服务器端运行成功并等待客户端连接四、开发MCP客户端1.MCP客户端任务在MCP服务端成功运行并等待客户端连接后,客户端需要完成以下3个任务。(1)建立连接并初始化协议(2)查询可用工具列表(3)调用工具并处理结果2.编写高德MCP客户端代码(1)连接配置与初始化在project5项目中,创建名称为mcp_client的文件,输入以下代码。importsocketimportjsonclassMCPClient:"""MCP客户端"""def__init__(self,host='',port=8765):self.host=host#MCP服务器地址self.port=port#MCP服务器端口self.socket=None#TCP套接字self.id=1#JSON-RPC请求ID(自增)self.tools_info=[]#存储完整的工具信息以上代码导入socket和json两个模块,socket模块建立客户端与服务器的网络连接通道,json模块处理MCP协议基于JSON-RPC格式的数据交换。初始化方法设置客户端的关键参数:host和port确定服务器的位置,socket采用延迟初始化策略(首次通信时才建立连接),id作为JSON-RPC协议要求的请求标识符自增计数器,tools_info用于存储从服务器获取的工具信息。(2)底层通信处理在以上代码下方,输入底层通信处理的代码,如下所示。def_send(self,req):"""发送请求"""ifnotself.socket:self.socket=socket.socket()#创建TCP套接字self.socket.connect((self.host,self.port))#连接服务器#发送JSON-RPC请求(添加换行符作为分隔符)self.socket.send((json.dumps(req,ensure_ascii=False)+"\n").encode('utf-8'))resp=b""#存储响应数据whileTrue:chunk=self.socket.recv(4096)#接收数据块(最大4096字节)ifnotchunk:#连接关闭breakresp+=chunkifb"\n"inchunk:#检测到换行符,表示完整响应结束break#解析JSON响应,如果无响应则返回空字典#处理接收到的数据ifresp:json_str=resp.decode('utf-8').strip()#解码并去除首尾空白returnjson.loads(json_str)#反序列化为Python对象else:return{}#空响应返回空字典以上代码完成请求发送、响应接收、数据解码与结果返回功能。①请求发送②响应接收③数据解码与结果返回(3)获取工具列表在以上代码下方,输入获取工具列表的代码,如下所示。defdiscover_tools(self):"""发现可用工具,显示所有工具名称和描述"""#初始化MCP连接self._send({"jsonrpc":"2.0","id":self.id,"method":"initialize","params":{}})self.id+=1#递增请求ID#获取工具列表res=self._send({"jsonrpc":"2.0","id":self.id,"method":"tools/list","params":{}})self.id+=1if"result"inres:#检查响应是否成功self.tools_info=res["result"].get("tools",[])#提取工具列表print(f"发现{len(self.tools_info)}个可用工具:")fori,toolinenumerate(self.tools_info,1):tool_name=tool.get("name","")tool_desc=tool.get("description","无描述")print(f"{i:2d}.{tool_name}")print(f"说明:{tool_desc}")return[tool.get("name")fortoolinself.tools_info]#返回工具名称列表return[]#无工具时返回空列表以上代码实现工具发现请求、响应验证与数据提取、返回值处理等功能。①工具发现请求②响应验证与数据提取③返回值处理(4)工具调用和结果解析在以上代码下方,输入工具调用和结果解析的代码,如下所示。defquery(self,tool,args):"""查询工具"""#初始化MCP连接(每次查询都需要)self._send({"jsonrpc":"2.0","id":self.id,"method":"initialize","params":{}})self.id+=1#调用工具请求call_req={"jsonrpc":"2.0","id":self.id,"method":"tools/call","params":{"name":tool,"arguments":args}#工具名称和参数}res=self._send(call_req)self.id+=1if"result"inres:#成功响应content=res["result"].get("content",[{}])#获取内容数组ifcontent:returncontent[0].get("text","")#返回文本内容以上代码实现MCP会话初始化与请求构建、请求发送与响应接收、响应验证与结果提取等功能。①MCP会话初始化与请求构建②请求发送与响应接收③响应验证与结果提取(5)主程序入口在以上代码下方输入主程序入口代码,如下所示。if__name__=="__main__":client=MCPClient()#创建客户端client.discover_tools()#发现工具以上主程序入口首先创建MCP客户端实例连接到本地服务器,然后调用discover_tools()方法查询并展示服务器提供的可用工具列表。运行mcp_client.py程序,结果如图5-27所示。图5-27MCP客户端获取MCP服务端工具列表从结果中发现,客户端运行后,发现并输出了MCP服务器端工具列表。五、智能体集成MCP客户端1.任务分解智能体通过集成MCP客户端访问MCP服务器,从而调用服务器端提供的各种工具能力,在集成客户端时,需要完成以下三个核心任务。(1)建立连接(2)智能体构建与能力集成(3)交互执行与闭环管理2.编写高德MCP客户端代码(1)客户端初始化在project5项目中,创建名称为mcp_client的文件,输入以下代码。frommodelimportllmfromlangchain.agentsimportcreate_agentimportjsonfromlangchain_core.toolsimporttoolfrommcp_clientimportMCPClient#创建MCP客户端mcp_client=MCPClient()以上代码完成了智能体集成MCP客户端的初始化准备工作,首先导入必要的依赖模块,包括语言模型、智能体框架、工具装饰器以及MCP客户端库,随后通过实例化MCP客户端,触发与远程MCP服务器的连接建立过程,为后续的工具发现、注册和调用做好通信基础准备。(2)定义封装工具在以上代码的下方,输入定义和封装工具的代码,如下所示。#创建MCP客户端mcp_client=MCPClient()#创建工具函数@tool("maps_weather")defweather_tool(city:str):"""查询城市天气,参数:city(城市名称)"""raw_result=mcp_client.query("maps_weather",{"city":city})returnraw_result[:500]ifraw_resultelse"无返回结果"@tool("maps_geo")defgeo_tool(address:str,city:str=""):"""地址转经纬度,参数:address(地址),cit
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年环保水务项目质量管控措施
- 2026年高考语文阅读答题专项训练及答案
- 《特殊器械感染处理流程》试题及答案
- 某汽配厂生产安全规范
- 某汽车零部件厂质量检测规则
- 某汽车厂安全管理规范
- 销售人员客户关系维护与长期合作建立指导书
- 人教版七年级英语Unit 8词汇深度教学与中考提优教案
- 初中七年级数学上册核心知识清单:一元一次方程解法(合并同类项与移项)
- 初中七年级数学“轴对称”单元深度学习探究式教案
- 头部损伤护理查房课件
- 2023年模具业界掀起低碳环保时代风报告模板
- 地下室聚氨酯防水技术交底
- 大学英语四级真题阅读练习10套(附参考答案)
- 贵阳市普通中学2022-2023学年度高一下学期期末语文试题(扫描版含答案)
- GB/T 42598-2023机械安全使用说明书起草通则
- 大学英语六级词汇表(全)含音标
- 设计成果确认单
- (11.5)-4.3.1高原珍宝红景天中药养颜秘籍
- 仁清参考资料法师:四部宗义精要
- JJG 921-2021环境振动分析仪
评论
0/150
提交评论