Files
awoooi/docs/adr/ADR-073-flywheel-full-audit.md
OG T d32d494320 docs: 四階段細化實施步驟 + 架構轉型截圖定案 + 防偏差守則
規格書 v2.0 新增:
- §十一 四階段細化實施步驟(階段1~4各含驗收清單)
  - 階段1: CD解鎖+debounce+alertname+冷啟動Playbook+KM向量化(9步)
  - 階段2: DB Migration+classify_alert_early+outcome寫入(5步)
  - 階段3: 分診站+SSH路由+TYPE-1/E/F+action解析+risk_level(Tier3,7步)
  - 階段4: KMConversionService+手動修復記錄(4步)
- §十二 防偏差守則(不跳步驟/Tier3授權/不改範圍/異常立刻報告)

ADR-073 更新:架構轉型截圖定案(舊架構中斷→新架構分診飛輪)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 13:30:37 +08:00

15 KiB
Raw Blame History

ADR-073: AIOps 飛輪完整盤點 — 問題根因 + 長期解決方案

狀態: Accepted — 等待統帥批准實作(細化步驟已完成)
日期: 2026-04-12 (台北時間)
更新: 2026-04-12 晚 — 加入架構轉型截圖定案 + 四階段細化實施步驟
作者: Claude Sonnet 4.6 + 首席架構師
觸發: 資料庫審計顯示飛輪從未真正運轉
完整規格: docs/superpowers/specs/2026-04-12-aiops-complete-flywheel-repair-design.md(§十一 細化步驟、§十二 防偏差守則)

架構轉型核心2026-04-12 截圖定案)

舊架構(中斷路徑):
  告警 → LLM 瞎目alertname=NULL→ 目標不明 Unknown → KM 空白

新架構(飛輪 V2.2
  告警 → 分診工作站decision_manager 入口)
         ├─ TYPE-1資訊→ 純文字通知,不進修復流程
         ├─ TYPE-4DDrift→ Drift 卡片,不進修復流程
         └─ TYPE-3需修復→ MCP 上下文 → LLM 推理 → 自動執行 → KM 向量化

關鍵洞察:分診工作站從 telegram_gateway 前移至 decision_manager 入口是防止「HostBackupFailed 產生 kubectl scale deployment unknown」的架構根治。


一、飛輪設計圖(截圖定案版)

正常模式(自主運行)

監控觀察 → 接入去重 → 環境診斷 → 推理匹配 → 執行燒橇 → 學習固化
   ↑                                                           ↓
   └─────────────────── 飛輪閉環 ──────────────────────────────┘

六個節點定義

節點 功能 對應程式碼
監控觀察 Prometheus/Alertmanager 接收告警Fingerprint 去重 webhooks.py alertmanager_webhook
接入去重 Debounce 30 分鐘,相同 fingerprint 只建一個 Incident webhooks.py fingerprint + debounce
環境診斷 MCP 收集真實環境狀態SSH/K8s/Prometheus decision_manager._collect_mcp_context()
推理匹配 查 KM Playbook → 有匹配直接執行;無匹配呼叫 LLM 推理 decision_manager._dual_engine_analyze()
執行燒橇 透過 MCP Provider 執行修復動作 decision_manager._auto_execute()
學習固化 成功→生成 Playbook失敗→生成 Anti-Pattern寫入 KM decision_manager._generate_playbook_draft_if_new()

人工介入模式(需人工路徑)

推理匹配
   ├→ TYPE-3高風險審核: AI 找到方案但動作風險高 → 人工批准 → 執行 → 學習固化
   └→ TYPE-4根因確認:  AI 無法判斷 → 人工手動處理 → 記錄手動步驟 → 生成新 Playbook

人工介入只發生在兩種情況

  1. risk_level = critical 或 DESTRUCTIVE_PATTERNS 命中 → TYPE-3 卡片
  2. confidence < 0.5 或 MCP 全失敗 → TYPE-4 卡片,人工確認後轉 Playbook

二、資料庫實際數據2026-04-12 統計)

Incidents132 筆)

