docs: 新增4份治理文件 — 告警目錄/AI模型卡/事後分析模板/值班手冊

- docs/reference/ALERT-TAXONOMY-CATALOG.md:16大類、56筆alertname、24條Rule優先順序表
- docs/ai/AI-MODEL-CARDS.md:7個AI模型治理卡(deepseek/qwen/gemini/claude/nemotron)+fallback順序
- docs/templates/POSTMORTEM-TEMPLATE.md:對齊report_generation_service,[AUTO]欄位已標記
- docs/operations/ON-CALL-HANDBOOK.md:P0/P1 SOP、Kill Switch、SLO應對、常用指令速查

建立: 2026-04-14 台北時間 Claude Sonnet 4.6(戰術B Phase 1 完整收尾)

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
OG T
2026-04-14 15:29:12 +08:00
parent 2c6ed4e9cf
commit 43c96890d1
4 changed files with 1242 additions and 0 deletions

288
docs/ai/AI-MODEL-CARDS.md Normal file
View File

@@ -0,0 +1,288 @@
# AWOOOI AI 模型治理卡AI Model Cards
> **文件類型**: AI 模型治理規格
> **版本**: v1.0(對應 models.json v1.3.0
> **建立日期**: 2026-04-14台北時間
> **建立者**: Claude Sonnet 4.6(首席架構師)
> **資料來源**: `apps/api/models.json` v1.3.0、`feedback_ai_model_config.md`
> **維護**: 每次更換主力模型後更新;費用變更須統帥批准(`feedback_cost_change_approval.md`
---
## 模型路由架構
```
告警進入
AIRouterADR-052
├─ purpose: rca → deepseek-r1:14bOllama priority 1
├─ purpose: summary → qwen2.5:7b-instruct
├─ purpose: embedding → nomic-embed-text
├─ purpose: code_review → qwen2.5-coder:7b
├─ Ollama 失敗 → Gemini 2.0 Flashpriority 2
├─ Gemini 失敗 → Claude 3 Haikupriority 3
└─ 特殊用途 → NVIDIA Nemotronpriority 4tool_calling only
```
**控制開關**: `USE_AI_ROUTER=true`絞殺者模式ADR-052
---
## 模型卡片
---
### 卡片 1deepseek-r1:14b
| 屬性 | 值 |
|------|---|
| **Model ID** | `deepseek-r1:14b` |
| **Provider** | Ollama本地|
| **Endpoint** | `http://192.168.0.111:11434` |
| **Priority** | 1最優先|
| **硬體** | 188 主機NVIDIA GPU |
| **Cost** | $0完全離線|
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `rca` | Root Cause Analysis — 告警根因分析 |
| `diagnose` | 深度診斷(含 log 關聯) |
| `log_anomaly` | 日誌異常偵測 |
**特性**
- 推理型模型Chain-of-Thought擅長多步邏輯
- 本地執行,無資料隱私疑慮
- 14B 參數P95 延遲 ~8-15s依硬體負載
**限制**
- 僅在 188 主機可用188 離線時全部 fallback 至 Gemini
- 無 Tool Calling 能力(使用 structured prompt 替代)
- 高負載時延遲可能超過 25s LLM timeout → Expert System 降級
**信心校準**
- RCA confidence 由 `confidence_scorer` 計算
- 規則精確匹配 → confidence=1.0;無 kubectl_command → confidence=0.0
---
### 卡片 2qwen2.5:7b-instruct
| 屬性 | 值 |
|------|---|
| **Model ID** | `qwen2.5:7b-instruct` |
| **Provider** | Ollama本地|
| **Endpoint** | `http://192.168.0.111:11434` |
| **Priority** | 1與 deepseek-r1 同層purpose 分工)|
| **Cost** | $0完全離線|
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `drift_summary` | 配置漂移摘要 |
| `rag_generate` | RAG 知識庫生成回答 |
| `playbook_draft` | Playbook 草稿生成 |
| `summary` | 事件摘要Incident Summary|
**特性**
- 指令微調版本(-instruct生成文字品質高
- 7B 參數,延遲較 deepseek 低P95 ~4-8s
- 適合結構化輸出JSON、Markdown
**限制**
- 推理深度不如 deepseek-r1複雜 RCA 不使用此模型
- 同在 188 主機;與 deepseek 共享 GPU 資源,高負載時互相競爭
---
### 卡片 3nomic-embed-text
| 屬性 | 值 |
|------|---|
| **Model ID** | `nomic-embed-text:latest` |
| **Provider** | Ollama本地|
| **Endpoint** | `http://192.168.0.111:11434` |
| **Priority** | 1embedding 專用)|
| **Cost** | $0完全離線|
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `embedding` | 文字向量化KM 搜尋、RAG 索引)|
**特性**
- 768 維向量輸出
- 速度快(~50ms/request適合即時 RAG 檢索
- 與 pgvector 整合PostgreSQL 向量索引)
**注意事項**
- 嵌入向量與文字模型的 embedding 不可混用
- 若 nomic-embed-text 下線KM 搜尋功能降級(知識庫返回空)
---
### 卡片 4qwen2.5-coder:7b
| 屬性 | 值 |
|------|---|
| **Model ID** | `qwen2.5-coder:7b` |
| **Provider** | Ollama本地|
| **Endpoint** | `http://192.168.0.111:11434` |
| **Priority** | 1code_review 專用)|
| **Cost** | $0完全離線|
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `code_review` | 程式碼審查CI/CD Pipeline 整合)|
**特性**
- 程式碼專用微調,理解 Python/TypeScript/YAML/Bash
- 適合靜態分析、安全掃描建議
---
### 卡片 5Gemini 2.0 Flash
| 屬性 | 值 |
|------|---|
| **Model ID** | `gemini-2.0-flash` |
| **Provider** | Google Gemini API雲端|
| **Priority** | 2Ollama 失敗時 fallback|
| **Daily Limit** | 70,000 tokens/day |
| **Cost** | 免費額度內 $0超出計費 |
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `rca` | Ollama 失敗時的 RCA fallback |
| `summary` | 事件摘要 fallback |
| `drift_summary` | 配置漂移摘要 fallback |
**特性**
- 速度快Flash 版),適合 fallback 場景
- 70K tokens/day 足夠支撐日均 ~20-30 incident 分析
- 雲端模型,有資料外送(請勿傳送含 secrets 的日誌)
**費用控制**
- Token 消耗監控Langfuse → `provider=gemini` traces
- 超過 60K tokens/day → Telegram 告警(`feedback_cost_change_approval.md`
- 費用變更必須停下等統帥批准
**限制**
- 超過日限後拒絕請求HTTP 429→ fallback 至 Claude 3 Haiku
- 網路中斷時不可用
---
### 卡片 6Claude 3 Haiku
| 屬性 | 值 |
|------|---|
| **Model ID** | `claude-3-haiku-20240307` |
| **Provider** | Anthropic API雲端|
| **Priority** | 3Gemini 失敗或超限時 fallback|
| **Daily Limit** | 35,000 tokens/day |
| **Cost** | 按用量計費($0.25/1M input tokens|
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `rca` | 緊急 fallbackOllama+Gemini 均失效)|
| `summary` | 緊急 fallback |
**特性**
- Anthropic 最快、最便宜的模型
- 35K tokens/day 作為「最後防線」使用,不應成為主力
**費用控制**
- 達到 Priority 3 代表 Ollama 和 Gemini 都失效,需立即告警
- 每次使用 Claude API → Langfuse 記錄 `provider=claude`
- 月度費用報告需包含 Claude 用量
**限制**
- 模型知識截止日期較 GPT-4 早
- 不含 Tool Calling 於此整合(純文字生成)
---
### 卡片 7NVIDIA Nemotron-Mini-4B
| 屬性 | 值 |
|------|---|
| **Model ID** | `nvidia/nemotron-mini-4b-instruct` |
| **Provider** | NVIDIA NIM API雲端|
| **Priority** | 4特殊場景專用|
| **Accuracy** | 83.3%`nemoclaw` 任務)|
| **Cost** | 按用量計費 |
**用途purposes**
| Purpose Key | 說明 |
|-------------|------|
| `nemoclaw` | Tool CallingOpenClaw 整合)|
| `tool_calling` | 結構化函式呼叫 |
**特性**
- 4B 小型模型,專為 Tool Calling 優化
- 83.3% Tool Call 準確率AIOps 場景測試)
- 整合 NVIDIA NIM 推論加速
**限制**
- 僅用於 `nemoclaw` / `tool_calling` purposeRCA 不使用此模型
- NIM API 延遲依網路狀況(通常 2-5s
- API Key 在 K8s Secret `nvidia-api-key`
---
## Fallback 順序總表
```
目的 Priority 1 Priority 2 Priority 3 Priority 4
─────────────────────────────────────────────────────────────────────────
rca deepseek-r1 → gemini-flash → claude-haiku → N/A
summary qwen2.5-7b → gemini-flash → claude-haiku → N/A
drift_summary qwen2.5-7b → gemini-flash → N/A → N/A
rag_generate qwen2.5-7b → N/A → N/A → N/A
playbook_draft qwen2.5-7b → N/A → N/A → N/A
embedding nomic-embed → N/A → N/A → N/A
code_review qwen2.5-coder→ N/A → N/A → N/A
nemoclaw N/A → N/A → N/A → nemotron
```
**Fallback 觸發條件**: Ollama timeout> 25s、HTTP 5xx、連線失敗、quota 超限
---
## 模型健康監控
| 指標 | 來源 | 告警閾值 |
|------|------|---------|
| Ollama 可用性 | Prometheus scrape 188:9090 | 失效 > 30s → Telegram |
| Gemini 日用量 | Langfuse `provider=gemini` | > 60K tokens/day |
| Claude 日用量 | Langfuse `provider=claude` | > 25K tokens/day |
| LLM P95 延遲 | SLO-2< 20s for P95 | 超過 25s → Expert System 降級 |
| Fallback 頻率 | Priority 2+ 被觸發次數 | > 3次/小時 → 告警 |
---
## 模型更換 SOP
1.`models.json` 新增/修改模型配置
2. 在本文件更新對應的模型卡片
3. 若涉及費用變更 → 停下等統帥批准(`feedback_cost_change_approval.md`
4. 更新 `LOGBOOK.md` + 推版至 Gitea
5. 驗證 Langfuse 追蹤正確記錄新 model_id
---
*本文件由 Claude Sonnet 4.6 於 2026-04-14 台北時間建立,以 models.json v1.3.0 為資料來源*

View File

@@ -0,0 +1,429 @@
# AWOOOI On-Call 值班手冊On-Call Handbook
> **文件類型**: 值班操作手冊
> **版本**: v1.0
> **建立日期**: 2026-04-14台北時間
> **建立者**: Claude Sonnet 4.6(首席架構師)
> **適用對象**: 統帥(首席)+ 未來 SRE 成員
> **相依文件**: `HUMAN-IN-THE-LOOP.md`、`SLO-SLI-DEFINITION.md`、`ALERT-TAXONOMY-CATALOG.md`
---
## 0. 哲學你是機長AI 是副駕駛
> **AI 永遠可以被覆蓋,你永遠是最後決策者。**
AWOOOI AIOps 系統設計為:
- **日常 P2/P3 告警** → AI 自動處理,你只需監控 Telegram 通知
- **P0/P1 高風險告警** → AI 分析後送審,你做最終決定
- **系統失控時** → Kill Switch 一鍵凍結所有自動操作
**值班的目標不是盯著告警,而是確保飛輪轉得順。**
---
## 1. 值班前準備Shift Start Checklist
每天(建議 08:00 台北時間)執行:
```bash
# 1. 確認系統健康
curl -s http://192.168.0.188:8000/health | python3 -m json.tool
# 2. 確認 Alertmanager 正常
curl -s http://192.168.0.110:9093/api/v1/status
# 3. 確認昨日 SLO 數字
curl -s http://192.168.0.188:8000/api/v1/slo/dashboard
# 4. 確認 AI 模型可用
curl -s http://192.168.0.111:11434/api/tags | python3 -c "import json,sys; [print(m['name']) for m in json.load(sys.stdin)['models']]"
# 5. 看 Telegram #awoooi-alerts 頻道最近 12 小時的告警
```
**每日晨報**: AIOps 系統於 08:00 台北時間自動發送前 24 小時摘要至 Telegram
---
## 2. 告警分級處理矩陣
### 告警嚴重度 → 處理方式
| 嚴重度 | P0 (CRITICAL) | P1 (HIGH) | P2 (MEDIUM) | P3 (LOW) |
|--------|--------------|-----------|-------------|----------|
| **AI 處理** | 分析 + 送審 | 分析 + 送審 | 自動執行 | 自動執行 |
| **你的角色** | 必須審核 | 必須審核 | 監控結果 | 可忽略 |
| **SLA** | 15 分鐘內 | 30 分鐘內 | 無強制 | 無強制 |
| **若超時** | 自動升級通知 | 自動升級通知 | 自動重試 | 自動記錄 |
### Telegram 卡片類型 → 你需要做什麼
| 卡片類型 | 外觀特徵 | 你的動作 |
|---------|---------|---------|
| **TYPE-1** INFO | `💚 INFO` 開頭 | 無需動作,系統已自動記錄 |
| **TYPE-2** AUTO | `⚡ AUTO REPAIR` | 觀察後續 RESULT 卡片即可 |
| **TYPE-3** REVIEW | `🔴 NEEDS REVIEW` + 按鈕 | **必須點擊 APPROVE 或 REJECT** |
| **TYPE-4** WAIT | `⏸️ WAITING` | 人工評估後決定要不要手動修復 |
| **TYPE-8M** SLO | `📊 SLO ALERT` | 評估是否暫停自動修復 |
---
## 3. 高頻場景 SOP
### 3.1 Pod CrashLoopBackOff
**Telegram 卡片**: TYPE-2 或 TYPE-3視 P 等級)
自動修復路徑AI 已執行):
```bash
kubectl rollout restart deployment/{name} -n {namespace}
```
若自動修復失敗,手動 SOP
```bash
# 1. 查看 Pod 日誌
kubectl logs {pod-name} -n {namespace} --previous --tail=100
# 2. 確認 Pod 狀態
kubectl describe pod {pod-name} -n {namespace}
# 3. 手動重啟
kubectl rollout restart deployment/{name} -n {namespace}
# 4. 確認恢復
kubectl rollout status deployment/{name} -n {namespace}
```
---
### 3.2 MinIO 下線(或其他 188 主機上的 Docker 服務)
**Telegram 卡片**: TYPE-3P1需審核
AI 建議的 SSH 修復:
```bash
ssh 192.168.0.188 'docker restart minio'
# 或
ssh 192.168.0.188 'docker ps | grep minio' # 先確認狀態
```
手動 SOP
```bash
# 1. 確認 188 主機可達
ping 192.168.0.188
# 2. SSH 進入主機
ssh 192.168.0.188
# 3. 確認容器狀態
docker ps -a | grep minio
# 4. 重啟容器
docker restart minio
# 5. 確認恢復
docker logs minio --tail=20
curl -s http://localhost:9000/minio/health/live
```
⚠️ **禁止**: `systemctl restart docker`(會殺死 Gitea 等所有容器)
---
### 3.3 PostgreSQL 下線
**Telegram 卡片**: TYPE-3CRITICAL必須審核
AI 會建議 kubectl rollout restart但必須先確認
```bash
# 1. 確認是服務問題還是 Pod 問題
kubectl get pods -n awoooi-prod | grep postgres
# 2. 若 Pod 崩潰 → 重啟
kubectl rollout restart deployment/postgresql -n awoooi-prod
# 3. 若 PVC 問題 → 不可自動處理,聯絡統帥
kubectl describe pvc postgres-pvc -n awoooi-prod
# 4. 確認 DB 可用
kubectl exec -n awoooi-prod deployment/postgresql -- psql -U postgres -c 'SELECT 1;'
```
**資料風險提示**: PostgreSQL 問題涉及持久化資料,`kubectl delete pvc` 被系統永久阻擋
---
### 3.4 告警鏈路斷裂NoAlertsReceived2Hours
這是最嚴重的情況:**你看不到告警 = 系統失明**
```bash
# 1. 確認 Alertmanager
curl http://192.168.0.110:9093/api/v1/status
curl http://192.168.0.110:9093/api/v1/alerts
# 2. 確認 AWOOOI API
curl http://192.168.0.188:8000/webhooks/test
# 3. 確認 Watchdog 心跳
# Watchdog 每分鐘送一個告警,若 2 小時沒收到 → 觸發此規則
# 4. 手動測試告警鏈路
curl -X POST http://192.168.0.110:9093/api/v1/alerts \
-H 'Content-Type: application/json' \
-d '[{"labels":{"alertname":"ManualTest","severity":"info"},"annotations":{"summary":"Manual test"}}]'
```
---
### 3.5 HostHighCpuLoad
**Telegram 卡片**: TYPE-1INFO系統自動記錄
通常不需動作。若持續 > 30 分鐘:
```bash
# 確認高耗 CPU 程序
ssh 192.168.0.{110/120/121/188} 'top -bn1 | head -20'
# 若是 Ollama 模型推理(正常,等它結束)
ssh 192.168.0.188 'ps aux | grep ollama'
```
---
### 3.6 SSL 憑證到期告警
**Telegram 卡片**: TYPE-1INFO
```bash
# 確認哪個憑證快到期
# 通常是 Let's Encrypt 憑證需要 renew
# 若在 K8s 中由 cert-manager 管理
kubectl get certificates -A
kubectl describe certificate {cert-name} -n {namespace}
# 手動 renew若 cert-manager 沒自動處理)
kubectl delete secret {tls-secret-name} -n {namespace} # 觸發重新申請
```
---
## 4. 審核決策指南APPROVE / REJECT
在 Telegram 收到 TYPE-3 審核卡時:
### 應 APPROVE 的情況
- AI 信心度 > 0.80,且 kubectl 指令是 `rollout restart` / `scale --replicas>0`
- 你已確認症狀與 AI 診斷吻合
- 修復操作是可回滾的rollout restart 可 rollout undo
- 這是已知的重複故障,上次 Playbook 記錄過
### 應 REJECT 的情況
- AI 信心度 < 0.65(系統通常會標記 LOW CONFIDENCE
- kubectl 指令包含不熟悉的資源名稱(可能是 LLM 幻覺)
- 時機不對(業務高峰期,即使必要也要評估)
- 你懷疑這是誤報
### REJECT 後手動 SOP
```bash
# 1. 確認實際狀態
kubectl get pods -n {namespace}
kubectl logs {pod-name} -n {namespace} --tail=50
# 2. 若確認需要修復,手動執行
{manual command}
# 3. 在 Telegram 回覆告知已手動處理
```
---
## 5. Kill Switch — 緊急凍結
當你判斷 AI 系統行為異常(瘋狂重啟、錯誤修復),立即啟動:
```bash
# 方法 1API Kill Switch推薦
curl -X POST http://192.168.0.188:8000/api/v1/kill-switch \
-H 'Authorization: Bearer {ADMIN_TOKEN}' \
-d '{"reason": "異常行為觀察到,手動凍結"}'
# 方法 2直接修改 ConfigMap
kubectl set env deployment/awoooi-api AUTO_REPAIR_ENABLED=false -n awoooi-prod
kubectl rollout restart deployment/awoooi-api -n awoooi-prod
```
**Kill Switch 效果**: 所有 auto_repair 自動執行停止TYPE-3 卡片不再自動批准;仍可手動操作
**重新啟動 Kill Switch**:
```bash
curl -X DELETE http://192.168.0.188:8000/api/v1/kill-switch \
-H 'Authorization: Bearer {ADMIN_TOKEN}'
```
---
## 6. SLO 監控與應對
### SLO 儀表板
```bash
curl -s http://192.168.0.188:8000/api/v1/slo/dashboard | python3 -m json.tool
```
### SLO 閾值與應對
| SLO | 指標 | 目標 | 警戒線 | 緊急線 | 應對 |
|-----|------|------|--------|--------|------|
| SLO-1 | 自動修復成功率7天| ≥ 80% | < 80% | < 50% | HITL-8評估暫停自動修復 |
| SLO-2 | 告警分析延遲 P95 | < 20s | > 20s | > 30s | 檢查 LLM / 切 Expert System |
| SLO-3 | 決策引擎可用性 | ≥ 95% | < 95% | < 80% | 確認 Ollama + Gemini 狀態 |
| SLO-4 | 未解決 P0/P1 逾時 | 0 件 | > 0 | > 2 | 立即介入 |
### SLO-1 下降處理
若 SLO-1 < 80%
1. 分析最近失敗的修復:`SELECT * FROM approval_requests WHERE execution_success=false ORDER BY created_at DESC LIMIT 20;`
2. 確認是新類型告警(知識庫沒有)還是已知告警修復失敗
3. 若是系統性問題 → 暫停自動修復,人工介入
4. 更新 `docs/postmortems/` 記錄分析結果
---
## 7. 常用指令速查
### Kubernetes
```bash
# 查看所有 Pod 狀態
kubectl get pods -n awoooi-prod
# 查看 Pod 日誌(最近 100 行)
kubectl logs {pod-name} -n awoooi-prod --tail=100
# 查看 Pod 日誌(上一個 Pod崩潰後
kubectl logs {pod-name} -n awoooi-prod --previous --tail=100
# 重啟 Deployment
kubectl rollout restart deployment/{name} -n awoooi-prod
# 查看 Deployment 狀態
kubectl rollout status deployment/{name} -n awoooi-prod
# 查看節點狀態
kubectl get nodes -o wide
# 查看所有資源
kubectl get all -n awoooi-prod
```
### Docker188 主機)
```bash
# SSH 進入 188
ssh 192.168.0.188
# 查看所有容器
docker ps -a
# 重啟特定容器
docker restart {container_name}
# 查看容器日誌
docker logs {container_name} --tail=100 -f
# 查看容器狀態
docker inspect {container_name} | python3 -m json.tool
```
### AIOps API
```bash
# 系統健康
curl http://192.168.0.188:8000/health
# 最近 Incident 列表
curl http://192.168.0.188:8000/api/v1/incidents?limit=20
# SLO 儀表板
curl http://192.168.0.188:8000/api/v1/slo/dashboard
# 知識庫搜尋
curl "http://192.168.0.188:8000/api/v1/knowledge?q=minio+restart"
```
---
## 8. 主機快速參考
| 主機 | IP | 主要服務 | SSH |
|------|-----|---------|-----|
| 主控節點 | 192.168.0.110 | K3s Master, Prometheus, Alertmanager | `ssh 192.168.0.110` |
| 工作節點-1 | 192.168.0.120 | K3s Worker | `ssh 192.168.0.120` |
| 工作節點-2 | 192.168.0.121 | K3s Worker, Kali | `ssh 192.168.0.121` |
| AI 主機 | 192.168.0.188 | Ollama, Harbor, Gitea, MinIO, AWOOOI | `ssh 192.168.0.188` |
詳細 Port 分配 → [reference_four_hosts.md](~/.claude/projects/-Users-ogt-awoooi/memory/reference_four_hosts.md)
---
## 9. 升級聯絡矩陣
> 目前系統為統帥單人值班;未來擴展 SRE 團隊時使用
| 情況 | 聯絡對象 | 方式 | 優先度 |
|------|---------|------|--------|
| P0 持續 > 15min | 統帥 | Telegram 直接訊息 | 立即 |
| SLO-1 < 50% | 統帥 | Telegram #awoooi-alerts | 15min 內 |
| Kill Switch 啟動 | 統帥 | Telegram 直接訊息 | 立即 |
| 疑似資安事件 | 統帥 | 電話 | 立即 |
---
## 10. 值班後交接Shift End Checklist
```
□ 所有 TYPE-3 卡片已處理APPROVE/REJECT
□ 未解決 Incident 已記錄在 LOGBOOK.md
□ SLO-1 在 80% 以上(若低於 80% 記錄原因)
□ 若觸發了 Kill Switch已確認原因並重啟或記錄保持凍結的理由
□ 有意義的新故障 → 撰寫 Postmortem使用 docs/templates/POSTMORTEM-TEMPLATE.md
□ 更新 docs/LOGBOOK.md 今日條目
```
---
## 附錄 A事件等級速查
| 等級 | Severity | 定義 | 典型案例 |
|------|---------|------|---------|
| P0 | CRITICAL | 服務完全中斷,用戶無法使用 | DB 下線、K8s 節點故障 |
| P1 | HIGH | 核心功能受損,影響大多數用戶 | MinIO 下線、OpenClaw 下線 |
| P2 | MEDIUM | 部分功能受影響,有降級措施 | Pod CrashLoop、SSL 到期 |
| P3 | LOW | 輕微問題,無直接用戶影響 | CPU 高負載、備份失敗 |
---
## 附錄 B相關文件索引
| 文件 | 路徑 | 說明 |
|------|------|------|
| HITL 規格書 | `docs/operations/HUMAN-IN-THE-LOOP.md` | 人工介入完整規格 |
| SLO 定義 | `docs/slo/SLO-SLI-DEFINITION.md` | SLO/SLI 量化定義 |
| 告警目錄 | `docs/reference/ALERT-TAXONOMY-CATALOG.md` | 告警分類完整列表 |
| 事後分析模板 | `docs/templates/POSTMORTEM-TEMPLATE.md` | Postmortem 標準格式 |
| AI 模型卡片 | `docs/ai/AI-MODEL-CARDS.md` | 各 AI 模型治理規格 |
| 服務端點 | `docs/reference/SERVICE-ENDPOINTS.md` | 所有服務 URL/Port |
| K3s 優化手冊 | `docs/runbooks/K3S-OPTIMIZATION-RUNBOOK.md` | 節點調優 SOP |
| 飛輪鐵律 | `memory/feedback_auto_repair_flywheel_v2.md` | ADR-068 五根因鐵律 |
---
*本文件由 Claude Sonnet 4.6 於 2026-04-14 台北時間建立*

View File

@@ -0,0 +1,297 @@
# AWOOOI 告警分類目錄Alert Taxonomy Catalog
> **文件類型**: 告警分類權威目錄
> **版本**: v1.0
> **建立日期**: 2026-04-14台北時間
> **建立者**: Claude Sonnet 4.6(首席架構師)
> **資料來源**: `alert_types.py`56 筆)、`alert_rules.yaml`24 條規則)、`classify_alert_early()`
> **維護方式**: `alert_types.py` 為 Layer 2 fallback新類型優先加入 `alert_rules.yaml`Layer 1
---
## 告警分類三層架構
```
Layer 1 → alert_rules.yaml (incident_type 欄位,優先)
Layer 2 → ALERTNAME_TO_TYPE dict (alert_types.pyfallback)
Layer 3 → "custom" (未匹配,兜底)
```
**程式碼入口**: `alert_rule_engine.get_incident_type(alertname)` — 已整合三層降級
---
## 類別目錄16 大類)
| # | 類別 ID | 中文說明 | 預設 Action | 風險等級 | 數量 |
|---|---------|---------|------------|---------|-----|
| 1 | `host_down` | 主機完全失去回應 | `RESTART_SERVICE` | HIGH | 5 |
| 2 | `host_cpu` | 主機 CPU 過載 | `NO_ACTION` | MEDIUM | 2 |
| 3 | `host_memory` | 主機記憶體不足 | `NO_ACTION` | MEDIUM | 2 |
| 4 | `disk_full` | 磁碟空間耗盡 | `NO_ACTION` | HIGH | 3 |
| 5 | `backup_failure` | 備份任務失敗 | `NO_ACTION` | MEDIUM | 3 |
| 6 | `k8s_node_failure` | K8s 節點異常 | `NO_ACTION` | CRITICAL | 3 |
| 7 | `k8s_pod_crash` | Pod 崩潰/未就緒 | `KUBECTL_ROLLOUT_RESTART` | HIGH | 4 |
| 8 | `k8s_deployment_mismatch` | 部署副本數不符 | `KUBECTL_SCALE` | MEDIUM | 1 |
| 9 | `database_down` | 資料庫服務下線 | `RESTART_SERVICE` | CRITICAL | 2 |
| 10 | `database_performance` | 資料庫效能異常 | `NO_ACTION` | MEDIUM | 6 |
| 11 | `service_down` | 內部服務下線 | `RESTART_SERVICE` | HIGH | 9 |
| 12 | `service_404` | 外部服務/網站無法連線 | `NO_ACTION` | MEDIUM | 5 |
| 13 | `ssl_expiry` | SSL/TLS 憑證到期 | `NO_ACTION` | MEDIUM | 2 |
| 14 | `alert_chain_broken` | 告警鏈路斷裂 | `NO_ACTION` | CRITICAL | 4 |
| 15 | `docker_container_unhealthy` | Docker 容器異常 | `RESTART_SERVICE` | MEDIUM | 2 |
| 16 | `auto_repair_degraded` | 自動修復效率下降 | `NO_ACTION` | HIGH | 2 |
| — | `high_cpu` / `high_memory` | 舊版相容 alias | — | — | 3 |
| — | `custom` | 未匹配兜底 | `NO_ACTION` | LOW | — |
---
## 詳細分類清單
### 1. 主機層Host Layer
#### `host_down` — 主機失去回應
| alertname | 說明 | SSH 可用? |
|-----------|------|-----------|
| `HostDown` | 主機完全失去 ICMP/TCP 回應 | 否(已失聯) |
- **決策路徑**: TYPE-3高風險人工審核
- **修復模式**: SSH 路徑若主機重新上線後or 手動介入
- **Rule 匹配**: `host_down` 規則priority 100
#### `host_cpu` — CPU 過載
| alertname | 說明 |
|-----------|------|
| `HostHighCpuLoad` | 主機 CPU 負載持續超過閾值 |
| `HighCPUUsage` | 舊版 alias相容保留 |
- **決策路徑**: LLM 分析 → 識別高耗 CPU 程序 → NO_ACTIONINFO
- **Rule 匹配**: `host_high_cpu` 規則priority 115
#### `host_memory` — 記憶體不足
| alertname | 說明 |
|-----------|------|
| `HostOutOfMemory` | 主機可用記憶體低於 10% |
| `HighMemoryUsage` | 舊版 alias相容保留 |
| `RedisMemoryHigh` | Redis 記憶體超過 80% |
- **決策路徑**: NO_ACTIONINFO建議人工清理
- **Rule 匹配**: `host_out_of_memory` 規則priority 110
#### `disk_full` — 磁碟空間耗盡
| alertname | 說明 |
|-----------|------|
| `HostOutOfDiskSpace` | 主機磁碟剩餘空間不足 |
| `DiskSpaceLow` | 舊版 alias相容保留 |
- **決策路徑**: TYPE-1INFOlog 分析後 NO_ACTION
- **Rule 匹配**: `disk_full` 規則priority 120
#### `backup_failure` — 備份失敗
| alertname | 說明 |
|-----------|------|
| `HostBackupFailed` | 主機備份腳本失敗 |
| `VeleroBackupFailed` | Kubernetes Velero 備份失敗 |
| `VeleroBackupNotRun` | Velero 備份超過預定時間未執行 |
- **決策路徑**: NO_ACTION通知統帥
- **SLA 影響**: RPO 可能受損,需人工確認
---
### 2. Kubernetes 層K8s Layer
#### `k8s_node_failure` — 節點異常
| alertname | 說明 |
|-----------|------|
| `K3sNodeNotReady` | K3s 節點 NotReady 狀態 |
| `KubeNodeNotReady` | Kubernetes 節點 NotReady |
| `KubeNodeUnreachable` | 節點無法連線 |
- **決策路徑**: TYPE-3CRITICAL強制人工審核
- **禁止自動修復**: 節點問題影響全叢集,不自動 drain/cordon
#### `k8s_pod_crash` — Pod 崩潰
| alertname | 說明 |
|-----------|------|
| `KubePodCrashLooping` | Pod 反覆崩潰重啟CrashLoopBackOff |
| `KubePodNotReady` | Pod 持續未就緒 |
- **決策路徑**: LLM RCA → rollout restart
- **標準 kubectl**: `kubectl rollout restart deployment/{name} -n {namespace}`
- **Rule 匹配**: `pod_crash_looping` / `pod_not_ready` 規則priority 50/55
#### `k8s_deployment_mismatch` — 副本數不符
| alertname | 說明 |
|-----------|------|
| `KubeDeploymentReplicasMismatch` | 實際 Pod 數 ≠ 期望副本數 |
- **決策路徑**: LLM 分析 → kubectl scale需人工確認
- **注意**: `--replicas=0` 被安全閘阻擋ADR-064
---
### 3. 資料庫層Database Layer
#### `database_down` — 資料庫下線
| alertname | 說明 |
|-----------|------|
| `PostgreSQLDown` | PostgreSQL 無法連線 |
| `RedisDown` | Redis 無法連線 |
- **決策路徑**: TYPE-3CRITICAL→ 人工審核後 rollout restart
- **Rule 匹配**: `postgresql_down` / `redis_down` 規則priority 30/35
#### `database_performance` — 資料庫效能
| alertname | 說明 |
|-----------|------|
| `PostgreSQLHighConnections` | 連線數過高 |
| `PostgreSQLSlowQueries` | 慢查詢偵測 |
| `PostgreSQLDeadlocks` | 死鎖偵測 |
| `PostgreSQLTooManyConnections` | 超過最大連線限制 |
| `RedisKeyEviction` | Redis key 被驅逐 |
| `RedisConnectionsHigh` | Redis 連線數過高 |
| `RedisCommandLatencyHigh` | Redis 命令延遲過高 |
- **決策路徑**: LLM 分析 → NO_ACTIONINFO + 建議)
---
### 4. 服務層Service Layer
#### `service_down` — 內部服務下線
| alertname | 說明 | 主機位置 |
|-----------|------|---------|
| `OpenClawDown` | OpenClaw AI 引擎下線 | 188 |
| `MinIODown` | MinIO 物件儲存下線 | 188 |
| `HarborDown` | Harbor 容器倉儲下線 | 188 |
| `GiteaDown` | Gitea CI/CD 服務下線 | 188 |
| `AlertmanagerDown` | Alertmanager 下線(鏈路失效) | 110 |
| `SignOzDown` | SignOz 監控平台下線 | 110 |
| `SentryDown` | Sentry 錯誤追蹤下線 | — |
| `KaliScannerDown` | Kali 安全掃描器下線 | 121 |
- **Rule 覆蓋**:
- `minio_down`priority 10→ SSH docker restart
- `gitea_down`priority 125→ NO_ACTIONCI/CD 服務,不自動修復)
- `openclaw_down`priority 40→ kubectl rollout restart
- **修復模式**: 視服務所在層K8s Pod / Docker Container / 主機服務)
#### `service_404` — 外部網站/服務異常
| alertname | 說明 |
|-----------|------|
| `MoWoooWorkDown` | 工作用外部網站下線 |
| `TsenyangWebsiteDown` | 個人網站下線 |
| `StockWoooWorkDown` | 股票工具網站下線 |
| `BitanWoooWorkDown` | 碧潭相關網站下線 |
| `ExternalSiteSSLExpiringSoon` | 外部網站 SSL 到期 |
| `TargetDown` | 舊版 blackbox 告警 alias |
- **Rule 匹配**: `external_site_down`priority 127→ NO_ACTION通知
- **決策路徑**: TYPE-1INFO
#### `ssl_expiry` — SSL/TLS 憑證到期
| alertname | 說明 |
|-----------|------|
| `SSLCertExpiringSoon` | 憑證即將到期(< 30 天) |
| `ExternalSiteSSLExpiringSoon` | 外部網站憑證到期 |
- **Rule 匹配**: `ssl_cert_expiring`priority 126→ NO_ACTION提醒
- **修復方式**: 人工 certbot renew / cert-manager 更新
---
### 5. 告警鏈路層Alert Chain Layer
#### `alert_chain_broken` — 告警鏈路斷裂
| alertname | 說明 |
|-----------|------|
| `AlertChainBroken_Alertmanager` | Alertmanager 停止發送告警 |
| `AlertChainBroken_Sentry` | Sentry 停止發送錯誤通知 |
| `NoAlertsReceived2Hours` | 2 小時無任何告警watchdog 失效) |
| `AlertChainUnhealthy` | 鏈路整體健康度低 |
- **嚴重性**: CRITICAL告警鏈路失效 = 系統失明)
- **Rule 匹配**: `alert_chain_broken`priority 20
- **通知**: Telegram 緊急通道(立即)
---
### 6. 容器層Docker Layer
#### `docker_container_unhealthy` — Docker 容器異常
| alertname | 說明 |
|-----------|------|
| `DockerContainerUnhealthy` | Docker healthcheck 失敗 |
| `DockerContainerExited` | 容器意外退出(非 K8s 管理的裸 Docker |
- **修復模式**: SSH → `docker restart {container_name}`
- **注意**: 不可用 `docker restart` 重啟整個 Docker Engine會殺死 Gitea
---
### 7. 自動修復監控Auto Repair Monitoring
#### `auto_repair_degraded` — 飛輪效率下降
| alertname | 說明 |
|-----------|------|
| `AutoRepairLowSuccessRate` | SLO-1 < 80%7天滾動 |
| `PermanentFixRequired` | 同一告警重複修復 > 3 次 |
- **觸發**: HITL-8SLO-1 < 50% 連續 2h
- **處理**: TYPE-8M 通知,建議暫停自動修復
- **Root Cause**: 見 `feedback_auto_repair_flywheel_v2.md`
---
## Alert Rule 優先順序速查
| Priority | Rule ID | alertname 關鍵字 | Action |
|----------|---------|-----------------|--------|
| 10 | `minio_down` | MinioDown, MinIODown | SSH restart |
| 20 | `alert_chain_broken` | AlertChainBroken_* | NO_ACTION |
| 30 | `postgresql_down` | PostgreSQLDown | kubectl restart |
| 35 | `redis_down` | RedisDown | kubectl restart |
| 40 | `openclaw_down` | OpenClawDown | kubectl restart |
| 50 | `pod_crash_looping` | KubePodCrashLooping | kubectl restart |
| 55 | `pod_not_ready` | KubePodNotReady | kubectl restart |
| 100 | `host_down` | HostDown | NO_ACTION |
| 110 | `host_out_of_memory` | HostOutOfMemory | NO_ACTION |
| 115 | `host_high_cpu` | HostHighCpuLoad | NO_ACTION |
| 120 | `disk_full` | HostOutOfDiskSpace | NO_ACTION |
| 125 | `gitea_down` | GiteaDown | NO_ACTION |
| 126 | `ssl_cert_expiring` | SSLCertExpiringSoon | NO_ACTION |
| 127 | `external_site_down` | MoWoooWorkDown | NO_ACTION |
| 999 | `generic_fallback` | * | NO_ACTION |
**總計**: 24 條規則56 個 alertname 對應
---
## 新增告警類別 SOP
1. 確認 alertname 是否已在 `ALERTNAME_TO_TYPE` 中 → 如有,只需在 `alert_rules.yaml` 補規則
2. 決定 `incident_type`(參考現有 16 類;必要時新增)
3.`alert_rules.yaml` 新增規則(`priority` < 999`> 127``< 999` 為安全區)
4. 若新 `incident_type`,在 `alert_types.py` 補 dict 條目
5. 更新本文件 + `LOGBOOK.md`
---
*本文件由 Claude Sonnet 4.6 於 2026-04-14 台北時間建立,以 `alert_types.py` v56筆 + `alert_rules.yaml` v24條 為資料來源*

228
docs/templates/POSTMORTEM-TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,228 @@
# AWOOOI 事後分析報告模板Postmortem Template
> **文件類型**: 事後分析標準模板
> **版本**: v1.0
> **建立日期**: 2026-04-14台北時間
> **建立者**: Claude Sonnet 4.6(首席架構師)
> **使用方式**: 複製本模板,替換 `{佔位符}` 後提交至 `docs/postmortems/YYYY-MM-DD-{alertname}.md`
> **對齊**: `report_generation_service.format_postmortem()` 自動填入欄位已標記 `[AUTO]`
---
# 事後分析:{INCIDENT_TITLE}
**Incident ID**: `{INC-YYYYMMDD-XXXXXX}`
**告警名稱**: `{alertname}`
**嚴重等級**: `{P0 / P1 / P2 / P3}`
**發生時間**: `{YYYY-MM-DD HH:MM}(台北時間)` [AUTO]
**解決時間**: `{YYYY-MM-DD HH:MM}(台北時間)` [AUTO]
**停機時長**: `{N} 分鐘` [AUTO]
**撰寫人**: `{統帥 / SRE / AI 自動生成}`
**審查日期**: `{YYYY-MM-DD}`
---
## 0. 執行摘要Executive Summary
> 三行以內,給不想讀全文的決策者看
- **發生了什麼**: {一句話描述事件}
- **根本原因**: {一句話描述根因}
- **最終處置**: {人工介入 / 自動修復 / 降級 / 重啟}
- **影響範圍**: {受影響服務} × {停機 N 分鐘} × {用戶影響程度}
---
## 1. 時間軸Timeline[AUTO from AIDecisionChain]
| 時間(台北)| 事件 |
|------------|------|
| `{HH:MM}` | Alertmanager 觸發告警:`{alertname}` |
| `{HH:MM}` | AWOOOI API 接收 webhook`POST /webhooks/alerts`|
| `{HH:MM}` | LLM RCA 完成hypothesis`{LLM假設}`confidence`{0.XX}` |
| `{HH:MM}` | Telegram 審核卡發出TYPE-{1/2/3/4}|
| `{HH:MM}` | `{統帥}` 審核:`{APPROVE / REJECT / 未審核}` |
| `{HH:MM}` | 自動執行:`{kubectl command / SSH command / NO_ACTION}` |
| `{HH:MM}` | 告警解除Alertmanager resolved|
| `{HH:MM}` | Playbook 萃取完成,知識庫更新 |
**總耗時**: {分析延遲 Xs} + {等待審核 Xm} + {執行 Xs} = **{總計 Xm}**
---
## 2. 根本原因分析Root Cause Analysis[AUTO]
### 2.1 AI 假設
```
{AIDecisionChain.hypothesis 欄位內容}
```
**AI 信心度**: `{AIDecisionChain.confidence}`
**模型**: `{AIDecisionChain.model_used}`
**推理步驟**:
```
{AIDecisionChain.reasoning_steps 列表}
```
### 2.2 實際根因(人工確認)
> 填寫AI 假設是否正確?若不正確,真正的根因是?
- **AI 假設是否正確**: `{是 / 否 / 部分正確}`
- **實際根因**: `{描述}`
- **觸發鏈**: `{A → B → C → 告警}`
### 2.3 原因分類
> 選擇適用的類別(可複選)
- [ ] 硬體問題(磁碟、記憶體、網路卡)
- [ ] 資源耗盡磁碟滿、OOM、連線池滿
- [ ] 程式碼 Buglogic error、memory leak
- [ ] 配置錯誤YAML 錯誤、環境變數缺失)
- [ ] 依賴服務故障(外部 API、上游服務
- [ ] 容量不足(流量峰值超出設計)
- [ ] 人為操作錯誤(誤刪、誤改)
- [ ] 告警誤報(規則設定過於敏感)
- [ ] 其他:`{描述}`
---
## 3. 影響評估Impact Assessment
| 維度 | 內容 |
|------|------|
| **受影響服務** | `{services}` [AUTO from `affected_services`] |
| **用戶影響** | `{無 / 部分功能降級 / 完全中斷}` |
| **停機時長** | `{N 分鐘}` [AUTO] |
| **資料影響** | `{無資料遺失 / 部分資料遺失 / 需確認}` |
| **SLO 影響** | SLO-1 成功率:`{X%}` / Error Budget 消耗:`{X%}` |
| **業務影響** | `{描述具體業務損失或用戶體驗影響}` |
---
## 4. 處置過程Resolution[AUTO + 人工補充]
### 4.1 自動修復
```
執行指令: {approval.action}
執行結果: {成功 / 失敗}
執行者: AIOps 自動執行
執行時間: {YYYY-MM-DD HH:MM}(台北)
```
### 4.2 人工介入
> 若有人工操作,填寫以下內容
- **操作者**: `{統帥 / SRE}`
- **操作時間**: `{YYYY-MM-DD HH:MM}(台北)`
- **執行步驟**:
```
{步驟 1}
{步驟 2}
...
```
- **為何需要人工介入**: `{AI 信心不足 / 自動修復失敗 / P0/P1 強制審核 / Kill Switch 啟動}`
### 4.3 修復驗證
- **驗證方式**: `{curl 測試 / Pod 狀態確認 / 告警解除 / 用戶確認}`
- **驗證結果**: `{服務恢復正常 / 部分恢復 / 降級運行}`
---
## 5. 飛輪學習KM Update[AUTO]
> 本次 Incident 是否產生了新的 Playbook
- **Playbook 萃取**: `{是 / 否}`
- **Playbook ID**: `{PB-YYYYMMDD-XXXXXX}` [若有]
- **修復步驟**: `{動作描述}`
- **加入知識庫**: `{是 / 否(原因:{效果評分 < 3 / 統帥不建議}}`
- **知識庫查詢觸發**: `{下次同類告警將自動匹配此 Playbook}`
**效果評分**: `{1-5}` / 統帥回饋: `{如有}`
---
## 6. 預防措施Action Items
| # | 類型 | 描述 | 負責人 | 截止日期 | 狀態 |
|---|------|------|--------|---------|------|
| AI-1 | 監控優化 | `{告警規則閾值調整}` | `{統帥}` | `{YYYY-MM-DD}` | `{TODO}` |
| AI-2 | 系統加固 | `{修復根本原因}` | `{統帥}` | `{YYYY-MM-DD}` | `{TODO}` |
| AI-3 | 知識庫 | `{更新 Playbook / 新增規則}` | AIOps | `{自動}` | `{自動}` |
| AI-4 | 演練計畫 | `{定期演練此類故障}` | `{統帥}` | `{YYYY-MM-DD}` | `{TODO}` |
---
## 7. 五個為什麼5 Whys
> 用於複雜/P0 事件;追溯到技術或流程根源
1. **為什麼服務中斷?**
→ `{描述直接原因}`
2. **為什麼 `{直接原因}` 發生?**
→ `{描述次級原因}`
3. **為什麼 `{次級原因}` 沒有被預防?**
→ `{描述`}
4. **為什麼 `{原因3}` 存在?**
→ `{描述}`
5. **為什麼 `{原因4}` 沒有在系統設計中被考慮?**
→ `{根本原因 — 技術債 / 流程缺失 / 資源不足}`
**根本改善方向**: `{描述}`
---
## 8. 附件Appendix
### 8.1 相關 Logs
```
# 關鍵錯誤日誌(僅附最相關的 5-10 行)
{log lines}
```
### 8.2 相關截圖
> 附 Grafana / SignOz / Telegram 截圖路徑
- `docs/postmortems/assets/{INC-ID}-grafana.png`
- `docs/postmortems/assets/{INC-ID}-telegram.png`
### 8.3 參考資料
- Incident DB: `SELECT * FROM incidents WHERE incident_id = '{INC-ID}'`
- Langfuse Trace: `https://langfuse.awoooi.internal/trace/{trace_id}`
- 相關 ADR: `{ADR-XXX}`
- 相關 Playbook: `{PB-ID}`
---
## 使用說明
**何時填寫**: P0/P1 事件 24 小時內P2 事件 72 小時內P3 可選
**自動填入欄位 [AUTO]**: 由 `report_generation_service.format_postmortem()` 自動填入,人工只需補充 2.2、4.2、5、6
**存放位置**:
```
docs/postmortems/
YYYY-MM-DD-{alertname}-{incident_id}.md
assets/
{incident_id}-*.png
```
**提交方式**: `git push gitea main` → 自動部署
---
*本模板由 Claude Sonnet 4.6 於 2026-04-14 台北時間建立*