helloAK96/chaosops
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
ChaosOps AI
Multi-agent incident-response simulator with rogue-agent detection — an OpenEnv training ground for scalable-oversight models.
As companies deploy AI agents into production operations — autoscalers, deployers, incident triagers — a new class of outage emerges: incidents caused BY AI, not just resolved by AI.
ChaosOps AI is a reinforcement-learning environment where four specialist LLM agents (SRE, Developer, Manager, Oversight) handle cascading production incidents under partial observability — and where the incident itself may have been caused by a rogue agent inside the fleet.
Try it / read more
- 🚀 Live demo (HF Space, runnable): <https://huggingface.co/spaces/helloAK96/chaosops>
- 🤖 Trained LoRA adapter (HF Hub): <https://huggingface.co/helloAK96/chaosops-grpo-lora-p3a> (Qwen 2.5-3B + curriculum + LoRA r=32 + 2× rogue-rubric reward; the live Space's `trained` lane uses this adapter)
- 📒 Phase-wise judge demo notebook: `notebooks/colab_train.ipynb` (25 cells, runs in ~15 min on a free T4. Phases 2–7 replay the same `autoscaler_cost_cut` HARD scenario with random / heuristic / oracle / trained so you can watch what learned-vs-untrained looks like; Phase 8 regenerates the full 540-episode comparison curve; Phase 9 is an optional 20-step mini-GRPO run that confirms the training pipeline reproduces.)
- 📝 Mini blog post: see BLOG.md (also on HF Posts)
- 🎬 2-minute screencast: (YouTube link added once recorded)
- 📦 Source repo: <https://github.com/vatsalllll/chaos_ops>
The Rogue-Agent Twist
Every episode samples one of six failures. Two of them are caused by other AI agents:
The Oversight agent gets a privileged view (all metrics + fleet-agent trace) and is rewarded for flagging the rogue before Dev remediates. False flags are penalized −75.
Architecture
┌──────────────────────────────────────────────────────────────┐
│ WorldSim (deterministic) │
│ 6 failure injectors · cascade physics · seeded RNG │
└──────────────▲───────────────────────────────────▲────────────┘
│ apply_action │ project_view(role)
│ │
┌────────┴──────────┐ ┌─────────┴──────────┐
│ ChaosOpsAction │ │ RoleView │
│ (pydantic) │ │ (partial obs) │
└────────▲──────────┘ └─────────▲──────────┘
│ │
│ ┌───────────────┐ │
└───────┤ LLM adapter │───────────┘
│ prompts/parse │
└───────▲───────┘
│
┌───────────┬───────┴────────┬──────────────┐
│ SRE │ OVERSIGHT │ DEV │ MANAGER
│ (LLM) │ (LLM) │ (LLM) │ (LLM)
└───────────┴────────────────┴──────────────┘
round-robin turn order: SRE → OVERSIGHT → DEV → MANAGERTurn order is deliberate. Oversight runs before Dev so a rogue flag can land before the fix, making the +50 rogue-catch bonus actually reachable.
Reward function (composable rubrics)
The total per-step reward is composed from four named OpenEnv-style rubrics in `chaosops/rewards/reward_fn.py`. Each rubric is a standalone callable so ablations can disable or replace individual components without touching the rest of the codebase.
R_step = resolution(state, flags) + mttr(state, flags) + oversight(state, flags) + cascade(state, flags)
R_terminal_unresolved = −60Two reward streams are blended for GRPO: combined = 0.6·team + 0.4·oversight, where team_reward excludes the oversight rubric and oversight_reward inherits a 30% weight on the team outcome (cooperative oversight, not pure flagging).
Use score_rubrics(state, outcome_flags) for per-rubric introspection during ablations or training-time logging.
Our approach — HF Jobs end-to-end (no Colab dependency)
Most participants in this hackathon will have trained on Google Colab. We didn't. We ran every single GRPO experiment on HuggingFace Jobs — the native pay-per-second compute platform on the same Hub the env itself is hosted on. The full training command is one shell line:
hf jobs run \
--flavor l4x1 \
--secrets HF_TOKEN \
-v hf://spaces/helloAK96/chaosops:/data \
-e GRPO_EPISODES=600 \
-e GRPO_GROUP_SIZE=2 \
-e GRPO_LORA_RANK=32 \
-e GRPO_LR=2e-5 \
-e GRPO_TEMP=0.8 \
-e GRPO_CURRICULUM=easy:200,medium:200,hard:200 \
-e GRPO_ROGUE_MULTIPLIER=2.0 \
-e GRPO_PUSH_TO_HUB=1 \
-e HUB_REPO_ID=helloAK96/chaosops-grpo-lora-p3a \
pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime \
bash /data/scripts/jobs_grpo_train.sh-v hf://spaces/helloAK96/chaosops:/data mounts the Space repo read-only inside the Job container — the trainer sees the exact same code judges click on the live Space. --secrets HF_TOKEN injects auth so the Job pushes the trained LoRA back to a model repo on completion. We never touched a Jupyter cell, never had a runtime disconnect, never re-uploaded source.
Phase 3A, 3B, and 3C all ran simultaneously as three Job IDs returned in milliseconds from one shell loop. Total spend across all 6 GRPO experiments + 6 evaluation jobs (8,060+ rollouts simulated): $9.80 of the $30 credit budget.
A Colab notebook (`notebooks/colab_train.ipynb`) is provided for parity — it walks the same story phase-by-phase so judges can re-run it locally. But the canonical, reproducible-anywhere path is the HF Jobs command above.
Training history — 3,200 episodes across 6 GRPO runs
The submitted Phase 3A LoRA isn't the result of one happy run. It's the winner of a 6-run experimental sweep that ran in 3 phases on HF Jobs. Total compute simulated: 3,200 GRPO training episodes + 3,240 evaluation episodes = 6,440 incident-response rollouts, all reproducible via scripts/jobs_grpo_train.sh. Each phase tested a specific hypothesis about what was bottlenecking the previous run.
Phase 0 — original baseline (pre-this-work)
Verdict: trained agent was identical to heuristic in eval (silent LoRA-load fallback bug — the trained lane was never actually loading the adapter). Even after fixing the loader, the policy hadn't learned much; the reward curve was flat.
Phase 1 — learning-rate fix (hypothesis: the gradient was too small)
Eval mean (E/M/H): −218.0 / −283.1 / −820.0 (≈ +33 / +32 / +6 over Phase 0) KL: peaked 1.0 transiently, settled around 0.5 Verdict: decisive — KL grew 4× the previous run within 30 steps, proving LR was indeed the bottleneck. But the LR-induced policy shift lost the rogue-catch metric (20% → 0%). Resolution rate also inched up to 5%/33%/0%. Hypothesis confirmed but not enough alone.
Phase 2 — curriculum + bigger LoRA (hypothesis: the model never sees harder scenarios)
Eval mean (E/M/H): −220.8 / −295.9 / −834.2 Resolution rate: 10% / 40% / 0% (nearly 2× Phase 1 on EASY/MED) KL: 0.14 final, controlled Verdict: the curriculum worked — training-time HARD-tier mean reward (−4.4) ended up better than EASY-tier mean (−6.1), and step 550 (HARD) hit the run's first positive reward step (+3.13). Resolution rate jumped meaningfully but mean reward only marginally better than Phase 1; rogue catch still 0%. Verdict: 1.5B is capacity-limited.
Phase 3 — bigger model + reward rebalance (3 parallel runs to A/B/C the next axes)
Three runs in parallel to triangulate the remaining bottleneck:
Phase 3A training-time per-tier mean rewards (60 log points):
All three tiers ended positive. The harder the tier, the higher the mean reward — the curriculum effect compounds. Final KL 0.595.
Phase 3 evaluation (5 seeds × 9 failures × 3 tiers, 540 episodes per LoRA)
Result: the 3B-vs-3A delta proves model capacity was the binding constraint — same reward shape on 1.5B got nowhere. The 3C regression falsifies the "ended on HARD = forgot EASY" hypothesis. Phase 3A wins on every single metric vs every other run. Submitted as helloAK96/chaosops-grpo-lora-p3a and pinned as the live trained lane on the Space.
Episode budget
Training episodes: Phase 0 : 400
Phase 1 : 400
Phase 2 : 600
Phase 3A : 600 ← winner
Phase 3B : 600
Phase 3C : 600
-------------
TOTAL : 3,200 GRPO training rollouts
Evaluation episodes: 6 LoRAs × 540 eps = 3,240
Baseline episodes: 3 scripted policies × 540 eps = 1,620
--------
GRAND TOTAL: 8,060+ incident rollouts simulatedAll training runs are tagged separately on HF Hub so the ablation table is independently reproducible:
- `chaosops-grpo-lora` — Phase 0, original baseline
- `chaosops-grpo-lora-p1` — Phase 1, LR fix
- `chaosops-grpo-lora-p2` — Phase 2, curriculum + r=32
- `chaosops-grpo-lora-p3a` — Phase 3A, submitted (live on Space) 🏆
- `chaosops-grpo-lora-p3b` — Phase 3B control, capacity-bound 1.5B
- `chaosops-grpo-lora-p3c` — Phase 3C control, reverse curriculum
Total HF Jobs spend: ~$9.80 of the $30 credit budget.
Judging-criteria alignment
Quickstart
# 1. Unit tests (no LLM/GPU required) — 110 tests
python -m pytest tests/
# 2. Scripted baselines — writes artifacts/baseline/{baseline.json, baseline_curve.png}
python -m chaosops.train.baseline --episodes-per-type 5
# 3. Live dashboard demo (try the autoscaler_cost_cut rogue scenario)
python -m chaosops.dashboard.terminal \
--scenario autoscaler_cost_cut --policy oracle --difficulty hard
# 4. GRPO training on a GPU (the run that produced the LoRA on HF Hub).
# --backend transformers avoids the Unsloth+triton+cc dep chain so this
# works on any standard PyTorch CUDA image.
python -m chaosops.train.grpo_train \
--model-name Qwen/Qwen2.5-1.5B-Instruct \
--backend transformers \
--total-episodes 400 --group-size 2 --lora-rank 16 \
--output-dir artifacts/chaosops-grpo
# 5. Evaluate trained policy vs. baselines (after step 4 or after pulling
# the LoRA from helloAK96/chaosops-grpo-lora)
python -m chaosops.train.evaluate \
--policies random heuristic oracle trained \
--adapter-path artifacts/chaosops-grpo/lora_adapter \
--episodes-per-type 5 --out-dir artifacts/evaluationFor one-click reproducibility on HF Jobs, see scripts/jobs_grpo_train.sh and the canonical invocation:
hf jobs run --flavor t4-small --secrets HF_TOKEN \
-v hf://spaces/helloAK96/chaosops:/data \
-e GRPO_EPISODES=400 -e GRPO_PUSH_TO_HUB=1 \
pytorch/pytorch:2.4.1-cuda12.4-cudnn9-runtime \
bash /data/scripts/jobs_grpo_train.shResults
Baselines — Random vs. Heuristic vs. Oracle
Mean cumulative episode reward across 5 seeds × 9 failure types per tier (EASY → MEDIUM → HARD). The clean monotone gradient Random < Heuristic < Oracle confirms the reward function rewards real problem-solving. Random's HARD score plummets to ≈ −1356 because it never flags the rogue agent and triggers cascades.
Trained Qwen 3B (GRPO + LoRA) vs. baselines
Trained policy after 600 GRPO steps on Qwen 2.5-3B-Instruct + LoRA r=32 with a 3-tier curriculum (`easy:200 → medium:200 → hard:200`), LR=2e-5, temperature 0.8, rogue-rubric reward × 2 (catch +100, FP −150). Benchmark conditions match the baseline plot (5 seeds × 9 failure types per tier).
Mean cumulative reward + resolution + rogue-catch rate, per tier
*The trained Qwen-3B closes the heuristic gap to ≤8 points on HARD, ≤45 on EASY, and is the only sub-oracle policy that flags rogue fleet agents on MEDIUM (100% catch rate vs heuristic's 0%). Resolution rates jumped from the previous 1.5B run's 10% / 40% / 0% to 85% / 80% / 40%. MTTR is 3.0 across all tiers* — matching the Oracle. The trade-off: a 13–35 % false-positive flag rate on tiers without a real rogue, an honest cost of incentivising oversight aggressiveness with the 2× rubric weight.
Learning curve
Mean combined reward (`0.6 × team + 0.4 × oversight`) over 600 GRPO steps with the `easy:200,medium:200,hard:200` curriculum schedule on Qwen-3B. Per-tier mean reward across the 60 log points:
All three tiers ended with positive mean reward — the curriculum let the model absorb easier-tier dynamics, then the harder the tier, the higher the mean reward as the policy stacked competencies. Final KL to base model: 0.595*. The flat-LR Qwen-1.5B baseline plateaued near KL=0 and never produced a positive-reward step; combining LR=2e-5
- Qwen-3B + rubric-weight 2× + 3-tier curriculum was the decisive recipe.*
Package layout
chaosops/
├── openenv.yaml # OpenEnv manifest (name, action, observation)
├── app.py # Gradio Space entry point
├── Dockerfile # HF Space build (Python 3.11, port 7860)
├── env/
│ ├── models.py # pydantic v2 typed contracts
│ ├── world_sim.py # deterministic simulator + cascade physics
│ ├── environment.py # OpenEnv-compatible wrapper (extends Environment)
│ └── openenv_wrapper.py # FastAPI server + ChaosOpsClient
├── agents/
│ ├── prompts/*.md # 4 role system prompts
│ ├── llm_adapter.py # render_observation / build_prompt / parse_action
│ ├── policies.py # random / heuristic / oracle scripted baselines
│ ├── trained_policy.py # LoRA-backed Policy (loads from disk or HF Hub)
│ └── runner.py # run_episode orchestration
├── rewards/
│ └── reward_fn.py # composable rubrics (resolution/mttr/oversight/cascade)
├── curriculum/
│ └── generator.py # easy → medium → hard + auto-promotion
├── dashboard/
│ ├── terminal.py # Rich demo UI with rogue-flag visualization
│ └── transcript.py # text-only transcript writer (used by Space)
├── train/
│ ├── baseline.py # scripted-policy baselines + reward curve
│ ├── evaluate.py # multi-policy sweep + comparison plot
│ └── grpo_train.py # TRL GRPO + LoRA (Unsloth or plain transformers)
└── scripts/
└── jobs_grpo_train.sh # one-shot HF Jobs entry pointReproducibility
Every episode is deterministic given (failure_type, seed). A regression test asserts two rollouts with the same scenario produce identical trajectories and rewards. Curriculum tiers derive their seeds from tier × 10_000 + failure_type_index × 100 + episode_offset, so artifact runs are bit-reproducible.
Why this matters
The AI-safety literature distinguishes "agents that break things" from "agents that catch other agents breaking things." ChaosOps AI is a compact, trainable testbed for the second class. Today's production fleets already have AI-driven autoscalers, deployers, and traffic routers. Tomorrow's SRE isn't replacing humans — it's watching the other agents.
