如何开发一个大模型Agent?

本案例我们介绍如何开发一个智能体(Agent)应用。该智能体通过查询天气情况,自动判断是否应该开启或关闭窗户,从而实现家居环境的智能管理。

我们知道,智能体可以使用工具调用的方式调用各种API接口,但为了能让工具调用变得更简单和高效,可以使用MCP协议将API接口封装成MCP工具。本文将分析MCP服务的基本概念与特点、开发流程与实施方法,并探讨它与智能体结合,在智能家居应用场景下的应用实践。

一、MCP架构说明

MCP即Model Context Protocol(模型上下文协议),是一种创新的解决方案,旨在解决大模型与外部数据源和工具连接的难题。

MCP定义了3种核心原语,这些原语是编写MCP的关键,并且决定了服务器能为大模型提供什么能力。这些原语包括:

(1)提示词(Prompts):指预定义的指令或模板,用于引导大语言模型处理输入或生成预期输出。提示词可以是用户可控的交互式模板,例如通过斜杠命令(如/summarize)或菜单选项进行调用。这些提示经过专门的设计和优化,旨在提升语言模型在特定任务或领域中的交互效果与生成质量,是实现高效人机协同的关键工具。

(2)资源(Resources):提供额外上下文的结构化数据,例如文件或数据库内容。资源是由应用控制、由客户端附加并管理的上下文数据,如文件内容、git历史记录。它们代表服务器想要提供给客户端的任何类型的数据,可以包括文件内容、数据库记录、API响应等。

(3)工具(Tools):指可执行的函数或功能接口,使大语言模型能够执行具体操作(如调用API、查询数据库、进行数学计算等)或获取外部信息。工具由系统提供并暴露给模型使用,属于模型可控的扩展能力。它们既可以是简单的本地函数,也可以是复杂的第三方服务接口。工具允许服务器暴露可执行的函数,这些函数可以被客户端调用并被大模型用来执行操作。

本例的模型上下文协议遵循“客户端-服务器”架构,如图1所示。其中每个宿主可以运行多个客户端实例,每个客户端背后对接一个MCP服务,该MCP服务管理自身的资源和API接口。这种架构使用户能够在应用程序之间集成AI功能,同时保持明确的安全边界和关注点隔离。MCP客户端与MCP服务端之间采用JSON-RPC 2.0通信协议,基于JSON-RPC,MCP提供了一个有状态的会话协议,专注于客户端和服务器之间的上下文交换和采样协调。

图1 MCP架构图

通过图1的“客户端-服务器”架构,可以隔离使用方与服务提供方,使服务提供方能将自身能力公布给其他开发者使用。

下面以构建智能家居领域的设备控制为例,演示如何构建一个完整的集成MCP服务的智能体。

二、构建智能家居MCP服务端

构建MCP服务比较方便的是使用Python的mcp库,执行pip install mcp命令即可安装该库。该库支持STDIO模式(本机模式)和SSE模式(远程模式)。STDIO模式可以对接本地的MCP服务,SSE模式可以对接第三方的MCP服务。本文为了演示方便,直接使用STDIO模式来演示。

本示例我们需要实现的功能是根据室外天气情况自动开关窗,因此需要将天气查询和设备控制的操作都封装成MCP服务中的工具,并描述这些工具的功能,方便客户端更好地调用大模型做工具选择。

【例1】构建MCP服务。

import os

import requests

from mcp.server.fastmcp import FastMCP
  1. 创建一个MCP服务
    ============
mcp = FastMCP("IoTServer")
  1. 包装MCP工具
    ==========
@mcp.tool()

def weather\_query(location: str):

"""根据提供的城市名,查询天气情况"""

api\_key = "xxxxxx"

base\_url = "https://restapi.amap.com/v3/weather/weatherInfo?parameters"

params = {

"key": api\_key,

"city": location

}

response = requests.get(base\_url, params=params, timeout=10)

if response.status\_code == 200:

data = response.json()

return data["lives"][0]

else:

return {"error": "无法获取到天气信息,请检查城市名称是否正确"}

@mcp.tool()

def window\_control(status: str):

"""控制窗户的开和关,status有开和关两种"""

if status == "开":

return "窗户已打开"

elif status == "关":

return "窗户已关闭"

return "不支持该操作:" + status

if **name** == '**main**':
  1. 启动MCP服务
    ==========
mcp.run()

上述代码即创建了一个智能家居的MCP服务,该服务包含两个工具:天气查询工具和窗户开关控制工具。天气查询工具与第6章介绍Function Calling时一样,不同的是这里使用MCP的工具装饰器包装。而对于设备控制的工具,在实际的物联网(Internet of Things,IoT)领域,需要请求设备提供的SDK接口做具体的开关控制,整条链路其实比较长也比较复杂,本示例为了方便演示做了简化。

