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 文件包含了完整的处理逻辑链:
- 意图识别:先过滤掉非运维问题
- 告警查询:获取当前活跃告警
- 日志收集:根据告警关联服务获取日志
- Prompt 构建:组织分析框架
- 模型调用:获取最终分析结果
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 构造是整个项目的灵魂所在。我的设计遵循了几个原则:
- 明确角色设定:"你是一个经验丰富的 SRE"
- 提供完整上下文:告警详情+错误日志+访问日志
- 结构化输出要求:分四点回答关键问题
- 事实约束:"请基于日志,不要编造不存在的事实"
完整的 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 的设计往往被忽视,但其实至关重要。我用了两重约束:
- 角色定位:"严谨的 SRE"
- 分析原则:"只能基于给定事实进行分析"
这相当于给模型戴上了"紧箍咒"。实测表明,这种约束能让模型输出的分析结果更加聚焦和可靠。
5. 生产环境适配建议
5.1 数据源对接方案
要将这个 demo 升级为生产级系统,需要对接以下数据源:
| 数据类型 | 推荐对接方案 | 数据用途 |
|---|---|---|
| 指标告警 | Prometheus Alertmanager | 触发分析流程 |
| 应用日志 | ELK/Loki | 获取错误详情 |
| 性能指标 | Grafana/Prometheus | 辅助根因分析 |
| 链路追踪 | Jaeger/SkyWalking | 定位慢请求 |
5.2 安全防护措施
调用外部 LLM 时必须注意数据安全:
- 敏感字段脱敏(IP、账号、token等)
- 设置 API 调用频率限制
- 关键业务数据建议使用本地化模型
- 实现审计日志记录所有查询
我常用的脱敏方法包括:
- 正则替换敏感信息
- 使用哈希值替代原始数据
- 移除非必要字段
6. 典型问题排查实录
在实际测试中,我遇到了几个典型问题:
问题1:模型输出过于笼统
- 现象:分析结论都是"可能是上游服务问题"
- 解决方案:在 Prompt 中明确要求引用具体日志行作为证据
问题2:误报率高
- 现象:将正常波动识别为故障
- 解决方案:在告警查询环节增加严重度过滤阈值
问题3:响应延迟
- 现象:完整分析耗时超过15秒
- 解决方案:
- 实现日志查询缓存
- 设置模型调用超时
- 对历史相似问题建立答案库
7. 性能优化技巧
经过多次迭代,我总结出几个提升效率的方法:
- 并行查询优化:
# 串行查询(旧) 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()- 结果缓存机制:
- 对相同告警的分析结果缓存5分钟
- 使用服务名+时间范围作为缓存键
- 分级响应策略:
- 简单问题:直接返回预置解决方案
- 中等复杂度:使用轻量级模型快速响应
- 复杂问题:调用高级模型深度分析
8. 扩展应用场景
这个基础框架稍加改造就能支持更多运维场景:
变更影响分析
- 获取最近部署记录
- 关联监控指标变化
- 评估变更与异常的相关性
容量规划建议
- 分析历史负载趋势
- 识别资源瓶颈
- 给出扩容建议
故障自愈
- 识别已知故障模式
- 执行预定义修复动作
- 验证修复效果
在实际部署时,建议先从"辅助分析"场景开始,逐步过渡到"自动处置"场景。每次迭代都要设置明确的回滚机制和人工复核点。