如何开发一个大模型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”)

2. 包装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’:

3. 启动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() # 初始化会话连接

2. 获取所有可用的工具列表

tools_response = await session.list_tools()

print(“可用工具:”, [tool.name for tool in tools_response.tools])

3. 调用天气查询工具

result = 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服务的交互次数。

构建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:

2. 连接MCP服务

server_script_path = “./server.py”

await mcp_client.connect_to_server(server_script_path)

3. 执行用户请求

message = “查询今天深圳的天气情况。如果天气是下雨,就关上窗户;否则打开窗户。”

final_text = await agent.process_message(message)

print(final_text)

finally:

4. 清理相关资源

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 ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

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

在这里插入图片描述

Logo

更多推荐