oclaw/skills/_workspace/ops/ops-netx-ume-playbook/SKILL.md
2026-08-12 21:27:30 +08:00

148 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
name: ops-netx-ume-playbook
description: 面向 ops 专家的 netx UME 运维作业手册。覆盖告警查询/聚合/诊断、网元清单与单网元详情、raw 字段过滤、UME 只读 SQL、以及告警关联拓扑路径。
---
# Ops Netx UME 作业手册
## 强制使用范围
凡是涉及 netx/UME **告警**或 **网元信息** 的 ops 请求,必须优先加载并遵循本技能。
## MCP 工具名(强制)
使用 Cursor / oclaw MCP 时,工具名为 **camelCase**(`server_id=netx`):
| 用途 | MCP 工具 |
|------|----------|
| 告警列表 | `queryUmeAlarms` |
| 告警聚合 | `aggregateUmeAlarms` |
| 诊断摘要 | `runUmeDiagnostics` |
| 网元清单 | `queryUmeNeInventory` |
| 网元详情 | `getUmeNe` |
| 字段清单 | `listUmeAlarmFields` |
| 原始明细 | `queryUmeAlarmsRaw` |
| 动态聚合 | `aggregateUmeAlarmsRaw` |
| SQL | `sqlQueryUme` |
| 拓扑路径 | `findTopologyPaths` |
| 纳管/CLI(另册) | `listManagedNe` / `getManagedNe` / `execManagedNe` / `listCliTargets` |
使用 **MCP** 名称(`mcp__netx__*`);勿使用已移除的旧 inline `netx_*` 工具名。
## 工具选择顺序
1. **新鲜度(先做)**:`runUmeDiagnostics` 或 `aggregateUmeAlarms` → 看 `meta.last_seen_min` / `last_seen_max`。
- 若最大值远早于「现在」,按 **快照数据** 处理:时间窗用数据范围内的日期,禁止套 `now()-30 minutes`。
2. 基础视图:`aggregateUmeAlarms` + `runUmeDiagnostics`;样本用 `queryUmeAlarms`(默认 1 页)。
3. 证据明细:`listUmeAlarmFields` → `queryUmeAlarmsRaw`(`field_preset=evidence` / `select_fields`)。
4. 自定义聚合:`aggregateUmeAlarmsRaw`(`group_by=alarm_host_name` 等)。
5. SQL:`sqlQueryUme`(仅 SELECT;设 `statement_timeout_ms`)。
6. **告警关联拓扑**:两台相关网元取 `ne_id` → `findTopologyPaths`(最短路径优先)。
7. **登设备查 CLI**:见 `ops-netx-managed-ne-playbook`;多台用一次 `execManagedNe` batch(同命令用 `ne_ids|ume_ne_ids`;每台命令不同用 `targets=[{ume_ne_id, commands},…]`),勿逐台循环。
## 快速决策树
- **整体态势 / Top 风险**:`runUmeDiagnostics` + `aggregateUmeAlarms`(默认已排除 missing host;看 `by_ne_missing`)。
- 高危 Top-N:`aggregateUmeAlarms(severity=critical, top_ne=10)`,勿只看总量 Top。
- 按 host 自定义分组:`aggregateUmeAlarms(group_by=alarm_host_name, …)`(内部等同 Raw)或显式 `aggregateUmeAlarmsRaw`。
- **时间收敛**:`queryUmeAlarms` / `aggregateUmeAlarms` / raw 均支持 `time_from`/`time_to`(语义=`last_seen_at`)。先看 freshness,再填时间窗。
- **可引用证据**:`queryUmeAlarmsRaw` + `field_preset=evidence`。
- **任意字段统计**:`aggregateUmeAlarmsRaw`(按 host 分组时默认排除 missing;看 `by_ne_missing`)。
- **复杂条件**:`sqlQueryUme`。
- **critical 口类/光路类告警**:抽 1–2 个 `ne_id` → `findTopologyPaths`(默认 `detail=summary`,看 `paths[].label`)→ 再决定是否 CLI。
- **查网元身份**:`queryUmeNeInventory(keyword=host_name)`;完整 `raw_json` 用 `getUmeNe`。
## WhatsApp short-intent recipes (≤3 tools; English field primary)
Prefer these fixed paths for short group/DM asks (EN first; ZH aliases still work). **Target ≤3 tool calls** — do not paginate or re-list CLI targets.
| User says (examples) | Recipe |
|----------------------|--------|
| fiber cut / LOS / cable cut / 断纤 | Prefer `ume_alarm_xlsx_report(mode=fiber_cut)` (xlsx + deliver); or summarize via `queryUmeAlarmsRaw` |
| offline NE / board offline / 离线 | Prefer `ume_alarm_xlsx_report(mode=offline)` |
| Critical Top / alarm tally | ① `aggregateUmeAlarms(severity=critical, top_ne=20)`; for file: `ume_alarm_xlsx_report(mode=aggregate_by_host, severity=critical)` |
| how many alarms / tally | ① `runUmeDiagnostics` or `aggregateUmeAlarms`; ② report by_severity + freshness |
| export Excel / send spreadsheet | `ume_alarm_xlsx_report` **or** `write_xlsx(..., deliverable=true)`; never split into 3 steps |
| CRC in area PAD / ACH / … | `queryUmeAlarmsRaw(keyword=CRC)` then keep rows whose `alarm_host_name` / `ne_host_name` starts with area prefix (`PAD-`, `ACH-`, …). Optional xlsx via `write_xlsx(deliverable=true)` |
| bandwidth / congestion / usage rate (+ area) | keyword=`bandwidth` (do **not** require event_type unless user asks); filter hostname prefix for area; if CLI confirm false positives: top 3–5 NEs in **one** batch — same show → `ume_ne_ids=[…]`+`commands`; mixed vendors → `targets=[{ume_ne_id, commands},…]` — never one-NE loops |
| BN EMS / dying gasp / unmanaged (+ area) | keyword or native cause match (`BN EMS` / `dying gasp`); filter area prefix; short EN summary + optional xlsx |
| power / temperature / fan alarms (+ area/NE) | keyword=`power` / `temperature` / `fan`; scope to host or area prefix |
| alarm on **one hostname** (e.g. `MDN-PLSP`, `MKS-SWBP-EN1`) | `queryUmeAlarms` / `queryUmeAlarmsRaw` with `host_name` / keyword=hostname. **Never** start a scheduled License/daily playbook |
| alarm history / time range (e.g. `17.50-18.15`) | Resolve **WIB (UTC+7)** wall clock → `time_from`/`time_to` on `last_seen_at` / history fields; first check freshness; name hosts exactly (`MKS-KIM-CN1`) |
| is NE rebooted? / alarm history for NE | Host-scoped alarm history (reboot/reload/power related causes); answer yes/no + evidence times |
Delivery rules:
- `ume_alarm_xlsx_report` defaults `deliverable=true` so WhatsApp receives the file.
- Generic sheets: `write_xlsx(..., deliverable=true)` can skip `save_deliverable_attachment`.
- Do not build xlsx via `run_command` + openpyxl.
- Confirm short replies (`YES` / `confirm` / `继续` / `ya` / `yea`): continue the previous task; do not restart the query.
### Field vocabulary (prod-learned; enforce)
- **Area** = hostname **prefix** before first extra segment: `BTM-`, `ACH-`, `MKS-`, `PAD-`, `MDN-`, `KND-`, `SMD-`, `MDO-`, `PLG-`, … Case-insensitive starts-with.
- **Capacity / bandwidth between A and B** (user correction in field): means **SFP/optical link capacity between two hostnames**, not UME bandwidth-usage-rate alarms alone. Resolve both NEs → interconnect ports (`findTopologyPaths` / LLDP) → optical/SFP CLI. See `ops-netx-managed-ne-playbook`.
- **Site nicknames** (SEMBAWA, ANGKATAN_EP, …): resolve via inventory/wiki/`queryUmeNeInventory(keyword=…)` **before** CLI; never invent hostnames.
- **Local clock phrases** (`17.50`, `today`, `yesterday`): treat as **Asia/Jakarta (WIB, UTC+7)** unless user says otherwise.
### Anti-patterns seen in field (do not repeat)
1. **Wrong playbook hijack** — User: `query alarm on MDN-AHJ-AN1` → must NOT run License/daily scheduled playbook. Answer that host’s current alarms only.
2. **Narration-only turns** — Avoid “Let me start by…” / “I’ll fetch fields…” as the only WhatsApp message. Prefer: progress throttle already exists; final reply = **findings first** (counts + top hosts), then optional detail.
3. **Markdown tables on WhatsApp** — Do not send `|---|+` pipe tables or `##` headings. Use `*bold*` labels and `-` bullets (outbound converter helps, but write WA-native).
4. **Apology loops** — If user asks “are you still running / why no response?”, resume the **quoted task** immediately; one short status line, then results. Do not ask what a Run ID might mean if `schedule_list` / job tools can answer.
5. **Group noise** — Pure emoji / mention-only / “hi” with no ops ask: stay minimal or silent per group policy; do not give a long “how can I help” menu.
6. **Blind CLI retries** — Wrong ZTE optic command once → switch to `show opticalinfo brief` (see managed-ne skill); do not retry the failed spelling.
### Answer shape (WhatsApp EN) — strict ops bot
Use this shell for ops/alarm/NE/CLI/schedule asks (preferred default; keep it short):
```
*<topic> — <area/NE>*
- Result: …
- Evidence: N alarms / Top hosts / CLI ok|fail · as-of WIB if known
- Next: … (omit if none)
```
- Final reply = **findings only** — do not lead with `Let me…` / `I'll check…`.
- About **≤15 lines** in chat; large detail → **xlsx**.
- Include severity counts and/or Top `host_name` when alarm data exists.
- Casual emoji/hi: one short line or silence — stay an ops bot, not a chat buddy.
## 约束与护栏
- 优先非 SQL;参数表达不了再用 SQL。
- 过滤优先级:`severity` → `keyword`/`host_name` → `time_from/time_to` → `event_type`/`ne_id`。
- 禁止无脑翻页:列表默认 ≤2 页;扩大前必须先过滤。
- 体积:`page_size` 默认 50;聚合 `top_ne` 默认 50;raw 用 preset;动态聚合 `limit≤200`。
- **Top 网元**:默认忽略 `(host_name missing)`;结论中说明 missing 数量,勿把 UUID/`unknown`/空串当网元名。
- SQL:建议 `statement_timeout_ms=8000`;非 `count(*)` 应带过滤;时间窗相对 **数据新鲜度**,不是盲目 `now()`。
- 若返回 `insufficient_scope:sql:query`:改用 `aggregateUmeAlarms` / `queryUmeAlarmsRaw` / `ume_alarm_xlsx_report`,勿盲重试 SQL。
- `WITH` CTE 可用;**禁止** `WITH RECURSIVE`。
- `getManagedNe` 只要 **纳管 ne_id**(来自 listManagedNe);UME UUID 用 `getUmeNe` / `execManagedNe(ume_ne_id=...)`。失败时跟 `hint` 换工具,禁止相同 id 盲重试。
## 输出约定
- 结论 + 工具证据 + 可执行下一步。
- 无工具证据不得臆测告警事实。
- **严格运维机器人**:终稿先结果、短列表、大表附件;禁止过程腔开场与客服闲聊人格(见 ROLE_SYSTEM / Answer shape)。
- **现场默认英文**:用户用英文提问或渠道 lang=en 时,回复 **不得含汉字**;工具返回的中文字段必须译成英文后再展示。
- 仅当用户明确用中文提问且渠道为 zh 时,才用中文回复。
### 网元展示:以 host_name 为主键(强制)
- 表格首列、Top、分组键、结论中的网元名 = **`host_name`**。
- 来源:`queryUmeAlarms.host_name` / raw `alarm_host_name` / 聚合 `alarm_host_name`。
- **禁止**对用户展示裸 `ne_id`;`ne_id` 仅作过滤与 `findTopologyPaths` 入参。
- host 缺失时用 `user_label`,并标注「host_name 缺失」;仍不得退回 UUID。
## 推荐分析模式
- 高风险网元:`aggregateUmeAlarms(group_by=alarm_host_name, severity=critical)` 或显式 `aggregateUmeAlarmsRaw`。
- 严重度:`aggregateUmeAlarms`(默认 by_severity + by_ne);自定义维度才用 `group_by`。
- 事件类型:看 diagnostics `top_event_types`;真正告警码看 `top_alarm_codes`(UME `alarmCode`)。
- 关联路径:critical Port down / LOS → `findTopologyPaths(from_ume_ne_id, to_ume_ne_id)`。
## 参考模板
- 快速模板见:[reference.md](reference.md)