欄位 數值 正常應有
severity P3 10882% P3 應是少數
severity P2 1814%
severity P0 64%
status INVESTIGATING 8766% 應該接近 0
status RESOLVED 4534%
alertname 全部 NULL 應有 alertname
alert_category 全部 NULL 應有分類
notification_type 全部 NULL 應記錄卡片類型
vectorized 全部 False 應 True已向量化進 KM
outcome 全部 null 應記錄修復結果

Approvals380 筆)

status 數量 說明
EXECUTION_FAILED 21155% 超過一半執行失敗
APPROVED 13235% 已核准,未執行或執行中
REJECTED 308% 人工拒絕
EXPIRED 5 超時未處理
EXECUTION_SUCCESS 20.5% 實際成功修復只有 2 次

Top Actions失敗根因

action 數量 問題
未知操作 |(空) 93 action 解析失敗,完全不知道要做什麼
重新啟動 postgres-primary-0 30 同一問題反覆重啟,未解決根因
重新啟動 postgresql-native 25 同上
重新啟動 harbor-core-7d4b8c9f5-xk2m3 21 Pod hash 寫死,每次不同
OBSERVE 16 LLM 判斷無法修復,只觀察

Playbooks = 0

Knowledge Entries699 筆)

  • INCIDENT_CASE: 690有案例但全部未向量化,無法 RAG 查詢)
  • RUNBOOK: 7
  • BEST_PRACTICE: 2

三、飛輪每個節點的實際狀態 vs 設計目標

節點 1監控觀察 部分正常

  • Prometheus → Alertmanager → webhooks.py 接收
  • 問題alertname 存入 signals JSONBsignals->0->>'alertname' 全為 NULL代表 signals 結構不對

節點 2接入去重 ⚠️ 部分異常

  • Fingerprint 機制存在
  • 問題debounce window 只有 5 分鐘Prometheus 每 1 分鐘 fire 一次5 分鐘後重新建 Incident導致同一問題產生多個 Incident反覆發 Telegram

節點 3環境診斷 未運作

  • _collect_mcp_context() 已實作commit c439277
  • 問題8be87b0 的修復程式碼 CD 失敗未部署,目前 Pod 是舊 imagea86ecf3),該 image 沒有 _collect_mcp_context()
  • MCP Providers 雖然 enabled但沒有在分析前被呼叫

節點 4推理匹配 嚴重問題

  • LLM 分析有在跑Nemotron NIM
  • 問題 APlaybooks = 0evaluate_auto_repair() 在 Playbook 匹配步驟永遠失敗,100% 走人工審核
  • 問題 Bsignals JSONB 裡 alertname = NULLLLM 拿到的是空告警名稱
  • 問題 Ctarget_resource 解析失敗DockerContainerUnhealthy → target = alertname or unknown
  • 問題 DLLM 習慣性回傳 risk_level = high,但 YAML 規則的 risk 沒有覆蓋 LLM 結果

節點 5執行燒橇 從未成功0.5%

  • _auto_execute() 三層安全守衛存在
  • 問題 A93 次 未知操作| → action 解析失敗LLM 回傳的 action 包含 | 分隔符,解析邏輯出錯
  • 問題 Btarget = unknowntarget = alertname → 安全守衛攔截 → 發 ❌ 自動修復失敗(而非 TYPE-4 卡片)
  • 問題 CK8s deployment 名稱含 hashharbor-core-7d4b8c9f5-xk2m3K8s 驗證失敗
  • 問題 DDocker/Host 層告警DockerContainerUnhealthy / HostBackupFailed走 K8s 路徑,根本路徑就錯

節點 6學習固化 完全失效

  • _generate_playbook_draft_if_new() 已實作commit 7eb49f9
  • 問題 APlaybooks 仍為 0代表觸發條件從未成立或有 exception 被靜默吞掉
  • 問題 B690 筆 INCIDENT_CASE 全部 vectorized = FalseRAG 查詢永遠找不到歷史案例
  • 問題 Coutcome / target_resource / alert_category 全為 NULLKM 記錄的案例沒有分類,無法被有效查詢
  • 問題 D重複發生的告警postgres-primary-0 被重啟 30 次)沒有任何學習,每次重新走全流程

四、與設計定案的落差對照表

