当前位置: 首页 > wzjs >正文

施工企业会计案例分析论文seo 优化技术难度大吗

施工企业会计案例分析论文,seo 优化技术难度大吗,网站建设需求网,哈尔滨网站建设优化👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理、AI应用🔥如果感觉…
  • 👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家
  • 📕系列专栏:Spring原理、JUC原理、Kafka原理、分布式技术原理、数据库技术、JVM原理、AI应用
  • 🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
  • 🍂博主正在努力完成2025计划中:逆水行舟,不进则退
  • 📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀

文章目录

  • MCP 是什么
  • MCP 核心概念
  • 设置环境
  • 正式构建应用
    • 导入包
    • 辅助函数
    • 工具开发
      • 基础版本
      • 测试运行
      • 基本版本2
      • cursor运行
      • 含有模板的 版本
      • 测试

MCP 是什么

如何去开发属于自己的MCP服务,并使用cursoor进行本地配置,那么MCP是什么?首先我们可以进入到MCP的官方网站

https://mcp-docs.cn/introduction

全称是Model Context Protocol,是连接大模型 与 外部资源工具的标准化接口服务,说的通俗一些呢,MCP就是标准化的function call,只不过这个function call是属于大模型与外部资源工具之间的交互。模型本身呢只是对数据进行计算 和 处理的。

模型本身是不具备获取外部资源 和 工具的能力,而MCP为大模型提供的 具备外部资源 和 工具的能力,并且MCP的诞生可以让大模型自行调用这些资源 和 工具,比如AI模型没有能力使用我们本地数据库的数据,然后使用特定结构的sql查询获取数据再生成图表的这个过程。

那么使用MCP来实现这个功能,一个MCP负责通过SQL查询获取数据,然后另一个MCP负责生成图表,比如生成图片格式或者HTML格式,这些都是可以让MCP提供工具,让大模型去使用的。

那么本篇文章会依据官方文档从零开始使用MCP开发一个天气查询服务。

我们可以继续看下mcp的整体运行流程。

上图是mcp的客户端 和 三个mcp服务在一台服务器上部署,前两个mcp服务对接的是本地的数据库数据,第三个mcp服务通过web api去请求了互联网上的外部资源数据,mcp客户端可以获知这三个mcp server的具体能力,然后再把这些能力交给大模型,那么大模型就会知道这三个mcp server的具体能力,那么在我们使用大模型的时候,大模型就可以自行判断是否要使用相关mcp的tools,也就是大模型的工具,接下来ai模型就可以通过某个mcp server提供的工具获取我哦们本地数据库的数据 或者 外部资源的数据,对相关数据进行计算 和 推理。

关于mcp server的开发,根据官方文档的描述,核心就是我们去创建一个天气查询的mcp服务,主要提供几个tools,然后我们把这几个tools连接到我们的mcp主机上,也就是带有client的大模型中,就可以正常使用了。

MCP 核心概念

接下来说一下mcp的核心概念,其实他可以提供三种主要类型的功能。

第一种resource,客户端可以读取类似文件的数据,如api响应 或 文件内容,也就是说,我们自己开发好的后端api 或 第三方的api接口 或者第三方文件可以通过resource来进行读取。区别在于传统api使用时或者我们程序主动调用 或 处理数据的过程,resource将数据源的注册为标准化URI资源,允许模型通过统一接口直接访问。无需关心底层实现细节。也就是说我们有一个url,这个url可以直接接入数据库某个表的数据,然后模型就可以直接通过这个url来获取这个表的数据,并且不会像使用tools那样需要我们进行确认,这样的做法,丰富了模型的上下文信息。对于resource,标准规范是只对数据进行读取,不能进行写入。

第二个 tools可以让模型进行相关的工具函数的使用,但是他需要用户批准,也就是说我们开发的mcp服务,可以提供很多函数,这些函数可以让模型自行去使用,比如说我们获取了一个获取天气预报的函数,那么模型就可以自己调用这个函数来获取天气信息,那么类比一下,就好比我们传统开发后端api一样,我们自己开发了一个获取天气预报的api接口,然后我们自己去使用这个api来获取天气预报信息,只不过这个过程是把我们自己替换成了模型而已。

