Mohit-Jhajhria/sre-incident-environment
GitHub: Mohit-Jhajhria/sre-incident-environment
一个符合 OpenEnv 标准的强化学习环境,用于训练和评估 SRE 事件响应智能体,通过模拟带噪声的微服务故障场景测试多跳因果诊断与风险评估能力。
Stars: 0 | Forks: 0
title: ProductionIncidentEnv
emoji: 🚨
colorFrom: red
colorTo: blue
sdk: docker
app_port: 7860
tags:
- openenv
- reinforcement-learning
- sre
- agent-evaluation
short_description: 用于 SRE 事件响应 Agent 训练的 OpenEnv 环境
# ProductionIncidentEnv
**一个符合 OpenEnv 标准的强化学习环境,用于生产环境 SRE 事件响应。**
Agent 扮演值班 Site Reliability Engineer (SRE),管理一个模拟的 8 服务微服务栈。系统中已被注入隐蔽故障;Agent 必须诊断根本原因,应用针对性的修复措施,并在级联故障引发全面中断之前恢复 SLO 合规性。
## 为什么选择这个领域?
现代 LLM Agent 越来越多地部署在代理式 SRE 工作流中 —— 读取仪表盘、提出修复建议并执行 Runbook。然而,目前尚不存在针对这一能力的标准化评估环境。
`ProductionIncidentEnv` 填补了这一空白。它测试了对生产级 Agent 至关重要的能力:
- **多跳因果诊断** —— 故障源头没有标签;Agent 必须从带有噪声的指标和部分日志信号中推断出来
- **具有后果的操作** —— 错误的修复措施会主动恶化系统状态并消耗影响范围预算
- **时序推理** —— 故障会逐步演变;在稳定之前重启会重新触发泄漏
- **结构性克制** —— 得分最高的 Agent 是*精确手术式*的,而非激进式的
该环境的设计使得随机或反应式 Agent 无法解决问题,并能有效区分不同能力水平的 LLM。
## 环境概述
### 服务拓扑
一个建模简化电商后端的 3 层有向无环图:
```
Tier 0 (edge): api-gateway
↓ ↓ ↓
Tier 1 (core): auth-svc product-svc cart-svc
↓
order-svc
↓ ↓
Tier 2 (data): payment-svc inventory-svc db-proxy
```
所有服务都有标准的错误率和 p99 延迟 SLO 阈值。故障通过依赖图以可配置的权重向上游传播。
### 故障类型
| 故障 | 来源 | 级联模式 |
|---|---|---|
| `MEMORY_LEAK` | 任意服务 | 性能降级在约 20 步内攀升,直到 OOM 崩溃 |
| `BAD_DEPLOY` | 任意服务 | 立即出现错误峰值;观测中可定位到版本 |
| `TRAFFIC_SURGE` | 边缘层 | CPU 饱和 → 延迟增加 → 下游错误级联 |
| `DB_CONN_EXHAUSTION` | 数据层 | 连接池填满;所有调用方超时 |
| `DEPENDENCY_LATENCY` | 任意服务 | p99 延迟攀升;调用方开始超时 |
| `NETWORK_PARTITION` | 任意对 | 跨分区的调用出现 100% 错误 |
## 动作空间
所有动作均为参数化的离散动作。无效动作会被扣分但不会被阻止。
| 动作 | 参数 | 爆炸半径成本 |
|---|---|---|
| `SCALE_SERVICE` | `service_id`, `delta ∈ {-3,-2,-1,1,2,3}` | — |
| `ROLLBACK_SERVICE` | `service_id`, `steps_back ∈ {1,2,3}` | 0.15 |
| `RESTART_SERVICE` | `service_id` | 0.20 |
| `OPEN_CIRCUIT_BREAKER` | `service_id` | 0.05 |
| `CLOSE_CIRCUIT_BREAKER` | `service_id` | — |
| `ADJUST_RATE_LIMIT` | `service_id`, `multiplier ∈ {0.25,0.5,0.75,1.0,1.5,2.0}` | 0.10 (若 ≤ 0.5) |
| `REROUTE_TRAFFIC` | `from_service`, `to_service`, `percentage ∈ {25,50,75,100}` | 0.10–0.25 |
| `QUERY_LOGS` | `service_id`, `window_minutes ∈ {5,15,30}` | — |
| `QUERY_METRICS` | `service_id`, `metric` | — |
| `ACKNOWLEDGE_ALERT` | `alert_id` | — |
| `PAGE_HUMAN` | `severity ∈ {P1,P2}` | — (终止) |
| `NO_OP` | — | — |
**爆炸半径预算** 初始值为 1.0,由高风险动作消耗。降至 0.0 会立即触发 `CATASTROPHIC` 终止状态并扣除 50 分惩罚。
## 观测空间
在每一步,Agent 接收:
```
{
"services": {
"api-gateway": {
"error_rate": 0.0023,
"latency_p50": 52.1,
"latency_p99": 88.4,
"cpu_utilization": 0.38,
"memory_utilization": 0.44,
"request_rate": 498.3,
"pod_count": 6,
"circuit_breaker_open": false,
"rate_limit_multiplier": 1.0,
"active_version": 3,
"is_slo_violated": false,
"slo_error_rate": 0.005,
"slo_latency_p99": 150.0
},
"...": "..."
},
"alerts": [
{
"id": "a3f2b1",
"service_id": "cart-service",
"metric": "error_rate",
"severity": "P2",
"current_val": 0.082,
"age_steps": 3,
"acknowledged": false
}
],
"infra": {
"cluster_capacity_used_pct": 0.27,
"db_conn_pool_used_pct": 0.21
},
"change_log": [...],
"step": 4,
"time_remaining": 56,
"blast_radius_budget": 1.0,
"query_result": null
}
```
指标值包含噪声(高斯分布 σ 与测量类型成比例)。Agent 永远不会直接观测到 `degradation_factor`、`is_crashing` 或故障类型/来源。
## 奖励设计
奖励在完整轨迹上是密集且成型的。
| 组成部分 | 描述 | 数值 |
|---|---|---|
| `slo_health` | 每一步所有服务的平均健康分 | `[0, 2.0]` |
| `resolution_bonus` | 成功奖励,随速度提升 | `[50, 75]` |
| `invalid_action` | 结构无效动作的惩罚 | `−2.0` |
| `redundant_action` | 重复无效动作的惩罚 | `−1.5` |
| `worsening` | 当动作导致健康度下降 > 5% 时的比例惩罚 | `−3.0 × drop` |
| `blast_radius` | 当预算 < 0.3 时的渐进式每步惩罚 | `−5.0 × (1 − budget)` |
| `escalation` | 升级给人类决策的奖励/惩罚 | `−10 to +20` |
| `diagnostic_novelty` | 首次查询每个服务/指标的一次性奖励 | `+0.3` |
**典型得分范围:** `−200` 到 `+100`。一个校准良好的 Agent 会在 15–60 步内解决事件并得分 `+60 to +85`。
## 任务
### 任务 1 — 简单:独立错误部署
```
Fault: BAD_DEPLOY on cart-service (version 4, ~15% error rate)
Seed: 42
Steps: max 60
```
cart-service 接收到了一个错误构建产物。其错误率已飙升,且观测中可见版本 4。级联尚未开始。只需一次 `steps_back=1` 的 `ROLLBACK_SERVICE` 即可解决该事件。
**评分标准:** 实现解决 (0.40) + 正确的回滚目标 (0.30) + 20 步以内 (0.20) + 预算保留 (0.10)
### 任务 2 — 中等:流量激增级联
```
Fault: TRAFFIC_SURGE on api-gateway (4× nominal RPS)
Seed: 137
Steps: max 100
```
黑色星期五风格的流量激增冲击边缘层。CPU 正在饱和,延迟级联正在向下游蔓延。Agent 必须识别出问题是吞吐量而非代码 Bug,并对*源头*应用扩容或限流,而不是追逐症状。
**评分标准:** 解决 (0.35) + 正确的源头操作 (0.25) + 精确聚焦 (0.15) + 速度 (0.15) + 预算 (0.10)
### 任务 3 — 困难:DB 连接耗尽 + 内存级联
```
Fault: DB_CONN_EXHAUSTION on db-proxy (~5 conns/step leak)
+ induced memory leak in order-service (compound)
Seed: 314
Steps: max 150
```
数据库连接池正在填满。频繁调用 db-proxy 的 order-service 在内存中累积了泄漏的连接句柄。在稳定 db-proxy 之前重启 order-service 将导致其立即重新泄漏。Agent 必须按顺序执行:
1. 稳定 db-proxy (对调用方限流或熔断)
2. 等待池压力 < 60%
3. 重启 order-service 以清除其内存状态
**评分标准:** 解决 (0.30) + 优先处理 DB (0.20) + 重启时机 (0.15) + 诊断质量 (0.15) + 速度 (0.10) + 预算 (0.10)
## 基线结果
来自启发式基线 Agent 的参考分数 (确定性,无 LLM):
| 任务 | 分数 | 终止状态 | 步数 |
|---|---|---|---|
| task_easy_bad_deploy | ~0.80 | SUCCESS | ~12 |
| task_medium_traffic_surge | ~0.65 | SUCCESS | ~35 |
| task_hard_db_cascade | ~0.45 | SUCCESS/TIMEOUT | ~80 |
| **平均** | **~0.63** | | |
使用 GPT-4o 的 LLM Agent 通常在简单任务中得分 0.70–0.85,中等任务 0.55–0.75,困难任务 0.35–0.60。
## 设置
### 本地环境 (Python 3.11+)
```
git clone
cd production-incident-env
pip install -r requirements.txt
# 运行 API server
PYTHONPATH=. uvicorn api.main:app --host 0.0.0.0 --port 7860 --reload
# 运行启发式基线
PYTHONPATH=. python scripts/baseline.py
# 运行 LLM 基线 (需要 OpenAI key)
OPENAI_API_KEY=sk-... PYTHONPATH=. python scripts/baseline.py --agent llm
# 运行特定任务并启用详细日志
PYTHONPATH=. python scripts/baseline.py --task task_easy_bad_deploy --verbose
```
### Docker
```
# 构建
docker build -t production-incident-env .
# 运行 (API server)
docker run -p 7860:7860 production-incident-env
# 运行并支持 LLM baseline
docker run -p 7860:7860 -e OPENAI_API_KEY=sk-... production-incident-env
# 在容器中运行 baseline 脚本
docker run -e OPENAI_API_KEY=sk-... production-incident-env \
python scripts/baseline.py --agent heuristic
```
服务将在 `http://localhost:7860` 可用。
## API 示例
### 在特定任务上启动一个 Episode
```
curl -X POST http://localhost:7860/reset \
-H "Content-Type: application/json" \
-d '{"task_id": "task_easy_bad_deploy"}'
```
### 执行一个动作
```
# 首先查询日志 (良好的诊断实践)
curl -X POST http://localhost:7860/step \
-H "Content-Type: application/json" \
-d '{"action_type": "QUERY_LOGS", "params": {"service_id": "cart-service", "window_minutes": 15}}'
# 回滚 cart-service
curl -X POST http://localhost:7860/step \
-H "Content-Type: application/json" \
-d '{"action_type": "ROLLBACK_SERVICE", "params": {"service_id": "cart-service", "steps_back": 1}}'
```
### 获取内部状态 (Ground Truth)
```
curl http://localhost:7860/state
```
### 列出任务和动作 Schema
```
curl http://localhost:7860/tasks
```
### 对 Episode 进行评分
```
curl -X POST http://localhost:7860/grader \
-H "Content-Type: application/json" \
-d '{"task_id": "task_easy_bad_deploy"}'
```
### 运行内置基线
```
curl -X POST http://localhost:7860/baseline \
-H "Content-Type: application/json" \
-d '{"task_ids": ["task_easy_bad_deploy", "task_medium_traffic_surge"]}'
```
## 仓库结构
```
production-incident-env/
├── env/
│ ├── __init__.py
│ ├── environment.py # Core environment: step(), reset(), state()
│ ├── models.py # Pydantic models: Observation, Action, Reward, ...
│ ├── tasks.py # Task definitions (easy / medium / hard)
│ └── graders.py # Deterministic graders, 0.0–1.0 scores
├── api/
│ ├── __init__.py
│ └── main.py # FastAPI app
├── scripts/
│ └── baseline.py # Heuristic + LLM baseline agents, CLI runner
├── openenv.yaml # OpenEnv spec compliance manifest
├── Dockerfile
├── requirements.txt
└── README.md
```
## 设计说明
**为什么要有噪声观测?** 真实的监控系统存在测量滞后和噪声。一个完美信息的环境会过于简单且不切实际 —— Agent 应当学会对传感器噪声具有鲁棒性。
**为什么要有爆炸半径预算?** 在生产环境中,一个"为了保险起见"重启 6 个服务的 Agent 是危险的。该预算强制进行手术式思考,并使不确定性的代价具体化。
**为什么困难任务要有复合故障?** 大多数真实事件涉及交互效应,而非单一根本原因。任务 3 专门测试 Agent 是否能发现在修复根本原因 B 之前修复症状 A 会导致立即复发 —— 这是一种简单的反应式策略无法处理的时间因果推理形式。
**故障传播模型。** 性能降级通过带有边权重的 DAG 流动。熔断器会打断传播。这意味着对级联故障的正确响应取决于 Agent 必须推断(而非直接观测)的拓扑知识。
标签:AIOps, AI智能体, Docker, LLM评估, Ollama, OpenEnv, Petitpotam, Python, SLO管理, SRE, 仿真模拟, 偏差过滤, 分布式系统, 响应大小分析, 因果推理, 多跳推理, 安全防御评估, 容错恢复, 强化学习环境, 故障诊断, 无后门, 服务拓扑, 根因分析, 生产环境模拟, 站点可靠性工程, 级联故障, 自治系统, 请求拦截, 运维自动化, 逆向工具, 错误注入