ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

AIOps告警归因实战:用提示工程让大模型替你做根因分析

AIOps告警归因实战:用提示工程让大模型替你做根因分析 做 AIOps 告警归因这件事最魔幻的地方在于你明明知道根因就在一堆监控数据里但人眼根本扫不过来。尤其是大促、故障演练、依赖服务抖动的场景一晚上几百条告警靠值班同学一条条看等定位到问题往往已经过去十几分钟。所以当大模型能理解上下文之后我第一时间就想让 LLM 去读告警和指标替人做第一层归因。这个方向听起来很顺真正落地却是一个“从能用到可上生产”的过程我把它拆成 4 个阶梯跑通、能用、能扛、可上生产。这篇文章就把每个阶梯要解决的核心问题、具体做法和踩过的坑一次说清楚。1. 先把问题说清楚告警归因为什么需要提示工程1.1 AIOps 告警归因真正难在哪AIOps 这个词已经被喊了很多年落到告警归因这个具体场景本质上是做一件事把一条或者一组告警结合系统当前的状态数据推断出最可能的原因。听起来不复杂但真正在运维环境里跑起来困难来自三个层面。第一告警本身只是“果”不是“因”。一条“数据库连接池耗尽”的告警根因可能是慢 SQL 堆积可能是上游服务调用量突增也可能是某个节点宕机导致连接分布不均。告警文本里只写了现象没有因果链必须结合指标、日志、拓扑、变更事件才能判断。第二数据维度太多且格式异构。同一时刻可能有时序指标、文本日志、链路追踪、配置变更、发布记录、工单历史。传统规则引擎擅长处理结构化的固定模式但要同时把这些维度揉在一起做综合判断规则会膨胀到无法维护。第三故障形态是动态演进的。今天遇到的可能是缓存雪崩明天可能是 DNS 解析异常后天可能是代码发布引入的慢接口。专家规则能Cover 住已知问题但遇到没见过的组合就失灵了。这也是我后来选择用大模型做告警归因的初衷它不需要针对每种故障单独写规则而是靠语义理解和跨维度推理来适应动态环境。1.2 为什么是这个场景先用到提示工程而不是直接微调很多人会问既然大模型这么强为什么不直接用故障数据微调一个专属模型我的实际经验是提示工程的投入产出比远高于微调尤其是在告警归因这个场景。原因是告警归因的知识更新频率非常高。故障模式会随着系统架构变化、代码发布、依赖变更而不断变化如果用微调意味着每次出现新型故障都要整理数据集、重跑训练、做评估、发布模型周期至少以周计。而提示工程只需要调整提示模板、更新 few-shot 示例、补充检索到的历史故障案例分钟级就能完成一轮迭代。另一方面提示工程天然具备可解释性。我可以在提示里明确要求模型“必须引用给定证据里的编号”这样输出的归因结果是可溯源的。微调模型更像一个黑盒出了问题很难说清楚它为什么给出这个结论。在运维生产环境归因结果要给人看、要进工单、要支持复盘可解释性比什么都重要。但也要泼一盆冷水提示工程不等于“把问题丢给模型”。它解决的是“具备理解能力的模型如何被可靠地约束在运维任务里”这件事核心工作是做上下文工程、输出约束和稳定性兜底。这也是后面四个阶梯要展开的内容。2. 第一阶梯能跑通单条告警与第一个提示词2.1 先定义任务边界别让模型自由发挥第一阶梯的目标只有一个让模型面对一条告警时能给出看起来合理的归因结果。这个阶段不追求准确率高也不追求覆盖全场景重点是确认“大模型理解运维上下文”的路径是通的。很多人第一步就做错了直接把告警原文丢给模型然后问“根因是什么”。模型确实会回答但答案往往是一段华丽的废话比如“可能是数据库连接池耗尽导致的建议检查数据库配置”没有结合任何实际证据等于没答。我在一开始就把任务边界定义得比较死模型要基于给定的告警内容、相关指标摘要和变更信息输出一个结构化的归因结论包括根因假设、支持该假设的证据、置信度和建议检查项。明确要求模型“只能基于提供的信息进行推理”不能引入外部知识或凭经验猜测。这个边界意识是整个提示工程的基石。2.2 第一版提示模板长什么样下面是我当时用的第一个可工作的提示模板虽然粗糙但结构已经成型。你是一名资深 SRE 工程师负责线上系统故障的初步归因分析。 请基于以下告警信息和上下文数据分析这次告警最可能的根因。 【告警信息】 告警标题{title} 告警内容{message} 发生时间{time} 影响对象{entity} 【上下文数据】 {evidence} 【分析要求】 1. 只能基于上面提供的信息分析不得引入未提供的信息。 2. 如果信息不足以判断根因请明确输出“证据不足”。 3. 输出格式为 JSON { root_cause_hypothesis: 根因假设, supporting_evidence: [证据1, 证据2], confidence: 0.0~1.0, next_actions: [建议检查项1, 建议检查项2] }这个模板放到今天看有不少问题但它的核心价值在于定义了三个关键要素角色、任务、输出约束。角色让模型使用运维专家的语气和思维模式任务明确要求做“初步归因分析”而不是“下最终结论”输出约束保证了结果可以被程序解析。2.3 这个阶段最容易踩的坑模型在“复读告警”第一阶梯测试时我印象最深的问题不是模型答错而是模型用告警标题的原文充当根因假设。例如告警写着“CPU 使用率超过 80%”模型的 root_cause_hypothesis 也是“CPU 使用率超过 80%”supporting_evidence 更是直接复制告警内容。模型其实没有做任何推理它在复读。原因是上下文里只有告警本身没有额外的指标变化趋势、没有相关联的服务状态模型根本无从推断所以它聪明地选择了“最安全”的输出来应付你。这个阶段解决不了这个问题的根本层面因为单条告警的信息量确实不够。但这个阶段证明了另一件事只要把输出格式约束成 JSON解析和下游处理就不会有问题后续能把更多上下文喂进来就意味着归因从“复读”进化为“推理”。3. 第二阶梯能用让模型看到足够多的上下文3.1 告警归因需要的证据链包含哪些维度从“跑通”到“能用”核心变化是上下文从“一条告警”变成“一套证据链”。AIOps 的价值恰恰在这里监控系统里不是没有数据而是数据散落在不同系统没人把它们串起来。提示工程要做的就是把这些数据串成一条模型能读的证据链。我整理了一个标准证据链模板包含五个维度告警本体标题、内容、级别、发生时间、涉及实体。时序指标告警对象及其依赖项的 CPU、内存、延迟、错误率、QPS 等重点关注告警前后 30 分钟的变化。日志摘要从相关服务的日志中提取异常片段用日志关键字聚类而不是把原始日志全部塞进去。变更事件发布、配置修改、扩缩容、开关切换等因为大量故障都是由变更触发的。历史相似故障从工单系统或故障库中检索到的类似 case作为参考依据和 few-shot 示例。这个证据链不是一开始就全都做好是逐步补全的。最开始我只接入了指标和告警本体日志和变更后补。但每多一个维度归因的准确率都有明显提升尤其是变更事件很多时候模型给出的根因就是一次发布引起的错误率抖动。3.2 上下文组装规范不是把所有数据都塞给模型有了数据源之后第二个关键问题是怎么组装上下文。刚开始我犯过一个典型错误把告警关联的所有指标、日志、链路数据全部拼进提示词结果 prompt 超过 2 万 token模型开始“一本正经地胡说八道”把不相关的数据也当成证据。后来我总结了一套上下文组装规范时间窗控制只保留告警前 30 分钟到告警后 5 分钟的数据更早的数据与本次故障相关性极低。指标排序按“偏离基线程度”排序变化最大的指标排在最前面因为它最可能是诱因。日志裁剪只保留异常级别为 ERROR/WARN 的日志并按关键字去重再加一行“共捕获 N 条异常日志”的统计摘要。实体关联优先展示告警对象本身的指标再展示其下游依赖和上游调用方的聚合指标避免全链路数据一股脑涌入。组装规范的核心思想是“让模型把注意力放在最可能相关的证据上”。你可以把它理解成给模型画重点重点越清晰幻觉越少归因越准。这个阶段我花的时间最多但收益也最大。3.3 引入历史故障库RAG 做少样本检索当上下文规范稳定之后我加入了 RAG 流程目的是给模型提供“历史相似故障”作为参考而不是让它每次从零推理。具体流程是每次收到告警先从故障历史库中检索最相似的 2-3 个历史 case把每个 case 的“故障描述、最终根因、处置措施”写入提示词的 few-shot 示例区。检索方式开始用的是简单的关键词匹配后来换成了向量检索效果更稳定。这里要注意few-shot 示例的质量比数量重要。示例必须满足三个条件和当前告警足够相似、根因是经过人工确认的、处置措施有效。如果示例本身是错的模型会模仿错误答案危害很大。所以我会在提示里明确标注“以下示例为历史已确认结论仅供参考不代表当前告警的根因”。加入 RAG 之后一个很明显的改观是模型输出的 next_actions 不再是空泛的“检查数据库”而是能说出“参考历史 case #xxx建议优先查看订单服务在 14:00 的发布变更”。这种输出已经可以直接发给值班同学参考了。3.4 用 JSON Schema 约束输出让程序能稳定消费第二阶梯的另一个重要工作是输出结构化。第一阶梯只靠提示词要求 JSON 格式但这个阶段的输出已经要被下游系统消费容不得字段名随意变化。我开始使用 JSON Schema 对输出做严格约束并在提示词里附带 schema 说明让模型严格遵循。一个典型的输出结构是{ alarm_id: string, root_cause_type: error_ratio | resource_saturation | dependency_failure | configuration_change | network_issue | unknown, root_cause_candidate: string, evidence_chain: [ { evidence_id: string, evidence_type: metric | log | change | history, content: string } ], confidence: number, evidence_insufficient: boolean, next_actions: [string] }这个 schema 里有几个字段是后来实践证明特别重要的。evidence_chain 要求模型每给出一个根因结论必须列出支撑它的证据 ID这样下游可以回溯evidence_insufficient 是给模型一个体面的“不知道”出口confidence 用于后续人工队列排序。通过结构化约束归因结果从一开始的“自然语言段落”进化为“可编程对象”这为后面的稳定性工程打下了基础。4. 第三阶梯能扛稳定性和反幻觉设计4.1 告警风暴场景下的输入压缩到第二阶梯单条告警的归因质量已经能接受但一遇到故障高峰期就露馅。最典型的是告警风暴同一时间几十条甚至上百条告警同时进来如果每条都做完整归因首先上下文组装就要查很多次数据库其次是这么多 prompt 并发调用大模型延迟和成本都撑不住。解决思路不是提升并发而是先做“告警压缩”。我会在归因服务前面加一层聚合逻辑把同一实体、同一时间段、疑似同一根因的告警归并成一个告警组再对组做统一归因。比如“订单服务错误率升高”和“订单服务 P99 延迟升高”很可能同源如果分开归因模型会被误导合并之后反而信息更完整。同时上下文组装也要压缩。告警风暴时指标和日志会指数级增长必须做两层处理指标只保留 Top 5 变化量最大的日志先用聚类算法提取出 3-5 类异常模板。这样即使系统异常数据再大喂给模型的上下文也能控制在一个稳定范围。4.2 从“能说”到“不乱说”反幻觉策略告警归因场景里幻觉比答错更可怕。答错还能靠人复核发现幻觉——尤其是看似合理、实际虚构的因果链——会直接把人带偏。我在第三阶梯做了几个强硬的反幻觉设计。第一提示词中反复强调推理边界。我会写明“只能使用【上下文数据】中提供的证据进行推理禁止推测未提供的信息禁止使用训练阶段获得的知识推断当前系统状态”。第二要求证据引用可校验。所有结论必须对应 evidence_id程序侧会检查模型引用的 ID 是否真实存在于输入上下文中如果引用了不存在的 ID直接判为无效输出。第三给模型一个“拒绝权”。当上下文中没有足够证据时模型应输出 confidence 小于 0.3 且 evidence_insufficient 为 true 的结果而不是硬凑一个根因。这个设计一开始很多人不理解觉得“模型说不知道那还要它干嘛”但实际上线后正是这个兜底设计避免了大量错误归因。模型采样的温度也直接设为 0同时在调用层固定随机种子尽量让同一输入每次输出一致。虽然不会绝对消除随机性但明显减少了无意义的输出抖动。4.3 稳定性建设超时、重试、降级与缓存生产环境里大模型调用不是一个稳定服务它可能超时、限流、报错。如果归因服务在这些情况下拖垮了整个告警链路那就本末倒置了。我在工程架构上做了几层保护。超时控制单次模型调用设置 10 秒超时宁可返回“归因超时未完成”也不阻塞告警通知。重试退避对可重试错误如限流、5xx做指数退避重试最多两次防止雪崩。降级开关当模型服务连续失败或响应质量下降时自动降级为规则引擎输出“暂无法归因请人工处理”并附带原始告警信息。结果缓存对相同告警内容的重复归因做缓存TTL 5 分钟减少重复调用。有一个原则我一直守着归因服务应该是告警处理的“增强层”而不是“关键路径”。告警触达值班人员永远不能被归因服务阻塞归因结果只是附加内容有就参考没有也不该影响告警本身的处理。4.4 成本和模型选型的现实问题用大模型做每一条告警归因成本不能不算。我算过一笔账每一条完整归因上下文大约 3000-5000 token输出约 500 token如果每天处理 2000 条告警用量并不小。所以必须做成本分层。我的做法是“大小模型搭配”。大部分简单告警比如单一指标阈值触发的资源类告警用参数较小的模型配合规则判断就能覆盖只有复杂跨域告警才调用更强的模型做深度推理。判断是否复杂的依据是告警是否关联到多个实体、是否涉及变更事件、历史相似案例是否有明确结论。整体算下来成本下降了约 60%准确率只降低不到 5%。模型选型的另一个维度是部署位置。部分企业要求数据不能出内网这种情况下可以考虑私有化部署一个中等规模的模型做归因再在关键场景用云端大模型兜底。具体选型取决于贵司的安全策略和预算没有绝对标准但一定要记住模型只是基础设施提示工程和上下文组装才是准确率的主要来源。4.5 建立回归评测集用数据说话第三阶梯开始的另一件事是建立稳定的归因评测集。这个评测集不是拍脑袋想出来的而是从历史真实告警中抽样的。我会选择过去三个月内的 300 条告警覆盖不同故障类型由 SRE 和研发一起人工标注出“根因结论、关键证据、处置方式”。标注完成之后每次修改提示词、调整上下文组装逻辑或者更换模型都跑一遍评测集记录准确率变化。评测指标我重点关注五个根因命中率模型给出的根因候选是否被人工标注确认。证据引用准确率引用的证据是否真实相关有没有虚构。无效输出率JSON 解析失败、引用不存在证据、明显复读告警的比例。平均延迟单条归因的 p95 耗时。人工复核通过率值班人员实际采纳归因结果的比例。有了这套评测集提示词迭代就变成了一个“有数据支撑”的工程行为而不是拍脑袋试 prompt。我后面几乎每一次 prompt 改动都必须先在评测集上跑一轮对比回归通过才敢发布。5. 第四阶梯可上生产闭环才是终点5.1 和告警平台、事件管理流程打通告警归因做到第三阶梯本质上还只是一个“分析工具”要可上生产必须融入真实事件处理流程。我的做法是在告警平台和事件管理中间插入一个归因服务。告警触发后事件管理平台会发一个 webhook 到归因服务归因服务完成分析后把结果写回事件单附带一个置信度标签。值班同学打开工单时第一眼就能看到“模型归因结果订单服务发布变更引发错误率上升置信度 0.82证据链已附”。如果置信度高可以直接作为处理参考如果低就当作排查线索。这里有一个细节值得强调融入流程不只是技术对接还要考虑人的体验。归因结果必须放在值班人员最容易看到的地方而不是藏在某个“AI 分析”tab 后面同时要明确说明这是“参考建议”而非“结论”避免值班同学被一个错误的“高置信度”带入歧途。5.2 人工复核与反馈回流让系统越用越准可上生产的另一个关键动作是反馈闭环。归因结果不能只出不进必须收集人的反馈来持续优化。我在事件工单上增加了一组操作按钮“采纳归因”“部分采纳、修改根因”“完全错误、忽略”。反馈数据统一写入一个样本库每周做一次分析把被采纳的 good case 和被认为错误 bad case 分别沉淀下来。good case 会成为之后 RAG 检索和 few-shot 的种子bad case 会用来诊断提示词或上下文组装中的问题。这个反馈闭环看起来简单却是整个系统从“可用”走向“好用”的核心。上线三个月后基于反馈不断调整 few-shot 示例和上下文优先级根因命中率从最初的 52% 提升到了 74%这个增长不是模型换出来的而是反馈数据喂出来的。5.3 给提示工程本身加监控一个很有意思的现象提示词和上下文组装规则上线后很多人会忘记它们也是“需要监控的代码”。如果某一天上游数据格式变了或者某个数据源开始返回空值归因质量会瞬间劣化但系统本身不报错。所以我在归因服务里加了专门的监控指标输入 token 数分布、输出 token 数、模型调用延迟、超时率、重试率、降级率、无效输出率、证据引用失败率、人工复核一致率。这些指标都打入了监控大盘并设置了告警比如“无效输出率超过 10% 触发警告”“降级率超过 20% 说明模型服务异常”。同时提示词模板本身也纳入版本管理。我在代码仓库里单独建了 prompts 目录每次修改都走 MR 流程带上评测集对比结果合并后发布到生产。不要小看这一步它避免了“谁偷偷改了一句话线上效果变差还找不到人”的混乱。5.4 灰度发布、权限与合规对于大模型场景安全和合规是上线前逃不掉的一关。归因服务会接触到告警内容、业务指标、日志摘要这些都可能包含敏感信息所以我在架构上做了几个设计。第一数据脱敏。日志和业务信息在进入 prompt 之前先做脱敏处理手机号、身份证、token 等敏感字段统一替换为占位符。宁可损失一些上下文信息也不能让敏感数据出域。第二灰度发布。归因服务先接 5% 的流量只输出不展示内部对比人工判断的差异确认无异常后再逐步放量到 10%、50%、100%。第三操作审计。所有调用记录都留存 request 和 response便于追责和复盘。这个在出问题的时候能救命甚至可能成为合规要求的硬指标。6. 落地复盘几个真实踩过的坑6.1 你以为模型“听懂了”其实它在复读告警第一个坑我前面已经提过但值得单独再说一次。早期我测试单条告警时模型给出的 root_cause_hypothesis 和告警标题几乎逐字相同我还以为是模型“认为这就是根因”后来才发现它根本没有可用的额外信息只能复读。这个问题的真正解法不是改提示词而是把上下文补齐。这也验证了那句话提示工程的核心一半是提示一半是数据。6.2 把全部上下文塞进去效果反而变差连续两次经历让我彻底打消了“数据越多越准”的天真想法。第一次是某个故障的告警关联了上百个指标模型把不相关的指标误认为强证据给出了一个完全错误的连接池假设。第二次是日志没有裁剪几千行日志塞进 prompt模型直接“看花眼”输出的结论和日志内容毫无关系。从那以后我严格执行上下文组装规范并养成一个习惯每次上线前检查喂给模型的 token 构成如果“证据占比”过高而“总结性摘要”过低就会主动压缩。对模型而言信息过载和缺乏信息一样致命。6.3 “证据不足”是救命的兜底不是失败的标志有一段时间我特别希望模型每次都能给出高置信度的根因后来线上事故打脸了。一次依赖服务故障告警发生在 A 服务但根因在 B 服务的一个底层库变更而 B 的变更信息当时没有接入归因服务。模型在信息不完整的情况下硬是编了一个“A 服务代码异常”的结论置信度还给了 0.75导致值班同学折腾了半小时才转向排查 B。教训很清楚必须允许模型“不知道”并且把“证据不足”当作一种有效输出而不是失败输出。后来我甚至在评测指标里单独统计了“证据不足判定准确率”鼓励模型在不该下结论的时候拒绝下结论。6.4 提示词不是写出来的是版本管理出来的提示词迭代过程中我发现很多“玄学”问题其实都源于版本混淆。有一次线上准确率突然波动排查了很久才发现是有人手动在调试环境改了提示词且没有同步到代码仓库。后来我把 prompt 当成代码一样管理线上只运行从仓库构建出的模板任何修改都必须走评审和评测流程。这一步做完之后线上效果肉眼可见地稳定了。6.5 从“能用”到“可上生产”关键不是模型有多聪明而是流程有多稳如果把这段经历浓缩成一句话我想说告警归因里的提示工程技术难点不在于“让模型说出一句话”而在于“让模型每次都在约束下说出合适的话并且系统能稳稳承接住”。模型再聪明没有上下文组装、没有输出约束、没有超时降级、没有人工反馈闭环照样上不了生产。最后再分享一个我个人的体会。做这个项目之前我以为提示工程是写提示词的艺术做完 4 个阶梯之后我意识到提示工程其实是一个“把模型能力约束到业务流程里”的系统工程。你可以从第一阶梯开始不需要一步到位但一定要清楚自己处在哪个阶梯以及下一步要补的是数据、稳定性还是反馈闭环。方向对跑起来就不怕慢。
返回列表