sarveshkb21/aiops-incident-response-assistant

GitHub: sarveshkb21/aiops-incident-response-assistant

基于多 agent 路由和领域隔离检索的 RAG 聊天机器人,帮助 IT 值班工程师快速从运维手册中定位事件故障排查步骤。

Stars: 0 | Forks: 0

# AIOps 事件响应助手 这是一个基于 RAG 的聊天机器人,旨在帮助 IT 值班工程师在事件发生时,利用 LangChain、ChromaDB、Gemini 和 Streamlit 即时找到 故障排查步骤。它使用了一个轻量级的 **多 agent 路由器**:每个查询首先被分类到一个 特定领域(kubernetes、database、infrastructure、network、security、cicd),然后由专门负责该领域的 agent 进行回答,且只从该领域的 runbook 中进行检索。 ## 技术栈 | 组件 | 工具 | |-----------------|-----------------------------| | LLM | Google Gemini 2.5 Flash | | Embeddings | Google gemini-embedding-2 | | 框架 | LangChain 1.x | | 向量数据库 | ChromaDB (本地) | | UI | Streamlit | | 编程语言 | Python 3.12+ | ## 工作原理(多 Agent 路由) ``` flowchart TD Q["🧑‍💻 Engineer query"] --> R["🧭 Router
(router.classify_query · Gemini)"] R -->|kubernetes| K["☸️ Kubernetes Agent"] R -->|database| D["🗄️ Database Agent"] R -->|infrastructure| I["🖥️ Infrastructure Agent"] R -->|network| N["🌐 Network Agent"] R -->|security| S["🔒 Security Agent"] R -->|cicd| P["🚀 CI/CD Agent"] R -->|general / fallback| G["🧭 General Agent"] K & D & I & N & S & P & G --> C[("🗃️ ChromaDB
filtered by domain")] C --> A["💬 Answer + agent badge + sources"] ``` 每个专门的 agent 由 `get_agent_chain()` 构建,并且只从其所在领域的 runbook 中进行检索。这些 agent 在 `agents.py` 中作为一个注册表定义(包含 `ROUTER` 和 `AGENTS`),由 `app.py` 统一驱动。 每个查询都会经过以下三个步骤: 1. **路由** — `router.classify_query()` 会进行一次 Gemini 调用,将查询分类到特定的领域:`kubernetes`、`database`、`infrastructure`、`network`、 `security`、`cicd` 或 `general`。 2. **检索(领域隔离)** — `rag_chain.get_agent_chain(domain)` 会构建一个 RetrievalQA 链,其 ChromaDB 检索器会根据 `domain` 元数据进行过滤,因此专门的 agent 只能看到自己领域的 runbook。`general` 不应用任何过滤,会搜索所有内容。 3. **回答与徽章** — 应用程序会在响应上方显示一个彩色的 agent 徽章(☸️ Kubernetes、 🗄️ Database、🖥️ Infrastructure、🌐 Network、🔒 Security、🚀 CI/CD、🧭 General), 下方则会列出引用的 runbook 来源。 **错误路由回退:** 如果路由到的领域没有匹配到任何 runbook,应用程序会 自动进行未过滤的重试(`general`),这样错误的路由永远不会 隐藏正确的 runbook。请注意,这意味着一次路由后的查询最多可能会进行 **两次** Gemini 调用(路由 + 回答),如果触发了回退机制,则可能达到三次——请合理控制免费额度的使用频率。 这些领域与 `data/runbooks/` 下的子文件夹是一一对应的。`domain` 元数据由 `ingest.py` 写入(根据每个文件所在的子文件夹派生),并由检索器过滤器读取——因此,添加一个新领域只需要新建一个子文件夹并 重新导入(同时需要在 `router.py` 中的 `DOMAINS` 里将其添加进去)。 ## 设置说明 (Windows) ### 第 1 步:克隆或创建项目文件夹 ``` cd C:\Users\YourName\Documents mkdir aiops-assistant cd aiops-assistant ``` ### 第 2 步:创建并激活虚拟环境 ``` python -m venv venv venv\Scripts\activate ``` ### 第 3 步:安装依赖项 ``` pip install -r requirements.txt ``` ### 第 4 步:设置你的 API key - 将 `.env.example` 复制为 `.env` - 打开 `.env` 并将 `your_gemini_api_key_here` 替换为你的实际密钥 - 从以下地址获取你的 Gemini API key:https://aistudio.google.com/app/apikey ### 第 5 步:添加你的 runbook - 将你的 `.txt` 或 `.pdf` runbook 文件放入 `data/runbooks//` 下 (每个领域对应一个子文件夹——子文件夹的名称即为路由的领域) - 为了方便你快速入门,项目中已经包含了涵盖所有领域的示例 runbook ### 第 6 步:将文档导入向量数据库 ``` python ingest.py ``` ### 第 7 步:启动应用 ``` streamlit run app.py ``` 应用将在以下地址打开:http://localhost:8501 ## 部署到 Streamlit Cloud 1. 将本项目推送到 GitHub 仓库(确保 `app.py` 位于仓库根目录)。 2. 在 [share.streamlit.io](https://share.streamlit.io) 上,创建一个指向 `app.py` 的应用。 3. 在 **Settings → Secrets** 下添加你的密钥(Streamlit 会将密钥作为 环境变量暴露出来,因此 `os.getenv("GOOGLE_API_KEY")` 可以正常工作): GOOGLE_API_KEY = "your_key_here" 4. **发布向量数据库。** 本仓库有意 **提交了** 预先构建好的 `chroma_db/`,这样全新的部署从第一个请求开始就自带知识库。 如果你更改了 runbook,请在本地重新运行 `python ingest.py`,并提交更新后的 `chroma_db/`。(备选方案:在服务器启动时运行导入—— 但这需要在运行时提供 API key,并且每次冷启动都会消耗 embedding 配额。) ## 项目结构 ``` aiops-assistant/ ├── app.py # Streamlit UI (router -> agent -> badge) ├── agents.py # Agent registry: ROUTER + 7 named agents ├── router.py # Classifies a query into a domain (Gemini) ├── rag_chain.py # RAG chain builder: get_agent_chain (domain-filtered) ├── ingest.py # Document ingestion pipeline (tags `domain`) ├── eval/ # Evaluation harness (see Evaluation Results) │ ├── run_eval.py # python eval/run_eval.py │ ├── test_queries.py # 20 labelled test queries │ ├── results.json # per-query records from the last run │ ├── summary.md # metrics summary from the last run │ └── extensibility_test.md # new-domain (CI/CD) test report ├── docs/screenshots/ # annotated demo screenshots + capture guide ├── requirements.txt # Python dependencies ├── LICENSE # MIT license ├── CLAUDE.md # Guidance for Claude Code sessions ├── .env.example # API key template ├── .env # Your actual API key (do not commit) ├── .gitignore ├── data/ │ └── runbooks/ # One subfolder per domain │ ├── kubernetes/ │ │ └── runbook_oom_kubernetes.txt │ ├── database/ │ │ └── runbook_database.txt │ ├── infrastructure/ │ │ ├── runbook_disk_space.txt │ │ ├── runbook_high_cpu.txt │ │ └── runbook_service_health.txt │ ├── network/ │ │ ├── runbook_dns_failure.txt │ │ └── runbook_high_latency.txt │ ├── security/ │ │ ├── runbook_unauthorized_access.txt │ │ └── runbook_ssl_cert_expiry.txt │ └── cicd/ │ ├── runbook_failed_deployment.txt │ ├── runbook_pipeline_stuck.txt │ └── runbook_artifact_registry.txt └── chroma_db/ # Prebuilt vector store (committed for Streamlit Cloud) ``` ## 评估结果 本仓库包含一个可复现的评估工具(`python eval/run_eval.py`),它会驱动 **真实的生产路径** —— 路由器 → 专门的 agent → 领域过滤检索 → 回答(包括错误路由回退机制)——涵盖 20 个带标签的查询,覆盖所有六个专门的领域以及特意设计的 模糊/跨领域场景。它主要测量: - **路由准确率** — 路由器是否选择了人类专家会选择的领域? - **检索命中率** — 预期的 runbook 是否包含在检索到的来源中? - **回退率** — 空检索的安全网触发的频率。 - **延迟** — 按阶段(路由 / 回答)和领域划分。 中期结果(评估正在进行中——该工具会根据 Gemini 免费层级每天 20 次请求的限制,在几天内控制调用频率,并使用 `--resume` 恢复进度;最终数据详见 [`eval/summary.md`](eval/summary.md)): | 指标 | 结果(目前已完成 20 个查询中的 11 个) | |---|---| | 路由准确率 | **11/11 (100%)** — kubernetes、database、infrastructure、network 已完全覆盖 | | 检索命中率 | **11/11 (100%)** — 预期的 runbook 始终包含在来源中 | | 空检索回退 | 0(预期情况:每个领域都有 runbook) | | 平均端到端延迟 | 10.46秒/查询(免费层级 API 往返时间) | **可扩展性测试**([`eval/extensibility_test.md`](eval/extensibility_test.md)): 在 **不到 10 分钟** 的时间内添加了一个新的 **CI/CD** 专业领域(3 个 runbook), 只需修改数据和两个注册表条目(在 `router.py` 和 `agents.py` 中约 8 行代码)——对路由、检索或分发逻辑的改动为零。导入过程正确标记了全部 3 个文档,领域过滤检索排他性地返回了 `cicd` 块,并且所有三个探测查询都将正确的 runbook 作为首要来源。 ## 用于测试的示例查询 - 如何解决 Kubernetes 中的 OOMKilled pod? - 处理 Linux 服务器 CPU 高负载告警的步骤? - 数据库连接池耗尽——该怎么办? - 如何响应磁盘空间告警? - 服务健康检查失败——有哪些故障排除步骤? ## 添加更多 Runbook 1. 将你的 `.txt` 或 `.pdf` 文件添加到 `data/runbooks/` 2. 重建向量数据库(参见下方的 **更新向量数据库 (ChromaDB)**) 3. 重启 Streamlit 应用 ## 更新向量数据库 (ChromaDB) `chroma_db/` 中的向量数据库是由 `ingest.py` 根据 `data/runbooks/` 中的文件构建的。每当你 **添加、编辑或删除** runbook 时,都需要重新构建它,以便应用程序能够感知到更改: ``` python ingest.py ``` `ingest.py` 会在重建之前自动删除任何现有的 `chroma_db/`,因此重新运行它永远不会导致文档重复。因为 `chroma_db/` 已被提交到代码库 (这样部署到 Streamlit Cloud 时就会自带预构建的知识库),请在重建后提交更新后的 数据库。如果删除操作失败并报出 “拒绝访问”错误,说明有程序正在占用该文件夹——请停止 Streamlit 应用(Ctrl+C),如果 OneDrive 正在同步该文件夹则暂停其同步,然后 重新运行。 成功重建后会打印出 `Loaded N document(s)` 和 `SUCCESS: N chunks stored in ChromaDB`。请确认 `N` 与你预期的 runbook 数量是否一致。 ### 何时必须重新构建 - 你在 `data/runbooks/` 中添加、编辑或删除了 runbook - 你更改了 `rag_chain.py` 中的 `EMBEDDING_MODEL`(旧/新 embedding 是 不兼容的——过期的 `chroma_db/` 会导致错误的回答或维度错误) - 应用程序提示 `Knowledge base not found` 重新构建后,**彻底重启 Streamlit**(按 Ctrl+C,然后执行 `streamlit run app.py`)。 领域链在进程内被缓存,而应用程序的 ⋮ 菜单 → Clear cache 并**不会** 重建它们——只有重启才能更新。 ## 故障排除 | 症状 | 原因 | 解决方案 | |---------|-------|-----| | `GOOGLE_API_KEY is not set` | 没有 `.env` 文件或缺少密钥 | 将 `.env.example` 复制为 `.env` 并粘贴你的密钥 | | `404 NOT_FOUND ... is not found for API version` | Gemini 模型名称已被弃用 | 更新 `rag_chain.py` 中的模型名称(参见上方的模型说明) | | `429 RESOURCE_EXHAUSTED ... limit: 0` | 该模型仅限付费层级使用(例如 `gemini-2.5-pro`) | 切换到免费层级模型,如 `gemini-2.5-flash`,或启用计费功能 | | `429 RESOURCE_EXHAUSTED ... retry in Ns` | 达到了免费层级的速率/每日限制 | 等待重试延迟结束;限制会随时间重置 | | 在 `rag_chain.py` 中更改模型对正在运行的应用程序没有生效 | 链在进程内被缓存了(`lru_cache`) | 彻底重启应用程序(Ctrl+C,重新运行)。⋮ 菜单 → Clear cache **并不会** 重建它们 | | `ModuleNotFoundError: No module named 'langchain...'` | 依赖项过期 | 重新运行 `pip install -r requirements.txt` | | 回答似乎与你的 runbook 无关,或者查询时出现维度错误 | 向量数据库是使用不同的 embedding 模型构建的 | 删除 `chroma_db/` 文件夹并重新运行 `python ingest.py` | | 应用程序中提示 `Knowledge base not found` | 从未运行过 `ingest.py` | 在启动应用程序之前运行 `python ingest.py` | ## 许可证 基于 [MIT License](LICENSE) 发布——可免费使用、修改和分发。 ## 毕业项目 **作者:** Sarvesh Bedsur 提交给 [AI Agents: Intensive Vibe Coding Capstone Project](https://www.kaggle.com/competitions/vibecoding-agents-capstone-project/), 这是 **Google × Kaggle 5-Day AI Agents Intensive — Vibe Coding** 课程(2026 年 6 月)的毕业项目。本着该课程的精神,本项目是利用 AI 编程 agent (Claude Code) 进行“氛围编程”(vibe-coded) 完成的:多 agent 架构、导入 pipeline 以及部署修复,都是通过迭代式的 AI 结对工作构建的,其中 `CLAUDE.md` 作为该 agent 的持久化项目记忆库。
标签:AI, ChromaDB, Kubernetes, LangChain, Streamlit, 多智能体, 智能运维, 检索增强生成, 自动化代码审查, 访问控制, 轻量级, 逆向工具