CoolFace
Apppublic

DevilNReality/Incident-Triage-Reinforcement-Learning

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
README.md323 linesDownload Raw Back to root
1---2title: Incident Triage & Alert Routing3emoji: ๐Ÿšจ4colorFrom: indigo5colorTo: red6sdk: docker7app_port: 78608tags:9  - openenv10  - sre11  - devops12  - incident-management13  - alert-routing14  - triage15  - fastapi16  - streamlit17short_description: OpenEnv โ€” Train AI agents like a senior SRE18---19 20# ๐Ÿšจ Incident Triage & Alert Routing โ€” OpenEnv21 22> **Meta ร— Hugging Face AI Hackathon | Round 1**  23> An OpenEnv environment for training AI agents to triage production incidents like a senior SRE.24 25---26 27## Environment Description28 29This environment simulates the real-world job of a **Site Reliability Engineer (SRE)** who receives a flood of production alerts and must:30 311. Identify the **root cause** from a set of correlated alerts322. Assign the correct **severity level** (P1โ€“P4)333. **Route** the incident to the correct on-call team (SRE, Database, Network, or App)344. *(Hard task only)* **Suppress noise alerts** โ€” flapping/self-resolving false positives35 36Every tech company faces alert fatigue. Reducing Mean Time To Detection (MTTD) by even 5 minutes has enormous operational value. This environment benchmarks how well an AI agent handles that pressure.37 38---39 40## Observation Space41 42At each step the agent receives an `AlertObservation`:43 44```python45class AlertObservation(BaseModel):46    alerts:       List[Alert]        # incoming monitoring alerts47    services_map: Dict[str, str]     # service โ†’ responsible team48    step:         int                # current step in the episode49    max_steps:    int                # maximum steps allowed50    task_id:      str                # "task_easy" | "task_medium" | "task_hard"51```52 53Each `Alert` contains:54 55```python56class Alert(BaseModel):57    alert_id:   str    # e.g. "alert-001"58    service:    str    # e.g. "postgres-primary"59    metric:     str    # e.g. "db_query_time_ms"60    value:      float  # current metric value61    threshold:  float  # value that triggered the alert62    duration_s: int    # how long it has been firing (seconds)63```64 65### Services Map66 67| Service | Team |68|---|---|69| `api-server-03`, `api-server-07`, `redis-cache-01` | `sre` |70| `postgres-primary`, `postgres-replica` | `database` |71| `checkout-service`, `payment-service`, `auth-service`, `reporting-service` | `app` |72| `load-balancer-01`, `cdn-edge-02`, `dns-resolver-01` | `network` |73 74---75 76## Action Space77 78```python79class TriageAction(BaseModel):80    severity:   Literal['P1', 'P2', 'P3', 'P4']81    team:       Literal['sre', 'database', 'network', 'app']82    root_cause: str        # one-sentence explanation, graded by keyword match83    suppressed: List[str]  # alert_ids believed to be noise (task_hard only)84```85 86| Field | Description |87|---|---|88| `severity` | **P1** = Critical (revenue impact), **P2** = High (users affected), **P3** = Medium, **P4** = Low |89| `team` | On-call team to page: `sre`, `database`, `network`, or `app` |90| `root_cause` | Free-text root cause. Scored by keyword match against ground truth. |91| `suppressed` | Alert IDs the agent believes are noise. Only scored in `task_hard`. |92 93---94 95## Reward Function96 97### task_easy98| Component | Weight |99|---|---|100| Severity correct | 0.50 |101| Team correct | 0.50 |102 103### task_medium104| Component | Weight |105|---|---|106| Severity correct | 0.35 |107| Team correct | 0.35 |108| Root cause keywords | 0.30 |109 110### task_hard111| Component | Weight |112|---|---|113| Noise suppression (F1) | 0.20 |114| Severity correct | 0.25 |115| Team correct | 0.25 |116| Root cause keywords | 0.30 |117| Over-suppression penalty | โˆ’0.20 per real alert wrongly suppressed |118 119---120 121## Task Descriptions122 123### ๐ŸŸข task_easy โ€” Single Alert, Obvious Root Cause124- 1 alert randomly chosen from 4 scenario variants125- Variants: CPU spike โ†’ SRE ยท DB timeout โ†’ Database ยท Network latency โ†’ Network ยท 5xx errors โ†’ App126- Max steps: 3127- **Expected score (frontier model):** 0.9โ€“1.0128 129### ๐ŸŸ  task_medium โ€” 3 Correlated Alerts, Identify Root Cause130- 3 correlated alerts from 4 scenario sets (Database overload, Network partition, App memory leak, CPU saturation)131- Agent must identify the single upstream root cause from downstream effects132- Max steps: 3133- **Expected score (frontier model):** 0.5โ€“0.75134 135### ๐Ÿ”ฅ task_hard โ€” 10โ€“15 Alerts, Suppress Noise & Escalate136- 6 real alerts (database outage root cause) + 5 noise alerts (short-duration, barely over threshold)137- Noise rule: `duration_s < 60` AND `value < threshold ร— 1.10`138- Agent must suppress noise alerts and correctly identify the P1 database root cause139- Max steps: 5140- **Expected score (frontier model):** 0.2โ€“0.45141 142---143 144## API Reference145 146All endpoints are available on port **7860** (via nginx reverse proxy).147 148| Method | Path | Description |149|---|---|---|150| `GET` | `/health` | Health check โ€” returns `{"status": "ok"}` |151| `GET` | `/tasks` | List all tasks with metadata |152| `POST` | `/reset` | Start a new episode. Body: `{"task_id": "task_easy", "seed": null}` |153| `POST` | `/step` | Submit a `TriageAction`. Returns observation, reward, done, info. |154| `GET` | `/state` | Full environment state including ground truth team/severity |155 156### Example: Full Episode157 158```python159import requests160 161BASE = "https://<your-username>-incident-triage-env.hf.space"162 163# 1. Reset164obs = requests.post(f"{BASE}/reset", json={"task_id": "task_medium"}).json()165 166# 2. Step167action = {168    "severity": "P1",169    "team": "database",170    "root_cause": "Database overload causing query timeouts and downstream 5xx errors",171    "suppressed": []172}173result = requests.post(f"{BASE}/step", json=action).json()174print(result["reward"], result["done"], result["info"])175```176 177---178 179## ๐Ÿš€ Setup & Deployment180 181### Option A โ€” Hugging Face Spaces (recommended)182 183#### Prerequisites184- Git installed185- A Hugging Face account with a token from https://huggingface.co/settings/tokens186 187#### Step 1 โ€” Install the HF CLI & login188 189```bash190pip install huggingface_hub191huggingface-cli login192```193 194#### Step 2 โ€” Create a new Space195 196Go to https://huggingface.co/new-space and set:197- **Space name:** `incident-triage-env`198- **SDK:** Docker199- **Visibility:** Public200 201#### Step 3 โ€” Clone and push202 203```bash204git clone https://huggingface.co/spaces/<your-username>/incident-triage-env205cd incident-triage-env206 207# Copy all project files here, then:208git add .209git commit -m "deploy: Incident Triage OpenEnv"210git push211```212 213HF Spaces detects the Dockerfile and builds automatically (~3โ€“5 min). Monitor progress in the **Logs** tab.214 215#### Step 4 โ€” Add secrets (for LLM agent mode)216 217In your Space โ†’ **Settings** โ†’ **Repository secrets**:218 219| Secret | Value |220|---|---|221| `HF_TOKEN` | Your HF token (`hf_...`) |222| `API_BASE_URL` | `https://router.huggingface.co/v1` |223| `MODEL_NAME` | `meta-llama/Llama-3.3-70B-Instruct` |224 225> The Streamlit UI and rule-based agent work without secrets. Secrets are only needed for LLM Agent mode.226 227---228 229### Option B โ€” Local Development230 231```bash232# 1. Install dependencies233pip install -r requirements.txt234 235# 2. Start FastAPI backend (terminal 1)236cd backend237uvicorn server:app --reload --port 8000238 239# 3. Start Streamlit UI (terminal 2, from project root)240BACKEND_URL=http://localhost:8000 streamlit run frontend/app.py241# Opens at http://localhost:8501242 243# 4. (Optional) Run the LLM baseline agent244cp .env.example .env   # fill in your API keys245source .env246python inference.py247```248 249### Option C โ€” Docker locally250 251```bash252docker build -t incident-triage-env .253docker run -p 7860:7860 \254  -e HF_TOKEN=hf_... \255  -e API_BASE_URL=https://router.huggingface.co/v1 \256  -e MODEL_NAME=meta-llama/Llama-3.3-70B-Instruct \257  incident-triage-env258 259# UI + API both at http://localhost:7860260```261 262---263 264## Architecture265 266```267Browser / OpenEnv Checker268         โ”‚269         โ–ผ port 7860 (public)270       nginx271      โ•ฑ     โ•ฒ272     โ–ผ         โ–ผ273FastAPI       Streamlit274 :8000         :8501275(API calls)   (Web UI)276```277 278nginx routes:279- `POST /reset`, `GET /health`, `/tasks`, `/step`, `/state` โ†’ **FastAPI** (OpenEnv checker)280- `/` and all other traffic โ†’ **Streamlit UI** (browser)281 282---283 284## Project Structure285 286```287incident-triage-env/288โ”œโ”€โ”€ Dockerfile           โ† Builds & runs nginx + FastAPI + Streamlit289โ”œโ”€โ”€ nginx.conf           โ† Reverse proxy: port 7860 โ†’ FastAPI:8000 / Streamlit:8501290โ”œโ”€โ”€ start.sh             โ† Startup script launching all three processes291โ”œโ”€โ”€ requirements.txt     โ† Python dependencies (latest versions)292โ”œโ”€โ”€ openenv.yaml         โ† OpenEnv spec: tasks, action/observation spaces, reward293โ”œโ”€โ”€ pyproject.toml       โ† Package config; server entry point: server.app:main294โ”œโ”€โ”€ .env.example         โ† Template for local env vars295โ”œโ”€โ”€ .dockerignore        โ† Excludes __pycache__, *.pyc, .git, uv.lock etc.296โ”œโ”€โ”€ inference.py         โ† LLM baseline agent (uses OpenAI client + HF router)297โ”œโ”€โ”€ backend/298โ”‚   โ”œโ”€โ”€ models.py        โ† Pydantic v2: Alert, AlertObservation, TriageAction, TriageReward299โ”‚   โ”œโ”€โ”€ tasks.py         โ† All task definitions + graders (easy / medium / hard)300โ”‚   โ”œโ”€โ”€ environment.py   โ† OpenEnv contract: reset() step() state()301โ”‚   โ””โ”€โ”€ server.py        โ† FastAPI app with /reset /step /state /health /tasks302โ”œโ”€โ”€ server/303โ”‚   โ””โ”€โ”€ app.py           โ† Entry point wrapper for multi-mode deployment (server.app:main)304โ””โ”€โ”€ frontend/305    โ””โ”€โ”€ app.py           โ† Streamlit UI: alert cards, routing table, score chart306```307 308---309 310## Baseline Scores311 312| Task | Score | Notes |313|---|---|---|314| `task_easy` | ~0.95 | Near-perfect on single alert |315| `task_medium` | ~0.63 | Good severity+team, partial root cause keyword match |316| `task_hard` | ~0.31 | Noise suppression is the primary challenge |317 318Scores from `meta-llama/Llama-3.3-70B-Instruct` via HF inference router.319 320---321 322*Built for the Meta ร— Hugging Face AI Hackathon, Round 1.*323