业界常把 AIOps 的能力分成三层,从易到难:
第一层:可观测性增强(描述"发生了什么")
User {id} login failed),只关注新出现的或频率突变的模板。第二层:关联与定位(解释"为什么发生")
第三层:自动化处置(决定"怎么办")
一句话总结:AIOps 的价值不是替代运维,而是把运维工程师从"找线索"的体力活里解放出来,专注做决策。
1. 异常检测:别只用阈值
静态阈值的两个死穴:定高了漏报,定低了误报。工程上常用的是季节性分解 + 残差判定:把指标拆成趋势、周期、残差三部分,对残差设动态阈值(如 3σ 或分位数)。更省事的做法是用 EWMA(指数加权移动平均) 做基线,简单、可解释、对突变敏感。
2. 告警聚合:靠拓扑,不靠文本相似度
很多早期方案用"告警文本相似度"聚类,效果有限。真正有效的是利用服务依赖图:如果 A 服务调用 B、B 调用 C,而 C 的延迟异常同时引发了 A、B 的告警,那么 C 就是候选根因。拓扑是免费的、可靠的先验。
3. 根因定位:从"谁先异常"到"谁最异常"
最朴素也最常用的是时间先后 + 拓扑下游优先:在依赖图上,异常最早出现且位于上游链路最深处的节点,嫌疑最大。进阶做法是因果推断(如 PC 算法、Granger 因果)或基于图神经网络的 RCA 模型,但工程落地时,"时间 + 拓扑 + 变更记录"三者的启发式规则往往性价比最高。
4. LLM 的角色:别神话,用在"解释"上
大模型在 AIOps 里最现实的用法不是"预测故障",而是:把告警、日志、变更记录、历史工单汇总成一段人话的故障摘要,并推荐历史上相似的处置方案(检索增强 RAG)。这大幅降低了值班人员的信息消化成本,且失败代价低——说错了人还能自己判断。
下面用约 45 行 Python 演示核心链路:异常检测 → 告警聚合 → 基于拓扑的根因排序。逻辑简化,但结构完整。
from collections import defaultdict
import statistics
# ---- 1. 动态基线异常检测:EWMA + 残差判定 ----
def detect_anomaly(series: list[float], alpha=0.3, k=3.0) -> list[int]:
"""返回异常点下标。用 EWMA 做基线,残差超过 k 倍标准差即判异常"""
baseline, residuals, anomalies = series[0], [], []
for i, x in enumerate(series):
baseline = alpha * x + (1 - alpha) * baseline # 指数加权基线
residuals.append(x - baseline)
# 用中位数绝对偏差(MAD)抗离群,比标准差稳健
med = statistics.median(residuals)
mad = statistics.median([abs(r - med) for r in residuals]) or 1e-6
for i, r in enumerate(residuals):
if abs(r - med) > k * 1.4826 * mad: # 1.4826: MAD→σ 换算
anomalies.append(i)
return anomalies
# ---- 2. 告警聚合:同一拓扑子树内的告警合并为一个事件 ----
def aggregate_alarms(alarms: list[dict], parent: dict[str, str]) -> list[dict]:
"""alarms: [{service, ts, metric}], parent: 服务->上游服务"""
def root_of(svc):
while svc in parent:
svc = parent[svc]
return svc
groups = defaultdict(list)
for a in alarms:
groups[(root_of(a["service"]), a["ts"] // 60)].append(a) # 按根+分钟窗口聚合
return [{"services": list({a["service"] for a in g}), "alarms": g}
for g in groups.values()]
# ---- 3. 根因排序:异常最早出现 + 拓扑越深越可疑 ----
def rank_root_cause(group: dict, parent: dict[str, str], depth: dict[str, int]):
score = {}
first_ts = min(a["ts"] for a in group["alarms"])
for a in group["alarms"]:
svc = a["service"]
# 越早异常加分;在依赖图越深(越靠下游)加分
score[svc] = (1.0 / (1 + (a["ts"] - first_ts))) + 0.5 * depth.get(svc, 0)
return sorted(score.items(), key=lambda kv: -kv[1])
# 使用示例
series = [100, 102, 99, 101, 400, 380, 120, 101] # 某指标序列
print("异常点:", detect_anomaly(series))
parent = {"gateway": "web", "web": "api", "api": "db"} # 服务依赖:gateway→web→api→db
depth = {"gateway": 0, "web": 1, "api": 2, "db": 3}
alarms = [{"service": s, "ts": 1000 + i * 5, "metric": "latency"}
for i, s in enumerate(["db", "api", "web", "gateway"])] # db 最先异常
for svc, sc in rank_root_cause(aggregate_alarms(alarms, parent)[0], parent, depth):
print(f"{svc}: {sc:.2f}")这段代码体现了三个工程要点:MAD 抗离群(比 σ 稳)、按拓扑根聚合而非按告警文本、时间先后与拓扑深度联合打分。生产环境会在此基础上加入变更记录特征、历史工单检索和人工反馈闭环。
1. 数据质量决定上限。 指标采集缺失、日志格式混乱、Trace 采样率低,任何模型都救不回来。AIOps 项目应先把可观测性底座打牢,再谈智能。
2. 标注几乎不存在。 故障是小概率事件,"哪些告警是根因"极少有标签。因此要重视无监督方法 + 专家反馈闭环,把每次人工确认的根因沉淀为训练样本。
3. 误报比漏报更伤。 频繁误报会让工程师直接忽略 AI 建议,系统信任度一旦崩塌就很难恢复。宁可少报、报得准。
4. 处置自动化要极度克制。 自动重启、自动回滚一旦误判会造成二次故障。成熟做法是先"建议"、再"一键执行"、最后"小范围自动",逐步放开权限。
5. 可解释性是刚需。 运维人员不会盲目相信黑盒。所有结论都要能给出证据链:哪条指标、哪条日志、哪次变更支撑了这个判断。
AIOps 市场已经从"概念炒作"进入"务实落地"阶段。主流云厂商提供开箱即用的告警降噪与异常检测;垂直厂商在根因定位与故障复盘上做深;开源侧有 Prometheus + Grafana 生态、OpenTelemetry 标准,以及各类 RCA 研究项目。
大模型的加入是近两年最大的变量:它把"读日志、写总结、检索历史方案"这类过去靠人力的环节自动化了,让 AIOps 从"给运维看图表"升级为"给运维写结论"。但请记住——LLM 擅长解释,不擅长证明因果。根因定位的可信度仍要建立在数据关联与拓扑推理之上。
AIOps 的本质,是在"数据过剩"的运维现场重建注意力经济:把 200 条告警压成 1 个事件,把 10 个可疑服务排成 1 个根因候选,把 1 小时的排查压缩成 5 分钟的阅读。
它不追求全自动的"无人运维"——那既不现实也不安全。它追求的是让工程师更快地看见、更快地判断、更稳地处置。真正做到这一点的团队,靠的不是最花的模型,而是最扎实的可观测性底座、最贴合业务的拓扑先验,以及一条能把每次故障变成经验的人机反馈闭环。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。