1. 告警风暴把我逼成了“人肉路由器”
1.1 原始告警链路的真实痛点
我在运维一线待了不少年头,最早接触的“告警分析”基本是这么个状态:监控平台每秒钟扫一遍指标,超过阈值就哐哐往外发告警,然后告警通知群就开始刷屏。白天还好,到了夜里大促或者版本变更窗口,那个消息滚动速度快得吓人。值班的人根本来不及逐条看,只能靠经验在脑子里快速分类:哪些是核心链路、哪些是老问题、哪些大概率是抖动、哪些需要立刻叫醒研发。
这套模式听起来没什么问题,毕竟有经验的人确实能处理。但问题在于“有经验的人”不够用。一个稍大一点的团队,核心服务几十个,依赖的中间件、数据库、缓存、消息队列加起来上百个,一个故障往往带出一片告警。像经典的数据库连接池被打满,下游所有服务都会报超时,瞬间几十条到上百条告警涌进来。值班同学第一反应不是分析,而是先“止血”——把服务重启、回滚、扩容,先把用户侧的影响压下去,再去翻日志找根因。
这个过程里,绝大部分时间花在了重复劳动上:在多个监控页面之间来回切换,人肉把不同资源的告警串成一条因果链路。做得多了我就想,这活儿其实没那么玄乎,很多步骤是固定的。既然步骤固定,能不能让AI来跑?
1.2 三个反直觉的观察
在真正动手之前,我先观察了一段时间的告警数据,然后发现了三个反直觉的现象。
第一个现象:告警数量多,不等于故障多。很多告警是同一个根因引发的“连锁反应”,比如一台物理机宕机,上面虚拟机的所有监控项都会告警,再加上依赖这台机器的下游服务,一次性可以生成几十条告警。但真正的根因就一个。
第二个现象:大量告警是“已知问题”的重复上报。基础设施层常有这种情况,某个磁盘降级了,运维已经知道要等硬件厂商来换盘,但监控是持续触发的,每隔五分钟来一条,纯纯的噪音。
第三个现象:根因分析高度依赖“关联关系”。单纯看一条告警根本看不出问题,你需要知道这个服务依赖了哪个数据库、调用了哪个下游接口、最近有没有变更记录。这些信息分散在CMDB、监控平台、日志平台、发布系统里,人肉去查非常耗时。
这三个观察直接决定了后面这个告警分析Agent的设计方向:它不能只做“告警摘要”,也不能只做“根因猜测”,它需要具备串联信息、交叉验证、输出结论的能力。而且它越熟悉历史故障案例,分析质量就会越高——这一点正好用上了RAG(检索增强生成)那套思路。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 这个告警分析Agent,本质上是“会查资料的实习生”
2.1 定位:不是全自动排障,是分析外脑
做这个东西之前,我给自己定了一个边界:它不是一个“全自动排障机器人”,而是一个“会查资料、会整理线索、会给出初步判断的分析外脑”。
为什么这么定位?因为全自动排障的风险太高了。故障场景下,任何基于错误判断的自动操作都可能放大影响。比如它把正在处理的故障节点误判为“负载过高”然后触发重启,如果这个节点其实是正常节点,重启它反而造成二次故障。所以在第一阶段,我只要求它做到“分析”,把结论和建议动作列出来,由值班人决定要不要执行。这个定位很重要,直接影响后面工具权限的设计。
2.2 五大核心模块分别管什么
按照告警分析这件事的实际流程,我把Agent拆成了五个模块。这里我把每个模块的职责和关键实现思路列出来,给想动手的同学一个参考。
信息接入模块(感知层)。负责接收告警平台推过来的webhook事件,把不同来源的事件数据统一成结构化格式。不同告警源的字段差别很大,Prometheus Alertmanager的字段、Zabbix的字段、云厂商监控的字段,全都长不一样。这个模块要做的第一件事就是标准化字段,至少包含:告警名、严重级别、资源标识、时间戳、标签列表、原始描述。
状态管理模块(记忆层)。Agent需要记住“当前在处理哪个故障”、“已经查过哪些信息”、“候选根因有哪些”,不能每查一步都从头再来。这里我参考了Agent框架里的State模式,用一个事件对象保存整个分析过程的上下文。这个模块在复杂故障场景下尤其重要,因为一次分析往往要跨很多步。
工具调用模块(执行层)。查指标、查日志、查CMDB、查变更记录,都是一个个独立工具。Agent通过函数调用的方式按需使用它们。这是整个Agent最核心的部分,后面我会专门展开。
分析推理模块(大脑层)。大模型承担主要的推理任务,但我会在提示词里强制要求“先列证据,再下结论”。同时接入了知识库RAG,把历史故障复盘文档、告警处理手册、架构说明文档切成片段灌进向量库,分析时检索相关内容作为参考。
输出与反馈模块(表达层)。分析结论不能是一大段纯文本,那样下游没法处理。我要求模型按固定的JSON结构输出,包含:结论摘要、关键证据、可疑根因列表(带置信度)、建议动作、风险提示。推送渠道可以是企微、钉钉或者工单系统。
2.3 为什么是Agent而不是普通的大模型问答
可能有人会说:我把告警丢给ChatGPT问一句“这是什么原因”不就行了?我最初也这么试过,效果非常拉胯。
原因很简单:告警分析是一个多步骤、强依赖信息的任务。你问模型“这个告警怎么回事”,它没有能力自己去查Prometheus,也没有能力去翻你内网CMDB。它只能基于你给它的那句告警描述瞎猜。而真实的故障分析需要动态获取信息:看到告警A,去查一下关联服务B的指标,发现B的CPU也高,又去查B最近有没有发版,发现凌晨两点刚上线了一个新功能。这一连串动作没法靠一次问答完成。
Agent的价值就在于它具备了“循环执行”的能力:根据当前目标,规划下一步动作,调用工具拿结果,把结果反馈给模型继续分析,直到收敛出结论。这正好解决了告警分析里最耗时的一个环节——多系统之间的信息串联。而且Agent的每一步Tool Call都有记录,出了问题可以回溯,这一点对后续做审计和复盘非常重要。
3. 让Agent“干活”的四个高频场景
3.1 告警收敛:把20条告警合并成1个结论
告警收敛是我最先实现的场景,也是效果最立竿见影的一个场景。它解决的就是前面提到的“告警风暴”问题。
传统做法是基于规则去做告警聚合,比如按资源ID分组、按告警名分组。规则的问题是太死板,两批告警明明有因果关联,但资源ID不一样,规则就聚不到一起。Agent的做法是语义级收敛。它会把一批时间窗口内的告警事件全部拉出来,结合CMDB的依赖关系判断它们之间的关联,再把同一根因下的所有告警合并成一条“告警簇”,生成一个整体的分析结论。
举个例子,我收到过一批这样的告警组:api-gateway服务的P99耗时飙升、order-service的调用失败率上涨、redis-cluster的主节点连接数打满、还有若干“磁盘使用率超过80%”的边缘告警。交给Agent后,它会先去查依赖关系,发现api-gateway和order-service都强依赖redis-cluster,而磁盘那几台机器跟这条链路没有直接关系。于是它把前三类告警聚成一个根因候选组,把磁盘告警单独标记为“无关告警”。最后输出结论:当前最可能的根因是redis主节点异常或连接瓶颈,建议优先检查redis的慢查询、内存淘汰策略和最近是否有配置变更。
整个过程从收到告警到生成报告,大概30秒到1分钟。以前这活儿至少要让一个经验比较丰富的人花五分钟以上来梳理,还未必梳理得这么全面。收敛之后,值班同学看到的告警从20条变成了1条,附带的分析报告里有完整的证据链。
3.2 根因假设生成与验证:以order-service错误率突增为例
告警收敛只是第一步,真正让Agent产生价值的是“根因假设生成与验证”。这点我用一个真实的模拟场景展开说,方便大家理解它内部做了什么工作。
假设Prod环境突然触发了一条“order-service错误率超过5%”的告警。Agent收到后会执行这么一串动作:
第一步,扩展事件上下文。从CMDB拿到order-service的拓扑信息:它依赖mysql-order库、redis-cluster、kafka的order-topic,还依赖一个外部接口pay-callback。同时去发布系统查了一下,昨晚22点整order-service v2.3.1刚发过一版。
第二步,交叉查询指标。查Prometheus发现order-service的错误率是22点10分开始上升的,QPS没有明显变化,说明不是流量突增;CPU和内存正常,排除资源瓶颈;但Redis的慢查询计数同时段上涨了3倍。
第三步,拉取日志验证。在日志平台检索order-service日志,发现大量“redis command timeout”错误,慢查询里正好有对应的KEYS命令。这个信息非常关键,它指向一个很经典的坑:Redis因为有大量带前缀的key未清理,某个代码路径在启动时执行了KEYS模糊匹配,直接打崩了Redis。
第四步,生成结论。Agent给出的根因排序是:Redis慢查询导致调用超时(置信度高)、v2.3.1版本代码引入的缓存查询逻辑变更(置信度中等)、外部依赖pay-callback变慢(置信度低)。它没直接说“就是Redis的问题”,而是把证据链和候选根因全部列出来,让值班同学判断。
这个场景里,Agent做的事本质上是把“老运维的排查路径”复刻了一遍:看拓扑、看指标、看日志、查变更,然后结合经验给结论。而且它比人强的一点是,人同时只能盯一个页面,Agent可以并行调多个工具,速度要快得多。
3.3 值班群里的“AI接线员”
第三个场景我没想到会这么受欢迎——值班群自动响应。先别急着否定这个场景,它不是用来回“收到”这种废话的,而是用来处理高频重复问答的。
实际情况是这样:告警一旦推到值班群,必然有人问“这个告警严重吗?”“影响哪些业务?”“有没有对应的负责人?”“之前遇到过类似问题吗?”这些问题如果靠值班人回答,一个故障高峰期能消耗大量精力。我把Agent接进群之后,它收到新告警会主动发一条结构化卡片:影响范围、关联服务、根因分析结论、建议动作、负责人标签。群里再有人追问,Agent会根据已有信息继续回答,直到发现自己解答不了,才会at真正的值班人。
后来我把这个场景又延伸了一下,做了一个“历史告警查一查”功能。群里有人发“上周五那个MySQL告警最后怎么解决的?”,Agent会自动去知识库检索历史故障单,把处理过程和最终结论返回给提问者。这个功能上线后,群里的重复提问肉眼可见地变少了。
3.4 变更后的观察期巡检
第四个场景相对小众,但我觉得很有代表性:变更后的观察期巡检。每次版本上线或者配置变更后,运维通常需要盯一段时间的核心指标,观察有没有异常。这个工作非常枯燥,而且人不可能全天盯着一堆图表。
我的做法是:Agent在变更单的状态变为“已完成”后,自动触发一个观察期巡检任务。它会每隔两分钟检查一次关联的核心指标,包括服务错误率、P99延迟、系统资源占用、下游依赖健康状态。如果检查通过,就静默不打扰;如果发现异常,它会先跟变更内容做关联分析,判断异常是否可能由变更引入,再输出一条带结论的告警。我实际用过之后觉得,这个场景适合处理“凌晨发版后早上起来才知道出问题”的尴尬情况,至少能提前两三小时发现问题。
4. 落地链路:从告警平台进来到结论出去
4.1 数据接入与事件结构化
有人可能会问,Agent这么能查,那它平时是不是跑在每个服务的旁边?并不是。我采用的是中心化部署方式:告警平台统一往Agent服务推送事件,Agent服务再按需调用各系统的只读API。
在告警接入的标准化环节,我造了一个通用事件结构,长这样:
json复制{
"alert_id": "alert_303910",
"alert_name": "APIErrorRateHigh",
"severity": "P1",
"status": "firing",
"start_time": "2025-06-14T22:10:00+08:00",
"resource": {
"type": "service",
"id": "svc-order",
"name": "order-service",
"namespace": "prod"
},
"labels": {
"cluster": "prod-main",
"instance": "10.20.31.15"
},
"summary": "error_rate 5.2%, threshold 5%"
}
不管来源是Prometheus还是Zabbix还是自研监控,先统一转成这个结构再进Agent。这个步骤不要省。字段不统一的话,后面的提示词模板、工具调用、结论生成都会出问题。
4.2 上下文构造:为什么不能把原始告警直接丢给大模型
很多人第一次做告警分析Agent,最容易犯的错就是把原始告警文本和一堆关联数据一股脑塞进大模型提示词里。结果就是模型输出一堆正确但无用的废话,甚至被无关告警带偏。
我在上下文构造上花了不少功夫,核心原则是“去噪、分级、压缩”。告警原文中很多字段没有分析价值,比如监控节点的IP列表、告警通道信息、标签里的内部编码,这些如果不加处理会干扰模型注意力。我先把这些字段过滤掉,再把真正有用的信息组织成三个层级:第一层是当前故障的基础信息,包括告警名、服务名、开始时间;第二层是动态查询到的关联数据,这一步是Agent在分析过程中逐步获取的;第三层是历史参考案例和处置文档,通过RAG检索得到。
这样构造出来的上下文,模型看到的不是一坨原始数据,而是一个有结构、有重点的分析素材包。效果差距非常明显,输出质量直接上了一个台阶。
4.3 Agent内部规划-执行-验证循环
Agent的推理主循环采用“规划-执行-验证”模式,我简称为PEV循环。这个循环在代码里的结构大概是:
python复制while step < max_steps and not finished:
plan = planner(context) # 根据当前context决定下一步动作
if plan.action == "call_tool":
result = execute_tool(plan.tool, plan.args)
context.add_tool_result(plan.tool, result)
verifier(context) # 检查这次结果是否合理
elif plan.action == "conclude":
final_report = generator(context)
finished = True
step += 1
关键点在于循环的终止条件。我不希望Agent在简单的告警上绕来绕去,耗费大量token和时间。所以我会给每个任务设置最大步数,一般是8到10步,超过就强制生成阶段结论:宁可给一个“初步判断+待确认项”,也不让它在故障场景里无限循环。
另一个细节是工具调用超时。Agent去查指标或查日志,如果外部系统本身响应就慢,会让整个分析链路阻塞。我给每个工具调用都设了超时时间,一般指标查询8秒、日志检索15秒,超时后返回“工具不可用”,模型会换一个路径继续分析。
4.4 输出与后续动作
分析结论的输出我上面提过,用JSON结构化。这里放一个示例:
json复制{
"summary": "order-service错误率突增,根因大概率是Redis慢查询导致调用超时",
"confidence": 0.82,
"impact_scope": ["order-service", "api-gateway", "依赖order-service的B端接口"],
"evidence": [
"error_rate从22:10开始上升,QPS无明显变化",
"redis-cluster慢查询同时段上涨3倍",
"日志中出现大量redis command timeout",
"昨晚22:00有v2.3.1版本发布"
],
"root_causes": [
{"cause": "Redis慢查询导致调用超时", "confidence": 0.85},
{"cause": "v2.3.1缓存查询逻辑变更", "confidence": 0.45},
{"cause": "外部依赖pay-callback变慢", "confidence": 0.2}
],
"suggestions": [
"优先排查Redis慢查询,检查是否存在KEYS命令",
"review v2.3.1版本中缓存查询相关代码改动",
"若影响严重,可考虑紧急回滚到v2.3.0"
],
"risk_flags": ["建议在业务低峰期执行验证操作"]
}
这个JSON会直接推送到值班群和工单系统。如果场景允许,Agent还可以自动创建一个故障单,把报告内容附带进去,省去值班人手工录入的时间。
5. 踩坑最集中的三个地方:上下文、权限、幻觉
5.1 上下文越长,推理越飘
我在测试阶段犯过一个很典型的错误:为了让Agent“看到更多信息”,我把关联服务的指标查询结果、日志片段、配置信息全部塞进上下文,结果模型的推理质量反而下降了。这个现象在技术圈叫“上下文过载”,信息太多时模型会把一些细枝末节的异常当成重点,甚至忽略关键告警。
后来我做了两件事。第一,给上下文设置了“摘要层”,长日志和时序指标先做一次本地预分析,只把统计特征(例如“错误日志中Redis timeout占比62%”“错误率在22:10到22:20间呈线性上升”)传给模型,其他原始数据留作证据存储在上下文外围,需要详细复核时再取。第二,把历史RAG检索结果控制在3到5条以内,只保留跟当前故障最相关的案例,避免知识库内容喧宾夺主。
效果立竿见影,尤其是在多根因场景下,模型的判断明显更稳定了。
5.2 工具权限要按“只读优先”设计
这个原则是我一直强调的:Agent的权限要按“只读优先”来设计,写操作必须加锁。具体来说,Agent能调用的是查询类工具:查指标、查日志、查CMDB、查变更记录、查历史故障单。它不能调用的东西包括:重启服务、发布版本、变更配置、执行SQL、删除资源。这些写操作要么完全不开放,要么必须通过人工审批。
我在工具注册层做了一个简单的权限标注:
python复制TOOLS = [
{"name": "query_metrics", "type": "read"},
{"name": "query_logs", "type": "read"},
{"name": "query_cmdb", "type": "read"},
{"name": "query_change", "type": "read"},
{"name": "create_incident", "type": "write", "require_approval": True},
]
所有写操作在执行前都会经过一个审批路由,推到值班人手机上确认。目前阶段,我连“自动拉群”这种轻量动作都设置了审批,宁可麻烦一点,也不能让Agent在运维体系里变成一个潜在大权限的“内鬼”。等以后模型能力更强、验证充分了,再逐步放开也不迟。
5.3 幻觉治理:让模型先把证据链列出来
做技术的人都比较烦“AI一本正经胡说八道”。在告警分析这种场景里,幻觉的代价非常高:如果模型给出一个错误的根因,值班人照着排查,耽误了真正的故障处理时间,这个责任谁都担不起。
我治理幻觉主要靠三条。第一条是提示词强制约束,要求模型在输出最终结论前,必须列出它依据的证据,证据来源要精确到具体的查询工具和查询结果,没有证据支撑的猜测必须标明“无证据,推测”。第二条是置信度分级,根因判断必须在同一个root_causes数组里带置信度字段,模型对自己的判断有数。第三条是事后验证,重要结论如果有关联工具,Agent会自动再查一次进行复核。举个例子,它说“Redis慢查询是核心问题”,会再去查一下慢查询命令的统计结果,确认一下占比,证据确实存在才会写进高置信度列表。
通过这三条,现阶段Agent的“谎报军情”明显减少,大部分情况下它给出的结论都有据可查。即使最终判断有偏差,值班人也能根据证据链快速纠正方向。
6. 效果评估:我用这四个维度衡量它值不值
6.1 准确率怎么定义才合理
很多人一上来就问我“告警分析准确率多少”,这个问题本身就很难回答。告警分析不是非黑即白的分类题,它是一个多选加排序的排序题。所以我评估时不只看“结论是不是最终根因”,还看四个维度。
第一是收敛率:同一批次原始告警中,能被Agent有效合并的比例。第二是根因命中率:Agent给出的Top 1根因,跟事后人工复盘确定的根因是否一致。第三是证据完整率:Agent输出的结论里,是否每条关键判断都有对应的证据来源。第四是处理时效:从告警触发到Agent输出可用结论的耗时。这四个维度合起来,才能比较全面地反映Agent的实际作用。
6.2 实测中真正改善的数据
我用自己维护的这个Agent跑了大概两个月时间,记录了一些效果数据,供大家参考。首先是告警收敛率,实验环境下可以达到70%到80%,也就是说原始100条告警,Agent最终合并成20到30条有分析价值的结论。生产环境的收敛率会低一些,在60%左右,因为生产环境故障模式更复杂,很多告警确实相互独立。
然后是根因命中率。对于高频的典型故障,比如数据库连接池打满、Redis慢查询、磁盘空间不足这类,Top 1根因命中率能做到70%以上。但对于跨团队、多依赖、需要很深业务知识才能判断的故障,命中率会掉到50%以下。
处理时效方面,简单告警的分析从触发到出报告大概在30秒到1分钟,复杂故障也基本控制在3分钟以内。这个速度虽然比不上规则引擎的秒级,但考虑到输出的是一份带证据链的分析报告,已经是很大的效率提升。
6.3 哪些地方用起来并不顺手
我也要坦诚说一些“并不顺手”的地方。最大的是知识库更新的滞后性。Agent的RAG效果非常依赖过去沉淀下来的历史故障复盘文档。我这边团队之前对故障文档维护得不是特别规范,导致前期Agent经常会检索到过时或者不完整的分析案例,反而影响判断。后来花了两周时间专门把近两年的故障单重新整理打标,效果才稳定下来。
其次是大模型推理的token成本比预期高。一次复杂故障的完整分析,可能消耗几十万token,累积下来是一笔不小的费用。后来我做了模型分级:用轻量模型做告警收敛和摘要生成,用更强大的模型做根因分析,成本下降了大概一半,效果基本没变。
7. 现阶段的使用建议与往后扩展
7.1 适合先落地的三件事
如果你也想做类似的告警分析Agent,我的建议是先挑这三件事落地。
第一,告警收敛与降噪。这个场景规则简单、收益明显、风险低,是最适合试水的方向。先让Agent把重复告警和同源告警合并,验证效果后再扩展。
第二,历史故障知识问答。把近一年的故障复盘文档整理干净,接入RAG,做一个“告警知识问答”机器人。这个做起来比较快,而且能立刻解决群里重复提问的问题。
第三,变更后观察期巡检。如果你的发布系统有比较完整的变更单流程,可以先把Agent接在变更单上,上线后自动盯一段时间的核心指标。这个场景边界清晰,不容易出大乱子。
7.2 暂时不建议交出去的事
我要明确说,以下这些事暂时不建议交给Agent去做。第一是直接执行运维操作,尤其是重启、回滚这种高危动作。第二是涉及跨团队审批的决策,比如判定哪个团队应该为故障负责、是否需要动线上配置。第三是需要“拼人品”的复杂判断,比如某些故障现象看起来像A但实际上是B,这种时候模型的判断只能作为参考,不能作为最终依据。
这个阶段我建议把Agent定位成“人机协作”中的一个加强节点,而不是替代决策者。它处理结构化的、有明确路径的任务,人负责最终拍板。等运行几个月积累足够多的正反样例,再逐步提高它的自主度。
7.3 我的下一步计划:从“分析Agent”走向“执行Agent”的谨慎尝试
这个项目做到现在,我最深的体会是:Agent在运维领域的价值不在“自动做多少事”,而在它把人的精力从重复劳动里解放出来,让人可以专心处理真正需要判断力的事情。
下一步我计划分三步走。第一步,继续补全和优化知识库,把生产环境的告警处理手册和SOP都结构化管理起来。第二步,尝试在低风险场景下做“建议动作的一键执行”,比如磁盘清理、扩容这类操作,通过工单系统走审批后自动执行。第三步,探索故障自愈的雏形,比如在确认是某类已知且安全的问题后,自动触发预定义的重试或隔离动作,但这一步我会非常谨慎,必须有完善的熔断和回滚机制才会考虑上线。
就我个人来说,做这个Agent最大的收获不是代码写了多少,而是重新梳理了一遍“告警分析”这件事本身的流程和边界。AI帮你干活的前提,是你得先清楚活应该怎么干。这句话放到运维领域,比任何技术细节都有用。
