首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

【大数据新手上路】“零基础”系列课程--MySQL 数据整库迁移到 MaxCompute

随着公司业务的增多,云数据库 RDS 下的 MySQL 数据库的表越来越多,想要把它全部迁移到 MaxCompute 中进行计算分析,但又愁要配置太多次同步任务。如何能将大量的数据表一次性上传到 MaxCompute 中呢?通过大数据开发套件的整库迁移功能,便可快速完成 MySQL 数据整库迁移到 MaxCompute,从而节省同步时间,提高工作效率。 下面介绍一个适用于中小企业用户,高效率低成本的数据同步方案: 对于自建或云数据库 RDS 的 MySQL 数据库中的数据,都可以通过整库迁移功能,快速同步到 MaxCompute 中进行存储与分析,流程图如下: 云数据库 RDS :RDS 是一种稳定可靠、可弹性伸缩的在线数据库服务,本实验主要使用 云数据库 MySQL 版。 MaxCompute:原名 ODPS,是由阿里云自主研发的一款服

优秀的个人博客,低调大师

企业应用如何解决Multi-Cloud的基础设施管理及应用部署问题

选择Multi-Cloud的因素 “Multi-Cloud”即企业将多个应用部署在多个云平台上,比如阿里云、AWS、Azure、OpenStack或其他云平台。通过下面的模形我们可以看到企业选择Multi-Cloud的因素及应用部署策略,包括7个主要因素:云计算平台数据中心的访问速度/云服务的性能/可用性、云计算平台的成本、云计算平台的安全性、客户服务质量、本地化、云计算平台的提供商、以及企业自有的数据中心地点。 ![tf](https://yqfile.alicdn.com/7f94679daec3bdbe148d6e0d5782a5d46c71d8be.png) RightScale的调查数据显示目前有越来越多的企业选择Multi-Cloud模式(2015年58%, 2016年增长到71%)。 挑战 虽然越来越多的企业选择

优秀的个人博客,低调大师

【大数据新手上路】“零基础”系列课程--Flume收集网站日志数据到MaxCompute

免费开通大数据服务:https://www.aliyun.com/product/odps 概述:大数据时代,谁掌握了足够的数据,谁就有可能掌握未来,而其中的数据采集就是将来的流动资产积累。 任何规模的企业,每时每刻都在产生大量的数据,但这些数据如何归集、提炼始终是一个困扰。而大数据技术的意义确实不在于掌握规模庞大的数据信息,而在于对这些数据进行智能处理,从中分析和挖掘出有价值的信息,但前提是如何获取大量有价值的数据。 相信很多做过网站管理的人对网站访问日志(Access Log)应该不会陌生,现在主流的网站服务器(如apache,tomcat,ngxin等)都支持将日志数据记录到服务器的日志文件中。 网站的访问日志中记录了很多有用的信息,比如正常用户的访问足迹、恶意捣乱的足迹、用户的入站方式、出站页面等信息。对以上信息汇总分类后,可以得

优秀的个人博客,低调大师

网站前端_jQuery-基础入门.玩转jQuery基本/层次/过滤/表单选择器?

对比选择: 1. CSS依靠CSS选择器使得网页的结构和表现样式完全分离,CSS选择器能轻松定位并修改指定元素样式,CSS选择器包括标签选择器(以文档元素作为选择器),ID选择器(以文档元素的唯一标识ID作为选择器),类选择器(以文档元素的class作为选择器),群组选择器(多个选择器应用同样的样式规则),后代选择器(元素X的任意后代元素Y),通配选择器(以文档的所有元素作为选择器),伪类选择器(以元素特定行为作为选择器),子选择器(元素X的直接子属元素Y),兄弟选择器(元素X的直属兄弟元素Y),属性选择器(以文档元素特定属性为选择器),详情参考(http://www.w3school.com.cn/css/css_selector_type.asp) 2. jQuery选择器完全继承了CSS选择器的风格,CSS选择器能轻松定位并修改指定元素属性和行为,而无需担心浏览器是否支持这一选择器,jQuery的行为规则都必须在获取到元素后才能生效 说明: jQuery不仅可以像原生CSS样修改元素样式,而且还可以修改元素行为,需要注意的是jQuery中涉及操作CSS样式的部分比单纯的CSS功能更为强大,并且拥有跨浏览器的兼容性. 错误处理: 说明: 原生JS如果返回的对象不存在则浏览器会报错,如果加if判断会增加代码量,而jQuery中$('selector')返回的永远是封装后的jQuery对象,因此不能直接if判断,也不需要if判断,如果非要去判断的话可通过判断$('selector').length属性是否大于0或$('selector')[0]转换为DOM对象(其实是调用的$('selector').toArray()转换为DOM对象数组然后再取指定DOM对象的)判断对象是否存在 <!DOCTYPEhtml> <htmllang="zh-cn"> <head> <metacharset="UTF-8"> <title>前端开发</title> </head> <body> </body> <scriptsrc="js/libs/jquery.min.js"></script> <scripttype="text/javascript"> //方式一:通过判断其length属性 if($("body").length>0){ alert("存在") } //方式二:转换为DOM对象判断是否存在 if($('body')[0]){ alert("存在") } </script> </html> JQ选择器: <!DOCTYPEhtml> <htmllang="zh-cn"> <head> <metacharset="UTF-8"> <title>前端开发</title> <styletype="text/css"> div,span,p{ width:200px; height:200px; margin:5px; background:#aaa; border:#0001pxsolid; float:left; font-size:17px; } div.mini{ width:66px; height:66px; background-color:#aaa; font-size:12px; } div.hide{ display:none; } </style> </head> <body> <h1>justfortest</h1> <divclass="one"id="one"> id为one,class为one的div <divclass="mini">class为mini的div</div> </div> <divclass="one"id="two"title="test"> id为two,class为one,title为test的div <divclass="mini"title="other">class为mini,title为other的div</div> <divclass="mini"title="test">class为mini,title为test的div</div> </div> <divclass="one"> class为one的div <divclass="mini">class为mini的div</div> <divclass="mini">class为mini的div</div> <divclass="mini">class为mini的div</div> <divclass="mini"></div> </div> <divclass="one"> class为one的div <divclass="mini">class为mini的div</div> <divclass="mini">class为mini的div</div> <divclass="mini">class为mini的div</div> <divclass="mini"title="test">class为mini,title为test的div</div> </div> <divstyle="display:none;"class="one">style的display为"none"的div</div> <divclass="hide">class为"hide"的div</div> <div> 包含input的type为"hidden"的div <inputtype="hidden"name="name"> </div> <spanid="mover">正在执行动画的span</span> </body> </html> # 基本选择器 说明: 基本选择器包括元素选择器/ID选择器/类选择器/通用选择器/分组选择器. <scriptsrc="js/libs/jquery.min.js"></script> <scripttype="text/javascript"> //改变id为one的元素背景颜色为#bbffaa $("#one").css("background-color","#bbffaa") //改变class为mini的元素的背景颜色为#bbffaa $(".mini").css("background-color","#bbffaa") //改变所有div元素的背景颜色为#bbffaa $("div").css("background-color","#bbffaa") //改变所有元素的背景颜色为#bbffaa $("*").css("background-color","#bbffaa") //改变所有span和id为two的元素的背景颜色为#bbffaa $("span,#two").css("background-color","#bbffaa") </script> # 层次选择器 说明: 层次选择器包括子选择器/后代选择器/兄弟选择器/后续选择器. <scripttype="text/javascript"> //改变body里面所有div元素的背景颜色为#bbffaa $("bodydiv").css("background-color","#bbffaa") //改变body内第一层同级div元素的背景颜色为#bbffaa $("body>div").css("background-color","#bbffaa") //改变class为one的后面第一个同级div的背景颜色为#bbffaa $(".one+div").css("background-color","#bbffaa") //改变id为two后面所有div元素的背景颜色为#bbffaa $("#two~div").css("background-color","#bbffaa") </script> 扩展: 在层次选择器中子选择器和后代选择器比较常用,而兄弟选择器和后续选择器在jQuery中可以用更简单的方法代替,兄弟选择器可通过.next("selector")代替,而后续选择器可通过.nextAll("selector")代替,需要注意的是.next("selector")和.nextAll("selector")都是基于同级的,还有一个基于同级但是不论前后的兄弟元素获取方法是.siblings("selector") # 过滤选择器 说明: 过滤选择器包括基本过滤选择器/内容过滤选择器/可见性过滤选择器/属性过滤选择器/子元素过滤选择器/表单属性过滤选择器. <scripttype="text/javascript"> //基本过滤选择器 //改变第一个div元素的背景色为#bbffaa $("div:first").css("background-color","#bbffaa") //改变最后一个div元素的背景色为#bbffaa $("div:last").css("background-color","#bbffaa") //改变class不为one的元素的背景色为#bbffaa $("div:not(.one)").css("background-color","#bbffaa") //改变索引为偶数的元素的背景颜色为#bbffaa $("div:even").css("background-color","#bbffaa") //改变索引为奇数的元素的背景颜色为#bbffaa $("div:odd").css("background-color","#bbffaa") //改变索引等于某值元素的背景颜色为#bbffaa $("div:eq(0)").css("background-color","#bbffaa") //改变索引大于某值的元素的背景颜色为#bbffaa $("div:gt(0)").css("background-color","#bbffaa") //改变索引小于某值的元素的背景颜色为#bbffaa $("div:lt(1)").css("background-color","#bbffaa") //改变所有的标题元素(h1~h6)的背景颜色为#bbffaa $(":header").css("background-color","#bbffaa") //改变所有正在执行动画的元素的背景颜色为#bbffaa $(":animated").css("background-color","#bbffaa") //内容过滤选择器 //设置包含文本内容为某值的元素背景色为#bbffaa $("div:contains(为)").css("background-color","#bbffaa") //设置不包含任何子元素或文本内容的元素背景色为#bbffaa $("div:empty").css("background-color","#bbffaa") //设置包含指定选择器的元素的元素背景色为#bbffaa $("div:has(div)").css("background-color","#bbffaa") //设置包含有子元素或文本的元素的背景色为#bbffaa(和empty相反) $("div:parent").css("background-color","#bbffaa") //可见过滤选择器 //设置所有不可见元素显示 $("div:hidden").show(3000) //设置所有可见div元素背景色设置为#bbffaa $("div:visible").css("background-color","#bbffaa") //属性过滤选择器 //设置含有title属性元素的背景色为#bbffaa $("[title]").css("background-color","#bbffaa") //设置title属性值等于test的元素背景色为#bbffaa //$("[title=test]").css("background-color","#bbffaa") //设置title属性值不等于test的元素背景色为#bbffaa $("[title!=test]").css("background-color","#bbffaa") //设置title属性值以te开头的元素背景色为#bbffaa $("[title^=te]").css("background-color","#bbffaa") //设置title属性值以st结尾的元素背景色为#bbffaa $("[title$=st]").css("background-color","#bbffaa") //设置title属性值中含有es的元素背景色为#bbffaa $("[title*=es]").css("background-color","#bbffaa") //设置包含id属性且title属性值为test的元素的背景色为"#bbffaa" $("[id][title=test]").css("background-color","#bbffaaa") //子元素过滤选择器 //设置class为one的div下的第一个子元素背景色为#bbffaa $("div.one:first-child").css("background-color","#bbffaa") //设置class为one的div下的最后一个子元素背景色为#bbffaa $("div.one:last-child").css("background-color","#bbffaa") //设置class为one的div下只有一个子元素的元素背景色为#bbffaa $("div.one:only-child").css("background-color","#bbffaa") //设置每个元素下的第index个子元素或偶数或奇数元素的背景色为#bbffaa $("div.one:nth-child(odd)").css("background-color","#bbffaa") </script> 说明: 在可见性过滤选择器中,:hidden不仅包括样式属性display:none的元素,也包括文本隐藏域<input type="hidden">和visible:hidden之类的元素,在子元素过滤选择器中,:nth-child将为每一个符合条件的父元素匹配子元素,但需要注意的是索引是从1开始,而:eq的索引从0开始,同理:first和:first-child,:last和:last-child类似 # 表单选择器 说明: 表单选择器包括表单对象属性过滤选择器和扩展表单过滤选择器. <scripttype="text/javascript"> //表单对象属性过滤选择器 //设置id为form1的表单下的可用元素的值为你改变了~ $("#form1input:enabled").val("你改变了~") //设置id为form1的表单下的不可用元素的值为你改变了~ $("#form1input:disabled").val("你改变了~") //获取多选框中选中的个数并显示在div中 $("div:first").html($("input:checked").length+"个被选中!").css({ "color":"red", "font-weight":"border" }) //获取多选下拉列表中被选中的个数并显示在div中 $("div:eq(1)").html($("select:first[selected=selected]").length+"个被选中").css({ "color":"red", "font-weight":"border" }) //获取单选下拉框中被选中的值并显示在div中 $("div:last").html($("select:last[selected=selected]").text()+"被选中").css({ "color":"red", "font-weight":"border" }) //表单选择器 //:input可匹配<input>/<textarea>/<select>/<button>元素 $(":input").css("border","solid1pxred") //:text可匹配<input>所有的单行文本框 $(":text").css("border","solid1pxred") //:password可匹配所有的密码框 $(":password").css("border","solid1pxred") //:radio可匹配所有的单选框 $(":radio").css("border","solid1pxred") //:checkbox可匹配所有的多选框 $(":checkbox").css("border","solid1pxred") //:submit可匹配所有的提交按钮 $(":submit").css("border","solid1pxred") //:p_w_picpath可匹配所有的图像按钮 $(":p_w_picpath").css("border","solid1pxred") //:reset可匹配所有的重置按钮 $(":reset").css("border","solid1pxred") //:button可匹配所有的按钮 $(":button").css("border","solid1pxred") //:file可匹配所有的文件上传域 $(":file").css("border","solid1pxred") //:hidden选取所有不可见元素 $(":hidden").css("border","solid1pxred") </script> 最佳实践: 1. 给网页中的所有的<p>元素添加点击事件,点击后弹出元素内的文本内容? <scripttype="text/javascript"> $("p").click(function(event){ alert($(this).text()) }); </script> 2. 使一个特定的表格隔行换色? <scripttype="text/javascript"> $("tabletr:odd").css("background-color","#bbffaa") </script> 3. 对多选框进行操作,输出选中的个数? <scripttype="text/javascript"> $("input[name=newselector]:checkbox").click(function(event){ $("div>span").html( ""+$("input[name=newselector]:checked").length+"个选项被勾选!" ).css("color","red") }) </script> 4. 如上要求用户进入页面时,品牌列表默认精简显示(从第5条开始隐藏后面的品牌,除了最后一条),用户单机"显示所有品牌"显示全部品牌同时高亮显示推荐的品牌,且按钮里的文字也换成"精简显示品牌",再次单击"精简显示品牌"恢复初始状态? <!DOCTYPEhtml> <htmllang="zh-cn"> <head> <metacharset="UTF-8"> <title>前端开发</title> <styletype="text/css"> *{margin:0;padding:0;} body{font-size:12px;text-align:center;} a{color:#04D;text-decoration:none;} a:hover{color:#F50;text-decoration:underline;} .SubCategoryBox{width:600px;margin:0auto;text-align:center;margin-top:40px;} .SubCategoryBoxul{list-style:none;} .SubCategoryBoxulli{display:block;float:left;width:200px;line-height:20px;} .showmore{clear:both;text-align:center;padding-top:10px;} .showmorea{display:block;width:120px;margin:0auto;line-height:24px;border:1pxsolid#AAA;} .showmoreaspan{padding-left:15px;background:url(img/down.gif)no-repeat00;} .promoteda{color:#F50;} </style> </head> <body> <divclass="SubCategoryBox"> <ul> <li><ahref="#">佳能</a><i>(30440)</i></li> <li><ahref="#">索尼</a><i>(27220)</i></li> <li><ahref="#">三星</a><i>(20808)</i></li> <li><ahref="#">尼康</a><i>(17821)</i></li> <li><ahref="#">松下</a><i>(12289)</i></li> <li><ahref="#">卡西欧</a><i>(8242)</i></li> <li><ahref="#">富士</a><i>(14894)</i></li> <li><ahref="#">柯达</a><i>(9520)</i></li> <li><ahref="#">宾得</a><i>(2195)</i></li> <li><ahref="#">理光</a><i>(4114)</i></li> <li><ahref="#">奥林巴斯</a><i>(12205)</i></li> <li><ahref="#">明基</a><i>(1466)</i></li> <li><ahref="#">爱国者</a><i>(3091)</i></li> <li><ahref="#">其它品牌相机</a><i>(7275)</i></li> </ul> <divclass="showmore"> <ahref="more.html"><span>显示全部品牌</span></a> </div> </div> </body> <scriptsrc="js/libs/jquery.min.js"></script> <scripttype="text/javascript"> /* 1.默认进去页面,从第5条开始隐藏后面的品牌(最后一条"其它品牌相机"除外) 2.当用户点击"显示全部品牌"按钮时 >显示隐藏品牌 >"显示全部品牌"按钮文本切换成"精简显示品牌" >高亮推荐品牌 3.当用户点击"精简显示品牌"按钮时 >从第5条开始隐藏后面的品牌(最后一条"其它品牌相机"除外) >"精简显示品牌"按钮文本切换成"显示全部品牌" >去掉高亮显示的推荐品牌 */ $(function(){ var$moreItems=$(".SubCategoryBox>ul>li:gt(5):not(:last)") var$moreBtn=$(".showmore>a") var$highlightItmes=$("ul>li").filter(":contains(佳能),:contains(索尼)") $moreItems.hide() $moreBtn.toggle(function(){ $moreItems.show() $(".showmore>a>span").css("background","url(img/up.gif)no-repeat00").text("精简显示品牌") $highlightItmes.addClass("promoted") },function(){ $moreItems.hide() $(".showmore>a>span").css("background","url(img/down.gif)no-repeat00").text("显示所有品牌") $highlightItmes.removeClass("promoted") }) }) </script> </html> 方法 说明 .show(speed,callback) 显示隐藏的匹配元素,支持设置显示速度以及回调函数 .css(name) 获取所有匹配元素的样式 .css(name, value) 设置所有匹配元素的单个样式 .css(name,function(index,value)) 设置所有匹配元素的单个样式,index为选择器index的位置,value为当前样式值 .css({k: v, k: v}) 设置所有匹配元素的多个样式 .filter(selector) 以单个过滤器过滤对应的集合 .filter(expr) 以多个过滤器过滤对应的集合,过滤器之间使用,隔开 .filter(func) 以函数过滤对应的集合,函数接收选择器index的值 .addClass(class) 为指定元素添加class .removeClass(class) 为指定元素删除class .toggle(func1,func2, func3....) 用于绑定两个或多个事件处理函数,以响应被选元素的轮流的.click事件

优秀的个人博客,低调大师

从0到1搭建一个智能分析OBS埋点数据的AI Agent|得物技术

一、背景 某天打开组内的Grafana仪表盘,突然好奇我们的埋点从被触发后是如何一步一步变成所展示的各种图表的,于是在我进行一系列的探索之后,总结出了以下链路: 在指标工厂新建指标,确定埋点key和埋点元数据。 代码中指定埋点key和埋点数据,通过watchDog发送kafka消息到obs monitor topic。 为埋点指标新建数据处理任务,将消费到的kafka消息落到指定的数据表中。 添加新的仪表盘,编写展示数据背后的SQL语句。 痛点:每需要添加一个新的数据分析大盘,就需要人工去分析各个表结构、表与表之间的联系、表各个字段的含义等,在充分理解其含义后再费时费力地编写SQL语句,并不断调优。这导致OBS埋点数据分析的场景相对固化,并且难以支持灵活的数据查询要求。 二、思考 在分析了当前系统的痛点后,我意识到这是一个典型的可以利用AI能力来对现有功能进行扩展的场景。因为: 场景多变,因为你不知道用户可能想查看什么样的数据,无法通过代码穷举; 需要了解业务同时又具备编写复杂数据查询SQL的人,并且费时费力; 看到大盘数据后,依赖每个人对业务的理解提炼出一套分析报告,报告质量与个人的理解与表达能力相关。 于是我就开始思考能否构建一个AI Agent,使其能够根据用户的要求,自主地生成各种各样的SQL查询语句,并将查询到的数据形成完整的数据分析报告返回给用户。 为了实现这个方案,有几个明显需要解决的点: 如何让AI理解每个表中各字段的含义、各个表的作用、表与表之间的联系,从而生成准确的SQL? AI生成完SQL之后,如何打通 AI 与数据平台之间的通路,从而成功执行该SQL 并拿到数据?因为数据库权限不在我这,我无法直接连接到数据库。 如何充分利用已有资源,减少人力投入?毕竟是个人想法,在不确定效果如何的情况下,不好直接打扰平台方专门为我写一些新功能,同时我个人也只能投入一些零碎的时间来做这件事。 三、方案 有了问题后,就带着问题去找答案。 3.1查询数据Tool 首先,我需要一个能够执行查询的端点。那么我就去抓取了大盘中的数据所调用的接口,意外地发现,不同的数据调用的是同一个接口https://xxx.com/api/ds/query,只是入参不同而已,而且发现,查询的逻辑是通过rawSql将查询语句直接传过去! 于是我将该Curl导入到ApiFox中,通过不断修改参数,发现最终与查询结果相关的入参可以精简到简单的几个参数:from、to、query(format,rawSql,intervalMs) 那么针对第一个问题我就想到了很好的办法,把这个查询API封装成一个Tool,描述清楚各个字段的含义,就可以让AI生成完整的参数来查询它想要的数据。 说干就干,我立马新建了一个Spring AI工程,把Tool的功能和需要的参数描述清楚。其中grafanaService.query()内部逻辑就是通过Feign来调用上面那个查询的API。 @Tool(name = "query_grafana", description= "使用Grafana中的SQL查询grafana数据") public JSONObject queryGrafana(@ToolParam(description = "查询开始时间") String from, @ToolParam(description = "查询结束时间") String to, @ToolParam(description = "查询数据类型:table|time_series") String format, @ToolParam(description = "查询时间间隔,单位毫秒。只有当format为time_series时需要传入。") Long intervalMs, @ToolParam(description = "Grafana SQL查询语句") String rawSql){ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime fromDateTime = LocalDateTime.parse(from, formatter); LocalDateTime toDateTime = LocalDateTime.parse(to, formatter); String fromTimestamp = String.valueOf(fromDateTime.toInstant(ZoneOffset.UTC).toEpochMilli()); String toTimestamp = String.valueOf(toDateTime.toInstant(ZoneOffset.UTC).toEpochMilli()); JSONObject resp = grafanaService.query(fromTimestamp, toTimestamp, intervalMs, rawSql, format); return resp; } @Resource private GrafanaClient grafanaClient; @Value("${grafana.cookie}") private String getGrafanaCookie; public JSONObject query(String fromTimestamp, String toTimestamp, Long intervalMs, String rawSql, String format) { GrafanaRequest request = new GrafanaRequest(fromTimestamp, toTimestamp, intervalMs, rawSql, format); return grafanaClient.query(getGrafanaCookie, request); } 3.2表结构RAG 有了能够执行查询的Tool之后,剩下的就是需要AI能够根据用户的query生成精准的参数以及查询SQL。 之前了解到公司部署了RAGFlow服务:https://xxx.com/knowledge,既然有了,那就得用起来! 创建知识集,发现支持添加飞书文档。 由于我们是需要完整的表结构,所以把配置修改为使用table的格式,一行数据便是一个chunk,以免出现语义上的中断。(埋点数据一般表都较小,语意较为明确。像一些字段很多的大表可能需要考虑更好的方案。) 创建飞书文档,手动到OBS的库中把我们想要AI帮助分析的表结构拉出来(验证想法时采取的临时方案),但由于建表时的不规范,很多表没有对表中字段添加comment,这会导致AI不理解每个字段的含义,也就无法准确地生成SQL。因此,我们手动补充每张表、每个字段的描述,以及与其它表之间的关联关系。 将飞书文档添加到数据集中,完成后点击名称查看切片详情。双击每个块也可以查看块的详情。 会发现RAGFlow自动给我们生成了一些关键词和问题,这些内容会对召回准确率产生影响。我自己觉得生成的不太准确,所以结合自己理解手动输入了一些关键词和可能的问题。 完成后,可以到检索测试tab测试召回的效果,根据结果确定合适的参数。并可以对chunk的内容和关键词等等进行适当的调整。 调优完成后,就需要对接RAGFlow的retrive接口,来把我们知识库召回的流程做成一个Tool。 @Resource private RagFlowService ragFlowService; @Tool(name = "get_table_schema", description= "根据query查询可能有关联的数据库表,返回建表语句。尽量传入多个中文关键词,每个关键词之间用空格隔开。") public List<String> getTableSchema(@Param("query") String question){ return ragFlowService.retrieval(question); } 3.3 OBS Agent 在我看来,想要构建一个能够 work 的Agent,需要以下几个要素: Agent=Architecture (Workflow、ReAct、Plan-Execute、Multi-Agent...) +LLM+Context Engineering(Prompt、Tool、Memory...) 本来是想用SpringAI Alibaba Graph或者 LangGraph来构建一个WorkFlow类或者Graph类的复杂智能体(ReAct、Plan-Execute、Multi-Agent)。但为了快速验证想法和节省个人时间,并且考虑到目前任务相对简单(PE+工具就足以完成),再加上部门正在试用Trae这个工具,所以决定基于Trae来构建一个Agent(可以顺便使用他们的高级模型/doge,也可以分享给其它同事使用)。 接入Trae之后,Architecture自然就是Trae的Agent架构了,根据我使用下来感觉采用的是基于ReAct的 Single-Agent。而Context Engineering的部分,对话功能以及长短期记忆,自然是Trae天生就具备的。而Tool则可以借助其自带的一些工具,另外还可以利用MCP来进行扩展,比如得物的MCP市场,提供了大量好用的Server,并且可以很方便的发布自己开发的Mcp Server。于是,我就把在第一步和第二步做的工具,在得物Mcp平台上进行发布,供我自己和其他感兴趣的同学使用。 最后,需要一个专门针对我这个场景的Prompt来指引LLM 顺利完成任务,经过我不断的修改,最终形成这样一段Prompt: # Role:数据分析专家 ## Background:用户需要专业的数据分析支持来解决复杂的业务问题,从海量数据中提取有价值的信息,为产品优化、运营策略和业务决策提供可靠依据。 ## Attention:数据准确性是分析工作的生命线,必须始终保持严谨细致的工作态度。每一次分析都可能影响重要决策,因此需要系统性思考、分步验证,确保每个环节的可靠性。 ## Profile: - Language: 中文 - Description: 专注于数据库表结构分析与Grafana-SQL查询的专业数据分析师,具备系统化解决复杂数据查询问题的能力 ### Skills: - 精通数据库表结构分析,能够快速识别表关系、字段含义和数据类型 - 熟练掌握Grafana-SQL语法规范,具备高效的查询语句编写和优化能力 - 具备专业的数据可视化技能,能够根据分析目标选择合适的图表类型 - 拥有深度业务需求理解能力,能够准确转化业务问题为数据查询方案 - 掌握系统化的问题分析方法,能够规划完整的数据分析流程和验证机制 ## Goals: - 准确理解用户业务需求,明确数据查询的核心目标和关键指标 - 系统分析相关表结构,确保对数据关系和业务逻辑的全面理解 - 设计高效的数据查询方案,平衡查询性能与结果准确性 - 生成专业的数据分析报告,包含可视化展示和深度业务洞察 - 确保所有分析过程可追溯、结果可验证、结论可执行 ## Constrains: - 查询不到数据时不要模拟任何数据,直接回复查不到数据 - 你自己所知道的时间是不准确的,如果涉及到时间,则需要使用工具获取当前时间 - 严格基于实际数据进行分析,严禁任何形式的数据虚构或推测 - 必须在完成表结构分析和需求理解后再执行具体查询操作 - 所有重要数据必须进行源头验证和多维度交叉检查 - 严格遵守数据安全和隐私保护原则,不超越授权数据范围 - 明确说明分析的局限性、假设条件和潜在的数据不确定性 ## Workflow: 1. 深度理解业务需求,明确查询目标、关键指标和预期输出 2. 不断使用工具获取你需要的表及其表结构,直到你认为已获取到足够的信息 3. 系统分析相关表结构,包括字段含义、数据类型、关联关系和索引结构 4. 设计查询逻辑方案,规划执行步骤、验证节点和性能优化策略 4. 编写符合Grafana语法的SQL查询语句,设置正确的参数和时间范围 5. 执行查询。如果查询出现401错误,则中断后续流程,并提示用户更新Cookie后重启obs-mcp-server;如果出现400错误,尝试修改自己的SQL语句重新查询; 6. 生成可视化图表和详细分析报告,报告中必须包含你执行查询的SQL语句 7. 调用飞书生成文档工具以Markdown格式创建飞书文档,返回最终的飞书文档地址 ## OutputFormat: - 分析报告,包含完整的分析过程和关键发现,创建新的飞书文档并保存在其中 - 可视化图表以嵌入式链接形式呈现,确保清晰展示数据趋势和分布 - 报告结构包含执行摘要、分析方法、数据结果、业务洞察和后续建议 ## Suggestions: - 建立系统化的表结构分析框架,提高数据关系识别的效率和准确性 - 持续学习Grafana-SQL最新语法特性,优化查询性能和资源消耗 - 培养多维度数据验证习惯,确保分析结果的可靠性和业务价值 - 深入理解业务场景,提升从数据到洞察的转化能力和决策支持水平 - 定期复盘分析案例,总结经验教训,持续改进分析方法论和工作流程 ## 工具描述 - query_grafana:使用Grafana中的SQL查询grafana数据 注意: 1. 当format为time_series时表示查询时间序列数据,SELECT的第一个字段必须是$__timeGroupAlias(timestamp, interval),表示时间分组别名。时间间隔intervalMs需要与rawSql中的$__timeGroup(timestamp, interval)保持对应。比如intervalMs=86400000L表示1天,rawSql中$__timeGroup(timestamp, 1d)也需要保持一致。 2. 当format为table时表示查询表格数据,SELECT的字段可以任意,intervalMs参数传null 3. 时间范围为闭区间,即包含开始时间from和结束时间to,格式为yyyy-MM-dd HH:mm:ss。 参数示例:{ "from": "2025-11-16 00:00:00", "to": "2025-11-16 23:59:59", "format": "table", "intervalMs": null, "rawSql": "SELECT region, COUNT(*) as user_count FROM intl_xxxxxxx WHERE $__timeFilter(timestamp) GROUP BY region ORDER BY user_count DESC" } ## Initialization 作为数据分析专家,你必须遵守Constrains,使用默认中文与用户交流。 最终,在 Trae 中构建了一个完整OBS Agent。 添加智能体:OBS大盘分析 四、成果 最终生成的报告(截取部分): 五、总结 AI时代来临,我们应该要善于发现当前系统中的哪些部分能够结合AI来进行提升,积极拥抱变化,有了想法就去做,边做边想边解决问题,永远主动向前一步。 本文章只是记录了从产生想法到构建MVP验证想法的整个过程,这中间当然有很多可以继续优化的地方,我本人目前有以下几个想法,也欢迎大家积极评论,贡献自己的独到见解。 接入数据库数据,通过动态监听Binlog的方式来识别各表之间的联系,比如select 语句的join,并将这种关系保存到Neo4j 这种图向量数据库中来实现表结构的 RAG。 基于LangGraph 或 SpringAI Alibaba 构建Multi-Agent System,细化各Agent的职责,精炼各Agent的Context 构成,以获得更好的效果。例如:协调者 Agent、表结构搜索 Agent、SQL 生成 Agent、分析报告 Agent等等。 接入飞书机器人,或者使用AI Coding工具生成一个前端页面。使得一些非技术人员,例如产品和运营也能很方便地使用。 往期回顾 数据库AI方向探索-MCP原理解析&DB方向实战|得物技术 项目性能优化实践:深入FMP算法原理探索|得物技术 Dragonboat统一存储LogDB实现分析|得物技术 从数字到版面:得物数据产品里数字格式化的那些事 一文解析得物自建 Redis 最新技术演进 文 /Neeson 关注得物技术,每周更新技术干货 要是觉得文章对你有帮助的话,欢迎评论转发点赞~ 未经得物技术许可严禁转载,否则依法追究法律责任。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册