adityavaasudevb/firewatch

GitHub: adityavaasudevb/firewatch

FireWatch是一个模拟分布式系统故障响应的强化学习环境,旨在评估AI Agent在非平稳条件下诊断根因并执行补救措施的能力。

Stars: 0 | Forks: 1

title: FireWatch Environment Server emoji: 🔥 colorFrom: blue colorTo: purple sdk: docker pinned: false app_port: 8000 base_path: /web tags: - openenv # FireWatch — SRE 故障响应 RL 环境 [![OpenEnv](https://img.shields.io/badge/OpenEnv-compatible-orange)](https://github.com/meta-pytorch/OpenEnv) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://python.org) [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE) FireWatch 模拟了一个包含 6 个互联服务的生产分布式系统。事故发生、服务降级,Agent 必须诊断根本原因并应用正确的补救措施 —— 同时系统会在每一步持续自主恶化。 **世界在运转,不会等待 Agent。** 与静态环境不同,FireWatch 通过 `tick()` 机制实现自主降级:无论 Agent 是否采取行动,不健康的服务每一步都会丢失健康值。这创造了一个真正的非平稳 MDP,并强制 Agent 在调查速度与行动质量之间取得平衡。 ## 为什么 FireWatch 很重要 ### 问题所在 每个生产团队都要处理故障响应。当系统在凌晨 3 点崩溃时,值班工程师必须在时间紧迫、信息不全的情况下诊断跨互联服务的根本原因。这是软件工程中风险最高的人类任务之一 —— 也是 AI Agent 最少被基准测试的领域之一。 ### 当前的缺失 现有的 Agent 基准测试评估的是静态推理:回答问题、编写代码、填写表格。没有评估 **非平稳条件下的分流处理** —— 即在你思考时系统在恶化,症状会将你误导到错误的服务,以及你的行动顺序会改变其有效性。 ### FireWatch 提供了什么 - **对于 RL 研究人员:** 一个具有密集奖励、部分可观测性和结构化陷阱的非平稳 MDP —— 这些属性被认为是当前基准中的关键差距。 - **对于 Agent 开发人员:** 对因果推理、优先级排序和适应能力的真实评估 —— 这些是将有用的 AI 助手与玩具演示区分开来的技能。 - **对于 SRE 团队:** 一个训练场,用于评估 AI Agent 是否能够处理真实的事故模式(级联故障、红鲱鱼/误导信息、有序补救)。 ## 快速开始 ``` from client import FireWatchClient from models import FireWatchAction try: env = FireWatchClient.from_docker_image("firewatch-env:latest") result = env.reset() print(f"System Health: {result.observation.system_health}") print(f"Active Alerts: {len(result.observation.active_alerts)}") actions = [ FireWatchAction(tool="get_topology", target="system"), FireWatchAction(tool="get_logs", target="database"), FireWatchAction(tool="restart_service", target="database"), FireWatchAction(tool="mark_resolved", target="system"), ] for action in actions: result = env.step(action) print(f"Action: {action.tool}({action.target})") print(f" -> Reward: {result.reward:.2f}") print(f" -> Health: {result.observation.system_health:.2f}") print(f" -> Done: {result.done}") if result.done: break finally: env.close() ``` ## 构建 Docker 镜像 ``` docker build -t firewatch-env:latest . ``` ## 部署到 Hugging Face Spaces ``` openenv push # 或 openenv push --repo-id your-username/firewatch --private ``` 部署的空间包括: - **Web 界面** 位于 `/web` - **API 文档** 位于 `/docs` - **健康检查** 位于 `/health` - **WebSocket** 位于 `/ws` ## 系统架构 FireWatch 模拟了 6 个具有以下依赖图的服务: ``` api-gateway --> auth-service api-gateway --> payment-service --> database \--> cache api-gateway --> notification-service ``` 每个服务都有:`health (0.0-1.0)`、`status (healthy/degraded/down)`、`error_rate`、`latency_ms` 和 `log_entries`。 ## 环境详情 ### 动作空间 **FireWatchAction**:包含工具选择和目标服务 | Tool | Target | Description | |------|--------|-------------| | `get_metrics` | any service | 观察健康状态、错误率、延迟 | | `get_logs` | any service | 读取最近的日志条目(揭示故障类型) | | `get_topology` | `system` | 查看完整的依赖图 —— **免费,不消耗步数** | | `restart_service` | any service | OOM 故障的正确修复方法 | | `rollback_config` | any service | 配置/内存泄漏故障的正确修复方法 | | `reset_ratelimit` | any service | 速率限制的正确修复方法(在 rollback_config 之后应用) | | `sync_replica` | any service | 副本滞后的正确修复方法 | | `clear_connections` | any service | 连接池耗尽的正确修复方法 | | `scale_service` | any service | 增加副本以帮助处理负载 | | `mark_resolved` | `system` | 结束回合(Agent 宣布事故已解决) | **有效目标:** `api-gateway`、`auth-service`、`payment-service`、`database`、`cache`、`notification-service`、`system` ### 观测空间 **FireWatchObservation**:包含完整的系统状态和元数据 | Field | Type | Description | |-------|------|-------------| | `step` | `int` | 当前步数 | | `system_health` | `float` | 聚合健康度 0.0-1.0(对所有服务加权) | | `active_alerts` | `List[AlertModel]` | 按严重程度排序的触发告警 | | `services` | `Dict[str, ServiceStatusModel]` | 所有 6 个服务的完整状态 | | `last_action_result` | `str` | 上一个动作的纯英文结果 | | `last_action_error` | `Optional[str]` | 上一个动作的原始错误字符串,或 `None` | | `incident_summary` | `str` | 事故的自然语言描述 | | `topology` | `Optional[TopologyModel]` | 依赖图(调用 `get_topology` 之前为 None) | | `step_budget` | `Optional[int]` | 剩余步数(在任务 4 中隐藏) | | `done` | `bool` | 回结束时为 True | | `reward` | `float` | 当前步的奖励 | | `metadata` | `dict` | 额外信息,如 episode_id、task_id、final_score | ### 奖励函数 奖励函数在 **每一步** 都提供信号 —— 从不稀疏,从不二元化。 ``` r(t) = health_delta * 2.0 # Health improvement/degradation + correct_fix_bonus # +1.0 one-time for applying the correct fix + diagnosis_bonus # +0.3 one-time for investigating the root cause - wrong_fix_penalty # -0.3 for restarting a healthy service - step_cost # -0.02 per step (prevents stalling) ``` `get_topology` 的步数成本为零 —— 在行动之前进行规划的 Agent 会因为不浪费预算而得到奖励。 **奖励示例:** | Action | Scenario | Reward | |--------|----------|--------| | `get_topology(system)` | 任何 | `0.00` — 免费动作 | | `get_logs(database)` | DB 是根本原因 | `+0.28` — 诊断奖励 | | `get_logs(cache)` | Cache 健康 | `-0.02` — 仅步数成本 | | `restart_service(database)` | DB 发生 OOM | `+1.55` — 健康差值 + 修复奖励 | | `restart_service(cache)` | Cache 健康 | `-0.37` — 错误修复惩罚 | | `mark_resolved(system)` | 回合结束 | `-0.02` — 仅步数成本 | ## 任务 FireWatch 提供了四个跨越不断增加的运营难度的任务: | Task | Difficulty | Primary Challenge | Step Budget | |------|------------|-------------------|-------------| | `task1` | Easy | 单一根本原因服务故障 | 10 | | `task2` | Medium | 带有红鲱鱼(误导信息)的级联故障 | 15 | | `task3` | Hard | 有序多修复补救 | 20 | | `task4` | Expert | 具有隐藏步数预算的非平稳事故 | 25 (隐藏) | ### 任务 1 — 单一服务故障 由于 OOM 错误,数据库宕机。Payment-service 和 api-gateway 显示延迟升高,作为下游症状。 - **根本原因:** `database` (OOM) - **正确修复:** `restart_service("database")` ### 任务 2 — 带有红鲱鱼(误导信息)的级联故障 数据库连接池耗尽,导致 payment-service 和 api-gateway 超时。Auth-service 有一个不相关的内存警告 —— 它 **没有** 导致任何问题。Agent 必须追踪依赖图,识别真正的根本原因,并避免在误导性信息上浪费动作。 - **根本原因:** `database` (连接池) - **正确修复:** `clear_connections("database")` - **红鲱鱼:** `auth-service` (内存警告,非因果关系) ### 任务 3 — 具有顺序依赖的多向量事故 三个同时发生的故障,**必须按特定顺序修复**: 1. `rollback_config("api-gateway")` — 首先停止内存泄漏 2. `reset_ratelimit("api-gateway")` — 仅在配置回滚后有效 3. `sync_replica("database")` — 修复陈旧读取 乱序应用修复会降低其效果。 ### 任务 4 — 非平稳自适应事故 世界在按固定时间表进行的过程中发生变化: - **第 0 步:** 数据库连接池耗尽 - **第 5 步:** Cache 独立发生故障(出现新问题) - **第 8 步:** Notification-service 开始降级(下游级联) 步数预算对 Agent 是 **隐藏** 的(部分可观测性)。Agent 必须处理初始根本原因,同时适应不断变化的系统。 ## 基线分数 使用 `meta-llama/Llama-3.3-70B-Instruct` 通过 Hugging Face 路由器、多轮 LLM 基线以及调查回退机制生成的分数: | Task | Name | Difficulty | Score | |------|------|------------|-------| | task1 | Single Service Failure | Easy | 0.91 | | task2 | Cascading Failure with Red Herring | Medium | 0.45 | | task3 | Multi-vector Ordered Incident | Hard | 0.69 | | task4 | Non-stationary Adaptive Incident | Expert | 0.60 | **分数解读:** - **任务 1 (0.91):** 单一故障,读取日志,应用修复,解决 —— 展示了最优行为。 - **任务 2 (0.45):** 模型正确修复了根本原因,但总是被红鲱鱼 所误导,对 auth-service 应用不必要的修复。这是一个有记录的 LLM 失败模式 —— 在有用助手数据上训练的模型会强制解决每个可见的告警。评分器正确地对此进行了惩罚。 - **任务 3 (0.69):** 当模型读取正确的日志时,会按正确的顺序应用所有三个修复。部分分数反映了已读取日志但修复未命中的情况。 - **任务 4 (0.60):** 模型处理了主要的数据库修复和缓存故障。非平稳特性和隐藏的预算创造了真正的专家级难度。 **关于任务 2 与任务 3/4 的说明:** 任务 2 分数较低并不是因为概念上更难,而是因为红鲱鱼专门利用了一个有记录的 LLM 偏差。一个避开红鲱鱼陷阱的模型得分约为 0.70+。任务 3 和 4 需要多步规划,这是另一种类型的难度。 要复现基线分数: ``` export HF_TOKEN="your_token" export MODEL_NAME="meta-llama/Llama-3.3-70B-Instruct" export API_BASE_URL="https://router.huggingface.co/v1" python inference.py ``` ## FireWatch 的独特之处 **非平稳世界:** 每个现有的 OpenEnv 环境都会耐心地等待 Agent。FireWatch 通过 `tick()` 每一步都在自主降级。被动性是由环境本身惩罚的,而不是由稀疏的最终奖励惩罚的。 **针对 LLM 的结构化陷阱:** 任务 2 的红鲱鱼利用了 LLM 修复最可见告警的倾向。任务 3 的顺序依赖打破了没有规划就跳转到行动的模型。任务 4 的部分可观测性导致静态推理器崩溃。这些都是经过记录和研究验证的前沿模型的失败模式 —— 而不是任意的难度。 **诊断-行动差距:** 我们的基线显示,即使是 70B 参数的模型也能正确诊断故障,但无法从证据跨越到补救。这种差距正是 RL 训练旨在弥合的。 **诚实的部分学分:** 每个评分器都在多个粒度上提供部分学分。没有评分器产生二元 0/1 结果。一个调查正确但应用了错误修复的 Agent 仍然能得 0.20-0.40 分。 ## 难度分析 ### 为什么任务 2 会击溃简单 Agent Auth-service 显示 `WARN memory usage at 78%` —— 一个显眼但不相关的告警。在有用助手数据上训练的 LLM 会强制解决每个可见的问题。对 auth-service 应用任何修复都会浪费步数并受到惩罚,而真正的根本原因继续降级。 ### 为什么任务 3 需要规划 三个所需的修复具有严格的依赖链。`reset_ratelimit` 仅在 `rollback_config` 之后才能完全工作。乱序应用修复会降低效果,并且评分器会惩罚错误顺序的尝试。 ### 为什么任务 4 会击败静态推理器 新的故障出现在第 5 步和第 8 步。步数预算是隐藏的。一个解决了初始数据库故障但忽略了第 5 步缓存崩溃的 Agent 只能得到约 0.45 分。需要持续重新评估。 ## 开发与测试 ### 本地运行 ``` pip install -r requirements.txt pip install -e . uvicorn server.app:app --reload --host 0.0.0.0 --port 8000 curl http://localhost:8000/health ``` ### 通过 Docker 运行 ``` docker build -t firewatch-env:latest . docker run -p 8000:8000 firewatch-env:latest curl http://localhost:8000/health ``` ### 运行基线推理 ``` export HF_TOKEN="your_huggingface_token" export MODEL_NAME="meta-llama/Llama-3.3-70B-Instruct" export API_BASE_URL="https://router.huggingface.co/v1" python inference.py ``` ## API 端点 | Endpoint | Method | Description | |----------|--------|-------------| | `/health` | GET | 健康检查 — 返回 `{"status":"healthy"}` | | `/reset` | POST | 重置环境,返回初始观测 | | `/step` | POST | 执行动作,返回观测 + 奖励 | `/state` | GET | 内部状态快照 | | `/docs` | GET | 交互式 API 文档 | | `/web` | GET | OpenEnv Web 界面 | | `/ws` | WS | 用于持久会话的 WebSocket 端点 | ## 项目结构 ``` firewatch/ |-- Dockerfile |-- LICENSE |-- README.md |-- openenv.yaml |-- pyproject.toml |-- requirements.txt |-- client.py |-- models.py |-- inference.py |-- firewatch/ | |-- __init__.py | |-- simulation.py | |-- reward.py | |-- tasks.py | `-- graders.py `-- server/ |-- __init__.py |-- firewatch_environment.py |-- app.py `-- Dockerfile ``` ## OpenEnv 合规性 - 实现了类型化的 `Action`、`Observation` 模型 (Pydantic) - 支持 `step()`、`reset()`、`state()` - 具有严格在 (0, 1) 范围内分数的确定性评分器 - 提供了 `openenv.yaml` - 通过 `openenv validate` - 成功部署于 `pepparrr/firewatch` ## License MIT
标签:Docker, OpenEnv, Python, SRE, 偏差过滤, 分布式系统, 响应大小分析, 安全防御评估, 强化学习, 故障响应, 故障诊断, 无后门, 智能运维AIOps, 机器学习环境, 根因分析, 模拟环境, 自动化运维, 请求拦截, 逆向工具, 非平稳MDP