ADR-054: DIAGNOSE Privacy-First Routing (已批准) - _local_fallback_chain 設計決策 - NEMOTRON privacy_level=local 首席架構師裁示 - 全部 local 失敗 → REJECT + Telegram ADR-055: Knowledge Auto-Harvesting (已批准) - AUTO_RUNBOOK DRAFT + ANTI_PATTERN PUBLISHED 設計理由 - compute_hash() 碰撞風險說明 - Fire-and-forget GC 防護強制規範 ADR-056: Config Drift Detection 四層架構 (已批准) - Detector→Analyzer→Interpreter→Remediator 職責邊界 - AI 只做意圖分析不做修復決策 - adopt() 暫停 + _recent_reports Phase 1 限制 ADR-057: adopt() Gitea PR API 實作路徑 (草案,待批准) - 解決 API Pod git add -A 安全風險 - PR review 流程保障 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.7 KiB
3.7 KiB
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 執行修復後,成功/失敗的知識停留在系統日誌中,無法被後續決策利用。特別是:
- 成功修復 → 修復步驟應被收錄為可參考的 Runbook
- 失敗修復 → 失敗模式應被記錄以防止重複嘗試相同方法
Knowledge Base 存在但靠人工填寫,形成知識孤島。
決策
D1: AUTO_RUNBOOK — 成功修復自動產生草稿 Runbook
# 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 — 失敗修復直接發布防災記錄
# 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) 防災閘門
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 閘門
# 症狀提取後、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() 必須:
- 持有引用至
self._pending_tasks - 在
done_callback中從集合移除
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 字元截斷的碰撞監控機制