NamanKansal230505/incident-response-openenv
GitHub: NamanKansal230505/incident-response-openenv
这是一个基于OpenEnv框架的云原生事件响应分诊模拟环境,旨在通过确定性模拟复现微服务故障,以训练和评估AIOps智能体。
Stars: 0 | Forks: 0
title: AIOps Triage Environment Server
emoji: 🛰️
colorFrom: indigo
colorTo: red
sdk: docker
pinned: false
app_port: 8000
base_path: /docs
tags:
- openenv
- aiops
- sre
- incident-response
# AIOps 筛选环境
针对两个现实世界 SRE 基准测试——Microsoft Research [AIOpsLab](https://github.com/microsoft/AIOpsLab) 和 IBM [ITBench](https://github.com/IBM/itbench)——的 OpenEnv 封装,在统一的 `reset / step / state` 接口下进行了整合。涵盖了 AIOpsLab 定义的四种典型 AIOps 任务类型(检测、定位、分析、缓解),跨越 15 个故障和 4 个微服务拓扑。
两个上游基准测试都需要一个带有 helm 和故障注入 hooks 的实时 Kubernetes 集群,这无法放入单个 Hugging Face Space 容器中。该环境提供了其问题语料库的确定性、可重现种子(seed-reproducible)模拟器——这与 [`tbench2_env`](https://github.com/meta-pytorch/OpenEnv/tree/main/envs/tbench2_env) 本地模式使用的策略相同,旨在提供一个无需 Docker-in-Docker 即可运行的 Terminal-Bench-2 封装。
## 快速开始
```
import asyncio
from client import AIOpsTriageEnv
from models import AIOpsAction, ActionType
async def main():
async with AIOpsTriageEnv(base_url="http://localhost:8000") as env:
result = await env.reset(task="mitigation__aiops_misconfig_app_hotel_res")
print(result.observation.task_instruction)
result = await env.step(AIOpsAction(
action_type=ActionType.INVESTIGATE,
command="check_config",
args={"service": "reservation"},
))
print(result.observation.telemetry)
result = await env.step(AIOpsAction(
action_type=ActionType.MUTATE,
command="update_config",
args={"service": "reservation",
"key": "db_connection_timeout_ms",
"value": "5000"},
))
print(result.reward, result.done)
asyncio.run(main())
```
## 构建 Docker 镜像
```
docker build -t aiops-triage:latest .
docker run --rm -p 8000:8000 aiops-triage:latest
curl http://localhost:8000/health
```
健康检查响应:`{"status":"healthy"}`
## 环境详情
### Action
**AIOpsAction**:针对模拟集群采取的 Agent 的一个步骤。
| 字段 | 类型 | 默认值 | 描述 |
|-------|------|---------|-------------|
| `action_type` | str | `"investigate"` | 动作类别:`investigate`(调查)、`mutate`(变更)或 `finalize`(终结) |
| `command` | str | — | 动作类型内的特定动词 |
| `args` | dict | `{}` | 作为关键字字典的命令参数 |
### Observation
**AIOpsObservation**:每次 `step()` 后返回。
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `message` | str | 来自上一次动作的人类可读反馈 |
| `telemetry` | dict | 来自上一次调查的结构化数据(日志 / 指标 / 配置 / 依赖关系) |
| `task_type` | str | `detection`(检测) \| `localization`(定位) \| `analysis`(分析) \| `mitigation`(缓解) |
| `task_instruction` | str | 在重置时显示的纯英文任务提示 |
| `alert_summary` | str | 针对该事件的模拟监控告警 |
| `available_services` | list[str] | 已安装拓扑中的服务 |
| `step_number` | int | 当前步骤索引 |
| `max_steps` | int | Episode 步数预算 |
| `reward` | float \| None | 累积奖励,严格在 (0, 1) 之间 |
| `done` | bool | Episode 已终止 |
| `finalized` | bool | Agent 已提交终结答案 |
| `last_action_error` | str \| None | 如果动作被拒绝则显示错误 |
### State
**AIOpsState**:通过 `/state` 暴露的服务端状态。
| 字段 | 类型 | 描述 |
|-------|------|-------------|
| `task_type` | str | 当前任务类型 |
| `task_id` | str | 组合场景 id `{fault}__{task_type}__{topology}__seed{N}` |
| `source_benchmark` | str | `aiopslab` 或 `itbench` |
| `scenario_seed` | int | 用于生成场景的种子 |
| `difficulty` | str | `easy`(简单) \| `medium`(中等) \| `hard`(困难) |
| `root_cause_id` | str | 真实故障 id(对 Agent 隐藏) |
| `finalized` | bool | 已提交终结答案 |
| `mitigation_applied` | bool | `mutate` 动作匹配了故障的有效缓解措施 |
| `actions_taken` | list[str] | Episode 的动作日志 |
| `score` | float | 当前累积分数 |
## 动作类型
| 类型 | Command | Args | 描述 |
|------|---------|------|-------------|
| `investigate` | `list_services` | `{}` | 列举集群中的服务 |
| `investigate` | `check_service` | `{"service": str}` | 状态、副本数、版本 |
| `investigate` | `check_logs` | `{"service": str}` | 最近的日志行 |
| `investigate` | `check_metrics` | `{"service": str}` | CPU、内存、延迟、错误率、RPS、特定于故障的指标 |
| `investigate` | `check_config` | `{"service": str}` | 服务配置字典 |
| `investigate` | `check_dependencies` | `{"service": str}` | 上游和下游边 |
| `mutate` | `restart_service` | `{"service": str}` | 将 pods 重置为就绪状态 |
| `mutate` | `scale_service` | `{"service": str, "replicas": int}` | 更改副本数 |
| `mutate` | `rollback_service` | `{"service": str}` | 回滚部署版本 |
| `mutate` | `update_config` | `{"service": str, "key": str, "value": str}` | 更改配置键 |
| `finalize` | `submit` | `{"answer": {...}}` | 提交 Detection / Localization / Analysis 的终结答案,或在 Mitigation 中记录根本原因 |
## 任务类型
直接基于 AIOpsLab 的四种 AIOps 任务类别建模。
| 任务类型 | Agent 目标 | 终结动作 | 难度 |
|-----------|------------|-----------------|-----------|
| Detection | 决定集群是否正在经历事件 | 带有 `{"anomaly": true\|false}` 的 `finalize` | easy |
| Localization | 识别作为根本原因的单个服务 | 带有 `{"component": ""}` 的 `finalize` | medium |
| Analysis | 识别组件 **以及** 故障类别 | 带有 `{"component": ..., "fault_class": ...}` 的 `finalize` | medium |
| Mitigation | 应用一个真正修复潜在故障的变更动作 | 匹配故障有效缓解签名的 `mutate` | hard |
有效的 `fault_class` 值:`application`(应用)、`resource`(资源)、`network`(网络)、`config`(配置)、`infrastructure`(基础设施)。
## 故障库
默认库中包含 15 个故障,每个都植根于特定的上游问题。精选示例:
| 故障 ID | 来源 | 上游问题 | 类别 |
|----------|--------|------------------|----------|
| `aiops_pod_failure` | aiopslab | `pod_failure` | infrastructure |
| `aiops_ad_service_failure` | aiopslab | `ad_service_failure` | application |
| `aiops_cart_service_failure` | aiopslab | `cart_service_failure` | application |
| `aiops_ad_service_high_cpu` | aiopslab | `ad_service_high_cpu` | resource |
| `aiops_network_loss` | aiopslab | `network_loss` | network |
| `aiops_network_delay` | aiopslab | `network_delay` | network |
| `aiops_recommendation_cache_failure` | aiopslab | `recommendation_service_cache_failure` | config |
| `aiops_k8s_target_port_misconfig` | aiopslab | `k8s_target_port_misconfig` | config |
| `aiops_misconfig_app_hotel_res` | aiopslab | `misconfig_app_hotel_res` | config |
| `aiops_auth_miss_mongodb` | aiopslab | `auth_miss_mongodb` | config |
| `aiops_kafka_queue_problems` | aiopslab | `kafka_queue_problems` | infrastructure |
| `aiops_loadgen_flood_homepage` | aiopslab | `loadgenerator_flood_homepage` | resource |
| `itb_checkout_error_rate` | itbench | "High error rate on service checkout" | application |
| `itb_network_fault_checkout` | itbench | network fault mechanism | network |
| `itb_resource_exhaustion_frontend` | itbench | resource exhaustion mechanism | resource |
每个故障都带有其上游归属和一个机器可检查的 `valid_mitigations` 列表,Mitigation 验证器使用该列表进行程序化状态比较——无需关键字匹配。
## 拓扑
| 拓扑 | 来源 | 服务 | 描述 |
|----------|--------|---------:|-------------|
| `online-boutique` | aiopslab | 11 | Google 的 Online Boutique 演示——许多 AIOpsLab `*_service_failure` 问题的目标 |
| `hotel-reservation` | aiopslab | 13 | DeathStarBench HotelReservation —— AIOpsLab 的旗舰演示应用 |
| `social-network` | aiopslab | 16 | DeathStarBench SocialNetwork |
| `otel-astronomy-shop` | itbench | 16 | OpenTelemetry Astronomy Shop —— ITBench 的默认 k8s 应用 |
每个拓扑都编码了上游应用的实际依赖关系图,这为 Localization/Analysis 任务提供输入,并限制了适用的故障。
## 奖励
奖励遵循 OpenEnv RFC 004 风格的标准组合。该环境默认使用 `IncidentRubric`,它结合了:
- **结果奖励**(在终结步骤上):由任务类型验证器应用,该验证器检查真实的模拟器状态(Mitigation)或结构化的终结负载(Detection / Localization / Analysis)。
- **过程奖励**(在非终结步骤上):针对新的拓扑邻近调查给予 +0.04,针对冗余的重复读取给予 −0.01,针对正确的缓解匹配给予 +0.25,针对错误服务上的破坏性变更给予 −0.08,针对无效动作给予 −0.03。
- **超时惩罚**:如果 `max_steps` 耗尽,则给予 −0.20。
- **限制**:根据 hackathon 规范,所有分数都被严格限制在 `(0.01, 0.99)` 之间——分数永远不会达到 0.0 或 1.0。
可以通过子类化 `IncidentRubric` 并在 `server/aiops_environment.py` 中连接新实例来注入自定义标准。
## 默认任务列表
推理脚本运行此固定列表,以便基线运行可重现。`reset(task="...", seed=N)` 也接受任意 `{task_type}__{fault_id}` 组合,而单独的 `{task_type}` 形式解析为第一个匹配的列表条目。
| # | 任务 ID | 类型 | 来源 | 难度 |
|---|---------|------|--------|-----------|
| 1 | `detection__aiops_pod_failure` | detection | aiopslab | easy |
| 2 | `detection__itb_network_fault_checkout` | detection | itbench | easy |
| 3 | `localization__aiops_network_loss` | localization | aiopslab | medium |
| 4 | `localization__itb_resource_exhaustion_frontend` | localization | itbench | medium |
| 5 | `analysis__aiops_recommendation_cache_failure` | analysis | aiopslab | medium |
| 6 | `analysis__itb_network_fault_checkout` | analysis | itbench | medium |
| 7 | `mitigation__aiops_misconfig_app_hotel_res` | mitigation | aiopslab | hard |
| 8 | `mitigation__itb_checkout_error_rate` | mitigation | itbench | hard |
## 基线
该环境附带了两个可重现的基线。
### 启发式基线(无 LLM)—— `baseline_smoke.py`
确定性基于规则的 Agent,读取告警,调查明显服务,并提交尽力而为的答案。故意设计得较弱,以便显示环境的难度梯度。
| 任务 | 类型 | 难度 | 分数 |
|------|------|------------|------:|
| `detection__aiops_pod_failure` | detection | easy | 0.99 |
| `detection__itb_network_fault_checkout` | detection | easy | 0.99 |
| `localization__aiops_network_loss` | localization | medium | 0.75 |
| `localization__itb_resource_exhaustion_frontend` | localization | medium | 0.99 |
| `analysis__aiops_recommendation_cache_failure` | analysis | medium | 0.65 |
| `analysis__itb_network_fault_checkout` | analysis | medium | 0.73 |
| `mitigation__aiops_misconfig_app_hotel_res` | mitigation | hard | 0.58 |
| `mitigation__itb_checkout_error_rate` | mitigation | hard | 0.50 |
| **平均值** | | | **0.77** |
### LLM 基线 —— `inference.py`
根据 hackathon 规范提供的 OpenAI 客户端线。默认通过 Hugging Face 路由器使用 `Qwen/Qwen2.5-72B-Instruct`。
| 任务 | 类型 | 难度 | 分数 | 步数 |
|------|------|------------|------:|------:|
| `detection__aiops_pod_failure` | detection | easy | 0.99 | 4 |
| `detection__itb_network_fault_checkout` | detection | easy | 0.99 | 5 |
| `localization__aiops_network_loss` | localization | medium | 0.99 | 5 |
| `localization__itb_resource_exhaustion_frontend` | localization | medium | 0.59 | 18 |
| `analysis__aiops_recommendation_cache_failure` | analysis | medium | 0.30 | 20 |
| `analysis__itb_network_fault_checkout` | analysis | medium | 0.99 | 6 |
| `mitigation__aiops_misconfig_app_hotel_res` | mitigation | hard | 0.99 | 8 |
| `mitigation__itb_checkout_error_rate` | mitigation | hard | 0.99 | 16 |
| **平均值** | | | **0.85** | |
前沿模型的困难案例失败:
- `localization__itb_resource_exhaustion_frontend`:Qwen2.5-72B 进行了详尽的调查,但从未将 `frontend` 确定为根本原因,最终超时得分为 0.59。
- `analysis__aiops_recommendation_cache_failure`:模型检查了每个面向用户的服务,但从未探测共享的 `redis` 后端存储,得分为 0.30。
两个 Mitigation 任务都达到了 0.99 —— 模型正确发现了 `db_connection_timeout_ms=0` 并应用了正向修复,并将 `feature_flag_payment_v2` 标志翻转回 `disabled`。
## 运行服务器
```
# 安装依赖(本地开发)
pip install -e ".[dev,inference]"
# 运行 server
uvicorn server.app:app --host 0.0.0.0 --port 8000
# 或者通过 pyproject.toml 中声明的入口点
server
```
## 运行基线
启发式基线:
```
docker run -d --name aiops -p 8000:8000 aiops-triage:latest
AIOPS_URL=http://127.0.0.1:8000 python baseline_smoke.py
```
LLM 基线:
```
export HF_TOKEN="..." # or API_KEY
export API_BASE_URL="https://router.huggingface.co/v1"
export MODEL_NAME="Qwen/Qwen2.5-72B-Instruct"
export IMAGE_NAME="aiops-triage:latest"
python inference.py
```
## 环境变量
| 变量 | 默认值 | 描述 |
|----------|---------|-------------|
| `HF_TOKEN` | — | OpenAI 兼容 LLM 端点的 API 密钥(推理基线) |
| `API_KEY` | — | `HF_TOKEN` 的后备选项 |
| `API_BASE_URL` | `https://router.huggingface.co/v1` | OpenAI 兼容 LLM 端点 |
| `MODEL_NAME` | `Qwen/Qwen2.5-72B-Instruct` | 推理基线的模型标识符 |
| `IMAGE_NAME` | `aiops-triage:latest` | `inference.py` 使用的本地 Docker 镜像标签 |
| `AIOPS_URL` | `http://127.0.0.1:8000` | `baseline_smoke.py` 使用的目标 URL |
| `ENABLE_WEB_INTERFACE` | `true` | 启用挂载在 `/web` 的 Gradio Web UI |
## OpenEnv 规范合规性
- 继承自 `openenv.core.env_server.types.Action`、`Observation` 和 `State` 的 Pydantic 模型。
- `server/app.py` 使用 `openenv.core.env_server.http_server.create_app`。
- `pyproject.toml` 声明 `server = "server.app:main"` 作为入口点。
- `openenv.yaml` 匹配参考环境使用的清单格式。
- 附带了 `uv.lock` 用于 `openenv validate`。
- 分数严格在 `(0.01, 0.99)` 之间。
- `openenv validate .` → `[OK] Ready for multi-mode deployment` 跨越 docker / openenv_serve / uv_run / python_module。
## 项目结构
```
aiops_triage/
├── __init__.py # Module exports
├── README.md # This file
├── Dockerfile # Container image definition
├── openenv.yaml # OpenEnv manifest
├── pyproject.toml # Package dependencies
├── uv.lock # Pinned dependency graph (required by openenv validate)
├── models.py # AIOpsAction / AIOpsObservation / AIOpsState
├── client.py # AIOpsTriageEnv (EnvClient)
├── inference.py # Baseline OpenAI-client loop across the 8-task roster
├── baseline_smoke.py # Deterministic no-LLM heuristic baseline
└── server/
├── __init__.py
├── app.py # FastAPI application
├── aiops_environment.py # Core reset/step/state logic
├── simulator.py # ClusterSimulator + 4 topology templates
├── fault_library.py # 15 faults with upstream provenance citations
├── scenario_generator.py # Procedural ScenarioGenerator(seed, task_type, fault_id)
├── verifiers.py # State-based graders per task type
└── rubrics.py # IncidentRubric (RFC 004-style)
```
## 参考资料
- Microsoft Research AIOpsLab — https://github.com/microsoft/AIOpsLab
- IBM ITBench — https://github.com/IBM/itbench
- IBM ITBench Scenarios — https://github.com/itbench-hub/ITBench-Scenarios
- OpenEnv reference environments — https://github.com/meta-pytorch/OpenEnv/tree/main/envs
标签:AIOps, AIOpsLab, API 服务器, Docker, Helm, Hugging Face Space, ITBench, OpenEnv, PyTorch, SRE, 云事故响应, 偏差过滤, 可复现环境, 命令行交互, 安全防御评估, 强化学习环境, 微服务拓扑, 故障分析, 故障分诊, 故障定位, 故障检测, 故障注入, 故障缓解, 智能运维, 模拟仿真, 混沌工程, 站点可靠性工程, 请求拦截, 逆向工具, 遥测数据