第三个 prompts提示词,帮助用户完成特定任务的预写模板,其实就是为tools工具提供了一个提示词,让模型可以根据提示词模板进行回答,就比如说我通过天气预报函数 获取今天天气的同时,我还想让模型给我出门穿衣服的建议,那么我就可以为这个天气函数提供一个提示词,让模型可以根据提示词模板来进行回答。

设置环境

接下来使用python来开发一下这个 server。版本必须在3.10以上、Python MCP SDK 1.2.0 或者更高版本

根据官方文档,简单设置下环境:

curl -LsSf https://astral.sh/uv/install.sh | sh

之后请确保重启终端,以确保 uv 命令被正确识别。

现在,让我们创建并设置我们的项目:

# 为我们的项目创建一个新目录
uv init weather
cd weather
# 创建虚拟环境并激活它,我们创建一个目录 weather_env 来存放虚拟环境
uv venv weather_env
source ./weather_env/Scripts/activate
# 测试 python 是否是指定的当前虚拟环境中的python
which python
# 安装 http 依赖用于调用外部API 和 mcp cli的相关命令行工具,
# --active 让 uv 使用当前激活的环境安装相关依赖
uv add "mcp[cli]" httpx --active
# 创建我们的服务器文件
touch weather.py

其中mcp clie提供了对mcp server进行本地调试的能力,而httpx主要是用于对外部的天气api接口进行请求,因为我们需要http请求的方式。

当前置的准备工具就位后,就可以在 weather.py 文件里开发了。。。

正式构建应用

接下来就开始正式开发了

导入包

from typing import Any# 用于发送 HTTP 请求
import httpx
# 用于创建 MCP 服务
from mcp.server.fastmcp import FastMCP# 初始化一个MCP服务实例,服务名称就是weather,这将作为 MCP 客户端或大模型识别服务的标识
mcp = FastMCP("weather")# 定义OpenWeatherMap API 的基础URL
OPENWEATHER_API_BASE = "https://api.openweathermap.org/data/2.5"# API 密钥
OPENWEATHER_API_KEY = "××"
# API 调用的身份识别
USER_AGENT = "weather-app/1.0"

关于openWeather没有注册的需要注册下

https://openweathermap.org/api

这里面有一个接口是根据城市名称获取天气信息的api接口。使用之前需要一个api key需要前置自己申请好!!!

辅助函数

# 核心工具函数:负责向OpenWeatherMap API 发送请求并处理响应
async def make_weather_request(url: str) -> dict[str, Any] | None:"""向OpenWeatherMap API 发送请求并处理响应,包括适当的错误处理。Args:url (str): 完整的OpenWeatherMap API 请求URLReturns:dict[str, Any]None: 如果请求成功,返回响应的JSON数据,否则返回None"""# 设置请求头,包含User-Agent标识headers = {"User-Agent": USER_AGENT,"Accept": "application/json","Content-Type": "application/json",}# 创建异步Http客户端会话async with httpx.AsyncClient() as client:try:# 发送GET请求,并设置请求头和超时response = await client.get(url, headers=headers, timeout=30.0)# 检查HTTP状态,非2XX状态码会抛出异常response.raise_for_status()# 解析JSON响应数据并返回return response.json()except Exception as e:print(f"错误 {e}")return None

调用的核心工具函数就以及开发完了,它主要是对天气API进行请求,并获取api返回的数据。

# 辅助函数:将当前JSON格式的天气数据转换为可读的文本格式
def format_weather_data(data: dict, units: str = "metric") -> str:"""将JSON格式的天气数据转换为可读的文本字符串格式Args:data (dict): JSON格式的天气数据Returns:str: 格式化的天气信息文本"""# 检查data是否为空if not data:return "无法获取天气数据"# 从 API 响应中提取关键天气信息# 获取国家代码country_code = data.get("sys", {}).get("country", "未知")# 获取城市名称city_name = data.get("name", "未知")# 获取天气描述weather_desc = data.get("weather", [{}])[0].get("description", "未知")# 获取当前温度(摄氏度)temp = data.get("main", {}).get("temp", "未知")# 获取体感温度(摄氏度)feels_like = data.get("main", {}).get("feels_like", "未知")# 获取湿度(百分比)humidity = data.get("main", {}).get("humidity", "未知")# 获取风速(m/s)wind_speed = data.get("wind", {}).get("speed", "未知")# 根据 units 参数确定温度和风速的单位temp_unit = "°C" if units == "metric" else "°F"wind_speed_unit = "m/s" if units == "metric" else "mph"# 构建格式化的天气信息字符串return f"""城市: {city_name}国家: {country_code}天气: {weather_desc}温度: {temp} {temp_unit}体感温度: {feels_like} {temp_unit}湿度: {humidity}%风速: {wind_speed} {wind_speed_unit}"""