从上述示例代码可知,构建一个最简单的MCP服务需要如下3步操作:

(1)创建一个MCP服务对象,设置服务名称,方便调用方进行MCP工具类的区分。

(2)包装MCP工具,使用@mcp.tool()装饰器即可将一个普通函数封装成一个MCP工具,通过解析该函数的函数名、参数名、参数类型、函数注释,即可完成MCP工具的函数签名解析,即将函数签名解析成OpenAI的大模型调用格式。对于客户端来说,可以直接将其传给大模型做工具选择的调用。

(3)启动MCP服务对外提供服务。有SSE和STDIO两种启动模式,默认采用STDIO模式启动。

三、构建智能家居MCP客户端

MCP服务启动后,接下来我们通过一个简单的客户端调用测试一下。比如要查询深圳的天气,就需要执行以下3步操作:

(1)配置连接参数,连接MCP服务。

(2)获取该MCP服务的所有工具描述信息。

(3)调用查询天气的工具。

【例2】构建MCP客户端。

import asyncio

from mcp import ClientSession, StdioServerParameters

from mcp.client.stdio import stdio\_client

async def main():

配置 MCP服务的启动参数

server\_params = StdioServerParameters(

command="python",

args=["server.py"],

env=None

)
  1. 启动服务端,并连接MCP服务
    =================
async with stdio\_client(server\_params) as (stdio, write):

async with ClientSession(stdio, write) as session:

await session.initialize() # 初始化会话连接
  1. 获取所有可用的工具列表
    ==============
tools\_response = await session.list\_tools()

print("可用工具:", [tool.name for tool in tools\_response.tools])
  1. 调用天气查询工具
    ===========

r

esult = await session.call\_tool("weather\_query", {"location": "深圳"})

print("工具调用结果:", result.content[0].text)

if **name** == '**main**':

asyncio.run(main())

因为MCP服务默认使用STDIO模式启动,因此需要设置stdio的连接参数。其中最重要的是设置MCP服务脚本路径,客户端通过这个路径先用command参数去启动该MCP服务端脚本,再去连接服务端。代码中的第3步,为了简化测试,直接指定天气查询调用weather_query工具。实际上MCP服务与智能体结合后,需要由大模型从所有可用的工具列表中根据任务描述,自动选择需要调用的工具,这部分在下一小节介绍。

另外,在上述代码中用到了非常多的异步操作,因为在MCP服务中一个工具的调用可能不是实时处理的,一个复杂的操作可能需要耗费较多的时间,所以整体MCP服务采用异步调用的方式。对于客户端来说,调用异步方法也需要采用异步的方式。

四、构建智能家居MCP智能体应用

有了MCP客户端-服务端架构的实现,接下来我们通过构建完整的智能体调用的方式来实现天气信息查询的应用。为了实现良好的工程化体验,我们将该智能体应用分成两个模块:

(1)MCPClient模块:设计专门的MCP客户端,用于操作MCP服务相关的功能。

(2)MCPAgent模块:设计专门的智能体,通过集成MCPClient对象,实现用户的输入请求。

MCPClient面向的是工具调用,完成具体任务的执行。MCPAgent面向的是用户,通过集成各种MCP工具,自主完成用户的请求。

  1. 构建MCPClient模块

【例3】构建智能家居的MCP客户端。

import asyncio

from contextlib import AsyncExitStack

import cachetools

from mcp import ClientSession, StdioServerParameters

from mcp.client.stdio import stdio\_client

class MCPClient():

def **init**(self):

self.session = None

self.exit\_stack = AsyncExitStack()

缓存工具列表,避免每次选择工具都需要重新查询MCP服务的所有工具

self.tools\_ttl\_cache = cachetools.TTLCache(maxsize=5, ttl=5)

self.CACHE\_TOOLS\_KEY = "tools"

连接MCP服务

async def connect\_to\_server(self, server\_script\_path: str):

server\_params = StdioServerParameters(

command="python",

args=[server\_script\_path],

env=None

)

stdio\_transport = await self.exit\_stack.enter\_async\_context(stdio\_client(server\_params))

self.stdio, self.write = stdio\_transport

self.session = await self.exit\_stack.enter\_async\_context(ClientSession(self.stdio, self.write))

await self.session.initialize()

await self.list\_tools() # 连接MCP服务后先缓存所有可用的工具

获取MCP服务中所有可用的工具

async def list\_tools(self):