設計定案要求 實際狀況 落差等級
告警 → 自動修復閉環 Playbooks=0100% 人工審核 🔴 P0
重複告警不重複觸發 5 分鐘 debounce每次重建 🔴 P0
失敗 → 學習 → 建立規則 690 案例未向量化Playbook 從未生成 🔴 P0
KM 三段資料完整 outcome/vectorized 全 NULL 🔴 P0
target 動態解析Docker/Host target = unknown/alertname 🔴 P0
NO_ACTION 告警不顯示按鈕 HostBackupFailed 仍有六個按鈕 🟠 P1
通知類型正確分類 notification_type 全 NULL 🟠 P1
severity/risk_level 正確 P3 佔 82%risk 被 LLM 覆蓋 🟠 P1
人工修復後轉 Playbook 無 handle_manual_fix_done 呼叫 🟠 P1
前端顯示飛輪狀態 截圖顯示 Playbook=0飛輪靜止 🟡 P2

五、長期解決方案(按優先順序)

P0-A修復 CD + 部署新 image

問題8be87b0 的三大修復未上線
解法:確認 Harbor 有 8be87b0 的 web image若沒有重新觸發 build
驗收Pod image = 8be87b0_collect_mcp_context 存在於 /app/src

P0-B修復 signals 結構 — alertname 存入正確欄位

問題signals->0->>'alertname' = NULL
解法webhooks.py 在建 Incident 時,確認 signal 的 alertname 正確寫入 JSONB或新增獨立欄位 alertname VARCHAR(100)
驗收:新 Incident 的 alertname 不為 NULL

P0-Cdebounce window 延長到 30 分鐘

問題5 分鐘 debounce → 同一問題每 5 分鐘重新建 Incident + 發 Telegram
解法webhooks.py fingerprint debounce window 從 5 分鐘 → 30 分鐘
驗收:同一告警 30 分鐘內只有 1 個 INVESTIGATING Incident

P0-D冷啟動 Playbook 生成

問題Playbooks = 0自動修復永遠失敗
解法:一次性腳本,讀取 approval_records 裡 EXECUTION_SUCCESS 的 2 筆 + APPROVED 的 top 10用 LLM 生成初始 Playbook 草稿,寫入 DB 標記 APPROVED
驗收Playbooks >= 10evaluate_auto_repair 至少有匹配

P0-E690 筆 INCIDENT_CASE 向量化

問題vectorized = FalseRAG 永遠找不到歷史案例
解法:一次性腳本,批次向量化所有 vectorized=False 的 knowledge_entries
驗收vectorized = TrueRAG 查詢返回相關案例

P0-FDocker/Host 層告警走 SSH MCP 路徑

問題DockerContainerUnhealthy → K8s 路徑 → deployment 不存在 → 失敗
解法_auto_execute() 判斷 alertname prefixDocker*/Host*)→ 走 SSH MCP ssh_docker_restart;不走 K8s 路徑
驗收DockerContainerUnhealthy 觸發 → SSH MCP 執行 → 成功

P1-Aaction 解析修復93 筆「未知操作|」)

問題LLM 回傳含 | 的 action解析後為空
解法_push_decision_to_telegram() 的 action 佔位符替換邏輯,加 | 分隔符清理
驗收:新的 approval_records action 不出現「未知操作|」

P1-BNO_ACTION → TYPE-1無按鈕

問題HostBackupFailed 仍有六個按鈕
解法classify_notification() 加判斷:suggested_action == "NO_ACTION" → TYPE-1
驗收HostBackupFailed Telegram 卡片無操作按鈕

P1-Coutcome / alert_category / notification_type 寫入

問題:三個欄位全 NULLKM 無法分類
解法

  • _auto_execute() 完成後寫 incident.outcome
  • webhooks.py 建 Incident 時寫 alert_category(從 YAML 規則取)
  • _push_decision_to_telegram() 發完寫 notification_type

P1-Drisk_level YAML 優先覆蓋 LLM

問題LLM 習慣性回傳 highYAML 規則的 risk 沒有覆蓋
解法_dual_engine_analyze() 中,若 YAML 規則有 risk 值,優先用 YAML 的,不採用 LLM 的
驗收HostHighCpuLoadYAML risk=medium→ Telegram 顯示 MEDIUM

P2-A前端飛輪狀態即時顯示

