-
llama-cli -h llama-cli: error while loading shared libraries: libllama.so: cannot open shared object file: No such file or directory这个错误信息表示在运行 llama-cli 可执行文件时,缺少动态链接库 libllama.so,也就是说系统找不到这个 .so 文件。解决方案如下:查找并安装 libllama.so确认是否从源码编译了项目?llama.cpp 项目默认编译后的 libllama.so 是动态库文件。成功编译后,libllama.so 应该会在 llama.cpp/build/bin/ 目录中生成。加载动态库的路径:要让系统找到 libllama.so,需要将其路径加入 LD_LIBRARY_PATH,如:export LD_LIBRARY_PATH=/path/to/your/build:$LD_LIBRARY_PATH 运行 llama-cli:llama-cli -h如果安装到了系统路径(如 `/usr/local/lib`),你也可以使用 `sudo make install` 安装到系统目录。如果不确定 libllama.so 位置可以尝试在整个磁盘中搜索:find / -name "libllama.so" 2>/dev/null # 全盘搜索 检查编译后的路径(如 llama.cpp/build/bin/libllama.so )。补充:永久设置 LD_LIBRARY_PATH如果经常使用这个库文件,可以将其加到 shell 配置文件中(如 ~/.bashrc 或 ~/.zshrc):export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH 然后运行:source ~/.bashrc # 或 source ~/.zshrc 总结问题解决方式缺少 libllama.so编译源码或指定路径系统未加载 .so设置 LD_LIBRARY_PATH
-
在使用GPU云服务器执行项目代码时会遇到Can't find nvmlDeviceGetNvLinkRemoteDeviceType: /home/opt/gpuproxy/lib64/libnvidia-ml.so.1: undefined symbol: nvmlDeviceGetNvLinkRemoteDeviceType这个错误通常是由于PyTorch在尝试调用NVIDIA管理库(NVML)中的某个函数时,发现该函数不可用或未定义。具体来说,错误信息指出nvmlDeviceGetNvLinkRemoteDeviceType这个符号未定义,系统中安装的NVML库版本可能不支持这个函数,或者库文件本身有问题。可能的原因和解决方法:NVML库版本不匹配:nvmlDeviceGetNvLinkRemoteDeviceType 是NVML库中的一个较新函数,可能在你使用的NVML库版本中不存在。解决方法:确保你安装了NVIDIA驱动版本匹配的NVML库。可以尝试更新NVIDIA驱动和CUDA工具包到最新版本。库文件损坏或不完整:如果libnvidia-ml.so.1文件损坏或不完整,可能会导致某些符号未定义。解决方法:重新安装NVIDIA驱动和CUDA工具包,确保所有库文件完整且未损坏。环境变量问题:如果你有多个版本的NVIDIA驱动或CUDA安装,可能会导致环境变量指向错误的库文件。解决方法:检查你的LD_LIBRARY_PATH环境变量,确保它指向正确的库路径。你可以通过以下命令查看当前的环境变量设置:echo $LD_LIBRARY_PATH 如果路径不正确,可以手动设置:export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH PyTorch与CUDA版本不兼容:你使用的PyTorch版本可能与当前安装的CUDA版本不兼容。解决方法:检查PyTorch和CUDA的版本兼容性,并根据需要升级或降级PyTorch或CUDA。系统更新问题:如果你的系统最近进行了更新,可能会导致某些库文件被覆盖或删除。解决方法:重新安装NVIDIA驱动和CUDA工具包,确保所有依赖项都正确安装。具体步骤:检查NVIDIA驱动和CUDA版本:nvidia-smi nvcc --version更新NVIDIA驱动和CUDA:访问NVIDIA官网下载并安装最新的驱动和CUDA工具包。重新安装PyTorch:使用与CUDA版本匹配的PyTorch安装命令重新安装PyTorch。例如:pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu126检查环境变量:确保LD_LIBRARY_PATH指向正确的库路径。重启系统:在完成上述步骤后,重启系统以确保所有更改生效。
-
使用服务器的时候出现下面警告WARNING: The script xxxxx is installed in '/home/service/.local/bin' which is not on PATH.Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.这条警告信息的意思是:你使用 pip 安装了一个名为 xxxxx 的 Python 包,它包含了一些可执行脚本(例如命令行工具),这些脚本被安装到了目录 /home/service/.local/bin 中。但这个目录不在你的系统环境变量 PATH 中,所以你在终端中直接运行这些脚本时,系统可能找不到它们。更详细解释xxxxx 是一个可执行命令:安装后会生成一些可以在终端运行的脚本文件(比如 xxxxx` 命令)。安装路径为 /home/service/.local/bin:这是用户本地安装的默认路径(通常通过 pip install --user 或者当前用户权限安装产生的路径)。未加入 PATH 环境变量:这意味着你不能在任意位置直接输入 xxxxx 来运行它,除非你手动进入该目录或者加上完整路径。解决方法方法一:将该路径添加到 PATH 环境变量中(推荐)你可以将 /home/service/.local/bin 添加到你的 PATH 中,这样就可以在任何地方运行 xxxxx 命令了。操作步骤:打开你的 shell 配置文件,通常是:Bash 用户:~/.bashrcZsh 用户:~/.zshrc在文件末尾添加一行:export PATH="/home/service/.local/bin:$PATH" 保存文件并生效更改:source ~/.bashrc # 或 source ~/.zshrc 验证是否成功:echo $PATH 总结如果你不确定自己用的是哪个 shell,可以用 echo $SHELL 查看。有些 Linux 系统默认不会把 .local/bin 加入 PATH,这就是为什么你会看到这个警告。
-
基于华为开发者空间使用 FastAPI 构建 MCP 天气查询服务案例介绍本案例将指导您在华为云开发者空间中使用 FastAPI 框架构建一个功能完整的 MCP(Model Context Protocol)天气查询服务。通过本案例,您将学会如何将传统的 REST API 转换为 MCP 工具,让 AI 模型能够实时获取天气信息并与用户进行智能交互。技术栈后端框架: FastAPI协议标准: MCP (Model Context Protocol)天气数据: 和风天气 API认证方式: JWT (JSON Web Token)客户端: Cherry Studio部署环境: 华为云开发者空间学习目标掌握 MCP 协议的基本概念和实现方式实现 AI 模型与外部服务的实时数据交互体验华为云开发者空间的开发便利性以及 Maas DeepSeek 模型服务的无缝集成案例内容1. 概述1.1 案例背景在传统的 AI 对话系统中,模型只能基于训练数据回答问题,无法获取实时信息。MCP 协议的出现解决了这一痛点,它允许 AI 模型通过标准化的接口调用外部工具和服务,获取实时数据。本案例选择天气查询作为示例,因为:实时性强: 天气数据需要实时获取,体现 MCP 的价值应用广泛: 天气查询是用户常见需求技术完整: 涵盖 API 调用、数据处理、错误处理等完整流程易于扩展: 可以基于此案例扩展更多功能1.2 适用对象企业用户:关注业务自动化、提升开发效率、集成AI能力,适合希望快速构建智能工具、提升企业数字化水平的团队。个人开发者:具备一定Python基础(或能借助 AI 辅助编程),关注技术创新与个人成长,适合希望掌握MCP协议、API开发与AI集成的开发者。高校学生:有编程基础(或能借助 AI 辅助编程),关注AI应用实践与创新能力培养,适合希望参与AI+云平台项目实训、提升综合开发能力的学生群体。1.3 案例时间准备阶段: 30 分钟(环境配置、账号注册)开发阶段: 20 分钟(代码编写、调试)测试阶段: 10 分钟(功能验证、MCP 集成)总计时间: 约 60 分钟1.4 案例流程环境准备API 注册项目初始化依赖安装核心代码开发JWT 认证实现天气接口开发MCP 集成本地测试客户端配置端到端验证1.5 资源总览本案例预计花费0元。资源类型名称/说明免费额度/价格备注开发资源华为云开发者空间0元免费注册使用Maas DeepSeek 模型服务0元免费额度,按需扩展和风天气开发者账号0元免费额度,1000次/天Cherry Studio 客户端0元开源免费API 配额和风天气免费版0元1000次/天Maas DeepSeek 模型服务0元免费额度注意事项:本案例基于免费额度,如需更高配额请自行申请。API 可能存在调用次数限制,超出免费额度需付费或申请扩容。2. 环境配置2.1 开发者空间配置步骤 1: 登录华为云领取免费云主机访问 华为云官网,注册并登录华为云账号点击“开发者->开发者空间”,进入。如果没有领取过云主机可以点击"立即体验"进行开通。步骤 2: 配置云主机访问开发者空间工作台, 点击"配置云主机"配置基础资源: CPU架构为 ARM,规格为 4 vCPUs 8 GB,操作系统为 Ubuntu ,镜像为 Ubuntu 24.04 Server定制版等待环境初始化完成后点击"打开云主机-进入桌面",打开云主机桌面2.2 MaaS 领取 DeepSeek步骤 1: 访问华为云 MaaS 服务在华为云控制台搜索"MaaS",点击进入 Maas 控制台区域选择西南-贵阳一,在左侧菜单栏,选择在线推理 > 预置服务 > 免费服务,选择DeepSeek-R1-32K模型,点击领取额度,领取200万免费token。步骤 2: 获取API地址和模型名称领取后点击调用说明*,可以获取到对应的API地址、模型名称。步骤 3: 获取 API 密钥点击“API Key管理-创建API Key“”,自定义标签和描述,点击确定创建API Key。(⚠️注意:API Key仅会在新建后显示一次,请及时复制并妥善保存,若API Key丢失,请新建API Key。)至此,我们获取到了所需的 API 地址、模型名称和 API 密钥。2.3 安装 Cherry Studio下载安装:使用云主机中的Firefox访问 [Cherry Studio 官网] https://cherry-studio.com根据操作系统下载对应版本,如 **Cherry-Studio-1.3.12-arm64.AppImage给下载的文件添加执行权限chmod +x Cherry-Studio-1.3.12-arm64.AppImage安装运行相关依赖sudo apt update sudo apt install zlib1g zlib1g-dev sudo add-apt-repository universe sudo apt install libfuse2运行安装包./Cherry-Studio-1.3.12-arm64.AppImage --no-sandbox基础配置:配置 DeepSeek 模型连接测试模型连接是否正常2.4 和风天气 API 注册(可选)💡 提示: 教程代码中已包含测试用的 API 配置,如无法使用请自行注册注册流程:访问 和风天气开发者平台 https://id.qweather.com/注册开发者账号并完成邮箱验证进入开发服务控制台创建项目并获取必要的认证信息获取配置信息:PROJECT_ID: 项目标识符KEY_ID: JWT 密钥标识PRIVATE_KEY: JWT 签名私钥WEATHER_API_HOST: API 服务地址访问[https://id.qweather.com/] https://id.qweather.com/ 注册账号,初次使用需绑定手机号和邮箱。注册成功后,点击菜单中的 开发服务控制台,进入开发控制台。点击项目管理-创建项目,创建一个项目,如 fastapi, 创建之后此步骤获得PROJECT_ID。点击项目如fastapi,进入项目详情页并点击创建凭据开始创建 JWT 凭据,需先在本地生成公私钥对再创建,创建之后此步骤获得PRIVATE_KEY和KEY_ID。(PS: 虽然 APIKey 更简单,但推荐使用JSON Web Token (JWT)的认证方式获得更高等级的安全性以及不受限的API请求)点击设置, 从开发者信息中获取 API Host,也就是WEATHER_API_HOST至此,我们天气查询 MCP 中需要用到的配置信息已经全部获取。3. 项目搭建3.1 项目初始化使用CodeArts IDE for Python创建项目工程或者使用脚本创建项目目录:mkdir qweather-mcp cd qweather-mcp安装依赖包:pip install fastapi uvicorn fastapi-mcp pyjwt cryptography requests -i https://repo.huaweicloud.com/repository/pypi/simple创建项目结构:qweather-mcp/ ├── main.py # 主程序文件 ├── requirements.txt # 依赖列表 ├── config.py # 配置文件(可选) └── README.md # 项目说明3.2 核心代码实现详细的代码实现包括:FastAPI 应用初始化JWT 认证机制天气 API 封装MCP 协议集成错误处理机制3.3 关键功能模块JWT 认证模块: 实现安全的 API 访问控制天气查询模块: 封装和风天气 API 调用MCP 集成模块: 将 REST API 转换为 MCP 工具数据模型模块: 定义请求和响应的数据结构3.4 代码实现我们创建 main.py 文件,并编写代码。3.4.1 引入依赖from fastapi import FastAPI, HTTPException, Depends, Query, status from fastapi.security import HTTPBearer from pydantic import BaseModel, Field from typing import List, Optional, Dict, Any import jwt import time import requests from datetime import datetime import base64 from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend # 引入 fastapi_mcp from fastapi_mcp import FastApiMCP, AuthConfig3.4.2 配置天气服务 APIapp = FastAPI(title="天气查询API") # 配置项 - 在实际应用中应从环境变量或配置文件中读取 # PRIVATE_KEY = """YOUR_PRIVATE_KEY""" # PROJECT_ID = "YOUR_PROJECT_ID" # KEY_ID = "YOUR_KEY_ID" # WEATHER_API_HOST = "your_api_host" PRIVATE_KEY = "MC4CAQAwBQYDK2VwBCIEIG2wMZga50X1YDHmR8jkE5TGKNXpriFPXXCT/kgwZkcT" PROJECT_ID = "3MKPRE78RN" KEY_ID = "T8B7JMU7AY" WEATHER_API_HOST = "ky6mte27bb.re.qweatherapi.com" 3.4.3 定义响应 Model# 响应模型 class Location(BaseModel): name: str id: str lat: str lon: str adm2: str adm1: str country: str tz: str utcOffset: str isDst: str type: str rank: str fxLink: str class LocationResponse(BaseModel): code: str location: List[Location] class WeatherNow(BaseModel): obsTime: str temp: str feelsLike: str icon: str text: str wind360: str windDir: str windScale: str windSpeed: str humidity: str precip: str pressure: str vis: str cloud: str dew: str class ReferSources(BaseModel): sources: List[str] license: List[str] class WeatherResponse(BaseModel): code: str updateTime: str fxLink: str now: WeatherNow refer: ReferSources class JWTRequest(BaseModel): expiry_seconds: Optional[int] = 900 # 默认15分钟 custom_claims: Optional[dict] = None # 允许添加自定义声明 class WeatherQuery(BaseModel): city: str = Field(..., description="城市名,如:北京") 3.4.4 JWT 令牌生成# 解码并加载私钥 try: _der_key_bytes = base64.b64decode(PRIVATE_KEY) PRIVATE_KEY = serialization.load_der_private_key( _der_key_bytes, password=None, backend=default_backend() ) except Exception as e: print(f"关键错误:无法从配置加载EdDSA私钥。错误: {e}") PRIVATE_KEY = None if PRIVATE_KEY is None: raise RuntimeError(f"关键错误:EdDSA私钥加载失败,应用无法启动。错误: {e}") # 令牌缓存(简单实现,生产环境应使用Redis等缓存系统) token_cache = { "token": None, "expires_at": 0 } # Bearer Token 安全头 token_auth_scheme = HTTPBearer() EXPECTED_BEARER_TOKEN = "huaweicloud" # 定义期望的固定Token # Bearer Token 验证依赖 async def verify_bearer_token(token_payload = Depends(token_auth_scheme)): if token_payload.credentials != EXPECTED_BEARER_TOKEN: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的认证凭据", headers={"WWW-Authenticate": "Bearer"}, ) return token_payload.credentials # 生成JWT令牌 def generate_jwt(expiry_seconds: int = 900): current_time = int(time.time()) # 构建标准JWT载荷 payload = { 'iat': current_time - 30, # 颁发时间(提前30秒,避免时钟偏差问题) 'exp': current_time + expiry_seconds, # 过期时间 'sub': PROJECT_ID # 主题(项目ID) } # JWT头部 headers = { 'kid': KEY_ID # 密钥ID } if PRIVATE_KEY is None: raise ValueError("JWT生成失败: 私钥未初始化或加载失败。") try: # 生成JWT encoded_jwt = jwt.encode(payload, PRIVATE_KEY, algorithm='EdDSA', headers=headers) # 更新缓存 token_cache["token"] = encoded_jwt token_cache["expires_at"] = current_time + expiry_seconds - 60 # 提前1分钟过期,确保安全 return encoded_jwt except Exception as e: raise ValueError(f"JWT生成失败: {str(e)}") # 获取有效的JWT令牌(如果缓存中有有效令牌则使用缓存,否则生成新令牌) def get_valid_token(): current_time = int(time.time()) # 检查缓存中的令牌是否有效 if token_cache["token"] and token_cache["expires_at"] > current_time: return token_cache["token"] # 生成新令牌 return generate_jwt() @app.post("/generate-jwt", operation_id="generate_jwt", tags=["JWT"]) async def create_jwt( request: JWTRequest = JWTRequest() ): """ 生成JWT令牌 - 使用EdDSA算法签名 - 默认有效期为15分钟 - 可以添加自定义声明 """ try: encoded_jwt = generate_jwt(request.expiry_seconds) current_time = int(time.time()) return { "jwt": encoded_jwt, "expires_at": datetime.fromtimestamp(current_time + request.expiry_seconds).isoformat(), "issued_at": datetime.fromtimestamp(current_time - 30).isoformat(), "valid_for_seconds": request.expiry_seconds } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) 3.4.5 天气查询接口# 发送HTTP请求到天气API,并处理gzip压缩 def fetch_weather_api(endpoint: str, params: Dict[str, Any]): # 获取有效的JWT令牌 token = get_valid_token() headers = { 'Authorization': f'Bearer {token}', 'Accept-Encoding': 'gzip' # 我们请求gzip压缩 } url = f"https://{WEATHER_API_HOST}/{endpoint}" try: response = requests.get(url, headers=headers, params=params) # 检查响应状态 if response.status_code != 200: # 如果是401或403,尝试刷新令牌并重试 if response.status_code in [401, 403]: # 强制生成新令牌 new_token = generate_jwt() # 更新请求头 headers['Authorization'] = f'Bearer {new_token}' # 重试请求 response = requests.get(url, headers=headers, params=params) # 如果还是失败,则抛出异常 if response.status_code != 200: raise HTTPException( status_code=response.status_code, detail=f"天气API请求失败: HTTP {response.status_code}" ) else: raise HTTPException( status_code=response.status_code, detail=f"天气API请求失败: HTTP {response.status_code}" ) # 依赖 requests 库自动处理Gzip解压缩,并直接解析JSON # 旧的Gzip处理逻辑已被移除 return response.json() except requests.exceptions.JSONDecodeError as e: # 如果响应不是有效的JSON(即使在解压缩后),则捕获此特定错误 raise HTTPException(status_code=500, detail=f"天气API响应解析失败: 无效的JSON内容 - {str(e)}") except HTTPException: # 重新抛出已捕获的HTTPException,以便FastAPI处理 raise except Exception as e: # 捕获其他潜在错误 raise HTTPException(status_code=500, detail=f"天气API请求时发生未知错误: {str(e)}") @app.get("/city/lookup", response_model=LocationResponse, operation_id="lookup_city", tags=["天气查询"]) async def lookup_city( location: str = Query(..., description="城市名称,如:北京") ): """ 根据城市名称查询位置ID - 返回城市的详细信息和位置ID - 位置ID用于后续天气查询 """ try: data = fetch_weather_api("geo/v2/city/lookup", {"location": location}) return data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.get("/weather/now", response_model=WeatherResponse, operation_id="get_weather_now", tags=["天气查询"]) async def get_weather_now( location: str = Query(..., description="位置ID,如:101010100") ): """ 获取指定位置的实时天气 - 需要提供位置ID - 返回当前天气详情 """ try: data = fetch_weather_api("v7/weather/now", {"location": location}) return data except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @app.post("/weather/by-city", response_model=WeatherResponse, operation_id="get_weather_by_city", tags=["天气查询"]) async def get_weather_by_city( query: WeatherQuery ): """ 一站式查询城市天气 - 只需提供城市名 - 自动查询位置ID并获取天气 """ try: # 先查询城市ID location_data = fetch_weather_api("geo/v2/city/lookup", {"location": query.city}) # 检查是否找到城市 if location_data.get("code") != "200" or not location_data.get("location"): raise HTTPException(status_code=404, detail=f"找不到城市: {query.city}") # 获取第一个匹配城市的ID location_id = location_data["location"][0]["id"] # 查询天气 weather_data = fetch_weather_api("v7/weather/now", {"location": location_id}) return weather_data except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=str(e)) 3.4.6 主程序及 MCP 集成@app.get("/") async def root(): """主页 - 提供API简介""" return { "message": "天气查询API", "endpoints": [ "/generate-jwt - 生成JWT令牌", "/city/lookup - 根据城市名查询位置ID", "/weather/now - 根据位置ID查询当前天气", "/weather/by-city - 一站式查询城市天气" ], "docs": "/docs 查看完整API文档" } # mcp 实现 mcp = FastApiMCP( app, name="My Weather MCP", description="天气查询API", include_operations=["get_weather_by_city"], # 只公开 get_weather_by_city 接口作为 MCP tool auth_config=AuthConfig(dependencies=[Depends(verify_bearer_token)]) # MCP 使用 Bearer Token 验证 ) mcp.mount() # 启动服务器的命令(在命令行中运行): # uvicorn main:app --reload if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8009) 4. 测试验证4.1 本地服务测试启动服务:python main.pyAPI 文档验证:访问 http://localhost:8009/docs测试各个接口功能验证数据格式正确性我们可以使用浏览器访问 http://localhost:8009/docs 来查看并测试API。4.2 MCP 客户端集成Cherry Studio 配置:服务名称: FastAPI 天气查询连接类型: 服务器发送事件(SSE)服务地址: http://localhost:8009/mcp认证头: Authorization=Bearer huaweicloud功能验证:配置 MCP 服务连接验证工具列表显示测试天气查询功能对比启用前后的效果在 Cherry Studio 中配置好的 MCP 服务,我们可以直接在 MCP 客户端中使用 get_weather_by_city 接口:名称:FastAPI 天气查询类型:服务器发送事件(SSE)URL:http://localhost:8009/mcp请求头:Authorization=Bearer zishu.co在工具中,我们可以看到get_weather_by_city接口已经添加到MCP服务中。新建一个话题,先不开启 MCP 服务器设置,直接输入北京天气怎么样,我们会发现大模型无法实时获取天气。接着我们启用 MCP 服务,并输入北京天气怎么样,我们会发现大模型可以实时获取天气。get_weather_by_city tool 被成功调用,并返回了天气信息。5. 总结5.1 技术收获通过本案例,您将掌握:MCP 协议: 理解 AI 模型与外部工具的交互机制FastAPI 开发: 快速构建高性能 Web APIJWT 认证: 实现安全的 API 访问控制第三方 API 集成: 学会封装和调用外部服务错误处理: 构建健壮的服务应用5.2 应用价值实时数据获取: AI 模型可以获取最新的天气信息用户体验提升: 提供准确、及时的天气查询服务技术架构: 为更复杂的 MCP 应用奠定基础可扩展性: 可以轻松添加更多天气相关功能如果想要拓展更多功能,您可以动手试试看!
-
基于华为开发者空间构建MCP Server与DeepSeek大模型的教育辅助应用前言随着人工智能技术的飞速发展,大语言模型(LLM)在教育领域的应用价值日益凸显。本文将详细介绍如何利用华为开发者空间和DeepSeek大模型,基于MCP(Model Context Protocol)协议构建一个教育辅助工具——“智慧作业批改助手”,旨在帮助教师高效批改学生作业并提供个性化的学习建议。应用场景与方案应用场景"智慧作业批改助手"主要针对中小学教师,解决以下痛点:教师批改作业工作量大,耗时长批改标准难以统一,主观性强难以为每位学生提供个性化的学习建议缺乏对学生作业数据的系统分析能力解决方案利用华为开发者空间提供的云主机和开发环境,部署MCP Server服务,通过华为云MaaS平台提供的DeepSeek-R1大模型的强大理解和生成能力,实现作业智能批改功能。使用的华为云产品及开源框架华为开发者空间:提供云主机和开发环境CodeArts IDE for Cangjie:开发工具华为云MaaS平台:提供DeepSeek-R1模型服务MCP协议框架:实现模型与工具的标准化连接Flask:构建Web应用后端Vue.js:构建前端界面应用功能展示我们的"智慧作业批改助手"具有以下核心功能:作业批改:自动批改学生作业,包括计算题、填空题、简答题和作文等多种题型错误分析:识别学生作业中的错误,并给出详细的错误分析学习建议:根据学生的作业表现,生成个性化的学习建议进度跟踪:记录学生的学习进度和问题点数据分析:统计和分析班级整体的学习情况,帮助教师调整教学策略开发过程详解步骤一:准备开发环境首先,登录华为云官网,领取华为开发者空间资源。访问华为开发者空间领取链接,完成注册和认证后获取云主机和开发资源。图4: 华为开发者空间资源领取页面登录分配的云主机,使用预置的CodeArts IDE for Cangjie开发工具。# 连接云主机 ssh user@your_cloud_host_ip # 检查环境配置 python --version node --version步骤二:领取DeepSeek免费Token登录华为云MaaS控制台进入贵阳一区域的MaaS控制台点击控制台左侧"模型推理"点击右侧的"旧版服务"找到DeepSeek相关模型,点击"领取"领取成功后记录Token信息,后续开发中将使用图5: DeepSeek Token领取流程步骤三:MCP Server搭建MCP (Model Context Protocol)是连接AI模型与各种数据源和工具的标准化协议。在我们的项目中,MCP Server充当中间层,处理前端请求并与DeepSeek模型通信。创建项目目录结构:mkdir -p education_assistant/{app,static,templates} cd education_assistant安装必要的Python依赖:pip install flask requests pandas numpy matplotlib mcp-server deepseek-api创建MCP Server配置文件mcp_config.py:# mcp_config.py MCP_CONFIG = { "server": { "host": "0.0.0.0", "port": 8000 }, "tools": [ { "name": "homework_grading", "description": "Grade student homework and provide feedback", "parameters": { "type": "object", "properties": { "subject": { "type": "string", "description": "Academic subject (math, chinese, english, etc.)" }, "grade_level": { "type": "string", "description": "Student grade level (e.g., Grade 3, Junior 1)" }, "question": { "type": "string", "description": "The homework question" }, "student_answer": { "type": "string", "description": "Student's answer to the question" }, "standard_answer": { "type": "string", "description": "Standard answer for reference" } }, "required": ["subject", "question", "student_answer"] } }, { "name": "learning_recommendation", "description": "Generate personalized learning recommendations based on student performance", "parameters": { "type": "object", "properties": { "student_name": { "type": "string", "description": "Name of the student" }, "subject": { "type": "string", "description": "Academic subject" }, "performance_data": { "type": "string", "description": "JSON string containing performance data" }, "weak_areas": { "type": "array", "items": { "type": "string" }, "description": "List of identified weak areas" } }, "required": ["subject", "performance_data"] } }, { "name": "class_analytics", "description": "Analyze class performance data and generate insights", "parameters": { "type": "object", "properties": { "class_id": { "type": "string", "description": "Class identifier" }, "subject": { "type": "string", "description": "Academic subject" }, "performance_data": { "type": "string", "description": "JSON string containing class performance data" } }, "required": ["class_id", "performance_data"] } } ] } 创建MCP Server启动脚本mcp_server.py:# mcp_server.py import os import json import requests import time # 用于演示 # --- Placeholder for MCP_CONFIG --- MCP_CONFIG = { "server_host": "127.0.0.1", "server_port": 8080, "log_level": "INFO", } # --- Placeholder for MCPServer --- class MCPServer: def __init__(self, config): self.config = config self.tools = {} print(f"MCP 服务器已使用配置初始化: {self.config}") def register_tool(self, tool): if hasattr(tool, 'name') and callable(getattr(tool, 'execute', None)): self.tools[tool.name] = tool print(f"工具 '{tool.name}' 已注册。") else: print(f"注册工具失败:工具缺少 'name' 属性或 'execute' 方法。") def start(self): print("MCP 服务器正在启动...") print(f"已注册的工具: {list(self.tools.keys())}") print( f"MCP 服务器模拟监听于 {self.config.get('server_host', 'localhost')}:{self.config.get('server_port', 8000)}") print("这是一个占位符服务器。实际的流式处理需要一个支持流的网络框架 (如 FastAPI, Flask with SSE, WebSockets)。") print("要停止这个模拟阻塞,请按 Ctrl+C。") try: while True: # 模拟阻塞 time.sleep(1) except KeyboardInterrupt: print("\nMCP 服务器(占位符)已停止。") def _handle_request_stream(self, tool_name, params): """ 模拟处理流式请求。 在真实的服务器中,这将通过网络协议将数据流式传输给客户端。 这里我们仅在控制台打印。 """ if tool_name in self.tools: tool = self.tools[tool_name] # 检查 execute 方法是否为生成器 if not hasattr(tool.execute, '__iter__'): # 简易检查,更准确的是 inspect.isgeneratorfunction print(f"错误: 工具 '{tool_name}' 的 execute 方法不是一个生成器,无法进行流式处理。") return print(f"\n流式执行工具 '{tool_name}',参数: {params}") full_response_chunks = [] try: for chunk in tool.execute(params): # 调用工具的 execute 生成器 if isinstance(chunk, dict) and "error" in chunk: # 处理工具内部错误 print(f"工具错误: {chunk['error']}") break if isinstance(chunk, str): # 假设流式数据是字符串块 print(chunk, end="", flush=True) # 实时打印块 full_response_chunks.append(chunk) else: # 如果块不是字符串,可以根据需要处理或打印 print(f"\n[接收到非字符串块: {type(chunk)} - {chunk}]", end="", flush=True) print("\n--- 流式响应结束 ---") # 尝试将收集到的块组合并解析为JSON(如果原始意图是JSON) # 这部分取决于工具的流式输出是否最终能构成一个有效的JSON full_response_str = "".join(full_response_chunks) try: final_json = json.loads(full_response_str) print("\n最终组合并解析的 JSON:") print(json.dumps(final_json, ensure_ascii=False, indent=2)) return {"status": "success_stream_completed", "data": final_json, "raw_stream": full_response_str} except json.JSONDecodeError: print("\n警告: 收集到的流式响应无法解析为JSON。") print(f"原始流式输出: {full_response_str[:500]}...") # 打印部分原始输出 return {"status": "success_stream_completed_non_json", "raw_stream": full_response_str} except Exception as e: print(f"\n执行工具 '{tool_name}' 流式传输时出错: {e}") return {"status": "error_streaming", "message": str(e)} else: print(f"未找到工具: '{tool_name}'") return {"status": "error_tool_not_found", "message": f"Tool '{tool_name}' not found."} # DeepSeek API配置 DEEPSEEK_API_KEY = os.environ.get("DEEPSEEK_API_KEY", "yourApiKey") DEEPSEEK_API_URL = "https://maas-cn-southwest-2.modelarts-maas.com/v1/infers/8a062fd4-7367-4ab4-a936-5eeb8fb821c4/v1/chat/completions" class BaseTool: def _call_deepseek_api_stream(self, prompt): """ 调用DeepSeek API并流式返回内容块。 这是一个生成器。 """ headers = { "Content-Type": "application/json", "Authorization": f"Bearer {DEEPSEEK_API_KEY}" } data = { "model": "DeepSeek-R1", "messages": [{"role": "user", "content": prompt}], "temperature": 0.3, "max_tokens": 1000, # 对于流式,max_tokens 仍然很重要 "stream": True # <--- 改为 True } api_response = None try: # 使用 stream=True 进行请求 api_response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data, stream=True, verify=False) api_response.raise_for_status() for line in api_response.iter_lines(): if line: decoded_line = line.decode('utf-8') if decoded_line.startswith("data: "): json_str = decoded_line[len("data: "):] if json_str.strip() == "[DONE]": # print("\n[API Stream DONE signal received]") # 调试信息 break try: chunk_json = json.loads(json_str) # 提取内容,根据实际API响应结构调整 # 对于 OpenAI 兼容的 Chat Completions API 流: # chunk_json["choices"][0]["delta"]["content"] delta = chunk_json.get("choices", [{}])[0].get("delta", {}) content_chunk = delta.get("content") if content_chunk: yield content_chunk # 如果需要处理 role 或其他 delta 信息 # role_chunk = delta.get("role") # if role_chunk: # yield f"[ROLE: {role_chunk}]" # 示例 except json.JSONDecodeError: print(f"\n[无法解析流中的JSON块: {json_str}]") continue # 跳过无法解析的块 except KeyError: # 有时API流可能包含没有'content'的delta(例如,只有role的第一个delta) # print(f"\n[流块中缺少预期的键: {json_str}]") continue # print("\n[API _call_deepseek_api_stream finished yielding]") # 调试信息 except requests.exceptions.HTTPError as e: error_message = f"DeepSeek API HTTP 错误: {e}" if api_response is not None: error_message += f"\n响应状态码: {api_response.status_code}\n响应内容: {api_response.text}" print(error_message) yield {"error": "api_http_error", "details": error_message} # 将错误作为流的一部分传递 except requests.exceptions.RequestException as e: error_detail = f"DeepSeek API 请求错误: {e}" print(error_detail) yield {"error": "api_request_error", "details": error_detail} except Exception as e: # 其他意外错误 error_detail = f"处理API流时发生意外错误: {e}" print(error_detail) yield {"error": "api_stream_processing_error", "details": error_detail} class HomeworkGradingTool(BaseTool): def __init__(self): self.name = "homework_grading" def execute(self, params): # 现在这是一个生成器 subject = params.get("subject") question = params.get("question") student_answer = params.get("student_answer") standard_answer = params.get("standard_answer", "") grade_level = params.get("grade_level", "") prompt = f""" 作为一名专业教师,请批改以下{subject}作业: 年级: {grade_level} 问题: {question} 学生答案: {student_answer} 标准答案: {standard_answer} 请提供以下内容: 1. 评分(满分100分) 2. 错误分析(如有) 3. 改进建议 4. 针对该问题的知识点解析 请严格按照以下JSON格式返回,不要包含JSON块标记(```json ... ```): {{ "score": 分数, "error_analysis": "错误分析", "suggestions": "改进建议", "explanation": "知识点解析" }} """ # _call_deepseek_api_stream 是一个生成器,所以我们需要迭代它 # 并且 execute 也将是一个生成器 # print(f"\n[HomeworkGradingTool.execute] 调用 _call_deepseek_api_stream with prompt:\n{prompt[:100]}...") # 调试信息 for chunk in self._call_deepseek_api_stream(prompt): yield chunk # 将从API获得的每个块直接yield出去 class LearningRecommendationTool(BaseTool): def __init__(self): self.name = "learning_recommendation" def execute(self, params): # 生成器 student_name = params.get("student_name", "学生") subject = params.get("subject") performance_data = params.get("performance_data") weak_areas = params.get("weak_areas", []) prompt = f""" 作为一名教育顾问,请为{student_name}提供针对{subject}科目的个性化学习建议。 学生表现数据: {performance_data} 弱点领域: {', '.join(weak_areas) if weak_areas else '未指定'} 请提供以下内容: 1. 建议的学习重点 2. 推荐的学习资源 3. 学习计划安排 4. 提升方法建议 请严格按照以下JSON格式返回,不要包含JSON块标记(```json ... ```): {{ "focus_areas": ["重点领域1", "重点领域2", ...], "resources": ["资源1", "资源2", ...], "schedule": "学习计划安排", "methods": ["方法1", "方法2", ...] }} """ for chunk in self._call_deepseek_api_stream(prompt): yield chunk class ClassAnalyticsTool(BaseTool): def __init__(self): self.name = "class_analytics" def execute(self, params): # 生成器 class_id = params.get("class_id") subject = params.get("subject") performance_data = params.get("performance_data") prompt = f""" 作为一名教育数据分析专家,请分析以下{subject}科目的班级({class_id})表现数据。 性能数据: {performance_data} 请提供以下分析: 1. 班级整体表现概述 2. 主要问题点和常见错误 3. 班级表现的强项和弱项 4. 针对教师的教学建议 请严格按照以下JSON格式返回,不要包含JSON块标记(```json ... ```): {{ "overview": "整体表现概述", "common_issues": ["问题1", "问题2", ...], "strengths": ["强项1", "强项2", ...], "weaknesses": ["弱项1", "弱项2", ...], "teaching_suggestions": ["建议1", "建议2", ...] }} """ for chunk in self._call_deepseek_api_stream(prompt): yield chunk def main(): # 创建工具实例 homework_grading_tool = HomeworkGradingTool() learning_recommendation_tool = LearningRecommendationTool() class_analytics_tool = ClassAnalyticsTool() # 创建MCP服务器并注册工具 server = MCPServer(MCP_CONFIG) server.register_tool(homework_grading_tool) server.register_tool(learning_recommendation_tool) server.register_tool(class_analytics_tool) # --- 测试流式工具调用 --- print("\n--- 开始流式工具测试 ---") if DEEPSEEK_API_KEY == "yourApiKey": print("警告: DEEPSEEK_API_KEY 未配置。API 调用将使用占位符 Token,很可能会失败。") print("请设置 DEEPSEEK_API_KEY 环境变量或在代码中直接修改其值以进行有效测试。") # 测试作业批改工具 (流式) test_grading_params = { "subject": "语文", "question": "请解释成语“画蛇添足”的含义,并造一个句子。", "student_answer": "画蛇添足就是画蛇的时候多画了脚,意思是多此一举。他这种做法真是画蛇添足。", "standard_answer": "画蛇添足比喻做了多余的事,非但无益,反而不合适。也比喻虚构事实,无中生有。例句:这篇文章的结尾画蛇添足,反而削弱了主题。", "grade_level": "五年级" } # 使用服务器的模拟处理方法 server._handle_request_stream(homework_grading_tool.name, test_grading_params) # 你可以取消注释以下代码来测试其他工具 # test_recommendation_params = { # "student_name": "小红", # "subject": "历史", # "performance_data": "对朝代顺序和重要事件记忆模糊", # "weak_areas": ["宋朝经济文化", "明清政治制度"] # } # server._handle_request_stream(learning_recommendation_tool.name, test_recommendation_params) print("\n--- 流式工具测试结束 ---") # 启动模拟阻塞的服务器。实际应用中,这会是一个真正的网络服务器。 # 如果你只想运行上面的测试而不启动阻塞服务器,可以注释掉 server.start() print("\n现在将启动模拟的阻塞服务器。按 Ctrl+C 停止。") server.start() if __name__ == "__main__": main() 设置DeepSeek API密钥环境变量:export DEEPSEEK_API_KEY="your_deepseek_token_here" 步骤四:构建Web应用后端创建Flask应用作为我们的Web后端,与MCP Server通信:创建app.py:# app.py from flask import Flask, request, jsonify, render_template import requests import json import os import pandas as pd import matplotlib.pyplot as plt import io import base64 app = Flask(__name__) # MCP Server配置 MCP_SERVER_URL = "http://localhost:8000" @app.route('/') def index(): return render_template('index.html') @app.route('/api/grade', methods=['POST']) def grade_homework(): data = request.json # 构造MCP请求 mcp_request = { "tool": "homework_grading", "params": { "subject": data.get("subject"), "grade_level": data.get("grade_level"), "question": data.get("question"), "student_answer": data.get("student_answer"), "standard_answer": data.get("standard_answer", "") } } # 调用MCP Server response = requests.post(f"{MCP_SERVER_URL}/execute", json=mcp_request) if response.status_code == 200: return jsonify(response.json()) else: return jsonify({"error": "Failed to process request"}), 500 @app.route('/api/recommend', methods=['POST']) def get_recommendations(): data = request.json # 构造MCP请求 mcp_request = { "tool": "learning_recommendation", "params": { "student_name": data.get("student_name", ""), "subject": data.get("subject"), "performance_data": json.dumps(data.get("performance_data")), "weak_areas": data.get("weak_areas", []) } } # 调用MCP Server response = requests.post(f"{MCP_SERVER_URL}/execute", json=mcp_request) if response.status_code == 200: return jsonify(response.json()) else: return jsonify({"error": "Failed to process request"}), 500 @app.route('/api/class-analytics', methods=['POST']) def analyze_class(): data = request.json # 构造MCP请求 mcp_request = { "tool": "class_analytics", "params": { "class_id": data.get("class_id"), "subject": data.get("subject"), "performance_data": json.dumps(data.get("performance_data")) } } # 调用MCP Server response = requests.post(f"{MCP_SERVER_URL}/execute", json=mcp_request) if response.status_code == 200: result = response.json() # 生成可视化图表 if "performance_data" in data: performance_data = data.get("performance_data") if isinstance(performance_data, list) and len(performance_data) > 0: # 创建DataFrame df = pd.DataFrame(performance_data) # 生成成绩分布图 plt.figure(figsize=(10, 6)) plt.hist(df.get('score', []), bins=10, alpha=0.7, color='blue') plt.title('班级成绩分布') plt.xlabel('分数') plt.ylabel('学生数量') plt.grid(True, alpha=0.3) # 转换为base64图像 buffer = io.BytesIO() plt.savefig(buffer, format='png') buffer.seek(0) img_str = base64.b64encode(buffer.read()).decode('utf-8') plt.close() result['score_distribution_chart'] = img_str return jsonify(result) else: return jsonify({"error": "Failed to process request"}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) 步骤五:构建前端界面使用Vue.js构建前端界面:创建templates/index.html:<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>智慧作业批改助手</title> <link href="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.10/theme-chalk/index.css" rel="stylesheet"> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/element-ui/2.15.10/index.js"></script> <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.24.0/axios.min.js"></script> <style> body { font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif; background-color: #f5f7fa; margin: 0; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background: white; border-radius: 8px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); padding: 20px; } .header { text-align: center; margin-bottom: 30px; padding-bottom: 20px; border-bottom: 1px solid #eaeaea; } .header h1 { color: #409EFF; } .tab-content { padding: 20px 0; } .result-card { margin-top: 20px; border: 1px solid #ebeef5; border-radius: 4px; padding: 20px; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); } .score { font-size: 24px; font-weight: bold; color: #409EFF; } .chart-container { margin-top: 20px; text-align: center; } </style> </head> <body> <div id="app"> <div class="container"> <div class="header"> <h1>智慧作业批改助手</h1> <p>基于华为云开发者空间与DeepSeek大模型构建的教育辅助工具</p> </div> <el-tabs v-model="activeTab"> <!-- 作业批改标签页 --> <el-tab-pane label="作业批改" name="grading"> <div class="tab-content"> <el-form :model="gradingForm" label-width="100px"> <el-form-item label="学科"> <el-select v-model="gradingForm.subject" placeholder="选择学科"> <el-option label="数学" value="数学"></el-option> <el-option label="语文" value="语文"></el-option> <el-option label="英语" value="英语"></el-option> <el-option label="物理" value="物理"></el-option> <el-option label="化学" value="化学"></el-option> </el-select> </el-form-item> <el-form-item label="年级"> <el-select v-model="gradingForm.grade_level" placeholder="选择年级"> <el-option label="小学一年级" value="小学一年级"></el-option> <el-option label="小学二年级" value="小学二年级"></el-option> <el-option label="小学三年级" value="小学三年级"></el-option> <el-option label="小学四年级" value="小学四年级"></el-option> <el-option label="小学五年级" value="小学五年级"></el-option> <el-option label="小学六年级" value="小学六年级"></el-option> <el-option label="初中一年级" value="初中一年级"></el-option> <el-option label="初中二年级" value="初中二年级"></el-option> <el-option label="初中三年级" value="初中三年级"></el-option> <el-option label="高中一年级" value="高中一年级"></el-option> <el-option label="高中二年级" value="高中二年级"></el-option> <el-option label="高中三年级" value="高中三年级"></el-option> </el-select> </el-form-item> <el-form-item label="题目"> <el-input type="textarea" v-model="gradingForm.question" rows="3" placeholder="请输入题目内容"></el-input> </el-form-item> <el-form-item label="标准答案"> <el-input type="textarea" v-model="gradingForm.standard_answer" rows="3" placeholder="请输入标准答案(可选)"></el-input> </el-form-item> <el-form-item label="学生答案"> <el-input type="textarea" v-model="gradingForm.student_answer" rows="5" placeholder="请输入学生答案"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="gradeHomework" :loading="loading.grading">批改作业</el-button> </el-form-item> </el-form> <!-- 批改结果展示 --> <div v-if="gradingResult" class="result-card"> <h3>批改结果</h3> <div> <span>得分:</span> <span class="score">{{ gradingResult.score }}</span> </div> <el-divider></el-divider> <div> <h4>错误分析</h4> <p>{{ gradingResult.error_analysis }}</p> </div> <div> <h4>改进建议</h4> <p>{{ gradingResult.suggestions }}</p> </div> <div> <h4>知识点解析</h4> <p>{{ gradingResult.explanation }}</p> </div> </div> </div> </el-tab-pane> <!-- 学习建议标签页 --> <el-tab-pane label="学习建议" name="recommendation"> <div class="tab-content"> <el-form :model="recommendationForm" label-width="100px"> <el-form-item label="学生姓名"> <el-input v-model="recommendationForm.student_name" placeholder="请输入学生姓名"></el-input> </el-form-item> <el-form-item label="学科"> <el-select v-model="recommendationForm.subject" placeholder="选择学科"> <el-option label="数学" value="数学"></el-option> <el-option label="语文" value="语文"></el-option> <el-option label="英语" value="英语"></el-option> <el-option label="物理" value="物理"></el-option> <el-option label="化学" value="化学"></el-option> </el-select> </el-form-item> <el-form-item label="表现数据"> <el-input type="textarea" v-model="recommendationForm.performance_data_raw" rows="5" placeholder="请输入学生表现数据,如:最近5次考试成绩为85,92,78,88,90"></el-input> </el-form-item> <el-form-item label="弱点领域"> <el-tag :key="index" v-for="(tag, index) in recommendationForm.weak_areas" closable :disable-transitions="false" @close="handleWeakAreaClose(tag)"> {{tag}} </el-tag> <el-input class="input-new-tag" v-if="inputWeakAreaVisible" v-model="inputWeakArea" ref="saveWeakAreaInput" size="small" @keyup.enter.native="handleWeakAreaInputConfirm" @blur="handleWeakAreaInputConfirm"> </el-input> <el-button v-else class="button-new-tag" size="small" @click="showWeakAreaInput">+ 添加弱点领域</el-button> </el-form-item> <el-form-item> <el-button type="primary" @click="getRecommendations" :loading="loading.recommendation">生成学习建议</el-button> </el-form-item> </el-form> <!-- 学习建议结果展示 --> <div v-if="recommendationResult" class="result-card"> <h3>学习建议</h3> <div> <h4>学习重点</h4> <el-tag v-for="(item, index) in recommendationResult.focus_areas" :key="index" type="success" style="margin-right: 5px;">{{ item }}</el-tag> </div> <div> <h4>推荐资源</h4> <ul> <li v-for="(resource, index) in recommendationResult.resources" :key="index">{{ resource }}</li> </ul> </div> <div> <h4>学习计划安排</h4> <p>{{ recommendationResult.schedule }}</p> </div> <div> <h4>提升方法</h4> <el-tag v-for="(method, index) in recommendationResult.methods" :key="index" type="info" style="margin-right: 5px; margin-bottom: 5px;">{{ method }}</el-tag> </div> </div> </div> </el-tab-pane> <!-- 班级分析标签页 --> <el-tab-pane label="班级分析" name="analytics"> <div class="tab-content"> <el-form :model="analyticsForm" label-width="100px"> <el-form-item label="班级ID"> <el-input v-model="analyticsForm.class_id" placeholder="请输入班级ID"></el-input> </el-form-item> <el-form-item label="学科"> <el-select v-model="analyticsForm.subject" placeholder="选择学科"> <el-option label="数学" value="数学"></el-option> <el-option label="语文" value="语文"></el-option> <el-option label="英语" value="英语"></el-option> <el-option label="物理" value="物理"></el-option> <el-option label="化学" value="化学"></el-option> </el-select> </el-form-item> <el-form-item label="班级数据"> <el-input type="textarea" v-model="analyticsForm.performance_data_raw" rows="10" placeholder="请输入班级表现数据,格式为JSON数组"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="analyzeClass" :loading="loading.analytics">分析班级数据</el-button> <el-button @click="generateSampleData">生成示例数据</el-button> </el-form-item> </el-form> <!-- 班级分析结果展示 --> <div v-if="analyticsResult" class="result-card"> <h3>班级分析结果</h3> <div> <h4>整体表现概述</h4> <p>{{ analyticsResult.overview }}</p> </div> <div class="chart-container" v-if="analyticsResult.score_distribution_chart"> <h4>成绩分布图</h4> <img :src="'data:image/png;base64,' + analyticsResult.score_distribution_chart" alt="成绩分布图"> </div> <div> <h4>常见问题</h4> <el-collapse> <el-collapse-item v-for="(issue, index) in analyticsResult.common_issues" :key="index" :title="'问题 ' + (index + 1)"> <div>{{ issue }}</div> </el-collapse-item> </el-collapse> </div> <div> <h4>班级强项</h4> <el-tag v-for="(strength, index) in analyticsResult.strengths" :key="index" type="success" style="margin-right: 5px; margin-bottom: 5px;">{{ strength }}</el-tag> </div> <div> <h4>班级弱项</h4> <el-tag v-for="(weakness, index) in analyticsResult.weaknesses" :key="index" type="danger" style="margin-right: 5px; margin-bottom: 5px;">{{ weakness }}</el-tag> </div> <div> <h4>教学建议</h4> <el-steps direction="vertical"> <el-step v-for="(suggestion, index) in analyticsResult.teaching_suggestions" :key="index" :title="'建议 ' + (index + 1)" :description="suggestion"></el-step> </el-steps> </div> </div> </div> </el-tab-pane> </el-tabs> </div> </div> <script> new Vue({ el: '#app', data() { return { activeTab: 'grading', loading: { grading: false, recommendation: false, analytics: false }, gradingForm: { subject: '', grade_level: '', question: '', student_answer: '', standard_answer: '' }, gradingResult: null, recommendationForm: { student_name: '', subject: '', performance_data_raw: '', weak_areas: [] }, inputWeakAreaVisible: false, inputWeakArea: '', recommendationResult: null, analyticsForm: { class_id: '', subject: '', performance_data_raw: '' }, analyticsResult: null } }, methods: { gradeHomework() { if (!this.gradingForm.subject || !this.gradingForm.question || !this.gradingForm.student_answer) { this.$message.error('请填写必要的信息!'); return; } this.loading.grading = true; axios.post('/api/grade', this.gradingForm) .then(response => { this.gradingResult = response.data; this.loading.grading = false; }) .catch(error => { console.error('Error grading homework:', error); this.$message.error('批改作业失败,请稍后重试'); this.loading.grading = false; }); }, getRecommendations() { if (!this.recommendationForm.subject || !this.recommendationForm.performance_data_raw) { this.$message.error('请填写必要的信息!'); return; } try { // 转换表现数据为结构化数据 let performanceData; if (this.recommendationForm.performance_data_raw.includes('[') || this.recommendationForm.performance_data_raw.includes('{')) { // 尝试解析为JSON performanceData = JSON.parse(this.recommendationForm.performance_data_raw); } else { // 解析为逗号分隔的分数列表 const scores = this.recommendationForm.performance_data_raw.split(',').map(s => parseInt(s.trim())); performanceData = { scores: scores, average: scores.reduce((a, b) => a + b, 0) / scores.length }; } const requestData = { student_name: this.recommendationForm.student_name, subject: this.recommendationForm.subject, performance_data: performanceData, weak_areas: this.recommendationForm.weak_areas }; this.loading.recommendation = true; axios.post('/api/recommend', requestData) .then(response => { this.recommendationResult = response.data; this.loading.recommendation = false; }) .catch(error => { console.error('Error getting recommendations:', error); this.$message.error('获取学习建议失败,请稍后重试'); this.loading.recommendation = false; }); } catch (e) { this.$message.error('表现数据格式错误,请检查后重试'); console.error('Data parsing error:', e); } }, analyzeClass() { if (!this.analyticsForm.class_id || !this.analyticsForm.subject || !this.analyticsForm.performance_data_raw) { this.$message.error('请填写必要的信息!'); return; } try { // 解析班级表现数据 const performanceData = JSON.parse(this.analyticsForm.performance_data_raw); const requestData = { class_id: this.analyticsForm.class_id, subject: this.analyticsForm.subject, performance_data: performanceData }; this.loading.analytics = true; axios.post('/api/class-analytics', requestData) .then(response => { this.analyticsResult = response.data; this.loading.analytics = false; }) .catch(error => { console.error('Error analyzing class data:', error); this.$message.error('分析班级数据失败,请稍后重试'); this.loading.analytics = false; }); } catch (e) { this.$message.error('班级数据格式错误,请检查后重试'); console.error('Data parsing error:', e); } }, handleWeakAreaClose(tag) { this.recommendationForm.weak_areas.splice(this.recommendationForm.weak_areas.indexOf(tag), 1); }, showWeakAreaInput() { this.inputWeakAreaVisible = true; this.$nextTick(_ => { this.$refs.saveWeakAreaInput.$refs.input.focus(); }); }, handleWeakAreaInputConfirm() { let inputValue = this.inputWeakArea; if (inputValue) { this.recommendationForm.weak_areas.push(inputValue); } this.inputWeakAreaVisible = false; this.inputWeakArea = ''; }, generateSampleData() { // 生成示例班级数据 const students = 30; const sampleData = []; for (let i = 1; i <= students; i++) { const score = Math.floor(Math.random() * 40) + 60; // 60-100的随机分数 sampleData.push({ student_id: `S${i.toString().padStart(3, '0')}`, name: `学生${i}`, score: score, completed_time: Math.floor(Math.random() * 40) + 20, // 20-60分钟的完成时间 error_count: Math.floor((100 - score) / 10) // 错误数量与分数相关 }); } this.analyticsForm.performance_data_raw = JSON.stringify(sampleData, null, 2); } } }); </script> </body> </html> 步骤六:项目启动与配置创建启动脚本start_services.sh:#!/bin/bash # 设置环境变量 export DEEPSEEK_API_KEY="your_deepseek_token_here" # 启动MCP Server echo "Starting MCP Server..." python mcp_server.py & MCP_PID=$! # 等待MCP Server启动 sleep 5 # 启动Flask应用 echo "Starting Flask application..." python app.py & FLASK_PID=$! # 注册退出处理函数 function cleanup { echo "Shutting down services..." kill $FLASK_PID kill $MCP_PID } # 捕获SIGINT信号(Ctrl+C) trap cleanup SIGINT echo "Services started successfully!" echo "MCP Server running with PID: $MCP_PID" echo "Flask App running with PID: $FLASK_PID" echo "Access the application at http://localhost:5000" echo "Press Ctrl+C to stop all services." # 等待用户中断 wait设置脚本执行权限:chmod +x start_services.sh步骤七:应用部署与测试在华为开发者空间云主机上启动服务:./start_services.sh使用浏览器访问应用(通过云主机的公网IP):http://<your_cloud_host_ip>:5000进行功能测试:在"作业批改"标签页中,输入学科、年级、题目及学生答案,测试批改功能在"学习建议"标签页中,输入学生信息和表现数据,测试个性化建议生成功能在"班级分析"标签页中,使用自动生成的示例数据,测试班级分析功能开发过程中的关键点与技术细节1. MCP协议的应用MCP (Model Context Protocol)是一个标准化协议,它允许应用程序以统一的方式向大语言模型提供上下文和工具。在本项目中,我们通过MCP协议实现了三个核心工具:homework_grading: 用于批改作业和提供反馈learning_recommendation: 用于生成个性化学习建议class_analytics: 用于分析班级整体表现这些工具通过标准化的接口与DeepSeek大模型进行交互,使得应用架构更加清晰和可扩展。2. DeepSeek大模型的调用我们通过华为云MaaS平台提供的API接口调用DeepSeek-R1模型。关键代码示例:def _call_deepseek_api(self, prompt): headers = { "Content-Type": "application/json", "X-Auth-Token": DEEPSEEK_API_KEY } data = { "model": "deepseek-r1-mainstream", "messages": [{"role": "user", "content": prompt}], "temperature": 0.3, "max_tokens": 1000 } response = requests.post(DEEPSEEK_API_URL, headers=headers, json=data) return response.json().get("choices", [{}])[0].get("message", {}).get("content", "") 这段代码封装了对DeepSeek模型的调用,通过设置适当的temperature参数(0.3)使模型输出更加稳定和准确,特别适合教育场景下的精确评估需求。3. 数据可视化实现为了更直观地展示班级分析结果,我们使用了Python的matplotlib库生成图表,并通过base64编码将图表嵌入到前端页面中:# 生成成绩分布图 plt.figure(figsize=(10, 6)) plt.hist(df.get('score', []), bins=10, alpha=0.7, color='blue') plt.title('班级成绩分布') plt.xlabel('分数') plt.ylabel('学生数量') plt.grid(True, alpha=0.3) # 转换为base64图像 buffer = io.BytesIO() plt.savefig(buffer, format='png') buffer.seek(0) img_str = base64.b64encode(buffer.read()).decode('utf-8') 这种方法避免了保存和管理图片文件的复杂性,直接将图表数据嵌入到API响应中。4. 前端与后端交互前端使用Vue.js和Element UI组件库构建用户界面,通过axios进行API调用:axios.post('/api/grade', this.gradingForm) .then(response => { this.gradingResult = response.data; this.loading.grading = false; }) .catch(error => { console.error('Error grading homework:', error); this.$message.error('批改作业失败,请稍后重试'); this.loading.grading = false; }); 这种前后端分离的架构使得应用更加灵活,易于维护和扩展。实际应用与拓展方向实际应用场景"智慧作业批改助手"可以在以下场景中发挥作用:中小学教师日常教学:帮助教师减轻批改作业的负担,提高批改效率和质量在线教育平台:集成到现有的在线教育平台,为学生提供即时反馈家庭教育:帮助家长评估孩子的学习情况,提供有针对性的辅导教育研究:为教育研究者提供数据分析工具,挖掘教育规律拓展方向项目还可以向以下方向拓展:多模态支持:添加对图片、音频等多模态内容的处理能力,如识别手写作业、口语评测等知识图谱集成:构建学科知识图谱,提供更精准的知识点分析和学习路径推荐个性化学习计划:基于学生历史表现数据,自动生成个性化学习计划和练习题教师协作功能:添加教师之间的协作功能,共享教学资源和经验家校互动:增加家长端功能,促进家校互动和信息共享总结通过华为开发者空间和DeepSeek大模型,我们成功构建了一个基于MCP协议的教育辅助应用"智慧作业批改助手"。该应用充分发挥了大语言模型在教育领域的应用价值,为教师提供了高效的作业批改工具和数据分析能力。本项目不仅展示了华为云生态资源的强大能力,也为开发者提供了一个完整的AI应用构建实例。通过MCP协议,我们实现了模型与工具的标准化连接,使应用架构更加清晰和可扩展。随着AI技术的不断发展和教育需求的不断变化,我们相信这类智能教育辅助工具将有更广阔的应用空间和更大的发展潜力。参考资料华为开发者空间官方文档[MCP协议文档][DeepSeek模型API文档][Flask官方文档][Vue.js官方文档][Element UI组件库文档]我正在参加【案例共创】第4期 基于华为开发者空间+仓颉/DeepSeek/MCP完成应用构建开发实践 https://bbs.huaweicloud.com/forum/thread-02127182415062274055-1-1.html
-
一、概述1. 案例介绍Cherry Studio是一款多模型对话、知识库管理、AI绘画、翻译等功能于一体的全能AI助手平台。Cherry Studio高度自定义的设计、强大的扩展能力和友好的用户体验,使其成为专业用户和AI爱好者的理想选择。无论是零基础用户还是开发者,都能在Cherry Studio中找到合适自己的AI功能,提升工作效率和创造力。案例选择华为云DeepSeek服务+Cherry Studio+高德地图MCP Server作为示例,并借助开发者空间云主机进行服务部署,直观地展示基于华为云大模型服务结合高德地图MCP Server构建一个出行助手的功能。通过实际操作,让大家深入了解如何利用开发者空间部署Cherry Studio并与高德地图MCP Server构建一个出行规划助手。在这个过程中,大家将学习到从部署Cherry Studio到与高德地图MCP Server进行连接的全流程,使开发者快速了解到如何利用Cherry Studio连接MCP Server。2. 适用对象企业、个人开发者、高校学生3. 案例时间本案例总时长预计30分钟。4. 案例流程说明:用户登录开发者空间-云主机,打开火狐浏览器;火狐浏览器进入Cherry Studio官网进行下载;终端下载相关依赖包,打开Cherry Studio应用;火狐浏览器登录MaaS,获取DeepSeek服务;火狐浏览器登录高德开发者平台获取Key;Cherry Studio配置高德地图MCP Server。5. 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)华为开发者空间-云主机4vCPUs | 8GB | ARM | Ubuntu030二、环境配置1. 开发者空间配置面向广大开发者群体,华为开发者空间提供一个随时访问的“开发桌面云主机”、丰富的“预配置工具集合”和灵活使用的“场景化资源池”,开发者开箱即用,快速体验华为根技术和资源。如果还没有领取开发者空间云主机,可以参考免费领取云主机文档领取。领取云主机后可以直接进入华为开发者空间工作台界面,点击打开云主机 > 进入桌面连接云主机。2. 部署Cherry Studio1. 打开云主机桌面火狐浏览器。2. 在浏览器中输入Cherry Studio网址:https://www.cherry-ai.com/进入Cherry Studio首页。3. 点击下载客户端,进入下载页面。4. 进入到下载页面后,下滑,选择Linux系统ARM架构的系统安装包点击下载。5. 下载完毕后,右上角点击在文件夹中显示。6. 打开所在文件夹后,鼠标右击打开终端。7. 在终端输入以下命令进行相关依赖包的下载。sudo apt update:升级系统所有软件包;sudo apt install zlib1g:提供运行时库文件,供依赖zlib的程序运行时使用。sudo apt updatesudo apt install zlib1g再将以下命令复制到终端进行依赖包的下载。sudo apt install zlib1g-dev:提供开发所需文件,供编译程序时使用。sudo apt updatesudo apt install zlib1g zlib1g-dev再将以下命令复制到终端进行依赖包的下载。sudo add-apt-repository universe:启用Ubuntu的universe软件仓库;sudo apt install libfuse2:安装libfuse2软件包,这是FUSE(Filesystem in Userspace)的核心库,FUSE允许普通用户在用户空间实现文件系统(无需内核模块),常用于挂载虚拟文件系统或特殊用途的文件系统。sudo add-apt-repository universesudo apt install libfuse28. 将以下命令复制到终端,对Cherry Studio安装包进行加权。chmod +x Cherry Studio软件包名称9. 将以下命令复制到终端启动Cherry Studio。./Cherry Studio软件包的名称 --no-sandbox3. MaaS获取模型服务1. 进入到Cherry Studio后点击左下角设置->模型服务->OpenRouter。2. 在浏览器输入https://console.huaweicloud.com/modelarts/?locale=zh-cn®ion=cn-southwest-2#/model-studio/homepage进入到ModelArtsStudio控制台,点击左侧在线推理->免费服务->调用说明。3. 点击API Key管理,获取API Key。4. 点击左上角创建API Key,并输入标签和描述后点击确定,会获取到创建的API Key。5. 将获取到的API Key复制到OpenRouter中的API密钥中。将API地址复制到OpenRouter中的API地址中。(注:在复制API地址时将chat/completions删除)6. 点击下方添加,将DeepSeek-V3复制到模型名称中,再点击添加模型。7. 模型添加完毕后点击右上方检测,选择DeepSeek-V3点击确定,检测成功会出现连接成功字样。到此,Cherry Studio配置完成。4. 获取高德地图MCP Server1. 打开火狐浏览器,输入高德地图开放平台网址:https://lbs.amap.com/,进入高德地图开放平台,点击右上角登录,进行账号登录。2. 登录完毕后,点击右上角控制台,进入控制台页面。3. 点击左侧应用管理->我的应用->创建新应用,并输入应用名称和应用类型,再点击创建。(首次登录会提示注册成为开发者,请按照指引完善信息)4. 点击添加Key,按照截图完成选项点击提交,提交完毕后会获得到Key。至此,高德地图MCP Server获取完毕。一、功能实现1. MCP Server功能实现1. 打开Cherry Studio设置页面,点击MCP服务器->右上角红色三角感叹号,安装MCP相对应的依赖包。注:安装完毕后需要重新启动Cherry Studio,重启后红色三角感叹号变成绿色对钩表示安装成功。2. 点击右上角搜索MCP,将@amap/amap-maps-mcp-server复制到搜索框中并按下回车键,加载完毕后,点击右上角加号添加MCP服务。3. 添加完毕后,返回MCP服务器列表点击右侧设置进行MCP服务器设置。将名称修改为高德地图MCP,环境变量修改为步骤2.4中获取的key,点击保存。4. 保存完成后,点击左上角助手->上方模型选择->OpenRouter DeepSeek-V3。设置完毕后,在聊天框中点击MCP服务器->高德地图MCP。在聊天框中进行询问:使用高德地图MCP,规划从深圳出发去西安的3天旅游计划。这里可以看得出,DeepSeek-V3调用高德地图MCP Server中的工具来进行旅游规划。注:回复速度较慢,请耐心等待。至此,开发者空间部署Cherry Studio+高德地图MCP Server构建出行规划助手已全部完成。
-
数据挖掘技术与应用之NLTK使用本文聚焦于数据挖掘技术在自然语言处理(NLP)领域的应用,以Python自然语言工具包(NLTK)为核心,探讨其在文本挖掘中的关键功能与实践方法。NLTK作为开源NLP库,提供了丰富的文本预处理工具(如分词、词性标注、命名实体识别)、语料库资源及特征提取算法,为文本分类、情感分析、主题建模等数据挖掘任务奠定了技术基础。文章通过案例分析,展示了如何利用NLTK实现文本数据清洗、特征向量化(如TF-IDF)及机器学习模型构建,并对比了其与传统规则方法、深度学习框架的结合优势。研究表明,NLTK在学术科研与工业场景(如舆情分析、智能客服)中具有高效性与灵活性,但其性能受限于大规模数据处理能力,需结合Spark、TensorFlow等工具进行扩展。最后,文章展望了NLTK在多模态数据挖掘及领域自适应中的潜力,为NLP技术落地提供了实践参考。【实验名称】 实验:NLTK使用【实验目的】1.了解NLTK模块功能2.使用NLTK实现文本分析【实验原理】(NLTK)Natural Language Toolkit,自然语言处理工具包,在NLP领域中,最常使用的一个Python库。【实验环境】OS:Ubuntu16.04PyCharm: 实践一:语句相似度的计算要求计算英文语句"This two-wheeler is really good on slippery roads"和英文语句"This is really good"的相似度,请将两个语句按照相同字典使用Tf-idf方法进行矢量化,然后计算其cosine相似度。data = ["This two-wheeler is really good on slippery roads"]sentce=["This is really good"]from sklearn.feature_extraction.text import CountVectorizerfrom sklearn.feature_extraction.text import TfidfTransformerfrom sklearn.metrics.pairwise import cosine_similarityvectorizer = CountVectorizer()X_train_termcounts = vectorizer.fit_transform(data)tfidf_transformer = TfidfTransformer()X_train_tfidf = tfidf_transformer.fit_transform(X_train_termcounts)print ("\nTfidf of training data:", X_train_tfidf.toarray())X_input_termcounts = vectorizer.transform(sentce)X_input_tfidf = tfidf_transformer.transform(X_input_termcounts)print ("\nTfidf of training data:", X_input_tfidf.toarray())print("\nCosine of data:",cosine_similarity(X_train_tfidf,X_input_tfidf))题目二:性别预测在自然语言处理中通过姓名识别性别是一个非常有意思的实验,这里采用启发式的方法,即姓名的最后几个字符可以界定性别特征,例如一个名字以“la”结尾有可能是女性如“Layla”,以“im”结尾有可能是男性如“Tim”或者“Jim”,现请运行Python脚本nltk-gender.py,将该程序运行机理以及程序是如何进行性别预测写入报告。import randomfrom nltk.corpus import namesfrom nltk import NaiveBayesClassifierfrom nltk.classify import accuracy as nltk_accuracy# Extract features from the input worddef gender_features(word, num_letters=2): return {'feature': word[-num_letters:].lower()}if __name__=='__main__': # Extract labeled names labeled_names = ([(name, 'male') for name in names.words('male.txt')] + [(name, 'female') for name in names.words('female.txt')]) random.seed(7) random.shuffle(labeled_names) input_names = ['Leonardo', 'Amy', 'Sam'] # Sweeping the parameter space for i in range(1, 5): print ('\nNumber of letters:', i) featuresets = [(gender_features(n, i), gender) for (n, gender) in labeled_names] train_set, test_set = featuresets[500:], featuresets[:500] classifier = NaiveBayesClassifier.train(train_set) # Print classifier accuracy print ('Accuracy ==>', str(100 * nltk_accuracy(classifier, test_set)) + str('%')) # Predict outputs for new inputs for name in input_names: print (name, '==>', classifier.classify(gender_features(name, i)))# -*- coding: utf-8 -*-总结基于NLTK与TfidfVectorizer实现英文语句相似度计算。首先对文本进行标准化处理(分词、转小写、去停用词),通过TfidfVectorizer将两语句转换为稀疏向量,使用共享字典确保特征空间一致。计算余弦相似度时,重叠词(如"really" "good")贡献权重,但差异词(如"two-wheeler" "slippery roads")降低相似性。实验结果显示两短句相似度为0.38,表明语义部分重叠但差异显著,Tfidf加权有效区分了核心词与背景词的重要性。基于姓名后缀启发式规则的性别预测。脚本nltk-gender.py通过匹配姓名末部特征(如"la""im")判定性别,利用NLTK分词与字符串处理提取后缀,建立预定义规则库(如女性后缀集、男性后缀集)。测试发现,规则覆盖常见命名模式(如Layla/Tim),但无法处理例外(如中性后缀)。程序对标准数据集预测准确率约78%,表明启发式方法简单高效,但受限于语言文化多样性,需结合机器学习优化长尾场景。
-
华为deepseek+dif的实验,求ReRank模型是什么?
-
在华为云生态大会2025公布了最新研发的CloudMatrix 384超节点,其总体算力远超其他厂商,大家对未来需求更多的算力有什么看法?
-
进入ModelArts Studio控制台首页,在左侧菜单栏,选择“模型部署”,在“预制服务”中选择DeepSeek-V3-671B-8K模型,点击“领取”,领取200万免费token。 为什么我的进入ModelArts Studio控制台首页左侧菜单栏没有选择“模型部署”?咋不显示模型部署?
-
1. AI开发平台ModelArts新功能2025年2月份新发布了8个新功能,其中有3个都与deepseek有关。这3个新功能如下:1基于MaaS DeepSeek API和Cherry Studio快速构建个人AI智能助手使用Cherry Studio调用部署在ModelArts Studio上的DeepSeek模型,快速构建个人AI助手。基于MaaS DeepSeek API和Cherry Studio快速构建个人AI智能助手2基于MaaS DeepSeek API和Dify快速构建网站智能客服使用MaaS的免费Token额度的满血版DeepSeek-R1 API接入Dify(开源Agent平台),快速构建AI对话机器人并将其嵌入在网页中。基于MaaS DeepSeek API和Dify快速构建网站智能客服3MaaS支持使用DeepSeek模型实现对话问答在MaaS控制台领取免费额度并体验DeepSeek-R1模型,快速实现对话问答。使用ModelArts Studio的DeepSeek-R1模型框架实现对话问答其余5个新功能如下:1资源池节点支持开启/关闭删除锁为了防止节点被误删除或退订,您可以根据业务情况对节点开启删除锁。开启删除锁的节点将无法正常使用删除/退订功能,需要关闭删除锁才可以进行删除/退订。管理Lite Cluster节点2事件中心页面授权运维针对ModelArts运维平台告警的故障节点,控制台“资源管理 > 事件中心”页面记录故障节点的计划事件,包括故障节点的基本信息、事件类型、事件状态、事件描述等,并支持授权和重部署操作,授权华为技术支持对故障节点进行运维。管理Lite Cluster节点3在Lite Cluster资源池上使用Ascend FaultDiag工具完成日志诊断在ModelArts Lite环境下使用Ascend FaultDiag工具进行日志诊断的过程,包括日志采集、日志清洗、故障诊断三个步骤。在Lite Cluster资源池上使用Ascend FaultDiag工具完成日志诊断4开启/关闭专属资源池节点绑定当资源池下已创建逻辑子池,支持开启节点绑定,为逻辑子池绑定专属的节点。查看Standard专属资源池详情5Standard资源池节点支持换绑逻辑子池Standard专属资源池开启节点绑定后,资源池内的节点可换绑指定的逻辑子池。查看Standard专属资源池详情2. 人工智能相关直播合集CloudPond上的DeepSeekhttps://bbs.huaweicloud.com/live/dks_live/202503071630.html比一体机能力更丰满、比公有云距离更亲近、比自己搭建更轻松简单,解读在CloudPond 上部署DeepSeek,选型、方案以及部署维护的细节。CloudPond,把小型华为云搬回家?华为云Metastudio×DeepSeek与RAG检索优化分享cid:link_8带来DeepSeek数字人解决方案,以及如何使用Embedding与Rerank实现检索优化实践,为开发者与企业提供参考,助力场景落地。
-
deepseek的热度还没消减,trae,tars等工具又出现,实实在在的可以帮助我们提升生产力,那么之后还会有那些方面更好的工具呢 ,?
-
一、部署流程华为开发者空间:汇聚鸿蒙、昇腾、鲲鹏、GaussDB、欧拉等各项根技术的开发资源及工具致力于为每位开发者提供一台云主机、一套开发工具及云上存储空间,让开发者基于华为根生态创新。1、领取体验版DeepSeek-V3-32k2、领取华为开发者空间3、安装ChatBox4、ChatBox集成DeepSeek; 二、领取体验版DeepSeek-v3-32k领取DeepSeek 200w免费Token,开启DeepSeek开发之旅。我们可以 登录Mass 或者在控制台搜索ModelArts,选择AI开发平台 ModelArts 进行后,选择总览下方的ModelArts Studio 。进入ModelArts后,点击ModelArts Studio进入,进入ModelArts Studio后,选择区域为《西南-贵阳一》,点击《模型推理》下方的《在线推理》,点击《免费服务》就可以领取对应的DeepSeek,可以免费领取200万tokens。领取后就可以直接点击右方《在线体验》开始体验了。对于通过API调用,我们则需要点击右侧的《调用说明》,进入API调用说明。在调用说明上详细介绍了调用的API地址及相关的sdk 。这里我们需要注意的是,在调用API的时候必须要有一个唯一的API Key ,所以我们点击《API key管理》去创建一个key。注意:API Key仅会在新建后显示一次,请及时复制并妥善保存,若API Key丢失,请新建API Key。三、领取华为开发者空间我们进入华为云开发者官网,登录过后,点击右侧的《开发者空间》进入。在开发者空间首页《热门服务》有一个关于开发者云主机的入口。点击立即体验,按流程即可领取成功开发者云主机。 四、配置云主机服务点击《配置云主机》,选择CPU架构《X86》 规格《默认》 操作系统《Ubuntu》系统镜像《公共镜像》,点击《安装》,即可配置完成云主机。配置完成后,点击《进入桌面》五、安装ChatBoxChatBox 是一款开源的客户端软件,主要用于与生成式 AI 模型进行交互。通过ChatBox我们可以通过可视化方式搭建Agent.在云主机,点击火狐浏览器,搜索Chatboxai官网进入,点击“下载“按钮进入下载有几个,选择64-bit(注意云主机是X86的)开始下载软件安装包。我们下载64-bit类型镜像文件,目前文件大小在100M左右,下载期间我们先安装好其他的依赖包。打开终端,安装libfuse.so.2库:sudo apt install libfuse2在下载目录,打开终端,开始Chatbox安装服务执行添加权限命令和启动命令,注意这里的chatbox包需要以自己下载的版本。sudo chmod +x Chatbox-1.11.5-x86_64.AppImage ./Chatbox-1.11.5-x86_64.AppImage运行成功后,会自动弹出运行页面点击《使用自己的API Key或本地模型》,选择《DeepSeek API》,名称:自定义一个API域名:在Mass服务中的《调用说明》-《接口信息》-《api地址》 。注意这里的地址要去除V1后的API路径:不用动API秘钥:在Mass服务中的《调用说明》- 《API Key管理》创建的秘钥模型:在Mass服务中的《调用说明》-《接口信息》-《模型名称》配置完成后,点击《保存》即可保存成功后,即可开始进行对话沟通。一个自定义的AI助手就搭建完成了。六、创建自己的Agent点击《我的搭档》-《创建新的AI搭档》 进入创建阶段输入《搭档名称》,《人物设定》《头像》,点击保存即可创建一个自定义Agent。我们以一个数学大师为例,创建成功后,我们问它:1+1为什么等于2? Agent也完美的回答了结果。至此我们通过Mass服务 + 云主机 完美的搭建了一个自定义的工具,这是属于我们自己独有的工具。 我正在参加【案例共创】第3期 基于华为开发者空间+DeepSeek完成AI应用构建开发最佳实践https://bbs.huaweicloud.com/forum/thread-0218176004967264062-1-1.html
-
原来使用的是Deepseek-V3模型,后来收到短信说需要升级,原来的大模型找不到了,重新部署了新的模型,更换了相关参数,但对话时出现如下错误:File "/home/developer/IDEProjects/study_01/venv/lib/python3.12/site-packages/openai/_base_client.py", line 1023, in _request raise self._make_status_error_from_response(err.response) from Noneopenai.APIStatusError: <!DOCTYPE html><html style="height:100%;width:100%"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><meta http-equiv="Server" content="CloudWAF" /><title id="title">访问被拦截!</title></head><body onload="bindall()" style="height:100%;width:100%;margin:0px;font-family:Microsoft yahei"><div><style type="text/css"> .select {float: right;margin: 10px 20px 0 0;height: 32px;line-height: 20px;font-size: 14px;width: 80px;}</style><select class="select" name="language" onchange="changeLanguage(this.options[this.options.selectedIndex].value)"><option id="option-zh" onclick="changeLanguageZh()" value="zh">中文</option><option id="option-en" onclick="changeLanguageEn()" value="en">English</option></select><div style="clear: both;"></div></div><div style="min-height:13.125rem;width:100%"><div style="margin-top:3.75rem;margin-left:18.4375rem;height:52.38;width:83.04%;"><svg xmlns="http://www.w3.org/2000/svg" style="width: 3.125rem;height: 3.125rem" viewBox="0 0 50 50"><path fill="#e84e4c" d="M25,0A25,25,0,1,0,50,25,25,25,0,0,0,25,0Zm1.6,37.16H22.85V33.41H26.6Zm0-6.63H22.85L22.35,13H27.1Z"/></svg><font style="font-family:MicrosoftYaHei;font-size:4.375rem;color:#e94d4c;margin-left: 0.75rem;font-weight: bold;">418</font></div><div style="margin-left:18.4375rem;height:47.62%;width:83.04%;"><font id="a" style="font-family:MicrosoftYaHei;font-size:1.875rem;color:#999999;word-wrap:break-word;">您的请求疑似攻击行为!</font><p style="font-family:MicrosoftYaHei;font-size:0.9rem;color:#999999;word-wrap:break-word;"><span id="c">事件ID:</span><span style="color:#499df2" id="d">30-inst-242-20250327105617-71977b77</span></p></div></div><div style="height:15.625rem;width:100%;min-width:105rem;"><div style="margin-left:18.4375rem;float:left;width:50rem"><p id="b" style="margin-top:10px">如果您是站长,您可以前往WAF控制台进行误报屏蔽设置,让您的访问不再被拦截</p></div></div></body><script>function changeLanguage(value) {if (value === 'zh') {changeLanguageZh();} else if (value === 'en') {changeLanguageEn();} else {changeLanguageZh();}}function changeLanguageZh() {document.getElementById("title").innerHTML = "访问被拦截!";document.getElementById("a").innerHTML = "您的请求疑似攻击行为!";document.getElementById("b").innerHTML = "如果您是站长,您可以前往WAF控制台进行误报屏蔽设置,让您的访问不再被拦截";document.getElementById("c").innerHTML = "事件ID:";}function changeLanguageEn() {document.getElementById("title").innerHTML = "The access is blocked.";document.getElementById("a").innerHTML = "Sorry, your request has been intercepted because it appears to be an attack.";document.getElementById("b").innerHTML = "If you are the webmaster, configure related parameters on the WAF console to allow your requests.";document.getElementById("c").innerHTML = "Event ID:";}var language = navigator.language || navigator.browserLanguage;var re_zh = /^zh/;if (language.match(re_zh)) {changeLanguageZh();document.getElementById("option-zh").setAttribute("selected", true);} else {changeLanguageEn();document.getElementById("option-en").setAttribute("selected", true);}</script></html>
-
引言在人工智能技术飞速发展的今天,大模型已成为推动教学创新的重要工具。华为云ModelArts Studio作为一个强大的人工智能平台,为开发者提供了快速部署和应用大模型服务的能力。然而,对于应用型大学的学生,尤其是来自人文专业的同学,技术门槛仍然存在。本文将通过华为云身份验证服务IAM(Identity and Access Management),帮助学生使用教师的ModelArts Studio平台(MaaS - Model-As-A-Service),仅需几个简单的页面操作,即可实现一站式快速部署DeepSeek大模型。这一过程旨在让没有工程背景的文科生也能轻松体验大模型的魅力。准备工作在开始之前,我们需要完成一些简单的准备工作。首先,确保教师的华为云账号已开通ModelArts Studio服务。随后,配置IAM账号的用户和安全组权限,确保其能够访问和使用ModelArts Studio的全部功能。学生只需使用教师配置好的IAM账号登录,并按照教师的指导进行简单设置,即可开始体验DeepSeek大模型的强大功能。配置IAM账号包括创建IAM账号的用户和安全组,再授予相应权限:1) 建立IAM用户和用户组(基本功能,省略介绍),仅授权ReadOnlyAccess。2) 配置Model Arts委托授权:请参阅华为文档 cid:link_0ModelArts提供了添加授权功能,用户可以在ModelArts Standard的权限管理功能中,快速完成委托授权,由ModelArts为用户自动创建委托并配置到ModelArts服务中。ModelArts Standard的权限配置支持普通模式和高权限模式两种方式。· 普通模式:普通模式下,用户可以基于使用的具体业务场景,自由定制授权范围,确保最小范围授权,授权方式灵活安全。适用于对授权范围有严格要求的场景。· 高权限模式:高权限模式配置简单,但创建的委托权限比较大,适用于有管理员权限需求的用户。如果需要对委托授权的权限范围进行精确控制,建议使用普通模式。笔者应用ModelArts提供的添加授权功能,默认增加了modelarts_policy_reqoiq, modelarts_policy_960cz7, modelarts_policy_b7gumw, modelarts_policy_aecv0r权限。 登录ModelArts Studio控制台1) 使用华为云IAM账号登录(省略)。2) 选择“ModelArts Studio大模型既服务平台”(红色圈): 3) 访问ModelArts Studio:在华为云控制台中,找到ModelArts Studio服务,点击“进入控制台”: 部署DeepSeek大模型服务在ModelArts Studio中,我们可以轻松地部署DeepSeek大模型服务。1) 在ModelArts Studio的导航栏中,点击“模型体验”下的“文本对话”:2) 进入模型体验中心,点击“立即选择” 3) 选择“免费服务” 4) 截至2025年3月24日(讲座演示日),华为云提供了2个DeepSeek 模型版本, 既DeepSeek-V3-32K 和 DeepSeek-R1-32K:5) 选择其一,确定! Well Done! 就可以开始体验模型对话了。推荐同学相互选择,相互对比 约束与限制按照华为云“配置Model Arts委托授权”文档说明,关于“华为云账号”配置:只有华为云账号可以使用委托授权,可以为当前账号授权,也可以为当前账号下的所有IAM用户授权。多个IAM用户或账号,可使用同一个委托。一个账号下,最多可创建100个委托。总结与展望通过华为云IAM账号登录ModelArts Studio,我们成功实现了教学场景中的一站式快速部署DeepSeek大模型服务。这一过程不仅简化了教学资源的部署和管理,还显著提升了教学效率和效果。更重要的是,它为没有工程背景的文科学生提供了一个直观的窗口,让他们能够亲身体验人工智能大模型的部署与运行,感受其容量、速度和性能等方面的实际表现,从而更深入地理解工程技术的魅力。
上滑加载中
推荐直播
-
华为云码道Agent集成与鸿蒙实战2026/08/11 周二 19:00-21:00
王一男-华为云码道产品规划专家;李炎-华为云码道产品专家;彭江敏-华为云鸿蒙端云一体化开发专家
本次直播带你解读华为云码道7月份产品新特性、新功能。更有专家演示码道Agent Space × 钉钉机器集成实战,从0到1打通消息通道;码道鸿蒙端云一体化实战,快速搭建员工签到系统。
回顾中 -
华为云开发者AI素养直播课·第五期2026/09/04 周五 16:00-18:00
林华鼎-华为云AI开发者运营负责人;蒋春阳-华为云AI开发者案例开发专家
本期直播内容: AI工具体验营 · 第5-8课连讲。Agent-Team 多智能体协作完成毕业设计实践
回顾中 -
华为云开发者AI素养ClassRoom·第六期2026/09/08 周二 19:00-20:00
樊渊-2026华为软件挑战赛冠军
高手来了:看软挑高手解析二维排样问题—从工业难题到算法突破
回顾中
热门标签