想知道具体的返回格式只需要 curl一下即可,就能拿到具体的返回值,然后直接封装解析即可。

工具开发

基础版本

# @mcp.tool() 是一个装饰器,用于将函数注册为 MCP 工具,允许大模型进行调用
# @mcp.tool(name="get_weather", description="获取指定城市的当前天气信息, 如果用户使用中文询问某城市天气,你必须将城市名转换为相应的英文名称再调用API。")
@mcp.tool()
# MCP 工具1:根据城市获取当前的天气信息,由大模型调用这个函数,函数参数由大模型传入
async def get_weather(city: str, country_code: str = None, state_code: str = None, units: str = "metric", lang: str = "zh_cn") -> str:"""获取指定城市的当前天气信息,如果用户使用中文询问某城市天气,你必须将城市名转换为相应的英文名称再调用API。Args:city: 城市名称 (例如:Beijing, Shanghai, New York)country_code: 国家代码(可选,例如:CN, US, JP)state_code: 州/省代码(可选,例如:BJ, SH, NY)units: 测量单位(可选,默认metric)lang: 语言(可选,默认zh_cn)Returns:str: 格式化的当前天气信息文本"""# 构建位置查询参数,支持城市名称、州代码和国家代码组合location_query = cityif state_code and country_code:# 格式:城市,州代码,国家代码location_query = f"{city},{state_code},{country_code}"if country_code:# 格式:城市,国家代码location_query = f"{city},{country_code}"# 构建API请求URL,参数包含位置查询、API密钥、测量单位和语言url = f"{OPENWEATHER_API_BASE}/weather?q={location_query}&appid={OPENWEATHER_API_KEY}&units={units}&lang={lang}"# 发送请求并获取响应数据data = await make_weather_request(url)# 检查 API 响应中的错误代码if "cod" in data and data["cod"] != 200:return f"获取天气信息失败,错误:{data.get('message', '未知错误')}"# 使用辅助函数格式化天气信息并返回,传入data和units参数return format_weather_data(data, units)

其实上述中的描述是最关键的,就按照这个格式来就好。

"""获取指定城市的当前天气信息,如果用户使用中文询问某城市天气,
你必须将城市名转换为相应的英文名称再调用API。Args:city: 城市名称 (例如:Beijing, Shanghai, New York)country_code: 国家代码(可选,例如:CN, US, JP)state_code: 州/省代码(可选,例如:BJ, SH, NY)units: 测量单位(可选,默认metric)lang: 语言(可选,默认zh_cn)Returns:str: 格式化的当前天气信息文本"""

描述的作用是 大模型最终会根据我们函数中的描述去选择它最终要去调用哪个tool工具

# 程序入口点
if __name__ == "__main__":# 初始化并运行 MCP 服务,使用标准输入输出作为传输方式mcp.run(transport='stdio')

我们目前是mcp服务会部署在本地,会使用cursor这个mcp客户端去使用。

接下来我们要怎么测试这个服务呢?

测试运行

mcp dev weather.py

替换路径即可,点击connect即可。

此时我们就连接成功了,然后在右侧输入测试即可。

基本版本2

