- CLAUDE.md: 紅區治理章節 - Skills 01/03: 版本更新 - ADR/Architecture: 標準化 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
11 KiB
11 KiB
Skill 03: OpenClaw Cognitive Expert
AI 認知引擎專家
管轄範圍: Incident Engine, GraphRAG, Multi-Sig, Event Bus 觸發條件: 修改
services/incident_*.py,services/multi_sig*.py,services/graph*.py
文件資訊
| 欄位 | 值 |
|---|---|
| 版本 | v1.3 |
| 建立日期 | 2026-03-20 (台北) |
| 建立者 | Claude Code |
| 最後修改 | 2026-03-25 23:58 (台北) |
| 修改者 | Claude Code |
變更紀錄
| 版本 | 日期 | 執行者 | 變更內容 |
|---|---|---|---|
| v1.0 | 2026-03-20 | Claude Code | 初始建立 |
| v1.1 | 2026-03-23 | Claude Code | DecisionManager 雙軌引擎 |
| v1.2 | 2026-03-25 | Claude Code | 智能路由引擎 + Tool/Modular 關係 |
| v1.3 | 2026-03-25 | Claude Code | 加入文件資訊區塊 |
核心架構 (三層記憶系統)
1. Working Memory (Redis Hash)
位置: 192.168.0.188:6380/10
用途: 活動中 Incident 狀態 (TTL 7天)
Key: incident:{incident_id}
2. Episodic Memory (PostgreSQL/SQLite)
位置: 192.168.0.188:5432 (Prod) / awoooi.db (Dev)
用途: 長期歷史記錄
Table: incident_records
3. Event Bus (Redis Streams)
Stream: stream:awoooi_signals
Group: awoooi_workers
用途: 告警信號傳遞
核心約束 (Cognitive Iron Laws)
1. 雙層記憶同步
# ✅ 正確 (必須同時寫入)
async def create_incident(incident: Incident):
# 1. Working Memory (即時狀態)
await redis_client.hset(f"incident:{incident.id}", mapping=incident.to_redis())
# 2. Episodic Memory (持久化)
await db.execute(insert(IncidentRecord).values(**incident.to_db()))
# ❌ 禁止 (單層寫入)
await redis_client.hset(...) # 只寫 Redis,遺漏 DB
2. LLM 調用必須走快取
# ✅ 正確
async def analyze_with_ai(context: str) -> str:
cache_key = f"ai_response:{hash(context)}"
cached = await redis_client.get(cache_key)
if cached:
return cached
response = await _call_ollama(context)
await redis_client.setex(cache_key, 3600, response)
return response
# ❌ 禁止 (無快取直接調用)
response = await _call_ollama(context)
3. Multi-Sig 動作必須 Dry-Run
# ✅ 正確 (先模擬,後執行)
async def execute_k8s_action(action: K8sAction) -> ExecutionResult:
# Step 1: Dry-Run 驗證
dry_result = await k8s_executor.execute(action, dry_run=True)
if not dry_result.success:
raise ValidationError(dry_result.error)
# Step 2: 等待 Multi-Sig 簽核
approval = await wait_for_approval(action.approval_id)
# Step 3: 真實執行
return await k8s_executor.execute(action, dry_run=False)
# ❌ 禁止 (跳過 dry_run)
return await k8s_executor.execute(action, dry_run=False)
Event Bus 規範
Signal Producer (告警輸入)
# Webhook 接收告警 → XADD 至 Stream
await redis_client.xadd(
"stream:awoooi_signals",
{"payload": json.dumps(signal.model_dump())},
maxlen=10000, # 告警風暴防護
)
Signal Consumer (Worker)
# XREADGROUP 消費 → ACK 確認
messages = await redis_client.xreadgroup(
groupname="awoooi_workers",
consumername=consumer_id,
streams={"stream:awoooi_signals": ">"},
count=10,
block=5000,
)
# 處理後必須 ACK
await redis_client.xack("stream:awoooi_signals", "awoooi_workers", message_id)
Incident Engine 聚合規則
| 參數 | 值 | 說明 |
|---|---|---|
| 時間窗口 | 30 分鐘 | 相近告警聚合 |
| 相似度閾值 | 0.7 | 文字相似度門檻 |
| 升級規則 | 3 筆 P2 → P0 | 自動提升 Severity |
🚨 提案防爆圈 Guardrails (2026-03-23 首席架構師指令)
目的: AI 生成的修復提案可能包含危險指令,必須裝上保險絲
鐵律 1: 毀滅性指令黑名單
# ❌ 絕對禁止出現在 AI 生成的提案中
FORBIDDEN_COMMANDS = [
"rm -rf /",
"rm -rf /*",
"DROP DATABASE",
"DROP TABLE",
"TRUNCATE",
"kubectl delete namespace",
"kubectl delete -A",
"> /dev/sda",
"mkfs",
":(){:|:&};:", # Fork bomb
]
def validate_proposal_safety(script: str) -> bool:
"""提案安全檢查 - 必須在生成後立即執行"""
for forbidden in FORBIDDEN_COMMANDS:
if forbidden.lower() in script.lower():
logger.critical("dangerous_command_blocked", command=forbidden)
return False
return True
鐵律 2: K8s Namespace 強制綁定
# ✅ 正確: 所有 K8s 指令必須帶 Namespace
kubectl rollout restart deployment/awoooi-api -n awoooi-prod
# ❌ 禁止: 無 Namespace (可能影響其他系統)
kubectl rollout restart deployment/awoooi-api
# ❌ 絕對禁止: 跨越到系統 Namespace
kubectl delete pod xxx -n kube-system
kubectl delete pod xxx -n default
鐵律 3: 提案白名單 Namespace
ALLOWED_NAMESPACES = ["awoooi-prod", "awoooi-dev"]
def validate_namespace(command: str) -> bool:
"""檢查 K8s 指令是否在許可 Namespace 內"""
if "kubectl" in command:
for ns in ALLOWED_NAMESPACES:
if f"-n {ns}" in command or f"--namespace={ns}" in command:
return True
return False # 無 Namespace 或不在白名單
return True
檢查清單 (每個提案生成後)
| 檢查項目 | 通過條件 |
|---|---|
| 毀滅性指令掃描 | 黑名單指令數量 = 0 |
| Namespace 驗證 | 所有 kubectl 指令帶 -n awoooi-prod |
| 權限邊界 | 不涉及 kube-system, default |
🚨 中文 Action 解析 (2026-03-23 教訓)
事故: Y 按鈕執行後顯示「錯誤」,因為 LLM 生成中文建議,
parse_operation_from_action()無法解析
根因
{"event": "background_execution_skip", "reason": "Could not parse operation type from action"}
{"action": "擴展 awoooi-api-deployment 副本數 + 啟用 HPA"}
{"action": "重新啟動 postgres-primary-0 服務"}
支援的中文模式
| 中文關鍵字 | 操作類型 | 備註 |
|---|---|---|
| 擴展...副本數 | SCALE_DEPLOYMENT | 自動移除 -deployment 後綴 |
| 重新啟動 | RESTART_DEPLOYMENT | 不需要「服務」後綴 |
| StatefulSet Pod (xxx-0) | DELETE_POD | 自動識別 -N 格式 |
驗證指令
# 查看目前支援的解析模式
grep -n "chinese" apps/api/src/api/v1/approvals.py
# 檢查 Action 解析函數
grep -A 5 "def parse_operation_from_action" apps/api/src/api/v1/approvals.py
教訓
- LLM 輸出不可預測: 生成的建議可能是中文、英文或混合
- 後綴可能錯誤: LLM 常加
-deployment後綴,需自動清理 - 資源類型識別:
xxx-0是 StatefulSet Pod,應使用 DELETE_POD 而非 RESTART_DEPLOYMENT
🤖 本地模型選擇策略 (Phase 12.2)
更新: 2026-03-25 | 硬體: 192.168.0.188 (62GB RAM, 無 GPU)
Tier 分層選擇
告警進入
↓
[判斷複雜度]
│
├─ 簡單 (單一指標) → llama3.2:3b (~2GB, 快速)
│
├─ 中等 (多指標) → qwen2.5:7b-instruct (~5GB, 平衡)
│
└─ 複雜 (跨服務) → qwen2.5:14b-instruct-q4 (~10GB, 深度)
模型配置
| 場景 | 推薦模型 | 參數 |
|---|---|---|
| 中文告警分析 | qwen2.5:7b-instruct | 中文優化 |
| 快速摘要 | llama3.2:3b | 低延遲 |
| 複雜提案 | qwen2.5:14b-instruct-q4 | 高準確度 |
| 推理鏈分析 | deepseek-r1:7b-qwen-distill | 備選 |
調用規範
# ✅ 正確 (根據複雜度選模型)
async def get_model_for_task(complexity: str) -> str:
model_map = {
"simple": "llama3.2:3b",
"medium": "qwen2.5:7b-instruct",
"complex": "qwen2.5:14b-instruct-q4_K_M",
}
return model_map.get(complexity, "qwen2.5:7b-instruct")
# ❌ 禁止 (硬編碼單一模型)
model = "qwen2.5:72b" # 超過硬體限制
硬體限制
| 資源 | 約束 |
|---|---|
| 最大模型 | 32B (Q4 量化) |
| 推薦模型 | 7B-14B |
| ☁️ Cloud 模型 | 移至 Phase 12.4 評估 |
🔀 智能路由引擎 (Phase 13.3)
目標: 用小模型判別意圖 + 評估複雜度,動態路由到不同 LLM
架構
告警進入
↓
┌─────────────────────────────────┐
│ Intent Classifier (Qwen2.5-1B) │ ← 新增
│ 延遲: < 100ms │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Complexity Scorer (1-5 分) │ ← 新增
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ AI Router │
│ ├─ 簡單 (1-2) → Ollama Local │
│ ├─ 中等 (3) → Ollama Large │
│ └─ 複雜 (4-5) → Gemini/Claude │
└─────────────────────────────────┘
意圖分類
| 意圖 | 範例 | 複雜度 |
|---|---|---|
| RESTART | Pod 重啟、服務重啟 | 1-2 |
| SCALE | 擴容、縮容 | 2-3 |
| CONFIG | 配置變更 | 3-4 |
| DIAGNOSE | 根因分析、跨服務追蹤 | 4-5 |
風險分級自動修復
| 風險等級 | 自動化策略 |
|---|---|
| LOW | ✅ 可自動執行 |
| MEDIUM | ✅ 可自動執行 (日誌記錄) |
| HIGH | 🟡 需 Telegram 快速確認 |
| CRITICAL | 🔴 必須人工審核 |
統帥指示: 真正嚴重緊急的告警,必須透過人工審核!
🧰 Tool 封裝與模組化關係
統帥澄清 (2026-03-25): Tool 封裝 ≠ 模組化,兩者是不同層次
| 維度 | leWOOOgo 模組化 | Tool 封裝 |
|---|---|---|
| 層次 | 軟體架構層 | 系統整合層 |
| 範圍 | 六大積木 | 外部系統連接 |
| 關係 | 是 Tool 的實作基礎 | 是模組化的應用場景 |
Tool 放置位置
Tool 封裝 → 放在 ACTION 積木內 → 遵循模組化原則開發
參考: memory/feedback_tool_vs_modular.md
參考文檔
apps/api/src/services/incident_engine.py: 聚合引擎apps/api/src/services/multi_sig_redis.py: 分散式狀態apps/api/src/workers/signal_worker.py: Event Bus 消費者apps/api/src/plugins/mcp/mcp_bridge.py: MCP Bridgememory/project_phase13_enterprise_aiops.md: Phase 13 規劃- Phase 6.0-6.3: 認知覺醒計畫