# ADR-055: Knowledge Auto-Harvesting(AUTO_RUNBOOK + ANTI_PATTERN) > **狀態**: ✅ 已批准 > **日期**: 2026-04-04 > **決策者**: 統帥 + 首席架構師 > **首席架構師評分**: 技術背書 > **關聯 ADR**: ADR-052 (AI Provider Registry), ADR-043 (Knowledge Base) > **實作**: Phase 25 P1 — commit 3455044 --- ## 背景 ### 問題陳述 AutoRepair 執行修復後,成功/失敗的知識停留在系統日誌中,無法被後續決策利用。特別是: 1. **成功修復** → 修復步驟應被收錄為可參考的 Runbook 2. **失敗修復** → 失敗模式應被記錄以防止重複嘗試相同方法 Knowledge Base 存在但靠人工填寫,形成知識孤島。 --- ## 決策 ### D1: AUTO_RUNBOOK — 成功修復自動產生草稿 Runbook ```python # auto_repair_service.py — execute_auto_repair() 成功後 task = asyncio.create_task(gen.generate_runbook(incident, playbook, result)) self._pending_tasks.add(task) task.add_done_callback(self._pending_tasks.discard) ``` - EntryType: `AUTO_RUNBOOK` - EntryStatus: `DRAFT`(需要人工審核後才升為 APPROVED) - Nemotron 生成內容,失敗時有最小化 fallback **理由**: 自動生成的 Runbook 品質未經驗證,保持 DRAFT 讓 SRE 審核,避免錯誤知識被自動採納。 ### D2: ANTI_PATTERN — 失敗修復直接發布防災記錄 ```python # auto_repair_service.py — execute_auto_repair() 失敗後 task = asyncio.create_task( gen.generate_anti_pattern(incident, playbook, fail_result, symptoms_hash) ) self._pending_tasks.add(task) task.add_done_callback(self._pending_tasks.discard) ``` - EntryType: `ANTI_PATTERN` - EntryStatus: `PUBLISHED`(直接發布,無需人工審核) - 理由:失敗記錄的目的是「防止重蹈覆轍」,早一秒發布早一秒保護 ### D3: SymptomPattern.compute_hash() — O(1) 防災閘門 ```python def compute_hash(self) -> str: key = ( "|".join(sorted(self.alert_names)) + "||" + "|".join(sorted(self.affected_services)) + "||" + json.dumps(self.label_patterns, sort_keys=True) ) return hashlib.sha256(key.encode()).hexdigest()[:16] ``` - 16 字元 hex = 2^64 碰撞空間,工程實踐上足夠 - 碰撞發生最壞結果:某次修復被誤攔截,需人工重試——可接受 ### D4: evaluate_auto_repair() 加入 ANTI_PATTERN 閘門 ```python # 症狀提取後、Playbook 匹配前 symptoms_hash = symptoms.compute_hash() anti_patterns = await get_knowledge_service().check_anti_pattern(symptoms_hash, days=7) if anti_patterns: return AutoRepairDecision( can_auto_repair=False, reason=f"過去 7 天有失敗案例: {anti_patterns[0].title}", blocked_by="ANTI_PATTERN", ) ``` 閘門位置:診斷症狀後、開始執行前,屬於預防性攔截。 ### D5: Fire-and-Forget 必須有 GC 防護 所有 `asyncio.create_task()` 必須: 1. 持有引用至 `self._pending_tasks` 2. 在 `done_callback` 中從集合移除 ```python task = asyncio.create_task(coro) self._pending_tasks.add(task) task.add_done_callback(self._pending_tasks.discard) ``` 成功分支與失敗分支必須對稱實作,不得有遺漏。 --- ## 後果 ### 正面影響 - Knowledge Base 自動積累修復經驗,形成正向循環 - 失敗模式即時保護,防止重複損耗 - SRE 工作聚焦於審核而非撰寫 ### 負面影響 / 風險 - Nemotron 生成的 Runbook 品質參差,需 SRE 審核成本 - ANTI_PATTERN 直接發布,若症狀 hash 碰撞可能誤攔正常修復 ### 未決事項(Backlog) - I2: `nvidia.chat()` system prompt 格式是否符合 NIM message format 規範 - M1: ANTI_PATTERN 是否需要 Telegram 確認視窗(human-in-the-loop 選項) - M2: symptoms_hash 16 字元截斷的碰撞監控機制