十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

把CPU、内存、网络流量同时丢给TimechoAI,做交叉分析

把CPU、内存、网络流量同时丢给TimechoAI,做交叉分析 把CPU、内存、网络流量同时丢给TimechoAI做交叉分析上一次我们聊了怎么把一条时间序列数据塞给TimechoAI。我们造了一个CPU的假数据让它帮我们找出了那个突刺的点。但是呢你回到真实的干活场景里想一想。现实情况往往比那个复杂得多。你光看一个CPU指标很多时候是看不出个所以然来的。你看到了CPU飙到了90%然后呢你不知道为什么飙高啊。你总不能直接跑去跟老板说老板CPU高了。老板肯定会问你那到底是为什么高所以今天这篇我们要往前再走一步。我们要把多条不同的时序数据同时喂给这个大模型。我们要让它帮我们做交叉分析。也就是看看这几个指标之间到底有没有什么勾连关系。一、 为什么单指标分析在实际中经常翻车1.1 老板的真实需求不是找异常点我们很多做技术的有个习惯。就是看到报警了赶紧去查指标。看到CPU报警了就盯着CPU的折线图看。看完了确认确实是高了就把这个截图发到群里。其实老板看到这个截图心里是没底的。他想要知道的不是“出了什么问题”而是“为什么会出这个问题以及怎么解决”。这两个东西差别很大。你光告诉他CPU高了这仅仅只是一个现象。现象背后的原因往往藏在别的地方。这就是单指标分析经常翻车的原因。你分析得很准确实找出了最高点在哪但是对解决问题毫无帮助。1.2 举个例子CPU高不一定是因为CPU的毛病那我们举个最常见的例子。你发现一台服务器的CPU使用率突然从20%飙到了90%并且持续了十分钟。如果你只看CPU这一条线你能猜出原因吗猜不出来的。因为导致CPU高的原因太多了。可能的情况是什么呢可能是内存泄漏了。内存泄漏了这是一个问题。那为什么会引起CPU高呢因为程序没有内存可用了它就会疯狂地触发垃圾回收机制也就是GC。这个垃圾回收动作本身是非常吃CPU的。所以表现出来就是CPU很高。还有一种可能。可能是网络流量突然被打满了。网络打满了之后大量的请求堆积在队列里。CPU得不断地去切换上下文去处理这些排队等待的线程。这样一来CPU也会被拉高。你看同样都是CPU高但是根因完全不一样。一个是内存的问题一个是网络的问题。如果你不把内存和网络的拉过来一起看你根本就无从下手。二、 多条数据怎么在代码里组织2.1 还是老办法自己造几份假数据既然要测交叉分析我们手里得有三份数据。分别是CPU使用率、内存使用率、还有网络流入流量。我们接着用上一次那个造数据的思路。不过这次我们要让这三份数据产生联动。我们要人为地制造一个“内存泄漏导致CPU高”的场景。打开你的代码编辑器我们把生成数据的函数稍微改复杂一点。importrandomdefgenerate_multi_metrics_data():cpu_data[]mem_data[]net_data[]base_time2023-10-24 10:00:foriinrange(100):time_strbase_timestr(i*60).zfill(2)# 默认正常状态cpu_valrandom.randint(20,30)mem_valrandom.randint(40,50)net_valrandom.randint(100,200)# 假设单位是MB# 制造联动异常从第50个点开始内存缓慢泄漏ifi50:# 内存一点点往上爬mem_val50(i-50)*2random.randint(-5,5)ifmem_val95:mem_val95# 到顶了# 当内存高到一定程度比如第60个点开始触发频繁GC导致CPU飙升ifi60:cpu_valrandom.randint(75,95)# 内存都在忙活GC了处理正常网络请求的能力下降网络流量反而跌了ifi60:net_valrandom.randint(20,50)cpu_data.append(f{time_str}, CPU使用率,{cpu_val}%)mem_data.append(f{time_str}, 内存使用率,{mem_val}%)net_data.append(f{time_str}, 网络流入流量,{net_val}MB)returncpu_data,mem_data,net_data你看这段代码我写了三个列表来存数据。重点在中间那个if i 50的逻辑里面。我先让内存从第50个点开始涨。它不是一下子暴涨是一点点爬。这很符合内存泄漏的真实表现。然后我加了个判断当内存涨到一定高度也就是到了第60个点的时候我让CPU跟着飙上去。同时我让网络流量掉下来。这就模拟了一个非常经典的故障链路。你把这段逻辑看懂了就知道我们等会儿要让大模型分析什么东西了。我们要看它能不能把这个“内存先涨然后CPU跟着涨同时网络掉下去”的先后顺序给理出来。2.2 数据的文本格式该怎么排版数据造好了下一个问题来了。我们有三组数据怎么拼成一个字符串丢给模型呢你不能把它们全混在一个列表里。比如第一行是CPU第二行是内存第三行又回到CPU。这样排布太乱了大模型看瞎了也找不出规律。通常来说我们要做分组。用一些明显的分隔符或者空行把不同指标的数据隔开。我们可以写一个专门的函数来干这个排版的事。defformat_multi_data(cpu_list,mem_list,net_list):# 把每个列表拼成多行字符串cpu_str\n.join(cpu_list)mem_str\n.join(mem_list)net_str\n.join(net_list)# 用大段的分隔符把它们隔开final_textf 第1组指标数据{cpu_str}第2组指标数据{mem_str}第3组指标数据{net_str}returnfinal_text你注意看这里我用了第X组指标数据这种很醒目的标题。然后在每组数据之间留了一个空行。为什么要这么干呢其实说白了就是在降低大模型的阅读负担。你把结构理得越清楚它就越不容易把内存的数据错看成CPU的数据。这个排版的工作本来应该是前端或者数据工程师做的现在在我们这个测试代码里只能自己手动拼。三、 提示词该怎么写才能引导它做交叉对比3.1 别只说“帮我分析一下”要给具体的对比方向数据格式化好之后就到了最关键的一步写Prompt。很多新手到了这一步就直接写“下面是三组数据帮我分析一下。”。你这么写大模型大概率会分别给你总结一下这三组数据各自的平均值和异常点。它不会主动去帮你找它们之间的联系。因为它没有接到“找联系”的指令。我们得把要求写得更具体一点。我们要明确告诉它我们要看时间线上的先后顺序。defbuild_cross_prompt(formatted_data_text):promptf 你现在是一个资深的运维专家。下面给你提供了同一台服务器在同一时间段内的三组监控数据。 格式是时间, 指标名称, 数值。 第1组是CPU使用率。第2组是内存使用率。第3组是网络流入流量。 请你仔细对比这三组数据在时间线上的变化趋势。不要孤立地看每一个指标。 你的任务是 1. 找出所有发生明显异常波动的具体时间点。 2. 重点分析这些异常点之间是否存在先后发生的关系。比如是不是A指标先变然后B指标跟着变。 3. 根据这种先后顺序推测一下最有可能的故障根因是什么。 数据如下{formatted_data_text}returnprompt你看我这段提示词。我先是给它设定了一个角色“资深的运维专家”。这个的话其实就是在约束它回答的口吻。不然它可能回答得像个教科书。然后我明确告诉它这三组数据分别是什么。接着我列了三个任务。特别是第二个任务我强调了“先后发生的关系”。这就是引导它去做交叉分析的核心指令。没有这句话它可能就只做横向对比不做纵向的时间轴追踪了。3.2 在示例页面先测一下提示词在用代码跑之前我强烈建议你先去这个页面试一下https://ai.timecho.com/realtime你可以手动复制几十行我们造的数据加上这段提示词扔到那个网页聊天框里。看看它怎么回。为什么要多这一步呢因为调接口是要消耗时间和额度的。如果你提示词写得不对你用代码跑一遍要等十几秒。你在网页上跑几秒钟就能看到结果。发现不对马上改提示词改到满意了再搬到代码里去。这其实是一个很实用的工作流。别一上来就死磕代码。先把业务逻辑和提示词在轻量级的环境里验证通了再写成自动化脚本。四、 改造代码把三组数据发出去4.1 把之前的单变量函数改成多变量前面的准备工作都做完了现在我们把主流程串起来。其实改动非常小也就是把原来调一个生成函数改成调三个然后拼起来。importrequests# 这里省略掉前面写的 generate_multi_metrics_data、format_multi_data、build_cross_prompt 这三个函数# 假设它们已经写在上面了defask_timecho_ai(question,api_key):urlhttps://ai.timecho.com/v1/chat/completionsheaders{Content-Type:application/json,Authorization:fBearer{api_key}}payload{model:timecho-model,messages:[{role:user,content:question}]}try:# 数据量变大了timeout给到60秒比较稳妥responserequests.post(url,headersheaders,jsonpayload,timeout60)response.raise_for_status()result_dictresponse.json()answerresult_dict[choices][0][message][content]returnanswerexceptExceptionase:returnf发生错误了{e}if__name____main__:my_keysk-你的真实KEY粘贴在这里print(正在生成三组联动假数据...)cpu_list,mem_list,net_listgenerate_multi_metrics_data()print(正在排版数据格式...)formatted_textformat_multi_data(cpu_list,mem_list,net_list)print(正在构造交叉分析提示词...)my_promptbuild_cross_prompt(formatted_text)# 如果你好奇拼出来的东西到底有多长可以把下面这行注释打开看看# print(my_prompt)print(正在请求TimechoAI接口数据量大请耐心等待...\n)final_answerask_timecho_ai(my_prompt,my_key)print( 多指标交叉分析结果 )print(final_answer)你对比一下上一篇的代码核心的请求函数ask_timecho_ai一点都没变。变的全都是外面的数据准备逻辑。另外注意看我把timeout从30秒改到了60秒。为什么呢因为这次我们发过去的数据量大概是上一次的三倍。大模型读的数据多了思考的时间肯定就长了。如果你还是给30秒很可能它刚想到一半你这边就强行掐断连接了。那你就只能收到一个超时的报错。4.2 跑一下看看它能不能找出“内存泄漏”这个假设现在你可以去运行这段代码了。去倒杯水等个半分钟结果就会出来。如果一切顺利你看到的结果应该会非常惊艳。它大概会给你返回类似这样的内容“经过对比三组数据在时间轴上的变化我发现了一个明显的先后异常链条首先在第50分钟左右10:50:00第2组指标内存使用率开始出现异常呈现出持续上升的趋势偏离了原来40%-50%的正常区间。接着到了第60分钟左右11:00:00随着内存压力的增大第1组指标CPU使用率突然从20%-30%飙升至80%以上。与此同时在第60分钟后第3组指标网络流入流量出现了断崖式下跌从100-200MB跌到了20-50MB。根因推测这是非常典型的内存泄漏导致的问题。内存先发生泄漏并持续增长。当内存水位达到一定阈值时触发了应用程序频繁的Full GC垃圾回收。GC过程会占用大量的CPU资源导致CPU使用率飙升。由于CPU被GC任务占满无法及时处理正常的网络I/O请求导致网络流入流量大幅下降。”你看它把我们在代码里埋的那个逻辑完完整整地给挖出来了。它不仅找出了三个异常点最关键的是它理清了“内存先变 - CPU后变 - 网络跟着变”这个时间顺序。如果你把这段分析报告发给老板老板一看就懂了。他会马上让开发去查是不是有内存泄漏的代码。这就是多指标交叉分析的价值。它帮你把散落的线索串成了一条完整的证据链。五、 如果它分析跑偏了怎么办5.1 大模型“瞎编”关联性的情况当然大模型也不是万能的。有时候你给它三组其实毫无关系的数据它为了完成你“找关联”的任务可能会硬编出一个逻辑出来。比如内存其实只是正常波动CPU也只是碰巧高了一下。它可能也会给你分析出一堆因果关系。这种情况在业内叫作“幻觉”。它不知道但是它装作知道。那怎么避免这种情况呢这就需要我们在提示词里加上限制条件。5.2 调整Prompt的技巧加入否定指令你不能光让它找你得告诉它如果找不到就直说。我们把刚才的build_cross_prompt函数稍微改几句话。defbuild_cross_prompt_safe(formatted_data_text):promptf 你是一个严谨的运维专家。下面是同一台服务器的三组监控数据。 请对比这三组数据在时间线上的变化。 注意只有当某个指标的异常明显发生在另一个指标异常之前比如相差两三个时间点以上并且逻辑上存在合理的因果关系时你才可以将它们关联起来分析。 如果三个指标的异常是同时发生的或者没有明显的时间先后顺序请不要强行建立因果关联只需分别列出它们各自的异常情况即可。 严禁在没有时间先后证据的情况下猜测根因。 数据如下{formatted_data_text}returnprompt你看这次我加了很多“只有当…才…”、“请不要强行…”、“严禁…”这样的词。这就是在给它上紧箍咒。你告诉它了必须要有时间差必须要逻辑合理。如果没有就老老实实分开报。这么一改它乱编的概率就会大大降低。写提示词其实就跟带新员工一样。你指令越模糊他干得越走样。你得把边界划得清清楚楚哪些能干哪些不能干它才能干好。六、 再聊聊Token消耗和成本的问题6.1 数据量翻倍Token也翻倍把三组数据丢进去效果是好了但是有一个很现实的问题我们躲不开。那就是钱。我们前面提到过Token的概念。你发过去的字数越多消耗的输入Token就越多。你要求它做复杂的交叉分析它生成的回答也会变长消耗的输出Token也就越多。三组数据每组100条。这就好几千个Token了。如果你要分析100台机器每台机器三组数据那你跑一次脚本消耗的Token量是非常惊人的。所以你在去 https://ai.timecho.com/settings/keys 这个后台看账单的时候一定要心里有数。不要写个死循环无限次地去调。一定要在代码里做好异常拦截避免发了无效的请求还在傻傻等。6.2 压缩数据文本的小技巧既然Token要花钱那我们能不能在不影响分析效果的前提下把发过去的文本缩短一点呢当然可以。你看我们现在的数据格式“2023-10-24 10:00:00, CPU使用率, 25%”这里面其实有很多废话。比如“2023-10-24”这个日期如果我们的数据都是在同一天的那这个日期部分就完全多余了。大模型又不需要知道今天是几月几号它只需要知道时间点的先后顺序。我们可以把格式简化成这样“00:00:00, CPU, 25”。你看省了多少个字符。如果是在同一个小时间段里比如都在10点到12点之间你甚至可以把小时去掉只保留分钟和秒“00分00秒, CPU, 25”。你别小看省下来的这几个字。乘上几百条数据再乘上三组指标省下来的Token可能就有上千个了。长年累月下来这也是不少钱。我们在代码里改一下拼接的逻辑就行了。# 极简版的数据生成foriinrange(100):# 只保留分和秒或者直接用序号代表时间先后time_labelf第{i}分钟cpu_data.append(f{time_label}, CPU,{cpu_val}%)# ...其他的类似这种极简格式大模型依然能看懂。它依然能根据“第50分钟”、“第60分钟”这种标签来判断先后顺序。但是你传输的成本就降下来了。这也是在实际业务里写代码必须要考虑的优化点。七、 总结与下期预告7.1 今天学到了什么核心逻辑今天这篇内容信息量比较大。我们解决了一个核心痛点就是怎么让大模型做关联分析。我们知道了单指标分析往往找不到根因。我们学会了在代码里造有联动关系的假数据。我们掌握了多组数据的排版技巧要用明显的分隔符把它们隔开。更重要的是我们学习了怎么通过写提示词里的具体要求去引导大模型关注“时间轴上的先后顺序”。我们还学了怎么加限制条件防止它乱编因果关系。最后我们也聊到了成本控制的问题。知道了可以通过简化时间戳的格式来压缩Token。这些其实都是干货。你把这套多指标交叉分析的代码跑通了你其实已经可以拿它去处理很多真实的运维报警了。你只要把造数据的部分换成你从真实数据库里查出来的数据它就能直接出报告。7.2 下一期我们玩点更高级的不过呢我们现在还是在自己造假数据玩。真实情况里数据都是存在数据库里的。比如IoTDB比如MySQL。总不能每次分析你都先写个脚本把数据导出来成txt然后再读进Python里去调接口吧。那样太繁琐了。所以在下一篇文章里我们打算引入真实的数据库查询。我们来看看怎么在代码里直接连上数据库把SQL查出来的结果直接扔给大模型。让整个流程变成一个全自动的闭环。这个的话就会涉及到一些数据库驱动安装的东西了。如果你对这一块感兴趣那就继续跟着往下看吧。我们下期见。
返回列表