AIOps Agent 实践:200行代码实现告警自动分析

📅 2026/7/14 4:23:57 👁️ 阅读次数 📝 编程学习
AIOps Agent 实践:200行代码实现告警自动分析

1. AIOps Agent 项目概述

最近在运维圈子里,AIOps 技术正逐渐从概念走向落地。我花了三周时间搭建了一个能自动分析线上告警的 AI Agent 原型系统,代码量不到 200 行,但已经实现了从告警识别到根因分析的完整闭环。这个项目最让我兴奋的是,它证明了用 LLM 处理运维问题不是天方夜谭——只要设计好数据流和约束条件。

这个 Agent 的核心工作流程非常直观:当用户询问线上状态时,它会先检查当前活跃告警,然后拉取相关服务日志,最后将所有证据组织成结构化 Prompt 交给大模型分析。整个过程就像有个经验丰富的 SRE 在帮你排查问题,但响应速度是人类的十倍以上。

2. 核心架构解析

2.1 四层架构设计

整个系统采用分层设计,每个模块职责明确:

monitor_agent/ ├── main.py # 入口层 ├── agent.py # 编排层 ├── llm.py # 模型层 └── tools.py # 数据层

入口层只负责接收问题并输出结果,保持极简设计。我在 main.py 里就做了两件事:构造用户问题字符串,然后调用 agent 函数获取分析结果。这种设计让后续扩展其他交互方式(如 API 或命令行)变得非常容易。

编排层是整个系统的大脑。agent.py 文件包含了完整的处理逻辑链:

  1. 意图识别:先过滤掉非运维问题
  2. 告警查询:获取当前活跃告警
  3. 日志收集:根据告警关联服务获取日志
  4. Prompt 构建:组织分析框架
  5. 模型调用:获取最终分析结果

2.2 关键实现细节

在意图识别环节,我采用了最简单的关键词匹配:

if "线上" not in question: return "我只能回答线上运行状态相关问题"

虽然看起来简陋,但在 MVP 阶段非常有效。后续可以升级为基于 embedding 的语义匹配,但当前版本已经能过滤掉 80% 的非相关提问。

告警查询模块返回了结构化数据示例:

{ "alertname": "nginx_5xx_high", "service": "backend-service", "since": "2026-03-02 09:41", "severity": "critical" }

这个设计让后续处理流程可以精准定位问题服务。在生产环境中,这里应该对接真实的告警系统 API。

3. 数据处理流程

3.1 日志收集策略

系统会同时收集两种 Nginx 日志:

  • error.log:包含 upstream timed out 等关键错误信息
  • access.log:统计 5xx 状态码出现频率

我特别设计了日志查询函数的参数传递:

error_log = query_nginx_error_log(alerts["service"]) access_log = query_nginx_access_log(alerts["service"])

通过告警中的 service 字段进行关联查询,确保日志与告警的上下文一致性。这个设计避免了"拿着锤子找钉子"式的盲目分析。

3.2 Prompt 工程实践

Prompt 构造是整个项目的灵魂所在。我的设计遵循了几个原则:

  1. 明确角色设定:"你是一个经验丰富的 SRE"
  2. 提供完整上下文:告警详情+错误日志+访问日志
  3. 结构化输出要求:分四点回答关键问题
  4. 事实约束:"请基于日志,不要编造不存在的事实"

完整的 Prompt 模板如下:

你是一个经验丰富的 SRE。 当前检测到告警: {alerts} Nginx error.log: {error_log} Nginx access.log: {access_log} 请分析: 1. 当前是否存在真实故障 2. 故障发生在哪一层(nginx / upstream / network) 3. 根因是什么 4. 给出修复建议 请基于日志,不要编造不存在的事实。

4. 模型调用优化

4.1 模型配置要点

在 llm.py 中,我做了几个关键配置:

response = client.chat.completions.create( model=MODEL, messages=[ {"role": "system", "content": "你是一个严谨的 SRE..."}, {"role": "user", "content": prompt} ], temperature=0.2 # 排障一定要低温度 )

特别需要注意的是 temperature 参数设为 0.2。在创意场景可以设为 0.7-1.0,但在故障分析场景,低温度值能显著减少模型的"胡言乱语"。

4.2 系统提示词设计

System Prompt 的设计往往被忽视,但其实至关重要。我用了两重约束:

  1. 角色定位:"严谨的 SRE"
  2. 分析原则:"只能基于给定事实进行分析"

这相当于给模型戴上了"紧箍咒"。实测表明,这种约束能让模型输出的分析结果更加聚焦和可靠。

5. 生产环境适配建议

5.1 数据源对接方案

要将这个 demo 升级为生产级系统,需要对接以下数据源:

数据类型推荐对接方案数据用途
指标告警Prometheus Alertmanager触发分析流程
应用日志ELK/Loki获取错误详情
性能指标Grafana/Prometheus辅助根因分析
链路追踪Jaeger/SkyWalking定位慢请求

5.2 安全防护措施

调用外部 LLM 时必须注意数据安全:

  1. 敏感字段脱敏(IP、账号、token等)
  2. 设置 API 调用频率限制
  3. 关键业务数据建议使用本地化模型
  4. 实现审计日志记录所有查询

我常用的脱敏方法包括:

  • 正则替换敏感信息
  • 使用哈希值替代原始数据
  • 移除非必要字段

6. 典型问题排查实录

在实际测试中,我遇到了几个典型问题:

问题1:模型输出过于笼统

  • 现象:分析结论都是"可能是上游服务问题"
  • 解决方案:在 Prompt 中明确要求引用具体日志行作为证据

问题2:误报率高

  • 现象:将正常波动识别为故障
  • 解决方案:在告警查询环节增加严重度过滤阈值

问题3:响应延迟

  • 现象:完整分析耗时超过15秒
  • 解决方案:
    1. 实现日志查询缓存
    2. 设置模型调用超时
    3. 对历史相似问题建立答案库

7. 性能优化技巧

经过多次迭代,我总结出几个提升效率的方法:

  1. 并行查询优化
# 串行查询(旧) error_log = query_nginx_error_log() access_log = query_nginx_access_log() # 并行查询(新) with ThreadPoolExecutor() as executor: error_future = executor.submit(query_nginx_error_log) access_future = executor.submit(query_nginx_access_log) error_log = error_future.result() access_log = access_future.result()
  1. 结果缓存机制
  • 对相同告警的分析结果缓存5分钟
  • 使用服务名+时间范围作为缓存键
  1. 分级响应策略
  • 简单问题:直接返回预置解决方案
  • 中等复杂度:使用轻量级模型快速响应
  • 复杂问题:调用高级模型深度分析

8. 扩展应用场景

这个基础框架稍加改造就能支持更多运维场景:

变更影响分析

  1. 获取最近部署记录
  2. 关联监控指标变化
  3. 评估变更与异常的相关性

容量规划建议

  1. 分析历史负载趋势
  2. 识别资源瓶颈
  3. 给出扩容建议

故障自愈

  1. 识别已知故障模式
  2. 执行预定义修复动作
  3. 验证修复效果

在实际部署时,建议先从"辅助分析"场景开始,逐步过渡到"自动处置"场景。每次迭代都要设置明确的回滚机制和人工复核点。