AS215932/noc-agent
GitHub: AS215932/noc-agent
面向网络运维(NOC)的自主调查代理,利用 AI 对监控告警进行结构化分析、主动巡检和漂移检测,生成可审查的运维提案。
Stars: 1 | Forks: 0
# Hyrule Networks (AS215932) NOC Agent
`noc-agent` 是面向运维人员的 Hyrule Networks (AS215932) 调查服务。
它接收监控事件,运行结构化的事件分析,记录人工审查提案,
并在聊天工具不可用时保持可用的本地回退控制平面。
## 运行时形态
- FastAPI 接收 Alertmanager 和 Icinga webhook。
- LangGraph 调查 runtime 对告警进行标准化,关联重复事件,
路由到专家配置,验证置信度,检查 golden-state 漂移,
并生成可审查的提案。
- Redis 存储 graph checkpoint 状态以及短期的事件记忆。
- Discord 可作为交互式运维控制台。
- 仅限 loopback 的本地控制 API 以及 `nocctl` 为运维人员提供了用于审查和记录决策的 SSH/VPN 回退方案。
- Hyrule MCP 提供实时诊断遥测;NOC Agent 通过配置的 daemon URL 或传统的 stdio 路径来使用它。
当前阶段特意设计为仅限诊断。批准记录并恢复运维状态,但不执行基础设施变更。
## 主要接口
保留的现有接口:
- `POST /webhook/alertmanager`
- `POST /webhook/icinga`
- `POST /task`
- `POST /mail/poll`
- `GET /health`
- `GET /health/mcp`
- `GET /health/config`
- `GET /health/model`
- `GET /health/mail`
- `GET /metrics`
新的控制平面接口:
- `GET /control/incidents/pending`
- `GET /control/incidents/{incident_id}`
- `POST /control/incidents/{incident_id}/decision`
- `POST /approval/resume`
- `GET /control/proactive/status`
- `POST /control/proactive/pause`
- `POST /control/proactive/resume`
- `POST /control/proactive/run-once`
- `GET /control/proactive/suppressions`
- `POST /control/proactive/ack` / `POST /control/proactive/unack`
`/control/...` 端点需要 `X-NOC-Control-Token`。已签名的恢复
端点需要使用 `NOC_APPROVAL_SIGNING_SECRET` 生成的 HMAC 签名。
## 运维控制
`nocctl` 是本地回退接口:
```
nocctl pending
nocctl show
nocctl decide approved --operator svag --comment "reviewed"
```
在生产环境中,这旨在通过现有的 SSH/VPN 访问在 `noc` 上运行,
并设置 `NOC_CONTROL_URL=http://127.0.0.1:8000`。
## 批准的修复(受控,首次为 no-op)
已批准的修复执行默认**关闭**。已批准的提案仅在
`NOC_ENABLE_APPROVED_EXECUTION=1` 时才会运行,即使如此,第一阶段也是不产生实际影响的:当 `NOC_ENABLE_NOOP_ROLLBACK_GUARDS=1` 时,执行将通过 hyrule-mcp no-op rollback guards 进行路由(`prepare_commit_confirm` → 在验证时执行 `confirm_change` 或 `rollback_change`),并且带有 `action_class="noop_rollback_guard"`
—— **不会重启服务,不会修改 FRR/PF/nftables/WireGuard**。每条执行
记录都包含 `execution_mode`、`guard_id`、`authorization_fingerprint`(原始 HMAC 签名永远不会被持久化),以及 `execution_audit` 轨迹。
| 状态 | 含义 |
|---|---|
| `execution_disabled` | 已批准,但 `NOC_ENABLE_APPROVED_EXECUTION` 处于关闭状态 |
| `noop_guards_prepared` | 为每个操作安装了 no-op guard |
| `verified` | guard 确认(no-op 执行完成) |
| `verification_failed` | guard 无法确认;已回滚 |
运维人员可以离线生成签名的授权(与 MCP HMAC 方案匹配),用于手动/冒烟测试:
```
nocctl approvals sign --proposal-id --action-id --operator svag --action-class noop_rollback_guard --ttl 300
```
签名需要 `HYRULE_MCP_ACTION_SIGNING_SECRET`(或 `NOC_APPROVAL_SIGNING_SECRET`)。
## 主动循环
除了响应式的 webhook 路径之外,`noc-agent` 还运行一个**主动运维循环**
(`app/proactive/`),它会在告警触发*之前*持续寻找问题。
它**在生产环境中已启用**(部署环境设置 `NOC_PROACTIVE_ENABLED=1`);
代码中的默认值保持为 `0`,因此本地开发和测试套件永远不会启动它。
它是只读的、有预算限制的,并以生产环境的 `engineering-loop`
(运行锁 + 每日账本 + 预算 + Icinga 心跳)和
`hyperliquid-trading-agent`(持续观察 → 提议 → 评估 → 学习)循环为模型。
保守的预算 —— 每次循环 1 次调查、每天 12 次、每天 $10、
`MEDIUM` 严重性下限、提议但不自动运行繁重的探测 —— 就是实际的安全防线。
每个循环:
1. **扫描** —— 对 Prometheus/Icinga 进行廉价的只读扫描 (`app/proactive/scanner.py`),寻找只有在硬化*之后*响应式触发器才会捕捉到的前兆:刚刚离开 Established 状态或正在发生 flapping 的 BGP peer,预计将在 24 小时内填满的文件系统,正在 flapping 的 scrape target,重启扰动 / 失败的 unit,mesh 链路上间歇性的 ICMP,即将过期的证书。
2. **排序与控制** —— 根据严重性评分,快照决策上下文,并根据每日账本和严重性下限控制昂贵的调查 (`app/proactive/governance.py`, `app/proactive/ledger.py`)。
3. **调查** —— 将首要热点渲染为合成告警,并通过 webhook 使用的*相同*调查 graph 运行它;除非 `NOC_PROACTIVE_AUTO_HEAVY_PROBES=1`,否则繁重的只读探测(`tcpdump_capture`, `dns_probe_burst`, `multi_source_probe`)将被剥离 (`app/proactive/investigate.py`)。
4. **报告** —— 发送 Discord 摘要以及可选的 Icinga 被动心跳。
5. **移交** —— 当发现的问题需要修改配置/文档时,开启一个幂等的 `loop:candidate` GitHub issue (`app/proactive/handoff.py`);由人工将其提升为 `loop:approved`,然后 engineering-loop 负责起草 PR。
6. **学习** —— 记录预测,将它们与随后的真实告警相关联,并在 `NOC_PROACTIVE_MEMORY_DIR` 下提议候选的经验教训 (`app/proactive/memory.py`);由人工将提议合并到 `lessons/` 中。
为了低成本地进行灰度测试,请设置 `NOC_PROACTIVE_SHADOW=1`(仅扫描和报告,不进行自主调查),并在扫描器看起来正常后将其翻转回 `0`。
要随时暂停生产环境,请设置 `NOC_PROACTIVE_ENABLED=0` 并重新应用,或者请求 `POST /control/proactive/pause`。
**闭环 —— 案例链接 + ack/snooze:** 每个摘要热点都带有一个 **ack id**(短指纹),并且一旦进行调查,就会带有指向其 **NOC case** 的链接(设置 `NOC_CONTROL_PUBLIC_URL` 以获取可点击的链接;否则显示案例编号)。
屏蔽已决定处理的已知问题:
```
curl -XPOST -H "x-noc-control-token: $TOK" http://127.0.0.1:8000/control/proactive/ack \
-d '{"fingerprint":"","reason":"tracked in network-operations#268","ttl_hours":168}'
```
从 **Web 仪表板** (`GET /control`):“Proactive loop”面板列出了
当前的热点(状态、ack id、摘要),带有内联的 **Ack** 按钮 + 原因/小时数输入框,以及带有 **Unack** 的已屏蔽列表 —— 由 `/control/proactive/status` 支持(它现在返回 `hotspots` + `suppressions`)。
从 **Discord 机器人**(ack id 就在摘要中):
`/noc_ack ack_id: [reason:...] [hours:...]`, `/noc_unack ack_id:`,
`/noc_acks`。ack id 作为前缀进行匹配(类似 git short-SHA 风格),因此摘要中显示的短 id 是有效的。
一个已 ack 的热点会从摘要**和**自主调查中剔除,
直到它被解决 —— 当它停止触发时,屏蔽会自动修剪,因此如果再次发生则会重新告警。`GET /control/proactive/suppressions` 列出活动的 ack;`POST /control/proactive/unack` 清除其中一个。
主动配置(代码内的默认值是保守的;部署环境启用了它):
- `NOC_PROACTIVE_ENABLED`(代码内默认值为 `0`,**部署为 `1`**;除非为 `1`,否则不会挂载循环)
- `NOC_PROACTIVE_SHADOW`(代码内默认值为 `1`,**部署为 `0`**;`1` = 仅报告热点)
- `NOC_PROACTIVE_INTERVAL_S`(默认值为 `120`) / `NOC_PROACTIVE_DEEP_SCAN_S`(默认值为 `900`)
- `NOC_PROACTIVE_MAX_INVESTIGATIONS_PER_CYCLE`(默认值为 `1`)
- `NOC_PROACTIVE_MAX_INVESTIGATIONS_PER_DAY`(默认值为 `12`)
- `NOC_PROACTIVE_MAX_COST_USD_PER_DAY`(默认值为 `10`)
- `NOC_PROACTIVE_COST_USD_PER_INVESTIGATION`(默认值为 `0.05`;在每次运行的 token→USD 计量落地之前,按固定估算值计入每日 $ 上限 —— 数量上限是主要预算)
- `NOC_PROACTIVE_AUTO_HEAVY_PROBES`(默认值为 `0`;提议繁重探测而不是自动运行)
- `NOC_PROACTIVE_HANDOFF_ENABLED`(默认值为 `0`)+ `NOC_PROACTIVE_HANDOFF_REPO`(默认值为 `AS215932/network-operations`)
- `NOC_PROACTIVE_SEVERITY_FLOOR`(默认值为 `MEDIUM`)
- `NOC_PROACTIVE_MEMORY_DIR`(默认值为 `/var/lib/noc-agent/memory`) / `NOC_PROACTIVE_STATE_DIR`(默认值为 `/var/lib/noc-agent/proactive`)
- 交接认证(仅在 `NOC_PROACTIVE_HANDOFF_ENABLED=1` 时需要),按优先顺序:
- **GitHub App(推荐):** `NOC_GITHUB_APP_ID` + 通过 `NOC_GITHUB_APP_PRIVATE_KEY_PATH` 提供的私钥(一个 PEM 文件;Vault Agent 在 `noc` 上渲染它)或内联的 `NOC_GITHUB_APP_PRIVATE_KEY`。安装会从 repo 中自动解析;使用 `NOC_GITHUB_APP_INSTALLATION_ID` 覆盖。该 app 在调用时生成短期的安装 token(已缓存)。该 app 需要在交接 repo 上具有 Issues: read/write + Metadata: read 权限。
- **PAT 回退:** `NOC_GITHUB_TOKEN`(细粒度,issues-scoped)。
- `NOC_PROACTIVE_ICINGA_URL` / `NOC_PROACTIVE_ICINGA_CHECK`(可选的被动心跳;复用 `ICINGA_API_USER`/`ICINGA_API_PASSWORD`)
也可以在 model-config TOML 中的 `[proactive]` 表下进行设置;环境变量具有优先权。
## Discord 机器人
当存在 `DISCORD_BOT_TOKEN` 时,服务会启动一个 `discord.py` 机器人,它支持:
- slash-command 调查
- 待处理/状态查找
- 批准/拒绝/确认决策
- 提及驱动的调查
Guild、channel 和 role 白名单配置如下:
- `DISCORD_ALLOWED_GUILD_IDS`
- `DISCORD_ALLOWED_CHANNEL_IDS`
- `DISCORD_ALLOWED_ROLE_IDS`
## Golden-state 上下文
Supervisor prompt 由以下内容组装而成:
- `app/prompts/supervisor_context.md`
- `app/prompts/golden_state_manifest.json`
该 manifest 是机器可读的预期状态锚点。在调查期间会将实时的 MCP 遥测数据与之进行对比,以便提案能够指出漂移,而不是凭空捏造配置情况。
## Knowledge 影子固件
此 repo 包含了位于 `evals/knowledge_shadow/` 下的只读 AS215932 knowledge context-pack 固件。
它们**仅在 shadow 模式下**验证未来的 `AS215932/knowledge` 集成:固件结构、引用、策略结果、所需的 NOC 章节以及 null vector-score 占位符。生产环境的 NOC runtime 不会使用这些固件,并且此阶段不会增加任何实时的 knowledge 服务调用。
运行固件评估:
```
uv run pytest tests/test_knowledge_shadow.py
```
固件绝不能包含 MCP 响应、Prometheus/Icinga 原始输出、日志、数据包数据、命令、凭据、授权标头或 secrets。
## 关键配置
- `NOC_REDIS_URL`
- `HYRULE_MCP_URL`
- `NOC_CONTROL_TOKEN`
- `NOC_APPROVAL_SIGNING_SECRET`(也接受 `HYRULE_MCP_ACTION_SIGNING_SECRET`)
- `NOC_ENABLE_APPROVED_EXECUTION`(默认值为 `0`;任何执行的总开关)
- `NOC_ENABLE_NOOP_ROLLBACK_GUARDS`(默认值为 `0`;通过惰性 no-op guards 路由执行)
- `NOC_ACTION_AUTH_TTL_SECONDS`(默认值为 `300`)
- `DISCORD_BOT_TOKEN`
-DISCORD_ALLOWED_GUILD_IDS`
- `DISCORD_ALLOWED_CHANNEL_IDS`
- `DISCORD_ALLOWED_ROLE_IDS`
- 用于默认 model 后端的 `OPENROUTER_API_KEY`
- 可选的 `OPENROUTER_MANAGEMENT_API_KEY`,用于账户范围的额度监控
- 可选的 `OPENROUTER_APP_TITLE` 和 `OPENROUTER_APP_URL`,用于 OpenRouter 归属
为了兼容性,仍然接受传统的 `HYRULE_MCP_CMD` 路径。
## Model 后端配置
模型选择可通过 TOML 进行配置。查找顺序为:
1. `NOC_AGENT_CONFIG`
2. `/etc/noc-agent/config.toml`
3. `config/noc-agent.toml`
4. 内置默认值
默认链是 OpenRouter DeepSeek V4 Pro,以 Claude Sonnet 4.6 作为回退:
```
[model]
primary = "openrouter:deepseek/deepseek-v4-pro"
fallbacks = ["openrouter:anthropic/claude-sonnet-4.6"]
```
可以使用 `openrouter:` 选择任何 OpenRouter 模型。密钥保留在环境变量中,而不是配置文件中。`AGENT_MODEL` 和 `AGENT_FALLBACK_MODELS` 仍然会覆盖配置文件以进行紧急更改。
Google/Gemini 仍然受支持以备将来使用:
```
[model]
primary = "google-gla:gemini-3.1-pro"
fallbacks = []
```
对于新的默认后端,请从 `GEMINI_API_KEY` 迁移到 `OPENROUTER_API_KEY`。`/health/model` 报告活动模型以及 OpenRouter 密钥限制和使用状态。`/metrics` 导出 OpenRouter 额度/使用量指标。
## 测试
请参阅 [TESTING.md](TESTING.md)。
*[Hyrule Networks (AS215932)](https://github.com/AS215932) 的一部分。*
标签:AIOps, AV绕过, FastAPI, LangGraph, NOC, 告警关联, 搜索引擎查询, 自动化分析, 自定义请求头, 跨站脚本, 运维, 逆向工具