读取缓存

if self.CACHE\_TOOLS\_KEY in self.tools\_ttl\_cache:

return self.tools\_ttl\_cache[self.CACHE\_TOOLS\_KEY]

获取 MCP 工具

response = await self.session.list\_tools()

将工具描述转换成大模型可理解的格式

available\_tools = [{

"type": "function",

"function": {

"name": tool.name,

"description": tool.description,

"parameters": tool.inputSchema

}

} for tool in response.tools]

设置缓存

self.tools\_ttl\_cache[self.CACHE\_TOOLS\_KEY] = available\_tools

return available\_tools

调用工具

async def call\_tool(self, tool\_name, tool\_args):

result = await self.session.call\_tool(tool\_name, tool\_args)

return result

async def cleanup(self):

"""清理资源"""

await self.exit\_stack.aclose()

对比上述代码与上一小节的简单测试脚本的代码,其实它们的逻辑大致类似,只不过为了工程化解耦,上述代码做了模块化的拆分。获取MCP服务的所有工具描述之后,可以将其缓存在内存中,并设置一定时间的有效期。因为智能体在调用MCP服务时需要经常查询有哪些工具可用,存在频繁请求工具列表的操作,设置缓存可大大减少MCP客户端与MCP服务的交互次数。

  1. 构建MCPAgent模块

智能体是面向用户的,它的主要工作是根据用户输入的任务自动选择合适的工具来完成请求。可能单次的MCP工具调用还不足以完成完整的用户请求,需要多次自主选择工具并执行,直到最后不需要调用任何工具即可完成用户请求。

MCPAgent通过集成MCPClient对象,将与MCP服务交互的操作都交给MCPClient完成。本示例依然使用智谱AI的glm-4-plus大模型完成工具的自动选择,示例代码如下:

【例4】构建智能家居的智能体。

class MCPAgent():

def **init**(self, mcp\_client):

self.mcp\_client = mcp\_client

self.client = ZhipuAI(api\_key="你的API Key")

self.llm\_model\_name = "glm-4-plus"
  1. 处理用户请求
    =========
async def process\_message(self, query: str) -> str:

messages = [{"role": "user", "content": query}]

message = await self.select\_tools(messages)

final\_text = [message.content or ""]

1.1 迭代请求大模型自动选择工具,当不需要再调用工具时,则用户请求处理完毕

while message.tool\_calls:

1.2 处理每一个工具调用

for tool\_call in message.tool\_calls:

tool\_name = tool\_call.function.name

tool\_args = json.loads(tool\_call.function.arguments)

result = await self.mcp\_client.call\_tool(tool\_name, tool\_args)

final\_text.append(f"[Calling tool {tool\_name} with args {tool\_args}]")

1.3 将工具调用结果加入历史消息记录中,作为大模型选择工具的背景知识

messages.append({

"role": "tool",

"tool\_call\_id": tool\_call.id,

"content": str(result.content)

})

message = await self.select\_tools(messages)

final\_text.append(message.content or "")

return "n".join(final\_text)
  1. 根据历史会话记录自动选择工具调用
    ===================
async def select\_tools(self, messages):

2.1 获取MCP服务中所有可用工具

available\_tools = await self.mcp\_client.list\_tools()

2.2 自动选择工具

response = self.client.chat.completions.create(

model=self.llm\_model\_name,

messages=messages,

tools=available\_tools

)

message = response.choices[0].message

return message

上述流程从process_message()函数处理用户请求开始,主要分3步:

(1) 根据用户输入以及MCP服务提供的所有工具列表信息,大模型自动选择应该调用哪个工具,并解析出工具调用所需的参数。

(2) 通过MCP客户端执行工具调用。

(3) 将工具调用的结果加到会话记录列表中,并迭代上述两个步骤,直到不需要调用工具即可完成用户请求为止。

五、测试智能家居智能体

以根据天气情况控制窗户开关的需求为例,进行如下测试。

【例5】测试智能家居的智能体。

async def main():

  1. 创建智能体对象
    ==========
mcp\_client = MCPClient()

agent = MCPAgent(mcp\_client)

try:
  1. 连接MCP服务
    ==========
server\_script\_path = "./server.py"

await mcp\_client.connect\_to\_server(server\_script\_path)
  1. 执行用户请求
    =========
message = "查询今天深圳的天气情况。如果天气是下雨,就关上窗户;否则打开窗户。"

final\_text = await agent.process\_message(message)

print(final\_text)

finally:
  1. 清理相关资源
    =========
await mcp\_client.cleanup()

if **name** == "**main**":

asyncio.run(main())

