-
案例介绍本案例基于免费的华为云开发者空间、华为云MaaS提供的DeepSeek-R1大模型,使用R语言工具构建AI Agent,该AI Agent可以在R语言环境下独立部署使用。也可以用R语言开发MCP server,和AI助手平台Cherry Studio配合使用。案例内容本案例由开发者:yd_259866430提供案例内容1 概述1.1 案例介绍R是一种自由、免费、源代码开放的计算机语言。它具有语法极其简单、代码量极少、没有复杂概念的显著优势,降低了人们了解更复杂技术的计算机语言门槛。本案例将介绍如何在华为云主机安装R,并用它开发AI Agent和MCP server。本案例用到的R语言工具包括ellmer和mcptools,是posit公司开发的智能体开发工具。如需在R中开发部署AI Agent,则用ellmer。如果R仅作为MCP server的运行环境,则使用mcptools。1.2 适用对象企业个人开发者高校学生1.3 案例时间本案例总时长预计60分钟。1.4 案例流程① 用户打开华为开发者空间云主机,下载安装R、ellmer、mcptools、Cherry Studio;② 使用ellmer包,配置华为云MaaS提供的DeepSeek-R1模型,运行测试AI Agent;③ 使用mcptools开发MCP server服务,并将MCP server部署在Chery Studios上,配置华为云MaaS提供的DeepSeek-R1模型,运行测试AI Agent;1.5 资源总览本案例预计花费0元。资源名称规格单价(元)时长(分钟)鲲鹏4vCPUs |8GB ARM|Ubuntu 24.04 Server定制版0602 环境配置2.1 开发者空间配置详细步骤请参考案例中步骤2.12.2 免费领取DeepSeek-R1详细步骤请参考案例中步骤2.22.3 安装R语言2.3.1 进入开发者云主机桌面后,打开一个终端2.3.2 在终端输入以下代码,安装R语言sudo apt update sudo apt install --no-install-recommends software-properties-common dirmngr wget -qO- https://cloud.r-project.org/bin/linux/ubuntu/marutter_pubkey.asc | sudo tee -a /etc/apt/trusted.gpg.d/cran_ubuntu_key.asc sudo add-apt-repository "deb https://cloud.r-project.org/bin/linux/ubuntu $(lsb_release -cs)-cran40/" sudo apt install --no-install-recommends r-base具体参考R官网安装指引。https://mirrors.sustech.edu.cn/CRAN/在终端中输入R,进入R console中,输入print("hello world!"),如正常输出,则R语言安装成功。2.4 安装ellmer和mcptools在R console中输入install.packages("ellmer")过程中报错,查看报错信息按照报错信息,先退出R console,在终端中安装libcurl4-openssl-dev。再进入R console,安装ellmer在R console中,安装usethis(用于配置R环境变量),install.packages("usethis")安装过程会报错,需要退出R console安装libgit2-dev,sudo apt install libgit2-dev,然后再进入R console安装usethis。然后,安装install.packages("mcptools"),过程中一样会报错,需要耐心debug。2.5 安装Cherry Studiosudo apt install gdebi-core sudo gdebi Cherry-Studio-1.5.3-arm64.deb3 构建AI Agent3.1 使用ellmer创建AI Agent在R console输入以下代码,编辑R环境变量library(ellmer) usethis::edit_r_environ() 将参考案例中步骤2.2中的url和api_key复制到R环境变量中,复制后,按:wq退出,和vim语法类似。在 R console输入如下命令library(ellmer) # 导入ellmer chat <- chat_openai( # 构建AI Agent system_prompt = NULL, base_url = Sys.getenv("base_url"), api_key = Sys.getenv("api_key"), model = "DeepSeek-R1", seed = NULL, api_args = list(), echo = "all" ) 3.2 测试AI Agent在R console里,输入chat$chat("讲三个关于统计学家的笑话") ,就可以看到这个AI Agent确实通过API连接上了华为云上Deepseek模型,并返回了结果。在R console里运行AI Agent,看起来很丑,其实posit公司开发了更好看的shinychat,如下图所示。但是安装部署shinychat,又是一个不小的工程,所以案例接下来转向R+Cherry Studio 配合使用。不过聊天仅仅是这个AI Agent一个很小的功能。作为这个AI Agent的使用者,我们更希望它能够利用由我们定义的外部工具。这不仅仅是希望,如果AI Agent不调用外部工具,它的回答可能是错误的。如下图所示,当我们问AI Agent今天是几号,在不调用外部工具的情况下,它给出的是2023年10月12日,这明显不对。3.3 使用mcptools开发MCP server,并配合Cherry Studio使用解决“今天几号”的问题,需要用mcptools开发一个MCP server,写一个mcptoolsExample.R脚本,代码如下。get_current_time <- function(tz = "CST") { format(Sys.time(), tz = tz, usetz = TRUE) } if (is_new_ellmer()) { res <- list( get_current_time = ellmer::tool( get_current_time, name = "get_current_time", description = "返回当前时间", arguments = list( tz = ellmer::type_string( "当前时区默认为 `\"CST\"`.", required = FALSE ) ) ) ) } else { res <- list( get_current_time = ellmer::tool( get_current_time, name = "get_current_time", description = "Returns the current time.", arguments = list( tz = ellmer::type_string( "当前时区默认为 `\"CST\"`.", required = FALSE ) ) ) ) } res然后,我们按照参考案例,在Cherry Studio上配置DeepSeek-R1模型。如下图所示。然后,在不配置MCP server的情况,我们再问下“今天是几号”。AI Agent无法回答这个问题。接下来,我们给这个AI Agent配上一个外部工具,如下图所示,点击添加服务器。在json中输入{ "mcpServers": { "r-mcptools": { "command": "Rscript", "args": ["-e", "mcptools::mcp_server("/path/mcptoolsExample.R")"] } } } 接下来,再次问“今天是几号”,AI Agent已经知道调用MCP server获取日期了。至此,基于华为开发者空间云主机、R语言搭建AI Agent和MCP Server到此结束。本案例使用华为开发者空间提供的免费主机作为开发环境,操作系统为华为云为新注册用户提供180小时免费主机,大家可以开心使用。本案例使用华为云MaaS提供的免费DeepSeek-R1模型。我正在参加【案例共创】第5期 开发者空间 AI Agent 开发 https://developer.huaweicloud.com/signup/0e966198e87a4210b5f88c0d759d4f3b”
-
列表是 R 语言的对象集合,可以用来保存不同类型的数据,可以是数字、字符串、向量、另一个列表等,当然还可以包含矩阵和函数。R 语言创建列表使用 list() 函数。如下实例,我们创建一个列表,包含了字符串、向量和数字:实例list_data <- list("runoob", "huaweiyun", c(11,22,33), 123, 51.23, 119.1)print(list_data)执行以上代码输出结果为:[[1]][1] "huaweiyun"[[2]][1] "google"[[3]][1] 11 22 33[[4]][1] 123[[5]][1] 51.23我们可以使用 names() 函数给列表的元素命名:实例# 列表包含向量、矩阵、列表list_data <- list(c("Google","huaweiyun","Taobao"), matrix(c(1,2,3,4,5,6), nrow = 2), list("huaweiyun",12.3))# 给列表元素设置名字names(list_data) <- c("Sites", "Numbers", "Lists")# 显示列表print(list_data)执行以上代码输出结果为:$Sites[1] "Google" "huaweiyun" "huaweiyun"$Numbers [,1] [,2] [,3][1,] 1 3 5[2,] 2 4 6$Lists$Lists[[1]][1] "huaweiyun"$Lists[[2]][1] 12.3访问列表列表中的元素可以使用索引来访问,如果使用来 names() 函数命名后,我们还可以使用对应名字来访问:实例# 列表包含向量、矩阵、列表list_data <- list(c("Google","huaweiyun","Taobao"), matrix(c(1,2,3,4,5,6), nrow = 2), list("runoob",12.3))# 给列表元素设置名字names(list_data) <- c("Sites", "Numbers", "Lists")# 显示列表print(list_data[1])# 访问列表的第三个元素print(list_data[3])# 访问第一个向量元素print(list_data$Numbers)执行以上代码输出结果为:$Sites[1] "Google" "huaweiyun" "Taobao"$Lists$Lists[[1]][1] "huaweiyun"$Lists[[2]][1] 12.3 [,1] [,2] [,3][1,] 1 3 5[2,] 2 4 6操作列表元素我们可以对列表进行添加、删除、更新的操作,如下实例:实例# 列表包含向量、矩阵、列表list_data <- list(c("Google","huaweiyun","Taobao"), matrix(c(1,2,3,4,5,6), nrow = 2), list("huaweiyun",12.3))# 给列表元素设置名字names(list_data) <- c("Sites", "Numbers", "Lists")# 添加元素list_data[4] <- "新元素"print(list_data[4])# 删除元素list_data[4] <- NULL# 删除后输出为 NULLprint(list_data[4])# 更新元素list_data[3] <- "我替换来第三个元素"print(list_data[3])执行以上代码输出结果为:[[1]][1] "新元素"$<NA>NULL$Lists[1] "我替换来第三个元素"合并列表我们可以使用 c() 函数将多个列表合并为一个列表:实例# 创建两个列表list1 <- list(1,2,3)list2 <- list("Google","huaweiyun","Taobao")# 合并列表merged.list <- c(list1,list2)# 显示合并后的列表print(merged.list)执行以上代码输出结果为:[[1]][1] 1[[2]][1] 2[[3]][1] 3[[4]][1] "Google"[[5]][1] "huaweiyun"[[6]][1] "Taobao"列表转换为向量要将列表转换为向量可以使用 unlist() 函数,将列表转换为向量,可以方便我们进行算术运算:实例# 创建列表list1 <- list(1:5)print(list1)list2 <-list(10:14)print(list2)# 转换为向量v1 <- unlist(list1)v2 <- unlist(list2)print(v1)print(v2)# 两个向量相加result <- v1+v2print(result)执行以上代码输出结果为:[[1]][1] 1 2 3 4 5[[1]][1] 10 11 12 13 14[1] 1 2 3 4 5[1] 10 11 12 13 14[1] 11 13 15 17 19
-
定义函数R 语言中的函数定义使用 function 关键字,一般形式如下:function_name <- function(arg_1, arg_2, ...) { // 函数体}说明:function_name : 为函数名arg_1, arg_2, ... : 形式参数列表函数返回值使用 return()。内置函数R 语言提供了很多有用的内置函数,我们无需定义它就可以直接使用。例如:seq(), mean(), max(), sum(x) 以及 paste(...) 等。实例# 输出 32 到 44 到的所有数字print(seq(32,44))# 计算两个数到平均数print(mean(25:82))# 计算 41 到 68 所有数字之和print(sum(41:68))执行以上代码,输出结果为: [1] 32 33 34 35 36 37 38 39 40 41 42 43 44[1] 53.5[1] 1526自定义函数我们可以自己创建函数,用于特定到功能,定义后可以向内置函数一样使用它们。下面演示两如何自定义函数:实例# 定义一个函数,用于计数一个系列到平方值new.function <- function(a) { for(i in 1:a) { b <- i^2 print(b) }}接下来我们可以调用函数:实例new.function <- function(a) { for(i in 1:a) { b <- i^2 print(b) } } # 调用函数,并传递参数new.function(6)执行以上代码,输出结果为:[1] 1[1] 4[1] 9[1] 16[1] 25[1] 36我们也可以创建一个不带参数的函数:实例new.function <- function() { for(i in 1:5) { print(i^2) }} # 调用函数,不需要传递参数new.function()执行以上代码,输出结果为:[1] 1[1] 4[1] 9[1] 16[1] 25带有参数值的函数函数参数,可以按函数创建时的顺序来传递,也可以不按顺序,但需要指定参数名:实例# 创建函数new.function <- function(a,b,c) { result <- a * b + c print(result)}# 不带参数名new.function(5,3,11)# 带参数名new.function(a = 11, b = 5, c = 3)执行以上代码,输出结果为:[1] 26[1] 58函数创建时也可以为参数指定默认值,如果调用的时候不传递参数就会使用默认值:实例# 创建带默认参数的函数new.function <- function(a = 3, b = 6) { result <- a * b print(result)}# 调用函数,但不传递参数,会使用默认的new.function()# 调用函数,传递参数new.function(9,5)执行以上代码,输出结果为:[1] 18 [1] 45懒惰计算的函数懒惰计算将推迟计算工作直到系统需要这些计算的结果。如果不需要结果,将不用进行计算。默认情况下,R 函数对参数的计算是懒惰的,就是只有我们在计算它的时候才会调用:实例f <- function(x) { 10}f()执行以上代码,输出结果为:[1] 10以上代码执行,并没有报错,虽然我们没有传入参数,但函数体内没有使用参数 x,所以不会去调用它,也不会报错。实例new.function <- function(a, b) { print(a^2) print(a) print(b) # 使用到 b,但未传入,所以会报错}# 传入一个参数new.function(6)执行以上代码,输出结果为:[1] 36[1] 6Error in print(b) : 缺少参数"b",也没有缺省值Calls: new.function -> print停止执行
-
循环类型repeatrepeat 循环会一直执行代码,直到条件语句为 false 时才退出循环,退出要使用到 break 语句。语法格式如下:repeat { // 相关代码 if(condition) { break }}以下实例在变量 cnt 为 5 时退出循环,cnt 为计数变量:实例v <- c("Google","huaweiyun")cnt <- 2repeat { print(v) cnt <- cnt+1 if(cnt > 5) { break }}执行以上代码,输入结果为:[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"while只要给定的条件为 true,R 语言中的 while 循环语句会重复执行一个目标语句。语法格式如下:while(condition){ statement(s);}在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环,程序流将继续执行紧接着循环的下一条语句。以下实例在在变量 cnt 小于 7 时输出 while 语句块中的内容,cnt 为计数变量:实例v <- c("Google","huaweiyun")cnt <- 2while (cnt < 7) { print(v) cnt = cnt + 1}执行以上代码,输入结果为:[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"forR 编程语言中 for 循环语句可以重复执行指定语句,重复次数可在 for 语句中控制。语法格式如下:for (value in vector) { statements}R 语言的 for 循环特别灵活,不仅可以循环整数变量,还可以对字符向量,逻辑向量,列表等数据类型进行迭代。以下实例输出 26 个字母对前面四个字母:实例v <- LETTERS[1:4]for ( i in v) { print(i)}执行以上代码,输入结果为:[1] "A"[1] "B"[1] "C"[1] "D"循环控制breakR 语言的 break 语句插入在循环体中,用于退出当前循环或语句,并开始脚本执行紧接着的语句。如果你使用循环嵌套,break 语句将停止最内层循环的执行,并开始执行的外层的循环语句。break 也常用语 switch 语句中。语法格式如下:break以下实例在变量 cnt 为 5 时使用 break 退出循环,cnt 为计数变量:实例v <- c("Google","huaweiyun")cnt <- 2repeat { print(v) cnt <- cnt+1 if(cnt > 5) { break }}执行以上代码,输入结果为:[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"[1] "Google" "huaweiyun"nextnext 语句用于跳过当前循环,开始下一次循环(类似其他语言的 continue)。语法格式如下:next以下实例输出 26 个字母的前面 6 个字母,在字母为 D 的时候跳过当前的循环,进行下一次循环:实例v <- LETTERS[1:6]for ( i in v) { if (i == "D") { # D 不会输出,跳过这次循环,进入下一次 next } print(i)}执行以上代码,输入结果为:[1] "A"[1] "B"[1] "C"[1] "E"[1] "F"
-
赋值一般语言的赋值是 = 号,但是 R 语言是数学语言,所以赋值符号与我们数学书上的伪代码很相似,是一个左箭头 <- :实例a <- 123b <- 456print(a + b)以上代码执行结果:[1] 579这个赋值符号是 R 语言的一个形式上的优点和操作上的缺点:形式上更适合数学工作者,毕竟不是所有的数学工作者都习惯于使用 = 作为赋值符号。操作上来讲,< 符号和 - 符号都不是很好打的字符,这会让很多程序员不适应。因此,R 语言的比较新的版本也支持 = 作为赋值符:a = 123b = 456print(a + b)这也是合法的 R 程序。注意:很难考证从 R 的哪个版本开始支持了 = 赋值,但是本教程习用的 R 版本是 4.0.0。
-
注释主要用于一段代码的解析,可以让阅读者更易理解,编程语言的注释会被编译器忽略掉,且不会影响代码的执行。一般编程语言的注释分为单行注释与多行注释,但是 R 语言只支持单行注释,注释符号为 #。其实如果有多行注释我们只需要在每一行添加 # 号就好了。单行注释# 这是我的第一个编程代码myString <- "Hello, World!"print ( myString )多行注释# R 语言实现两个数相加 # 变量赋值a <- 9b <- 4 # 输出结果print(a + b)其实多行注释还有一个变通的写法,就是使用 if 语言,如下实例:多行注释if(FALSE) { " 这是一个多行注释的实例 注释内容放在单引号或双引号之间 "}myString <- "Hello, World!"print ( myString)
-
直播回放:https://bbs.huaweicloud.com/live/education_live/202109021900.html探索性数据分析方法核心理念与基本步骤1.理解数据科学“数据科学家不仅仅需要构建出色的数据模型,更重要的是能够阐释已获得的成果并将成果用于商业智能的开发当中”--Suresh Kumar Mukhiya➢涉及多个领域的跨学科知识,包括计算机科学,数据信息,统计学,以及数学➢数据科学正处于热度不减的巅峰时刻,同时数据科学家的技能也正在改变➢要成为顶尖的数据科学家,我需要学习什么类型的技能?2.探索性数据分析方法的核心理念“将探索性数据分析方法纳入统计学专家的工具箱,以便于对数据进行探查和发现信息并建立更加崭新的假设,从而在数据收集与实验的过程中开发出更加新颖的研究方法。”--John Tuckey➢探索性数据分析方法,Exploratory Data Analysis[EDA]指的是探查现有可用的数据集从而发现数据模型,异常点,检验假设,以及采用统计度量措施来验证假设的过程➢主要目的就是在实际进行正式建模或者形成假设之前探查出数据可以告知我们什么信息➢该方法让我们通过可视化技术来理解数据并为进一步的分析做出假设。其重点就是为后续步骤建立数据概要或者提供洞察信息➢在没有做出任何基本假设的情况下,探索性数据分析方法实际上揭示出了数据隐含的基本事实3.探索性数据分析方法的阶段划分➢8个阶段类似于跨行业数据挖掘标准流程(CRISP)中用到的框架➢数据需求确定[多种数据源/存储类型/数据分类]➢数据收集[以正确的格式进行存储]➢数据处理[预整理过程/导出数据集/存放到正确的表格/结构化处理]➢数据清洗[数据转换/完整性/数据重复性/数据错误/缺失值检查]➢探索性数据分析[数据中隐含的信息/采用多种类型的数据转换技术]➢数据建模与算法应用[模型用来描述自变量和因变量之间的关系]➢数据产品[数据作为输入,进而产生输出/推荐模型]➢信息传递与成果展示[成果传递/服务于商业智能/数据可视化]4.探索性数据分析方法的基本步骤➢问题定义[在提取有用的洞察信息之前,定义需要解决的业务问题]➢数据准备[定义数据源/定义数据架构模式和数据表/理解数据的主要特征/清洗数据集/删除不相关的数据集/转换数据/数据分块]➢数据分析[汇总数据/发现数据之间隐藏的相关性和关联关系/开发预测模型/评估模型/计算精度/汇总表,图表,描述性统计,推断统计,相关性统计,检索,分组,以及数学模型]➢应用开发与成果表示[以图表,汇总表,地图,以及图解示意图的形式向目标群体展示数据集信息/从数据集获取到的分析成果应该便于业务相关人员进行解读,这是探索性数据分析的主要目标之一/散点图,字符图,直方图,箱线图,残差图,均值图]5.常用软件与工具➢Python语言[广泛用于数据分析,数据挖掘,以及数据科学领域]➢R语言[广泛用于统计计算以及图形数据分析领域]➢Weka[开源的数据挖掘软件包/含有探索性数据分析方法中用到的多种工具和算法]➢KNIME[基于Eclipse集成开发环境,用于数据分析的开源工具]➢Python库-NumPy[数据分析与科学计算基础软件包]➢Python库-Pandas[数据分析支持库]➢Python库-SciPy[用于科学计算的开源Python库]➢Python库-Matplotlib[大量的可自定义的绘图库,全面完整的后端程序。报表应用程序/交互式分析应用程序/复杂仪表盘应用程序]6.答观众问见评论区:https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=151651
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签