用 GCN 做故障定位之前,先承认拓扑图里有些边没采到
服务图上,错误最多的节点往往最像故障源。但它也可能只是流量入口,把下游异常都接在了自己身上。图神经网络能利用邻居信息,却不能替我们补齐未采集到的依赖事实。
模型会沿着什么传播
GCN 原始论文讨论图结构上的半监督分类。把该思路用于运维时,节点特征、邻接关系和标签定义都要重新设计;论文任务的结果不是微服务根因准确率。
最常见的输入缺口有三类:采样漏掉低频调用,异步消息没有接成同步调用链,以及图版本落后于最近一次发布。没有观察到 A→B,至少存在“确实没有调用”和“调用存在但没采到”两种可能,不能都编码成确定的零。
2026年10月21日的 运维 Agent 上下文评估把拓扑与变更记录列为重要材料。借鉴它时,我更关心缺失信息怎样返回,而不是把厂商实验的分数贴到自己的模型上。
一个邻居聚合的反例
下面不是 GCN 训练代码,只用均值演示一件事:漏边会改变输入到分类器之前的表示。它完全使用 Python 3 标准库。
features = {'A': 0.2, 'B': 0.8, 'C': 0.1, 'D': 1.0} def aggregate(node, outgoing): neighbors = outgoing.get(node, []) values = [features[node]] + [features[n] for n in neighbors] return sum(values) / len(values) observed = {'A': ['B'], 'B': ['C']} with_missing_edge_restored = {'A': ['B'], 'B': ['C', 'D']} first = aggregate('B', observed) second = aggregate('B', with_missing_edge_restored) assert round(first, 2) == 0.45 assert round(second, 3) == 0.633 assert first != second print({'observed_only': first, 'with_extra_edge': second})这里的数值只是教学特征,不是概率,也不是线上异常分。实际 GCN 还有归一化、权重与非线性,不能把这个均值实现命名为“生产级 GCN”。例子的价值在于让拓扑敏感性变得可见。
评测应主动拆掉一些边
按事故与时间切分训练、验证集,避免同一次事故的相邻采样进入两边。然后分别测试完整拓扑、随机漏边、按采集器故障成片漏边、发布后旧图等情况。比较 Top-k 候选召回的同时,记录模型是否愿意输出“不足以定位”。
每个候选最好返回支持节点、边的来源、图版本及缺失范围。若加入一条未经核实的边就能让第一名剧烈翻转,应先提高调查优先级,而不是让 Agent 自动重启该节点。
本文没有训练 GCN、调用 PyG 或复现生产定位指标,只验证了聚合对输入边的敏感性。根因定位的第一层可靠性来自输入证据;模型层数再多,也不能把未知关系变成已发生的调用。