KhushviB/sre-incident-response
GitHub: KhushviB/sre-incident-response
一个AI代理SRE事件响应训练环境,通过模拟生产服务器故障场景测试多步骤因果诊断能力。
Stars: 0 | Forks: 0
# SRE 事件响应 — OpenEnv
一个 [OpenEnv](https://huggingface.co/openenv) 环境,其中 AI 代理扮演
值班 SRE 工程师的角色,诊断并修复日益复杂的生产服务器
级联故障。
代理通过结构化操作与**模拟 Linux 服务器**交互
(终止进程、修复配置、设置环境变量、重启服务),并在每一步后根据服务器健康状况获得**部分信用奖励**。
## 为何选择此环境
站点可靠性工程是软件行业中风险最高、技能要求最高的工作之一。当生产服务器在凌晨 2 点宕机时,SRE 必须:
- 阅读嘈杂的日志并找到真正的根本原因
- 按正确顺序修复问题(某些修复依赖于其他修复)
- 仅在解决根本原因后才重启
- 验证修复是否真正有效
此环境正是测试这种推理链——不是模式匹配,
不是检索,而是压力下的真正多步骤因果诊断。
## 环境描述
### 领域
SRE 事件响应——诊断和修复故障的生产服务器。
### 伪造服务器
环境维护一个**Python 字典**来表示服务器状态。没有真正的操作系统,没有真正的 Docker-in-Docker。代理通过 FastAPI HTTP API 与其交互,返回结构化观察结果。
### 操作空间
| 操作 | 必填字段 | 描述 |
|--------|----------------|-------------|
| `read_logs` | — | 读取当前服务器日志输出 |
| `list_processes` | — | 列出运行中的进程及 CPU/内存使用情况 |
| `kill_process` | `pid` | 根据 PID 终止进程 |
| `restart_service` | `service` | 重启 nginx、数据库或应用 |
| `fix_config` | `config_key`、`config_value` | 更改服务器配置值 |
| `clear_disk` | — | 删除旧日志文件以释放磁盘空间 |
| `set_env_var` | `env_key`、`env_value` | 设置环境变量 |
| `check_health` | — | 运行 HTTP 健康检查,获取响应码 |
**操作格式**(发送 JSON 到 `/step`):
```
{ "action_type": "kill_process", "pid": 1042 }
{ "action_type": "fix_config", "config_key": "nginx_port", "config_value": "8080" }
{ "action_type": "restart_service", "service": "nginx" }
```
### 观察空间
每一步返回结构化观察结果:
```
{
"message": "Alert received. Server is unhealthy.",
"nginx_status": "crashed",
"memory_usage": 95.0,
"disk_usage": 42.0,
"db_status": "running",
"http_status": null,
"processes": [
{ "pid": 1042, "name": "memory_hog", "cpu_percent": 4.5, "mem_percent": 92.0 }
],
"logs": "[CRITICAL] nginx crashed\n[WARNING] memory_hog pid 1042...",
"env_vars": { "PORT": "80", "APP_MODE": "debug" },
"config": { "nginx_port": "80", "worker_count": "4" },
"step_number": 1,
"task_id": 1
}
```
### 奖励空间
- 类型:`float`,取值范围为 `[0.0, 1.0]`
- **每一步后获得部分信用**——绝非二进制
- 每个标准独立评分——修复一个问题总是有帮助的
- `breakdown` 字典显示具体哪个修复获得了哪些分数
- `is_improvement` 标志告诉代理上一步操作是否有帮助
## 任务
### 任务 1 — 内存泄漏修复(简单)
**场景:** 一个恶意进程(`memory_hog`,pid 1042)已消耗 95% 的服务器内存,导致 nginx 崩溃。服务器无响应。
**代理必须执行的操作:**
1. `read_logs` — 查看 nginx 崩溃和 memory_hog 警告
2. `list_processes` — 确认 pid 1042 占用 92% 内存
3. `kill_process`(pid 1042)— 终止恶意进程
4. `restart_service`(nginx)— 现在内存已释放,重启 nginx
5. `check_health` — 验证 HTTP 200
**评分标准:**
| 标准 | 分数 |
|-----------|--------|
| 恶意进程已清除 | +0.10 |
| 内存低于 80% | +0.30 |
| nginx 运行中 | +0.40 |
| HTTP 200 | +0.20 |
**目标分数:** ~0.8 | **最大步数:** 10
### 任务 2 — 级联 500 错误(中等)
**场景:** 生产环境中出现 HTTP 500 错误。三处同时故障:
一个内存泄漏的 `app_worker` 进程,nginx 代理到错误端口(9999 而非 8080),以及 `APP_MODE` 设置为 `debug` 而非 `production`。
**代理必须执行的操作:**
1. 阅读日志以识别所有三个根本原因
2. `kill_process`(app_worker)— 修复内存问题
3. `fix_config`(nginx_port → 8080)— 修复路由
4. `set_env_var`(APP_MODE → production)— 修复应用模式
5. `restart_service`(nginx)— 仅在所有三个修复完成后才能生效
**评分标准:**
| 标准 | 分数 |
|-----------|--------|
| 内存低于 70% | +0.20 |
| app_worker 已清除 | +0.10 |
| nginx_port == 8080 | +0.20 |
| APP_MODE == production | +0.15 |
| nginx 运行中 | +0.20 |
| HTTP 200 | +0.15 |
**目标分数:** ~0.5 | **最大步数:** 15
### 任务 3 — 多故障恢复(困难)
**场景:** 完全生产中断。五处同时级联故障:
1. **磁盘 98% 满** — 旧的轮转日志阻塞所有磁盘写入
2. **DB_HOST 错误** — 指向已停用的主机 `db-old.internal`
3. **APP_ENV = staging** — 未加载生产配置
4. **Nginx 配置错误** — 错误端口(7777→443)和过少的 worker(1→8)
5. **失控的 cron**(pid 3077)— 占用 85% 内存和 99% CPU
**关键顺序依赖:** 磁盘必须先清理**然后**数据库才能重新连接,因为满的磁盘会阻塞 postgres WAL 写入。
**代理必须执行的操作:**
1. `read_logs` — 解析 14 行嘈杂日志,找到 5 个根本原因
2. `clear_disk` — 解除 postgres WAL 写入阻塞
3. `set_env_var`(DB_HOST → db.internal)— 重新连接数据库
4. `set_env_var`(APP_ENV → production)— 加载生产配置
5. `fix_config`(nginx_port → 443)— 修复 nginx 端口
6. `fix_config`(worker_count → 8)— 修复 worker 数量
7. `kill_process`(pid 3077)— 终止失控的 cron
8. `restart_service`(nginx)— 所有修复后重启
9. `check_health` — 验证 HTTP 200
**评分标准:**
| 标准 | 分数 |
|-----------|--------|
| 磁盘低于 60% | +0.15 |
| DB_HOST 正确 | +0.15 |
| 数据库已连接 | +0.10 |
| APP_ENV 为 production | +0.10 |
| nginx_port 为 443 | +0.15 |
| worker_count 为 8 | +0.10 |
| 失控 cron 已清除 | +0.10 |
| 内存低于 50% | +0.10 |
| HTTP 200 | +0.05 |
**目标分数:** ~0.25 | **最大步数:** 20
## 项目结构
```
sre-incident-response/
├── env/
│ ├── __init__.py
│ ├── models.py ← Pydantic models: Action / Observation / Reward
│ ├── environment.py ← Core env: reset() / step() / state()
│ ├── tasks/
│ │ ├── task_easy.py ← Task 1 fake world + apply_action()
│ │ ├── task_medium.py ← Task 2 fake world + apply_action()
│ │ └── task_hard.py ← Task 3 fake world + apply_action()
│ └── graders/
│ ├── grader_easy.py ← Task 1 scorer → 0.0–1.0
│ ├── grader_medium.py← Task 2 scorer → 0.0–1.0
│ └── grader_hard.py ← Task 3 scorer → 0.0–1.0
├── server.py ← FastAPI: /reset /step /state /health /tasks
├── inference.py ← Baseline agent (OpenAI client)
├── test_local.py ← Local test suite (50 checks)
├── openenv.yaml ← OpenEnv spec metadata
├── Dockerfile
├── requirements.txt
└── README.md
```
## 设置与使用
### 前置条件
```
python 3.11+
pip install fastapi uvicorn pydantic openai requests pyyaml
```
### 本地运行
```
# 终端 1 — 启动环境服务器
python server.py
# → http://localhost:7860
# 终端 2 — 运行测试套件(无需 API key)
python test_local.py --offline
# 终端 3 — 运行 baseline agent(需要 API key)
export HF_TOKEN=hf_your_token_here
python inference.py
```
### 手动 API 测试
```
# health check
curl http://localhost:7860/health
# list tasks
curl http://localhost:7860/tasks
# start task 1
curl -X POST http://localhost:7860/reset \
-H "Content-Type: application/json" \
-d '{"task_id": 1}'
# send an action
curl -X POST http://localhost:7860/step \
-H "Content-Type: application/json" \
-d '{"action_type": "kill_process", "pid": 1042}'
# check state
curl http://localhost:7860/state
```
### Docker
```
docker build -t sre-incident-response .
docker run -p 7860:7860 sre-incident-response
```
### 提交前验证
```
./validate-submission.sh https://your-space.hf.space ./sre-incident-response
```
## 推理用环境变量
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `HF_TOKEN` 或 `API_KEY` | — | 您的 HuggingFace / API 密钥(必填) |
| `API_BASE_URL` | `https://router.huggingface.co/v1` | LLM 端点 |
| `MODEL_NAME` | `openai/gpt-oss-20b` | 模型标识符 |
| `ENV_URL` | `http://localhost:7860` | 环境服务器 URL |
## 基线分数
使用通过 HuggingFace 路由的 `openai/gpt-oss-20b` 进行基线运行:
| 任务 | 名称 | 分数 |
|------|------|-------|
| 1 | memory-leak-fix | — |
| 2 | cascading-500-errors | — |
| 3 | multi-failure-recovery | — |
| | **平均** | **—** |
## 奖励设计
奖励函数设计为在每一步都提供**有意义的信号**——不仅仅是剧集结束时。
关键属性:
- **始终是部分的**——修复一件事总是会提高分数
- **确定性**——相同的服务器总是返回相同的分数
- **独立标准**——每个修复单独评分
- **顺序感知**——某些修复仅在先决条件完成后才能生效(例如 nginx 重启仅在根本原因修复后才能成功)
- **没有总是相同的分数**——确保剧集步骤之间的方差
分数进展示例:
```
Task 1 (easy): 0.075 → 0.400 → 1.000 (3 steps)
Task 2 (medium): 0.347 → 0.500 → 0.700 → 0.850 → 1.000 (4 steps)
Task 3 (hard): 0.034 → 0.176 → 0.426 → ... → 1.000 (7+ steps)
```
## 运行时限制
- 最大推理时间:20 分钟
- 最大 vCPU:2
- 最大内存:8 GB
- Python:3.11
- 端口:7860
## 许可证
MIT
标签:AI代理, AV绕过, Docker, FastAPI, Homebrew安装, Linux服务器, OpenEnv, Python, SRE, 偏差过滤, 安全防御评估, 强化学习, 故障恢复, 故障诊断, 无后门, 服务器运维, 服务网格, 根因分析, 模拟环境, 生产环境, 监控告警, 站点可靠性工程, 自动化运维, 请求拦截, 运维自动化, 逆向工具