Arijit-07 commited on
Commit
e1b5cb0
Β·
verified Β·
1 Parent(s): 783b86b

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +582 -67
README.md CHANGED
@@ -1,67 +1,582 @@
1
- ---
2
- base_model: unsloth/Llama-3.2-3B-Instruct
3
- library_name: peft
4
- pipeline_tag: text-generation
5
- tags:
6
- - lora
7
- - unsloth
8
- - grpo
9
- - reinforcement-learning
10
- - devops
11
- - incident-response
12
- ---
13
-
14
- # ARIA β€” DevOps Incident Response Agent
15
- ### Llama-3.2-3B fine-tuned with GRPO
16
-
17
- Fine-tuned on the [ARIA DevOps Incident Response](https://huggingface.co/spaces/Arijit-07/devops-incident-response)
18
- RL environment using Group Relative Policy Optimization (GRPO).
19
-
20
- ## Training Details
21
-
22
- - **Algorithm:** GRPO (Group Relative Policy Optimization)
23
- - **Base model:** Llama-3.2-3B-Instruct
24
- - **Fine-tuning:** Unsloth LoRA (rank=16, alpha=32, 4-bit quantized)
25
- - **Episodes:** 140 across easy + medium tasks
26
- - **Training time:** ~10 hours on Kaggle T4 x2
27
- - **Environment:** Live DevOps incident response simulation
28
-
29
- ## What the Agent Learns
30
-
31
- The agent is trained to respond to production software incidents by:
32
- 1. Gathering information (read_logs, read_metrics, search_logs)
33
- 2. Diagnosing the root cause before acting
34
- 3. Applying the correct fix (restart, rollback, scale_up, block_ip etc.)
35
- 4. Avoiding collateral damage to healthy services
36
-
37
- ## Environment
38
-
39
- 7 task types of escalating difficulty:
40
- - **Easy:** Single service OOM crash-loop
41
- - **Medium:** Cascading connection pool failure
42
- - **Hard:** Silent data corruption (all services green)
43
- - **Bonus:** Two simultaneous independent failures
44
- - **Security:** DDoS botnet credential stuffing
45
- - **Database:** Missing index causing full table scans
46
- - **Failover:** Multi-region network partition
47
-
48
- 14 action types Β· Dense reward shaping Β· Partial log observability Β· SLA degradation per step
49
-
50
- ## Links
51
- - **Live environment:** https://huggingface.co/spaces/Arijit-07/devops-incident-response
52
- - **Interactive API:** https://arijit-07-devops-incident-response.hf.space/docs
53
- - **GitHub:** https://github.com/Twilight-13/devops-incident-response
54
-
55
- ## Usage
56
-
57
- ```python
58
- from peft import PeftModel
59
- from transformers import AutoModelForCausalLM, AutoTokenizer
60
-
61
- base = AutoModelForCausalLM.from_pretrained(
62
- "unsloth/Llama-3.2-3B-Instruct",
63
- load_in_4bit=True
64
- )
65
- model = PeftModel.from_pretrained(base, "Arijit-07/aria-devops-llama3b")
66
- tokenizer = AutoTokenizer.from_pretrained("Arijit-07/aria-devops-llama3b")
67
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: ARIA DevOps Incident Response
3
+ emoji: 🚨
4
+ colorFrom: blue
5
+ colorTo: red
6
+ sdk: docker
7
+ pinned: true
8
+ license: apache-2.0
9
+ tags:
10
+ - openenv
11
+ - reinforcement-learning
12
+ - devops
13
+ - incident-response
14
+ - rl-environment
15
+ - multi-agent
16
+ - llm-agent
17
+ - grpo
18
+ - curriculum-learning
19
+ - huggingface
20
+ - pytorch
21
+ - meta
22
+ short_description: RL environment for DevOps incident response agents
23
+ ---
24
+
25
+
26
+ # ARIA β€” DevOps Incident Response
27
+ ### *The first OpenEnv RL environment for production incident response*
28
+
29
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Twilight-13/devops-incident-response/blob/main/train_grpo.ipynb)
30
+ [![HF Space](https://img.shields.io/badge/πŸ€—-Live%20Environment-orange)](https://huggingface.co/spaces/Arijit-07/devops-incident-response)
31
+ [![Trained Model](https://img.shields.io/badge/πŸ€—-Trained%20Model-blue)](https://huggingface.co/Arijit-07/aria-devops-llama3b)
32
+ [![License](https://img.shields.io/badge/License-Apache_2.0-green.svg)](LICENSE)
33
+
34
+ > **ARIA** β€” Adaptive Reward & Incident Architecture
35
+ > Built for the Meta Γ— PyTorch Γ— HuggingFace OpenEnv Hackathon Finals | Bangalore, April 2026
36
+
37
+ ---
38
+
39
+ ## πŸ”— Quick Links for Judges
40
+
41
+ | Resource | Link |
42
+ |---|---|
43
+ | **Live Environment** | https://arijit-07-devops-incident-response.hf.space |
44
+ | **Interactive API (Swagger)** | https://arijit-07-devops-incident-response.hf.space/docs |
45
+ | **Trained Model (Llama-3B LoRA)** | https://huggingface.co/Arijit-07/aria-devops-llama3b |
46
+ | **Training Curve** | https://huggingface.co/Arijit-07/aria-devops-llama3b/resolve/main/training_curve.png |
47
+ | **HuggingFace Blog** | https://huggingface.co/blog/Arijit-07/aria-devops-incident-response |
48
+ | **GitHub** | https://github.com/Twilight-13/devops-incident-response |
49
+ | **Validate (self-test)** | https://arijit-07-devops-incident-response.hf.space/validate |
50
+
51
+ ---
52
+
53
+ ## ⚑ Run a Complete Episode Right Now
54
+
55
+ ```bash
56
+ # 1. Start an easy incident
57
+ curl -X POST https://arijit-07-devops-incident-response.hf.space/reset \
58
+ -H "Content-Type: application/json" \
59
+ -d '{"task_id": "easy", "seed": 42}'
60
+
61
+ # 2. Read logs on the failing service (reward: +0.15)
62
+ curl -X POST https://arijit-07-devops-incident-response.hf.space/step \
63
+ -H "Content-Type: application/json" \
64
+ -d '{"action_type": "read_logs", "service": "payment-service"}'
65
+
66
+ # 3. Diagnose the root cause (reward: +0.30)
67
+ curl -X POST https://arijit-07-devops-incident-response.hf.space/step \
68
+ -H "Content-Type: application/json" \
69
+ -d '{"action_type": "diagnose", "root_cause": "memory leak in payment-service"}'
70
+
71
+ # 4. Fix it (reward: +0.40)
72
+ curl -X POST https://arijit-07-devops-incident-response.hf.space/step \
73
+ -H "Content-Type: application/json" \
74
+ -d '{"action_type": "restart_service", "service": "payment-service"}'
75
+
76
+ # 5. See the final score
77
+ curl https://arijit-07-devops-incident-response.hf.space/state
78
+
79
+ # 6. Validate all 7 tasks pass
80
+ curl https://arijit-07-devops-incident-response.hf.space/validate
81
+ ```
82
+
83
+ ```python
84
+ # Or install and use the Python client
85
+ pip install git+https://github.com/Twilight-13/devops-incident-response.git
86
+
87
+ from devops_incident_response import DevOpsIncidentEnv, Action, ActionType
88
+
89
+ env = DevOpsIncidentEnv(task_id="easy", seed=42)
90
+ obs = env.reset()
91
+ result = env.step(Action(action_type=ActionType.READ_LOGS, service="payment-service"))
92
+ print(f"Reward: {result.reward}") # 0.15
93
+ ```
94
+
95
+ ---
96
+
97
+ ## 🎯 The Problem This Solves
98
+
99
+ Every software company running microservices faces the same brutal reality: **production incidents are expensive, unpredictable, and happen at 3am.**
100
+
101
+ A single SEV-1 incident β€” a payment service crashing, a data corruption silently corrupting prices, a DDoS botnet overwhelming your login endpoint β€” can cost millions and require hours of expert engineer time to diagnose and fix. On-call rotations are stressful. Tier-2 incidents that follow recognizable patterns are handled by engineers when they could, in principle, be handled by an AI agent.
102
+
103
+ **Yet no RL benchmark exists for this domain.**
104
+
105
+ SWE-bench tests code generation. WebArena tests web navigation. AgentBench tests general tool use. None of them model **operational intelligence** β€” the ability to reason under uncertainty about live production systems, gather information strategically, and take precise actions where wrong choices cause additional damage.
106
+
107
+ ARIA fills that gap.
108
+
109
+ ---
110
+
111
+ ## πŸ—οΈ Environment Architecture
112
+
113
+ ARIA simulates a production microservices e-commerce platform. Agents interact with the environment through a standard OpenEnv API: `reset()`, `step()`, `state()`.
114
+
115
+ ### What the Agent Observes
116
+
117
+ Each step returns a structured `Observation` object:
118
+
119
+ ```
120
+ Observation
121
+ β”œβ”€β”€ step, max_steps, task_id, task_description
122
+ β”œβ”€β”€ services: List[ServiceStatus]
123
+ β”‚ β”œβ”€β”€ name, status (healthy/degraded/down/unknown)
124
+ β”‚ β”œβ”€β”€ cpu_percent, memory_percent
125
+ β”‚ β”œβ”€β”€ error_rate, latency_p99_ms
126
+ β”‚ β”œβ”€β”€ replicas_running, replicas_desired
127
+ β”‚ β”œβ”€β”€ current_version, last_deployed
128
+ β”‚ └── sla_breach, minutes_degraded ← SLA tracking per step
129
+ β”œβ”€β”€ active_alerts: List[Alert] ← may include red herrings
130
+ β”œβ”€β”€ recent_logs: Dict[str, List[str]] ← PARTIAL: only 2 lines shown
131
+ β”œβ”€β”€ service_dependencies: List[ServiceDependency] ← call topology
132
+ β”œβ”€β”€ evidence_log: List[EvidenceEntry] ← accumulates across steps
133
+ β”œβ”€β”€ sla_status: Dict[str, str] ← ok/warning/breached
134
+ └── available_runbooks: List[str]
135
+ ```
136
+
137
+ **Key design: Partial Log Observability**
138
+
139
+ The agent only sees 2 log lines per service upfront. Full history requires calling `read_logs` explicitly. This models real observability tools (Datadog, Kibana) where engineers run queries β€” agents must develop a search strategy, not just read everything.
140
+
141
+ ### The Services
142
+
143
+ | Service | Stack | Role |
144
+ |---|---|---|
145
+ | `api-gateway` | Go | Routes external requests |
146
+ | `payment-service` | Java (Spring) | Processes payments |
147
+ | `order-service` | Python | Creates and tracks orders |
148
+ | `inventory-service` | Java | Manages product stock |
149
+ | `user-service` | Node.js | Auth and profiles |
150
+ | `notification-service` | Python | Email and push alerts |
151
+ | `data-pipeline-service` | Python | Writes catalog data |
152
+ | `product-catalog-service` | Go | Stores and serves product data |
153
+ | `price-validation-service` | Python | Validates prices |
154
+ | `analytics-service` | Python | Aggregates business metrics |
155
+ | `ml-inference-service` | Python | Serves recommendation models |
156
+ | `log-aggregator` | Go | Collects and stores logs |
157
+
158
+ ### Service Dependency Map
159
+
160
+ Every observation includes the call topology β€” agents can trace cascades:
161
+
162
+ ```
163
+ api-gateway β†’ order-service β†’ inventory-service
164
+ api-gateway β†’ payment-service
165
+ order-service β†’ notification-service
166
+ data-pipeline-service β†’ product-catalog-service β†’ price-validation-service
167
+ ```
168
+
169
+ ---
170
+
171
+ ## 🎬 The 7 Tasks
172
+
173
+ ### Task 1 β€” Single Service OOM (`easy`)
174
+ **Max steps: 15 | Expected strong LLM: 0.85–1.00 | Random agent: 0.05**
175
+
176
+ One service crash-loops with an OutOfMemoryError. The affected service rotates by seed across payment-service, order-service, and user-service β€” with different log formats (Java heap errors, Python memory errors, Node.js heap dumps). A secondary circuit-breaker alert fires on api-gateway as a visible symptom.
177
+
178
+ **What makes it interesting:** The agent must identify the ROOT cause service (the one running out of memory) not the SYMPTOM services (everything downstream that's erroring because the root is down).
179
+
180
+ **Optimal sequence:** `read_logs` β†’ `read_metrics` β†’ `diagnose` β†’ `restart_service`
181
+ **Reward breakdown:** +0.10 read_logs, +0.10 read_metrics, +0.30 diagnose, +0.40 restart = **0.99 with efficiency bonus**
182
+
183
+ ---
184
+
185
+ ### Task 2 β€” Cascading Failure (`medium`)
186
+ **Max steps: 20 | Expected strong LLM: 0.55–0.75 | Random agent: 0.03**
187
+
188
+ A bad deployment of `inventory-service` causes connection pool exhaustion, cascading timeouts to `order-service` and elevated error rates on `api-gateway`. **Red herring:** a `notification-service` HIGH CPU alert fires (scheduled batch job β€” completely unrelated).
189
+
190
+ **What makes it interesting:** The agent must follow the dependency chain backwards. Three services are visibly failing, but only one is the root cause. Touching the wrong service gives -0.15 collateral damage penalty.
191
+
192
+ **Optimal sequence:** Investigate `api-gateway` β†’ trace to `order-service` β†’ trace to `inventory-service` β†’ `rollback`
193
+ **Reward breakdown:** +0.20 trace cascade, +0.05 runbook, +0.25 diagnose, +0.35 rollback = **0.92**
194
+
195
+ ---
196
+
197
+ ### Task 3 β€” Silent Data Corruption (`hard`)
198
+ **Max steps: 25 | Expected strong LLM: 0.30–0.50 | Random agent: 0.01**
199
+
200
+ **All services show green.** Zero error rates. Normal latency. No standard alerts. The signal is buried in:
201
+ - `price-validation-service` WARN logs: 15% price mismatch rate (baseline: 0.2%)
202
+ - `analytics-service` anomaly: avg order value $847 vs $89 historical baseline
203
+
204
+ Three noise alerts distract: TLS renewal, analytics backlog, replica lag.
205
+
206
+ **What makes it interesting:** This requires qualitatively different reasoning β€” ignoring green health checks, correlating subtle business metric anomalies, and understanding that a data pipeline deployment 2 minutes ago is the causal explanation.
207
+
208
+ **Full credit requires BOTH:** `rollback(data-pipeline-service)` AND `alert_oncall` (data audit needed)
209
+ **Reward breakdown:** +0.15 subtle signals, +0.10 pipeline metrics, +0.05 runbook, +0.20 diagnose, +0.25 rollback, +0.15 alert_oncall = **0.87**
210
+
211
+ ---
212
+
213
+ ### Task 4 β€” Dual Simultaneous Failure (`bonus`)
214
+ **Max steps: 25 | Expected strong LLM: 0.35–0.55 | Random agent: 0.01**
215
+
216
+ Two completely independent failures at once:
217
+ 1. `log-aggregator` disk 100% full β€” dropping 48k log messages/min
218
+ 2. `ml-inference-service` stuck in model checksum reload loop β€” CPU 99%+
219
+
220
+ **What makes it interesting:** Neither failure is related to the other. Solving one doesn't help the other. The agent must decompose and fix independently. This tests whether agents can maintain multiple hypotheses simultaneously.
221
+
222
+ **Full credit requires BOTH:** `alert_oncall` (disk cleanup) AND `rollback/restart(ml-inference-service)`
223
+ **Optimal score: ~0.77**
224
+
225
+ ---
226
+
227
+ ### Task 5 β€” Security Incident: DDoS (`security`)
228
+ **Max steps: 20 | Expected strong LLM: 0.40–0.60 | Random agent: 0.01**
229
+
230
+ A botnet is targeting the login endpoint with 12,000 req/s from the `185.220.x.x` IP range. Standard rate limiting is ineffective (distributed attack). The access logs show 1,847+ failed login attempts per 60 seconds from that range.
231
+
232
+ **New action: `block_ip_range`** β€” models real network-level DDoS mitigation.
233
+ **Wrong actions:** Restarting api-gateway won't help. Scaling up won't help. Must block at network level + escalate to security team.
234
+
235
+ **Full credit:** `block_ip_range("185.220.0.0/16")` AND `alert_oncall`
236
+ **Optimal score: ~0.80**
237
+
238
+ ---
239
+
240
+ ### Task 6 β€” Database Degradation (`database`)
241
+ **Max steps: 20 | Expected strong LLM: 0.45–0.65 | Random agent: 0.01**
242
+
243
+ A schema migration added a `user_segment` column to the `orders` table 15 minutes ago β€” without an index. Every query is now doing a full sequential table scan. DB CPU is spiking. The slow query log shows `seq_scan on orders (847ms)`.
244
+
245
+ **New action: `create_index`** β€” models real DBA response to missing indexes.
246
+ **Alternative fix:** Rolling back the migration is also accepted for full credit.
247
+
248
+ **Optimal score: ~0.80**
249
+
250
+ ---
251
+
252
+ ### Task 7 β€” Multi-Region Failover (`failover`)
253
+ **Max steps: 25 | Expected strong LLM: 0.35–0.55 | Random agent: 0.01**
254
+
255
+ A network partition affects `us-east-1`. Four services support automatic failover to `us-west-2` and should be switched. Two services MUST NOT be failed over:
256
+ - `payment-service` β€” PCI-DSS compliance requires human approval
257
+ - `postgres-primary` β€” replication lag risk causes data loss
258
+
259
+ **New action: `failover`** β€” with `target_region` parameter.
260
+ **Heavy penalty: -0.25 per wrong service.** Failing over payment or postgres is catastrophic.
261
+
262
+ **The runbook explicitly lists which services are safe** β€” reading it first is rewarded.
263
+ **Optimal score: ~0.70**
264
+
265
+ ---
266
+
267
+ ### Task 8 β€” Generated Incident (`generated`)
268
+ **Max steps: 20 | Variable difficulty | Seed-deterministic**
269
+
270
+ The Incident Generator creates procedural incidents from any integer seed (0–99,999). Same seed always produces the same incident. Different seeds produce unique combinations of:
271
+ - 6 failure modes Γ— 8 services Γ— 3 severity levels Γ— 0–3 noise alerts
272
+
273
+ ```bash
274
+ # Preview any incident before running it
275
+ curl "https://arijit-07-devops-incident-response.hf.space/generate/preview?seed=12345"
276
+
277
+ # Run it as a full episode
278
+ curl -X POST .../reset -d '{"task_id":"generated","seed":12345}'
279
+ ```
280
+
281
+ ---
282
+
283
+ ## πŸ† Reward Function Design
284
+
285
+ ### The Formula
286
+
287
+ ```
288
+ Final Score = Ξ£(step_rewards)
289
+ + efficiency_bonus # (1 - steps/max_steps) Γ— 0.05 if resolved
290
+ + diagnosis_precision_bonus # +0.03 if β‰₯50% keyword overlap, +0.01 if β‰₯30%
291
+ - noop_penalty # (noop_count - 3) Γ— 0.02
292
+ - repeat_restart_penalty # (restarts - 1) Γ— 0.05 per service
293
+ ```
294
+
295
+ All scores clamped to **(0.001, 0.999)** β€” never exactly 0 or 1.
296
+
297
+ > **Why (0.001, 0.999) not (0, 1)?** GRPO advantage normalization requires non-constant rewards within a group. Hard 0 or 1 creates zero-variance groups where the model doesn't update. The tiny clamp ensures a gradient signal always exists.
298
+
299
+ ### Step-Level Rewards
300
+
301
+ | Action | Reward | Condition |
302
+ |---|---|---|
303
+ | `read_logs` (failing service) | +0.10–0.15 | First time only |
304
+ | `read_metrics` (failing service) | +0.10 | First time only |
305
+ | `read_runbook` (relevant) | +0.05 | Correct runbook for scenario |
306
+ | `search_logs` (relevant query) | +0.05 | Query returns useful results |
307
+ | `diagnose` (full match) | +0.30–0.35 | β‰₯50% keyword overlap |
308
+ | `diagnose` (partial match) | +0.10–0.15 | β‰₯30% keyword overlap |
309
+ | `restart_service` (correct) | +0.35–0.45 | Root cause service |
310
+ | `rollback` (correct) | +0.30–0.40 | Root cause service |
311
+ | `block_ip_range` (correct) | +0.40 | Security task, correct CIDR |
312
+ | `create_index` (correct) | +0.40 | Database task, correct table/column |
313
+ | `failover` (eligible service) | +0.30 | Per correctly failed-over service |
314
+ | `alert_oncall` (required) | +0.15 | Hard/security/database/failover tasks |
315
+
316
+ ### Penalties (Anti-Gaming)
317
+
318
+ | Action | Penalty | Why |
319
+ |---|---|---|
320
+ | Restart healthy service | -0.15 | Collateral damage β€” realistic cost |
321
+ | Fix without diagnosing | -0.10 | Blind remediation β€” models real risk |
322
+ | Failover payment-service | -0.25 | PCI-DSS compliance violation |
323
+ | Failover postgres-primary | -0.25 | Data loss risk |
324
+ | Excessive noops (>3) | -0.04/each | Forces active investigation |
325
+ | Repeat restart same service | -0.05/extra | Discourages guess-and-check |
326
+
327
+ ### Semantic Diagnosis Matching
328
+
329
+ The `diagnose` action uses **keyword overlap** not exact string matching. An agent saying "memory exhaustion in payment-service" correctly matches the ground truth "memory_leak_payment_service". This is critical for LLM agents that paraphrase β€” exact string matching would unfairly penalize valid diagnoses.
330
+
331
+ ### SLA Degradation
332
+
333
+ Every step where an incident is unresolved, the environment worsens:
334
+ - `down` services: error_rate increases
335
+ - `degraded` services: latency_p99 increases
336
+ - SLA status: `ok` β†’ `warning` (~3 steps) β†’ `breached` (~7 steps)
337
+
338
+ This creates real time pressure and rewards faster resolution.
339
+
340
+ ---
341
+
342
+ ## 🌟 ARIA Features
343
+
344
+ ### Curriculum Engine
345
+
346
+ The Curriculum Engine tracks agent performance per task using a rolling average of the last 5 episodes.
347
+
348
+ - **Promotion:** rolling_avg > 0.75 β†’ advance mastery level (Novice β†’ Intermediate β†’ Advanced β†’ Mastered)
349
+ - **Demotion:** rolling_avg < 0.30 β†’ step back mastery level
350
+ - **Scaffolding:** if avg < 0.30 over 3+ episodes β†’ provide task-specific hint
351
+
352
+ ```bash
353
+ GET /curriculum/status # See mastery per task
354
+ GET /curriculum/next # Get recommended next task
355
+ GET /curriculum/hint/easy # Get scaffolding hint for a task
356
+ POST /curriculum/record # Feed your training results in
357
+ ```
358
+
359
+ **Why this matters for training:** RL fails when agents never see successful trajectories. The curriculum ensures agents always train at the edge of their capability β€” easy tasks first, harder tasks as they master the fundamentals.
360
+
361
+ ### Incident Generator
362
+
363
+ Procedural incident generation from seeds. 6 failure modes Γ— 8 services Γ— 3 severities Γ— 0–3 noise alerts = thousands of unique training scenarios.
364
+
365
+ **Difficulty formula:** `base_difficulty[failure_mode] + (noise_count Γ— 0.05)`, clamped to 1.0
366
+
367
+ | Failure Mode | Base Difficulty |
368
+ |---|---|
369
+ | oom | 0.20 |
370
+ | cascade | 0.50 |
371
+ | database | 0.60 |
372
+ | security | 0.60 |
373
+ | network_partition | 0.70 |
374
+ | corruption | 0.80 |
375
+
376
+ ```bash
377
+ GET /generate/preview?seed=42 # Preview without starting
378
+ POST /reset # body: {"task_id":"generated","seed":42}
379
+ ```
380
+
381
+ ### Dual-Agent Mode
382
+
383
+ One incident. Two agents. Split observability.
384
+
385
+ - **Agent A (Observer):** Sees logs, alerts, evidence. Can ONLY call `share_finding` β€” passes natural language observations to Agent B. Reward: +0.05 per finding.
386
+ - **Agent B (Responder):** Sees metrics, service dependencies, SLA status. Cannot see logs directly. Must rely on Agent A's findings. Executes all real actions.
387
+
388
+ Neither agent can solve the incident alone.
389
+
390
+ ```bash
391
+ # Start a dual-agent session
392
+ POST /multi-agent/reset {"task_id":"easy","seed":42}
393
+ # β†’ returns session_id + split observations
394
+
395
+ # Agent A shares a finding
396
+ POST /multi-agent/step/a/{session_id} {"finding":"payment-service OOM, memory at 98%"}
397
+
398
+ # Agent B takes action (has access to Agent A's findings)
399
+ POST /multi-agent/step/b/{session_id} {"action_type":"restart_service","service":"payment-service"}
400
+
401
+ # See full session state
402
+ GET /multi-agent/state/{session_id}
403
+ ```
404
+
405
+ ---
406
+
407
+ ## 🧠 Training
408
+
409
+ ### Model
410
+
411
+ **Llama-3.2-3B-Instruct** fine-tuned with **GRPO** (Group Relative Policy Optimization) using HuggingFace TRL and Unsloth.
412
+
413
+ - **LoRA:** rank=16, alpha=32, targeting all 7 projection layers
414
+ - **Adapter size:** ~97MB
415
+ - **Training:** 140 episodes (easy + medium tasks) on Kaggle T4 x2 GPUs
416
+ - **Model repo:** https://huggingface.co/Arijit-07/aria-devops-llama3b
417
+
418
+ ### Why GRPO?
419
+
420
+ GRPO eliminates the value network that PPO requires. For environment-based RL where rewards come from an external API, a value model adds complexity without benefit. GRPO estimates the baseline from a group of 6 completions per step β€” simpler, more memory-efficient, and well-suited to fast environment APIs.
421
+
422
+ ### Training Loop
423
+
424
+ ```python
425
+ # Each training step:
426
+ # 1. Generate 6 completions for the current observation
427
+ # 2. Score each on a FRESH env snapshot (prevents reward gate exhaustion)
428
+ # 3. Normalize rewards to advantages (GRPO)
429
+ # 4. Policy gradient update on best completion + KL penalty
430
+ # 5. Advance episode with best action
431
+
432
+ # Key hyperparameters:
433
+ learning_rate = 5e-6
434
+ group_size = 6
435
+ kl_coefficient = 0.05 # prevents catastrophic forgetting
436
+ update_strategy = "episode-level" # one update per full episode
437
+ ```
438
+
439
+ ### Results
440
+
441
+ | | Base Model | Fine-tuned (ep140) |
442
+ |---|---|---|
443
+ | **Easy task** | 0.000 | 0.150 |
444
+ | **Behavior** | Jumps to diagnose immediately | Reads logs on correct service first |
445
+ | **Why the difference** | Base model triggers blind remediation penalty | Fine-tuned model learned to gather information before acting |
446
+
447
+ **The trained model consistently reads logs on the failing service before acting** β€” this is the foundational operational behavior: information gathering before remediation. The base model never does this.
448
+
449
+ **Training challenge identified:** The original training loop called `env_step` during group generation, burning reward gates before the best action could advance the episode. After fixing to score completions on fresh environment snapshots, the model successfully learned step 1 of the optimal policy. With more episodes using the corrected loop, the full sequence would emerge.
450
+
451
+ ### Training Notebook
452
+
453
+ See `train_grpo.ipynb` β€” Colab-compatible, runs against the live HF Space API (no local setup needed).
454
+
455
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Twilight-13/devops-incident-response/blob/main/train_grpo.ipynb)
456
+
457
+ Compatible with: TRL, SkyRL, ART, Oumi, Axolotl.
458
+
459
+ ---
460
+
461
+ ## πŸš€ Setup
462
+
463
+ ### Docker (Recommended)
464
+
465
+ ```bash
466
+ docker build -t aria-devops-incident .
467
+ docker run -p 7860:7860 aria-devops-incident
468
+ curl http://localhost:7860/health
469
+ ```
470
+
471
+ ### Local Python
472
+
473
+ ```bash
474
+ pip install -r requirements.txt
475
+ uvicorn api:app --host 0.0.0.0 --port 7860
476
+ ```
477
+
478
+ ### Validate
479
+
480
+ ```bash
481
+ python validate.py # 22 automated checks, exit 0 = all pass
482
+ curl http://localhost:7860/validate
483
+ ```
484
+
485
+ ---
486
+
487
+ ## πŸ“‘ API Reference
488
+
489
+ | Method | Endpoint | Description |
490
+ |---|---|---|
491
+ | GET | `/health` | `{"status":"ok"}` liveness check |
492
+ | GET | `/about` | Full environment description (machine-readable) |
493
+ | GET | `/tasks` | All 8 tasks with descriptions |
494
+ | POST | `/reset` | Start episode: `{"task_id":"easy","seed":42}` |
495
+ | POST | `/step` | Take action: Action JSON |
496
+ | GET | `/state` | Full state + ground truth + analytics |
497
+ | GET | `/validate` | Self-test: random agent on all 7 tasks |
498
+ | GET | `/metrics` | Aggregate episode statistics |
499
+ | GET | `/leaderboard` | Top 10 episodes |
500
+ | WS | `/ws` | WebSocket: real-time agent-environment |
501
+ | GET | `/curriculum/status` | Per-task mastery and recommendations |
502
+ | GET | `/curriculum/next` | Recommended next task for training |
503
+ | GET | `/curriculum/hint/{task_id}` | Scaffolding hint for struggling agents |
504
+ | POST | `/curriculum/record` | Feed episode result to curriculum engine |
505
+ | GET | `/generate/preview` | Preview procedural incident: `?seed=N` |
506
+ | POST | `/multi-agent/reset` | Start dual-agent session |
507
+ | POST | `/multi-agent/step/a/{id}` | Agent A shares a finding |
508
+ | POST | `/multi-agent/step/b/{id}` | Agent B takes an action |
509
+ | GET | `/multi-agent/state/{id}` | Full dual-agent session state |
510
+ | GET | `/multi-agent/sessions` | List active sessions |
511
+ | GET | `/docs` | Swagger UI β€” interactive documentation |
512
+
513
+ ---
514
+
515
+ ## πŸ“Š Benchmark Comparison
516
+
517
+ | Benchmark | Domain | Partial Obs | Dense Reward | Multi-Step | Curriculum | Multi-Agent |
518
+ |---|---|---|---|---|---|---|
519
+ | SWE-bench | Code repair | βœ— | βœ— | βœ“ | βœ— | βœ— |
520
+ | WebArena | Web navigation | βœ“ | βœ— | βœ“ | βœ— | βœ— |
521
+ | AgentBench | General tools | βœ— | βœ— | βœ“ | βœ— | βœ— |
522
+ | **ARIA (ours)** | **Incident response** | **βœ“** | **βœ“** | **βœ“** | **βœ“** | **βœ“** |
523
+
524
+ ---
525
+
526
+ ## πŸ—οΈ OpenEnv Compliance
527
+
528
+ ```bash
529
+ openenv validate .
530
+ ```
531
+
532
+ - Inherits from `openenv.core.env_client.EnvClient`
533
+ - Standard `reset()`, `step()`, `state()` interface
534
+ - Valid `openenv.yaml` manifest with all 8 tasks
535
+ - FastAPI server with health endpoint
536
+ - WebSocket support at `/ws`
537
+ - Hosted on HuggingFace Spaces
538
+
539
+ ---
540
+
541
+ ## πŸ“ Repository Structure
542
+
543
+ ```
544
+ aria-devops-incident-response/
545
+ β”œβ”€β”€ api.py # FastAPI app β€” all endpoints
546
+ β”œβ”€β”€ env.py # DevOpsIncidentEnv β€” thin dispatcher
547
+ β”œβ”€β”€ models.py # Pydantic models β€” Action, Observation, State
548
+ β”œβ”€β”€ tasks/
549
+ β”‚ β”œβ”€β”€ base.py # BaseTask ABC, InternalState, reward logic
550
+ β”‚ β”œβ”€β”€ task_easy.py # OOM crash-loop
551
+ β”‚ β”œβ”€β”€ task_medium.py # Cascading failure
552
+ β”‚ β”œβ”€β”€ task_hard.py # Silent data corruption
553
+ β”‚ β”œβ”€β”€ task_bonus.py # Dual simultaneous failure
554
+ β”‚ β”œβ”€β”€ task_security.py # DDoS attack
555
+ β”‚ β”œβ”€β”€ task_database.py # Missing index
556
+ β”‚ β”œβ”€β”€ task_failover.py # Multi-region failover
557
+ β”‚ └── task_generated.py # Procedural incidents
558
+ β”œβ”€β”€ curriculum/
559
+ β”‚ └── engine.py # CurriculumEngine β€” adaptive difficulty
560
+ β”œβ”€β”€ generator/
561
+ β”‚ └── incident_factory.py # IncidentFactory β€” procedural generation
562
+ β”œβ”€β”€ multi_agent/
563
+ β”‚ └── session.py # DualAgentSession β€” split observability
564
+ β”œβ”€β”€ graders/
565
+ β”‚ └── grader.py # Deterministic episode grader
566
+ β”œβ”€β”€ data/runbooks/ # 6 operational runbooks (Markdown)
567
+ β”œβ”€β”€ client.py # openenv-core EnvClient implementation
568
+ β”œβ”€β”€ inference.py # LLM baseline (CoT + fast modes)
569
+ β”œβ”€β”€ train_grpo.ipynb # GRPO training notebook (Colab-compatible)
570
+ β”œβ”€β”€ validate.py # 22 automated validation checks
571
+ └── openenv.yaml # OpenEnv spec manifest
572
+ ```
573
+
574
+ ---
575
+
576
+ ## πŸ“ License
577
+
578
+ Apache 2.0
579
+
580
+ ---
581
+
582
+ *Built solo for the Meta Γ— PyTorch Γ— HuggingFace OpenEnv Hackathon Finals β€” Bangalore, April 2026*