問題截圖顯示飛輪靜止Playbook=0成功率 0.5%,需人工介入
解法:前端飛輪元件(已有)連接以下 API

  • GET /api/v1/stats/flywheel → 返回六節點狀態(活躍/靜止/錯誤)
  • GET /api/v1/stats/summary → 返回 Playbook 數量、成功率、今日處理數
  • WebSocket 推送:每次節點狀態變化即時更新
    驗收飛輪動畫跟隨真實告警流轉動Playbook 數量即時更新

P2-B前端顯示人工介入路徑

問題:截圖第二張「需人工介入」時,飛輪顯示 TYPE-4根因確認和 TYPE-3高風險審核路徑
解法飛輪元件增加「顯示人工干預路徑」toggle已有觸發時

  • 紅色虛線顯示從「推理匹配」到「人工處理中心」的路徑
  • TYPE-3 / TYPE-4 標籤顯示在對應節點旁邊

六、實作優先順序與批准等待

以下所有變更等待首席架構師批准後才開始實作

Sprint ADR-073-A本週讓飛輪真的動起來

# 任務 風險等級 估計工時
1 CD 修復 + 8be87b0 部署確認 Tier 2 30 分鐘
2 signals alertname NULL 修復 Tier 2 1 小時
3 debounce 5→30 分鐘 Tier 2 30 分鐘
4 冷啟動 Playbook 生成腳本(一次性) Tier 2 2 小時
5 690 筆 KM 向量化腳本(一次性) Tier 1 1 小時

Sprint ADR-073-B下週修復路由 + 通知品質

# 任務 風險等級 估計工時
6 Docker/Host 告警 → SSH MCP 路徑 Tier 3 3 小時
7 action 解析「未知操作 」修復 Tier 2
8 NO_ACTION → TYPE-1 無按鈕 Tier 2 1 小時
9 outcome/alert_category/notification_type 寫入 Tier 3 2 小時
10 risk_level YAML 優先 Tier 2 1 小時

Sprint ADR-073-C再下週前端飛輪即時化

# 任務 風險等級 估計工時
11 /api/v1/stats/flywheel API Tier 1 2 小時
12 前端飛輪元件連接真實 API Tier 2 3 小時
13 WebSocket 即時推送 Tier 2 2 小時

Sprint ADR-073-B 補充(整合 ADR-071 工作序2026-04-12 更新)

# 任務 風險等級 ADR-071 對應
B-DB DB Migration: incidents +9 欄位 Tier 1 ADR-071-A
B1 檢傷分類站前移decision_manager 入口) Tier 3 ADR-071-A0+B
B2 TYPE-1 純資訊卡片 Tier 2 ADR-071-C
B3 KMConversionServiceRESOLVED→KM→向量化 Tier 2 ADR-071-G
B4 TYPE-4 手動修復記錄 Tier 2 ADR-071-H

Sprint ADR-074監控補全依賴 ADR-073-A/B 完成後)

# 任務 告警名稱 嚴重度
M1 飛輪健康度 Prometheus Exporter + 告警規則 FlywheelPlaybookZero / FlywheelExecutionSuccessLow P0 Critical
M2 主機間網路 Blackbox probe HostNetworkPartition P0 Critical
M3 CoreDNS 解析失敗監控 CoreDNSResolutionFailed P0 Critical
M4 Gitea CI/CD 管線失敗 webhook GiteaCIPipelineFailed P0 Critical
M5 備份還原週排程測試 BackupRestoreTestFailed P0 Critical
M6 Docker 188 容器詳細健康 DockerContainerUnhealthyDetailed P1 Warning
M7 Redis Streams 積壓 RedisStreamBacklogHigh P1 Warning
M8 PostgreSQL 磁碟增長率 PostgreSQLDiskGrowthRate P1 Warning
M9 Gemini API 錯誤率 GeminiAPIErrorRateHigh P1 Warning

完整規格: docs/superpowers/specs/2026-04-12-aiops-complete-flywheel-repair-design.md


七、驗收標準(飛輪真正運轉的指標)

完成後 7 天內,以下指標必須達到:

指標 當前 目標
Playbooks 數量 0 ≥ 20
EXECUTION_SUCCESS 率 0.5% ≥ 30%
重複告警同 Incident 率 < 10% ≥ 70%
KM vectorized 0% ≥ 90%
alertname NULL 100% 0%
飛輪節點有活動的告警 0 ≥ 1 筆/小時