MCP服务不太方便的地方在于,因为有很多的异步调用操作,所以整个调用链条都需要采用异步的方式包装,实际开发起来会比较麻烦。

执行上述测试用例,结果如下:

[Calling tool weather\_query with args {'location': '深圳'}]

[Calling tool window\_control with args {'status': '开'}]

今天深圳的天气情况是阴天,气温27℃,东南风3级,湿度56%。因为没有下雨,所以窗户已经打开了。

从执行过程可知,在循环调用大模型自主选择MCP工具时,根据用户的输入,第一步规划需要调用天气查询的工具。获取到天气信息后,再次判断需要调用设备控制的工具,从而实现窗口的开和关操作。在最后一次循环中,大模型自动判断不需要再调用其他工具即可完成用户的任务,因此退出循环,并将最终的结果打印出来。

由此实现了智能家居场景下的设备自动控制功能,根据室外天气情况自动操控家居设备的状态。上述演示只是最简单的示例,读者可以参考上述示例,结合具体的IoT接口,完成更复杂的智能家居场景设备控制功能,例如开关灯、控制空调到合适的温度和风速等。

六、案例小结

在本案例中,我们展示了如何利用智能体与MCP服务构建智能家居领域的一个实际应用。该案例通过查询天气情况,自动判断是否应该开启或关闭窗户,从而实现家居环境的智能管理。

首先,我们介绍了MCP的基本概念和架构设计逻辑,接着详细阐述了如何构建MCP服务,包括服务构建、工具获取和调用等关键步骤,最后通过一个完整的示例介绍如何将智能体与MCP服务结合使用,以实现智能家居场景下的自动化决策。

通过本案例的学习,读者不仅可以掌握MCP的基本原理和应用方法,还可以了解如何利用智能体技术实现智能家居场景下的自动化决策。这些知识和技术对于从事智能家居领域的开发人员和研究人员来说,具有重要的参考价值。

最后

为什么要学AI大模型

当下,⼈⼯智能市场迎来了爆发期,并逐渐进⼊以⼈⼯通⽤智能(AGI)为主导的新时代。企业纷纷官宣“ AI+ ”战略,为新兴技术⼈才创造丰富的就业机会,⼈才缺⼝将达 400 万!

DeepSeek问世以来,生成式AI和大模型技术爆发式增长,让很多岗位重新成了炙手可热的新星,岗位薪资远超很多后端岗位,在程序员中稳居前列。

在这里插入图片描述

与此同时AI与各行各业深度融合,飞速发展,成为炙手可热的新风口,企业非常需要了解AI、懂AI、会用AI的员工,纷纷开出高薪招聘AI大模型相关岗位。
在这里插入图片描述
最近很多程序员朋友都已经学习或者准备学习 AI 大模型,后台也经常会有小伙伴咨询学习路线和学习资料,我特别拜托北京清华大学学士和美国加州理工学院博士学位的鲁为民老师给大家这里给大家准备了一份涵盖了AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频 全系列的学习资料,这些学习资料不仅深入浅出,而且非常实用,让大家系统而高效地掌握AI大模型的各个知识点。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

AI大模型系统学习路线

在面对AI大模型开发领域的复杂与深入,精准学习显得尤为重要。一份系统的技术路线图,不仅能够帮助开发者清晰地了解从入门到精通所需掌握的知识点,还能提供一条高效、有序的学习路径。

img

但知道是一回事,做又是另一回事,初学者最常遇到的问题主要是理论知识缺乏、资源和工具的限制、模型理解和调试的复杂性,在这基础上,找到高质量的学习资源,不浪费时间、不走弯路,又是重中之重。

AI大模型入门到实战的视频教程+项目包

看视频学习是一种高效、直观、灵活且富有吸引力的学习方式,可以更直观地展示过程,能有效提升学习兴趣和理解力,是现在获取知识的重要途径

在这里插入图片描述
光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

海量AI大模型必读的经典书籍(PDF)

阅读AI大模型经典书籍可以帮助读者提高技术水平,开拓视野,掌握核心技术,提高解决问题的能力,同时也可以借鉴他人的经验。对于想要深入学习AI大模型开发的读者来说,阅读经典书籍是非常有必要的。
在这里插入图片描述

600+AI大模型报告(实时更新)

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。
在这里插入图片描述

AI大模型面试真题+答案解析

我们学习AI大模型必然是想找到高薪的工作,下面这些面试题都是总结当前最新、最热、最高频的面试题,并且每道题都有详细的答案,面试前刷完这套面试题资料,小小offer,不在话下
在这里插入图片描述

在这里插入图片描述

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