Superkart/Incident_Response_Agent

GitHub: Superkart/Incident_Response_Agent

这是一个AI辅助的事件响应系统,用于自动化微服务故障的上下文收集、分析和报告生成。

Stars: 0 | Forks: 0

# 事件响应智能体 一个用于本地微服务的AI辅助事件响应系统。 该项目将应用程序遥测数据、警报、日志和LLM分析连接到一个统一的事件工作流中。该智能体自动收集第一层上下文信息并生成结构化的事件摘要,而不是让值班工程师在Prometheus、Loki、服务日志和源代码之间来回切换。 **演示:** [YouTube](https://www.youtube.com/watch?v=KXLgdUAnoSU&t=2s)  |  **DevPost:** [devpost.com/software/incident-responce-agent](https://devpost.com/software/incident-responce-agent) ## 功能概述 当出现问题时——服务宕机、MongoDB依赖故障或5xx错误率上升: 1. Prometheus评估警报规则。 2. Alertmanager向`incident-agent-workflow`发送webhook。 3. 智能体从Prometheus查询实时指标。 4. 智能体从Loki查询受影响服务的近期日志。 5. 一个由3个智能体组成的流水线执行分类、调查和根本原因分析。 6. 生成包含完整证据和发现的PDF事件报告。 7. 通知程序通过电子邮件将报告发送给值班人员。 8. 修复流程会打开一个草稿GitHub拉取请求供人工审核。 该3智能体流水线作为`incident-agent-workflow`的一部分在Docker栈内运行: | 智能体 | 角色 | 职责 | |---|---|---| | 智能体1 — 分类 | 服务解析 | 识别受影响的服务,对严重性进行分类,从注册表中解析配置 | | 智能体2 — 调查 | 运行时证据 | 运行健康检查,扫描日志,提取堆栈跟踪和请求上下文 | | 智能体3 — 代码分析 | 根本原因 | 读取故障点周围的源代码上下文并提出修复建议 | ## 系统设计 ``` A service fails ↓ Prometheus detects the outage ↓ Alertmanager calls the AI agent ↓ Agent gathers context (Prometheus metrics + Loki logs) ↓ 3-Agent Pipeline runs inside incident-agent-workflow ┌──────────────────────────────────────────────┐ │ Agent 1: Triage │ │ Classifies severity, resolves service config│ │ ↓ │ │ Agent 2: Investigation │ │ Health checks, log scan, stack trace extract│ │ ↓ │ │ Agent 3: Code Analysis │ │ Source-level root cause, fix suggestion │ └──────────────────────────────────────────────┘ ↓ PDF incident report generated (WeasyPrint) ↓ Notifier emails the report ↓ Draft GitHub PR opened for human review ↓ Engineers review evidence and merge when ready ``` ### 一个服务故障 被监控的服务崩溃、无法访问或开始返回错误。每个服务都暴露`/metrics`端点并在`apps//logs/`下写入日志。 ### Prometheus检测到中断 Prometheus从`monitoring/targets.docker.yml`抓取目标。当某个目标`up == 0`持续30秒,或`monitoring/alert-rules.yml`中的其他规则触发时,事件开始。 ### Alertmanager调用AI智能体 当规则触发时,Alertmanager向以下地址发送一个与Alertmanager兼容的负载: ``` http://incident-agent-workflow:9100/alerts ``` ### 智能体收集上下文 该工作流从Prometheus查询服务健康状况和5xx错误率,然后使用警报中的相同服务标签从Loki查询近期日志。 ### 3智能体流水线运行 该流水线由`incident-agent-workflow`容器内的`pipeline.py`编排。每个智能体将其输出传递给下一个: - **TriageAgent** — 在`service_registry.json`中解析服务,对错误类型和严重性进行分类 - **InvestigationAgent** — 检查健康端点,读取日志文件,提取堆栈跟踪 - **CodeAnalysisAgent** — 读取堆栈跟踪中引用的源文件,生成根本原因分析 ### 生成PDF报告 WeasyPrint渲染一份结构化的PDF,包含完整的调查证据、智能体发现、时间线和修复说明。 ### 通知程序发送事件邮件 通知程序接收流水线结果,并通过电子邮件发送PDF报告,内容包括警报名称、服务、摘要和分析。 ### 人类保持控制权 当调查发现具体的修复方案时,系统会打开一个草稿GitHub拉取请求。工程师在合并并解决事件之前审查证据、测试和差异。 ## 智能体化调查与Git流程 ``` Incident Alert ↓ Agent 1 — Triage Resolves service from service_registry.json Maps alert → health URLs, log paths, repo paths, language ↓ Agent 2 — Investigation Checks service health endpoints Reads logs, searches for errors Extracts stack traces and request context ↓ Agent 3 — Code Analysis Reads source files and line ranges from stack trace Moves from "what failed" to "why this code failed" ↓ PDF Report + Draft GitHub PR Evidence packaged into report Proposed fix opens as draft PR for human review ``` ## 构建过程 整个环境使用Docker Compose编排。 ### 应用层 - `weather-app1` — 在端口8000上运行的FastAPI天气服务 - `mongo-api-service` — 在端口9000上运行的、由MongoDB支持的FastAPI CRUD服务 - 通过`prometheus-fastapi-instrumentator`暴露的Prometheus `/metrics`端点 - 挂载到Promtail的基于文件的日志 ### 可观测性栈 - **Prometheus** — 指标抓取和警报规则 - **Alertmanager** — 警报分组和webhook分发 - **Promtail + Loki** — 日志聚合 - **Grafana** — 指标和日志探索 ### 警报工作流 1. `incident-agent-workflow`接收`POST /alerts` 2. 从Prometheus查询`up`和5xx速率信号 3. 从Loki查询近期的服务日志 4. 构建一个结构化的事件上下文对象 5. 运行3智能体流水线(`pipeline.py`) 6. 生成PDF报告(WeasyPrint, `reports/generator.py`) 7. 将结果发布到通知程序以进行邮件传递 8. 当识别出修复方案时,打开一个草稿GitHub PR ### 通知系统 一个FastAPI通知服务在`apps/notifier/`下运行。 - 支持带PDF附件的SMTP邮件 - 工作流将事件结果发布到`/notify` - 邮件内容包括服务名称、警报、摘要、分析和PDF报告 - 本地演示邮件工具(如Mailpit)通过将通知程序的SMTP设置指向本地服务器即可工作 ### 报告 PDF报告由Docker容器内的WeasyPrint生成,并写入`apps/incident-agent-workflow/reports/`下。该仓库还包括宿主机端的工具: - `apps/log_watcher.py` — 扫描日志文件并调用分析流水线 - `apps/monitor_service.py` — 监控服务健康状况 - `apps/report_generator.py` — 生成Word (.docx)事后分析文档 ## 仓库布局 ``` . ├── docker-compose.yml ├── architecture.html ├── README.md ├── apps/ │ ├── weather-app1/ │ ├── mongo-api-service/ │ ├── incident-agent-workflow/ │ │ ├── agents/ │ │ │ ├── triage.py │ │ │ ├── investigation.py │ │ │ ├── code_analysis.py │ │ │ └── quick_analysis.py │ │ ├── tools/ │ │ │ ├── logs.py │ │ │ ├── health.py │ │ │ └── git.py │ │ ├── reports/ │ │ │ └── generator.py │ │ ├── pipeline.py │ │ ├── main.py │ │ ├── config.py │ │ └── service_registry.json │ ├── notifier/ │ ├── log_watcher.py │ ├── monitor_service.py │ └── report_generator.py └── monitoring/ ├── prometheus.yml ├── targets.docker.yml ├── alert-rules.yml ├── alertmanager.yml ├── loki-config.yml ├── promtail-config.yml └── grafana/provisioning/ ``` ## 本地运行 ### 前置条件 - Docker 和 Docker Compose - [Ollama](https://ollama.com/download) 在您的主机上运行(或一个OpenAI API密钥) **使用Ollama(默认):** ``` ollama pull mistral-nemo ollama serve ``` 如果Ollama已经在运行,`ollama serve`可能报告端口被占用。这是正常现象。 **使用OpenAI** — 在`apps/incident-agent-workflow/.env`中设置: ``` LLM_BASE_URL=https://api.openai.com/v1 LLM_API_KEY=sk-... LLM_MODEL=gpt-4o ``` ### 配置服务 复制示例环境文件并填入您的值: ``` cp apps/incident-agent-workflow/.env.example apps/incident-agent-workflow/.env cp apps/notifier/.env.example apps/notifier/.env cp apps/mongo-api-service/.env.example apps/mongo-api-service/.env ``` ### 启动技术栈 ``` docker compose up -d --build ``` 检查状态: ``` docker compose ps ``` 停止技术栈: ``` docker compose down ``` ### 服务URL | 服务 | URL | |---|---| | 天气API | http://localhost:8000 | | Mongo API | http://localhost:9000 | | 事件工作流 | http://localhost:9100 | | 通知程序 | http://localhost:8002 | | Prometheus | http://localhost:9090 | | Alertmanager | http://localhost:9093 | | Grafana | http://localhost:3000 | | Loki | http://localhost:3100 | | MongoDB | localhost:27017 | Grafana凭据:`admin` / `admin` ## 验证演示 检查服务健康状况: ``` curl http://localhost:8000/ curl http://localhost:9000/health curl http://localhost:9100/health ``` 检查Prometheus目标: ``` http://localhost:9090/targets ``` 创建一个Mongo项目: ``` curl -X POST http://localhost:9000/items/ \ -H "Content-Type: application/json" \ -d '{"name":"demo","description":"test item","value":42}' ``` 手动触发一个测试警报: ``` # on. Alternatively, since it's a heading, it might be part of a larger document, so keep it as is. But the user wants translations, so I need to output something. curl -X POST http://localhost:9100/alerts \ -H "Content-Type: application/json" \ -d '{ "alerts": [ { "status": "firing", "labels": { "alertname": "ServiceDown", "service": "weather-app1" }, "annotations": { "summary": "weather-app1 is not responding" } } ] }' # Looking at the other headings, "PowerShell" is a tool, so keep it as "PowerShell". But the user wants a translation, so maybe just output "PowerShell" as is? That seems odd because it's not translated. But in the context, perhaps these headings are from a document where each is a section title, so they might be kept in English if they're all technical. However, the user explicitly said to translate, so I need to provide Chinese equivalents. Invoke-WebRequest -Method POST http://localhost:9100/alerts ` -ContentType "application/json" ` -Body '{"alerts":[{"status":"firing","labels":{"alertname":"ServiceDown","service":"weather-app1"},"annotations":{"summary":"weather-app1 is not responding"}}]}' ``` 观察流水线运行: ``` docker compose logs -f incident-agent-workflow ``` 查找类似`[Pipeline ABC123] TriageAgent running…`、`InvestigationAgent done`、`CodeAnalysisAgent done`的日志行。完成后,将生成PDF并调用通知程序。 ## 活跃警报 | 警报 | 条件 | 严重性 | |---|---|---| | `ServiceDown` | Prometheus在30秒内无法抓取一个服务 | critical | | `MongoDependencyDown` | mongo-api-service在30秒内无法ping通MongoDB | critical | | `Service5xxErrors` | 一个服务在30秒内5xx错误率非零 | warning | ## 有用查询 **Prometheus:** ``` up sum by (service) (up) sum by (service, handler, method, status) (rate(http_requests_total[1m])) sum by (service) (rate(http_requests_total{status="5xx"}[2m])) dependency_up{service="mongo-api-service", dependency="mongodb"} ``` **Loki:** ``` {service="weather-app1"} {service="mongo-api-service"} {service="incident-agent-workflow"} {service="incident-agent-workflow"} |= "Pipeline" {service="incident-agent-workflow"} |= "CodeAnalysisAgent" {service="mongo-api-service"} |= "ERROR" ``` ## API参考 ### Let's check the user's examples again: 'Running Naabu' -> '运行 Naabu'. So "Running" is translated to "运行", but "Naabu" is kept. Similarly, 'Kubernetes Setup' -> 'Kubernetes 设置'. So "Setup" is translated to "设置". Therefore, for "Git Bash / Linux / Mac", since all are technical terms, perhaps no translation is needed, but the user wants translations, so maybe translate the slashes to "或" or something. But that might not be accurate. Alternatively, since "Git Bash" is a tool, "Linux" is an OS, "Mac" is an OS, they are all proper nouns, so keep them in English. But the heading might be implying options, so in Chinese, it could be "Git Bash / Linux / Mac" as is, but that's not a translation. | 方法 | 路径 | 描述 | |---|---|---| | GET | `/` | 基本服务检查 | | GET | `/weather/latitude={lat}&longitude={lon}` | 从Open-Meteo获取天气数据 | | GET | `/metrics` | Prometheus指标 | ### Perhaps the user means that for headings that contain both technical and non-technical terms, translate the non-technical parts. But here, all headings seem to be technical names. Let's see each one: | 方法 | 路径 | 描述 | |---|---|---| | GET | `/health` | 存活检查 | | GET | `/health/ready` | MongoDB就绪检查 | | POST | `/items/` | 创建项目 | | GET | `/items/` | 列出项目 | | GET | `/items/{item_id}` | 获取项目 | | PUT | `/items/{item_id}` | 更新项目 | | DELETE | `/items/{item_id}` | 删除项目 | | GET | `/metrics` | Prometheus指标 | ### 1. Git Bash / Linux / Mac: All are tools/OS, so keep as is? But then it's not translated. However, the user might expect the slashes to be translated to Chinese punctuation, but in technical contexts, slashes are often kept. In the user's example, "Running Naabu" has a space, which is kept. So perhaps for this one, output "Git Bash / Linux / Mac" but in Chinese characters for the slashes? That seems unlikely. | 方法 | 路径 | 描述 | |---|---|---| | GET | `/health` | 存活检查 | | POST | `/alerts` | Alertmanager webhook接收器 | | GET | `/metrics` | Prometheus指标 | ## 遇到的挑战 ### Docker到宿主机LLM通信 Ollama在宿主机上运行,而工作流在Docker中运行。工作流使用`host.docker.internal:11434`,以便容器可以访问宿主机上的LLM服务器。 ### 在Docker内集成3智能体流水线 将所有三个智能体保持在同一个Docker服务内需要精心的编排——每个智能体将结构化输出传递给下一个,并且一个智能体的失败不能默默中断整个链条。使用流水线ID记录每个阶段使调试变得可行。 ### 可观测性集成 该系统依赖于Prometheus、Alertmanager、Loki和Promtail之间一致的标签。如果服务标签或日志路径错误,智能体可能会收到警报但错过日志上下文。 ### 可靠的LLM JSON输出 让LLM在所有三个智能体阶段一致地返回结构化JSON需要提示工程和输出验证。该流水线必须处理模型返回散文而非JSON的情况。 ### Docker内生成PDF WeasyPrint具有复杂的字体和渲染依赖项,在最小化Docker容器中的行为与宿主机不同。获得清晰的PDF输出需要调整Dockerfile和字体配置。 ### 安全的草稿PR自动化 自动提出修复方案存在风险,如果系统写入过多或未经审查就合并。该项目使用草稿GitHub拉取请求作为交接点,以便人类批准修复方案。 ## 成就 - 构建了从警报到AI生成PDF报告的完整本地事件响应循环。 - 连接了指标、日志、警报和LLM上下文,而不是构建一个独立的聊天机器人。 - 实现了一个完全在Docker内运行的3智能体流水线——无需单独的宿主机进程。 - 添加了生产风格的可观测性栈:Prometheus、Alertmanager、Loki、Promtail和Grafana。 - 使用WeasyPrint生成了结构化PDF事件报告。 - 添加了基于通知程序的、带PDF附件的事件邮件。 - 添加了GitHub草稿PR交接,用于提出的修复方案。 ## 我们学到了什么 - 警报只是触发器;上下文才是真正的产物。 - AI分析只有当它基于遥测数据时才有用。 - 标签和日志路径与模型本身同样重要。 - 事件期间,结构化摘要比冗长的解释更有用。 - 自动化应在执行更改之前产生可审查的建议。 - 从LLM获得可靠的结构化输出所需的工程量与周围管道一样多。 ## 下一步计划 - 对提出的修复方案进行置信度评分 - Slack和PagerDuty通知渠道 - Runbook查找和Jira/Linear问题创建 - 更智能的路由:简单警报使用快速分类,复杂警报使用完整流水线 ## 故障排除 ### incident-agent-workflow记录LLM错误 检查Ollama是否正在运行且模型可用: ``` ollama list ollama pull mistral-nemo ``` ### Prometheus目标显示DOWN ``` docker compose ps docker compose logs weather-app1 docker compose logs incident-agent-workflow ``` ### Mongo API启动失败 确认`apps/mongo-api-service/.env`文件存在且MongoDB健康: ``` docker compose ps mongo docker compose logs mongo ``` ### Grafana没有日志 ``` docker compose logs promtail docker compose logs loki ``` 确认日志文件存在于`apps/*/logs/`下。 ### PDF未生成 ``` docker compose logs incident-agent-workflow | grep -i "pdf\|weasy\|report" ```
标签:AI 辅助运维, AI风险缓解, Docker, GitHub 集成, LLM, Loki, NIDS, PDF报告, Unmanaged PE, 代码修复建议, 安全防御评估, 容器化, 应用遥测, 微服务监控, 故障排查, 根因分析, 监控告警, 自定义请求头, 请求拦截, 运维自动化, 邮件通知