kathirvelarun/air-dev-java

GitHub: kathirvelarun/air-dev-java

一个结合 AI agent 与规格驱动开发的运维事件响应平台,通过告警关联、自动调查和根本原因分析帮助 SRE 团队高效处置生产事件。

Stars: 0 | Forks: 0

# AIR — Agentic Incident Response 一个专为 SRE 工程师、事件指挥官和工程主管设计的 AI 驱动的事件调查与响应平台。AIR 同时也是**结合 AI 编程 agent 的规格驱动开发**的参考实现 —— `specs/` 目录下的每一个 spec 文件都是可以直接交给 agent 的 prompt。 ## AIR 的功能 1. **接入**来自日志流、监控工具、API 和 Slack 的运维告警,并将它们**关联**成去重后的告警组 2. 根据关联的告警组或直接通过 UI **创建事件** 3. 使用专门的 AI agent 流水线(日志、指标、部署历史、依赖关系)对每个事件进行**调查** 4. **诊断**可能的根本原因 —— 提供排序后的假设,每个假设均附带置信度分数和引用的证据 5. **推荐**进行了风险分类的修复选项,其中首选选项会带有直链指向对应的 runbook 6. **保持人类在环** —— runbook 需要手动执行;AIR 绝不会自行更改生产环境状态 7. 在解决事件时**生成复盘报告** —— 包含时间线、影响范围、根本原因分析和待办事项 8. **丰富自身的知识库** —— 经过批准的复盘报告和 runbook 会被向量化,以供未来的调查使用 其核心理念是**受控的调查**:每一个事件都会积累从告警到解决的完整证据链,且每一个 AI 生成的结论都是可解释的,并可追溯到其来源。 ## 架构 三个服务,两条通信通道: ``` Browser ──HTTP──▶ air-web (React SPA, :5173) │ /api proxy │ ▼ air-backend (Spring Boot, :8080) │ Internal REST API │ ▼ air-agent (FastAPI, :8000) │ pgvector RAG │ ▼ PostgreSQL (:5432) ``` `air-web` 仅与 `air-backend` 通信。`air-backend` 调用 `air-agent` 进行 AI 相关工作。`air-agent` 通过 callback 返回结果,且绝不修改事件状态。 **实时更新:**调查进度通过 Server-Sent Events (SSE) 实时流式传输到浏览器。 | 服务 | 技术栈 | |---------|-------| | `air-web` | React 18, TypeScript, Vite, React Router v6, TanStack Query | | `air-backend` | Java 21, Spring Boot 3.4.1, Spring Security 6, Spring Data JPA, Flyway, PostgreSQL | | `air-agent` | Python 3.12+, FastAPI, LangChain, Ollama (self-hosted LLM), pgvector | ## 已构建的功能 ### 阶段 1 — 项目脚手架 ✅ 三个通过健康检查互联的可运行服务。 - **`air-backend`**: 采用 Gradle 多项目构建的 Spring Boot,`GET /api/health`(检查 DB + agent 可达性),已配置 Flyway - **`air-web`**: Vite + React + TypeScript,带有占位路由的 React Router 外壳,TanStack Query provider,指向后端的 `/api` 代理 - **`air-agent`**: 带有 Pydantic 设置的 FastAPI,`GET /health` 端点 - **`docker-compose.yml`**: PostgreSQL (pgvector)、Ollama、air-backend、air-agent 及其健康检查依赖 - **Flyway V1**: `users` 表 — UUID 主键,邮箱 (唯一),BCrypt 密码哈希,角色检查约束 **冒烟测试:** `GET http://localhost:8080/api/health` → `{"status":"ok","db":"connected","agent":"reachable"}` ### 阶段 2 — 身份验证 ✅ 实现具有基于角色的访问控制 (RBAC) 的、端到端的基于 JWT 的身份验证。 **后端:** - `POST /api/auth/login` — 验证邮箱 + BCrypt 密码 + 角色匹配 → 签发 HS256 JWT (1小时过期) - `GET /api/auth/me` — 从 `@AuthenticationPrincipal` 返回用户信息 - `POST /api/auth/logout` — 无状态返回 200 - `JwtAuthFilter` (`OncePerRequestFilter`) — 验证每次请求中的 Bearer token,设置以 `ROLE_` 为前缀的权限 - `SecurityConfig` — 无状态会话,针对 `localhost:5173` 的 CORS,为未来的 `@PreAuthorize` 启用 `@EnableMethodSecurity` - `DataInitializer` — 初始化 `sre@air.dev` (SRE_ENGINEER) 和 `commander@air.dev` (INCIDENT_COMMANDER),密码均为 `password` **前端:** - 登录页 — 全屏 AmEx 深蓝色背景,白色卡片表单,角色选择器,预填的演示凭证 - `AuthProvider` / `useAuth()` — token + 用户信息持久化存储到 `localStorage` - `ProtectedLayout` — 使用侧边栏包裹所有需验证的路由;遇到 401 时重定向至 `/login` **演示凭证:** | 邮箱 | 密码 | 角色 | |-------|----------|------| | `sre@air.dev` | `password` | SRE Engineer | | `commander@air.dev` | `password` | Incident Commander | ### 阶段 3 — 告警接入与关联 ✅ 告警流入,经过标准化,并去重关联为告警组。 **Flyway V2** — 两张新表: ``` alert_groups (id, dedup_key, service, first_seen, last_seen, occurrence_count, linked_incident_id) alerts (id, source, source_id, summary, service, metric, error_signature, severity_hint, dedup_key, alert_group_id, raw_payload, reported_at, created_at) ``` **后端端点:** | 方法 | 路径 | 描述 | |--------|------|-------------| | `POST` | `/api/alerts` | 接入告警 → 标准化 → 计算 dedup key → 关联至告警组 → `201` | | `GET` | `/api/alerts` | 列出告警,按 `source` / `service` 过滤,使用 `limit` / `offset` 分页 | | `GET` | `/api/alert-groups/:id` | 包含所有成员告警的告警组详情 | **关联逻辑:** - Dedup key = `service + ":" + metric + ":" + errorSignature` - 5分钟时间窗口:新告警会附加到具有相同 dedup key 的最近开启的告警组中,或开启一个新告警组 - 并发接入受组查找时的 `@Lock(PESSIMISTIC_WRITE)` (`SELECT ... FOR UPDATE`) 保护 - 幂等性:相同的 `source + source_id` 组合视为空操作 — 返回已有告警的关联状态 **限流:** - 每个 `source` 在内存中的固定窗口计数器 - 可通过 `RATE_LIMIT_ALERTS_PER_MINUTE` 配置 (默认 60);超出限制时返回 `429` **前端 — 告警页 (`/alerts`):** - 过滤栏:source 下拉菜单 + service 文本过滤器 - 表格视图:严重程度徽标 (彩色圆点 + 标签)、service 标签、source、摘要、发生时间 - 可展开行:点击任意行查看告警组统计信息 (发生次数、首次/最后一次发现时间、dedup key) 以及所有同级告警 - 带有可直接复制的 `curl` 命令的空状态界面,方便快速测试 **新增共享组件 — `Layout.tsx`:** - 深蓝色侧边栏 (`#00175a`),带有 AIR 品牌 - 角色感知导航:Incident Commander 可看到 Integrations + Settings - 页脚包含用户名、角色标签和登出按钮 - 所有受保护路由现在均采用 `` → `` 模式 ## 本地运行 (无需 Docker) **前置条件:** Java 21, Node.js 20+, Python 3.12+, PostgreSQL 17 ### 1. 数据库 ``` # 创建数据库和用户(仅首次) psql -c "CREATE USER air WITH PASSWORD 'air';" psql -c "CREATE DATABASE air OWNER air;" ``` ### 2. 后端 ``` # 从 repo 根目录 — Flyway migrations 在启动时自动运行 ./gradlew :air-backend:bootRun # 监听于 http://localhost:8080 ``` ### 3. Agent ``` cd air-agent python3 -m venv .venv .venv/bin/pip install -r requirements.txt .venv/bin/uvicorn main:app --reload --port 8000 # 监听于 http://localhost:8000 ``` ### 4. 前端 ``` cd air-web npm install npm run dev # 监听于 http://localhost:5173 ``` 打开 `http://localhost:5173` — 你将被重定向至登录页。 ### 验证所有服务是否启动 ``` curl http://localhost:8080/api/health # {"status":"ok","db":"connected","agent":"reachable"} ``` ### 接入测试告警 ``` # 获取 token TOKEN=$(curl -s -X POST http://localhost:8080/api/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"sre@air.dev","password":"password","role":"SRE_ENGINEER"}' \ | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])") # 摄入 alert curl -s -X POST http://localhost:8080/api/alerts \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"source":"ELF","summary":"DB connection pool exhausted","service":"checkout-service","severityHint":"P2","metric":"db.pool.size","errorSignature":"HikariPool-1"}' \ | python3 -m json.tool ``` ## 环境变量 所有变量都有合理的本地默认值。在生产环境中请覆盖以下配置: | 变量 | 默认值 | 描述 | |----------|---------|-------------| | `SPRING_DATASOURCE_URL` | `jdbc:postgresql://localhost:5432/air` | PostgreSQL JDBC URL | | `SPRING_DATASOURCE_USERNAME` | `air` | 数据库用户名 | | `SPRING_DATASOURCE_PASSWORD` | `air` | 数据库密码 | | `JWT_SECRET` | `air-dev-jwt-secret-…` | HS256 签名密钥 (最少 32 字节) | | `JWT_EXPIRY_MINUTES` | `60` | Token 有效期 | | `AIR_AGENT_BASE_URL` | `http://localhost:8000` | air-agent 的基础 URL | | `CORRELATION_WINDOW_MINUTES` | `5` | 告警关联窗口 | | `RATE_LIMIT_ALERTS_PER_MINUTE` | `60` | 每个 source 每分钟允许的最大告警数 | ## 项目结构 ``` air/ ├── specs/ │ ├── mission.md # What AIR is, why it exists, core principles │ ├── tech-stack.md # Architecture, service breakdown, design decisions │ └── roadmap.md # 12 feature-sized phases with definitions of done ├── air-web/ │ └── src/ │ ├── components/ │ │ └── Layout.tsx # Sidebar navigation shell │ ├── lib/ │ │ ├── api.ts # Typed fetch client with 401 handling │ │ └── auth.tsx # AuthProvider + useAuth hook │ └── pages/ │ ├── Login.tsx # Auth page │ └── Alerts.tsx # Alert ingestion + correlated groups ├── air-backend/ │ └── src/main/ │ ├── java/com/amex/air/ │ │ ├── controller/ # HealthController, AuthController, AlertController │ │ ├── domain/ # User, Alert, AlertGroup (JPA entities) │ │ ├── dto/ # Request/response records │ │ ├── repository/ # JPA repos (AlertGroupRepository has PESSIMISTIC_WRITE lock) │ │ ├── security/ # JwtService, JwtAuthFilter, SecurityConfig │ │ └── service/ # AlertService (correlation + rate limiting) │ └── resources/ │ ├── application.yml │ └── db/migration/ │ ├── V1__create_users.sql │ └── V2__create_alerts.sql └── air-agent/ ├── main.py # FastAPI app └── config.py # Pydantic settings ``` ## 路线图 | 阶段 | 标题 | 状态 | |-------|-------|--------| | 1 | 项目脚手架 | ✅ 已完成 | | 2 | 身份验证 | ✅ 已完成 | | 3 | 告警接入与关联 | ✅ 已完成 | | 4 | 事件创建 | 待办 | | 5 | 调查 Agent 与 SSE | 待办 | | 6 | RCA Agent | 待办 | | 7 | Runbook Agent 与知识库 | 待办 | | 8 | 通信 Agent 与 Slack 视图 | 待办 | | 9 | 复盘 Agent 与回顾 | 待办 | | 10 | 仪表盘与分析 | 待办 | | 11 | 集成与设置 | 待办 | | 12 | 强化与端到端测试 | 待办 | 请查看 `specs/roadmap.md` 获取每个阶段的完整完成标准。 ## 设计原则 1. **证据优先。** 每个 AI 生成的结论都必须引用其来源。拒绝毫无根据的断言。 2. **人类在环。** AIR 负责提出建议;工程师负责决策和执行。 3. **可解释性高于魔法。** 置信度分数、引用的证据以及 `INSUFFICIENT_EVIDENCE` 状态,与答案本身一样重要。 4. **受控的知识库。** 只有经过人工批准的内容才能进入知识库 — 未经批准的 AI 输出绝不能反哺给自身。
标签:AIOps, AI智能体, AI风险缓解, RAG, SRE, 偏差过滤, 后端开发, 测试用例, 请求拦截, 运维, 逆向工具