# MCP 工具2:提供5天天气预报的查询功能,传入城市名称、国家代码(可选)、州代码(可选)、测量单位(可选)和语言(可选)
@mcp.tool()
async def get_forecast(city: str, country_code: str = None, state_code: str = None, units: str = "metric", lang: str = "zh_cn") -> str:"""获取指定城市的5天天气预报信息,如果用户使用中文询问某城市5天天气预报,你必须将城市名转换为相应的英文名称再调用API。Args:city: 城市名称 (例如:Beijing, Shanghai, New York)country_code: 国家代码(可选,例如:CN, US, JP)state_code: 州/省代码(可选,例如:BJ, SH, NY)units: 测量单位(可选,默认metric)lang: 语言(可选,默认zh_cn)Returns:str: 格式化的5天天气预报信息文本"""# 构建位置查询参数,支持城市名称、州代码和国家代码组合location_query = cityif state_code and country_code:# 格式:城市,州代码,国家代码location_query = f"{city},{state_code},{country_code}"if country_code:# 格式:城市,国家代码location_query = f"{city},{country_code}"# 构建API请求URL,参数包含位置查询、API密钥、测量单位和语言url = f"{OPENWEATHER_API_BASE}/forecast?q={location_query}&appid={OPENWEATHER_API_KEY}&units={units}&lang={lang}"# 发送请求并获取响应数据data = await make_weather_request(url)# 检查data是否为空if not data:return "无法获取天气数据"# 检查 API 响应中的错误代码if "cod" in data and data["cod"] != "200":return f"获取5天天气预报信息失败,错误:{data.get('message', '未知错误')}"# 提取5天天气预报信息forecast_list = data.get("list", [])# 如果天气数组为空if not forecast_list:return "无法获取5天天气预报信息"# 构建格式化的5天天气预报信息数组forecast_data = []# 遍历5天天气预报信息,并提取日期和时间for forecast in forecast_list:# 提取日期和时间date_time = forecast.get("dt_txt", "")# 提取天气描述weather_desc = forecast.get("weather", [{}])[0].get("description", "未知")# 提取温度temp = forecast.get("main", {}).get("temp", "未知")# 提取湿度humidity = forecast.get("main", {}).get("humidity", "未知")# 提取风速wind_speed = forecast.get("wind", {}).get("speed", "未知")# 根据 units 参数确定温度和风速的单位temp_unit = "°C" if units == "metric" else "°F"wind_speed_unit = "m/s" if units == "metric" else "mph"# 构建格式化的5天天气预报信息字符串forecast_str = f"""日期: {date_time}天气: {weather_desc}温度: {temp} {temp_unit}湿度: {humidity}%风速: {wind_speed} {wind_speed_unit}"""# 提取天气预报数据forecast_data.append(forecast_str)# 返回格式化的5天天气预报信息数组,使用分隔符链接所有天气预报return "\n---\n".join(forecast_data)

测试同上。

cursor运行

接下来给cursor配置mcp server

{"mcpServers": {"weather": {"command": "uv","args": ["--directory","/ABSOLUTE/PATH/TO/PARENT/FOLDER/weather","run","weather.py"]}}
}

含有模板的 版本

# 这个就是告诉大模型你应该使用什么文本形式给我答案
# mcp.prompt() 是一个装饰器,用于将函数注册为 MCP 提示,允许大模型进行调用
@mcp.prompt()
# 那么这个函数接收的数据是由大模型传入的,也就是说它把天气数据传入进来。
async def weather_prompt(city: str, weather_desc: str, temp: float, humidity: float, wind_speed: float, temp_unit: str, speed_unit: str) -> str:"""用于生成天气报告的提示模板Args:city: 城市名称weather_desc: 天气描述temp: 温度humidity: 湿度wind_speed: 风速temp_unit: 温度单位speed_unit: 风速单位"""# 构建天气报告的格式化文本return f"""请你作为专业的气象播报员,根据以下天气数据生成一份简介、易懂的天气报告:城市: {city}天气: {weather_desc}温度: {temp} {temp_unit}湿度: {humidity}%风速: {wind_speed} {speed_unit}报告内容包括:1.今日天气概况2.根据温度和湿度分析体感情况3.根据天气状况提供穿衣建议4.适合的户外活动推荐最后请使用自然、专业的语言,避免过于技术性的术语,要贴近生活。"""
# mcp工具3:获取指定城市的天气信息并提供报告模板
@mcp.tool()
async def weather_report(city: str, country_code: str = None, state_code: str = None, units: str = "metric", lang: str = "zh_cn") -> dict:"""获取指定城市的天气信息并提供报告模板Args:city: 城市名称country_code: 国家代码(可选,例如:CN, US, JP)state_code: 州/省代码(可选,例如:BJ, SH, NY)units: 测量单位(可选,默认metric)lang: 语言(可选,默认zh_cn)Returns:dict: 包含天气数据和提示模板信息的字典"""# 获取原始天气信息weather_result = await get_weather(city, country_code, state_code, units, lang)# 解析天气文本获取关键信息import re# 使用正则表达式提取天气信息city_match = re.search(r'城市: (.*?)(?:\n|$)', weather_result)weather_match = re.search(r'天气: (.*?)(?:\n|$)', weather_result)temp_match = re.search(r'温度: ([\d.]+)(.*?)(?:\n|$)', weather_result)humidity_match = re.search(r'湿度: ([\d.]+)%', weather_result)wind_match = re.search(r'风速: ([\d.]+) (.*?)(?:\n|$)', weather_result)# 提取数据值,如果无法提取则使用默认值city_name = city_match.group(1) if city_match else cityweather_desc = weather_match.group(1) if weather_match else "未知"temp_value = float(temp_match.group(1)) if temp_match else 0.0temp_unit = temp_match.group(2) if temp_match and len(temp_match.groups()) > 1 else "°C"humidity_value = int(float(humidity_match.group(1))) if humidity_match else 0wind_speed = float(wind_match.group(1)) if wind_match else 0.0speed_unit = wind_match.group(2) if wind_match and len(wind_match.groups()) > 1 else "m/s"# 构建返回结果,包含三个部分:原始的数据,模板名称,模板参数# 大模型调用这个工具会收到包含原始数据,模板名称,模板参数的结构化返回结果# 大模型识别到prompt_template字段指向 weather_report 这个函数模板,# 会调用这个函数,并传入模板参数# 大模型自动用 template_args 中的值填充 weather_report 模板中的对应参数。# 填充后的模板会成为大模型自己的 “思考提示”,然后大模型会根据这个提示,生成最终的回答。# 这就像我们去餐厅点餐:# mcp.prompt()的定义就相当于菜单上的标准食谱# weather_prompt 函数相当于收集食材# 当模型调用这个weather_report工具时,# 模型接收到了食谱(prompt_template)和食材(template_args)# 模型就相当于厨师,按照食谱(提示模板),使用食材(模板参数)烹饪菜品(回答)return {"raw_data": weather_result,"prompt_template": "weather_prompt","template_args": {"city": city_name,"weather_desc": weather_desc,"temp": temp_value,"temp_unit": temp_unit,"humidity": humidity_value,"wind_speed": wind_speed,"speed_unit": speed_unit,}}

测试

继续使用cursor,项目重新启动一下。

http://www.dtcms.com/wzjs/173298.html

相关文章:

  • 如何自己做网站做淘宝客网站开发需要的技术
  • 潜江公司做网站优化大师的优化项目有哪7个
  • 石家庄专业网站营销注册网站在哪里注册
  • 网站开发神器站长工具域名查询ip
  • iapp做网站免费淘宝关键词工具
  • 什么平台做网站举例说明什么是seo
  • 沈阳网站专业seo百度关键词优化
  • 如何做更改网站的图片郑州网站建设用户
  • 企业网站开发要学什么seo排名大概多少钱
  • 泰安做网站网络公司品牌策划方案范文
  • vs2010怎么做网站全国培训机构排名前十
  • 做网站会出现什么问题网络优化器免费
  • 摄影素材库网站引流推广怎么做
  • 我爱做衣服网站常见的网络营销手段
  • 免费资源源码网站网页入口网站推广
  • 网站建设教程突网络推广工作好吗
  • 网站建设的功能需求文档seo中文
  • dw网站建设基本流程百度seoo优化软件
  • 桂林北站到两江机场大巴时刻表营销案例
  • 民政局网站建设工作总结冯耀宗seo课程
  • 上海 企矩 网站建设网站seo具体怎么做?
  • 柳州哪里有网站建设黑锋网seo
  • 郑州网站建设时一定需要注意的六点日本网站源码
  • 公司网站制作定制软件测试培训
  • 企业网站制作运营搜索营销
  • 遂宁建设机械网站天津网站建设公司
  • 电子商务范围宁波企业seo推广
  • 登陆网站取消备案宽带业务如何推广
  • wordpress栏目设置到导航直通车优化推广
  • h5 和手机网站迅雷下载磁力天堂