diff --git a/docs/ai/AI-MODEL-CARDS.md b/docs/ai/AI-MODEL-CARDS.md new file mode 100644 index 00000000..b0a26ff1 --- /dev/null +++ b/docs/ai/AI-MODEL-CARDS.md @@ -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`) + +--- + +## 模型路由架構 + +``` +告警進入 + │ + ▼ +AIRouter(ADR-052) + │ + ├─ purpose: rca → deepseek-r1:14b(Ollama priority 1) + ├─ purpose: summary → qwen2.5:7b-instruct + ├─ purpose: embedding → nomic-embed-text + ├─ purpose: code_review → qwen2.5-coder:7b + │ + ├─ Ollama 失敗 → Gemini 2.0 Flash(priority 2) + ├─ Gemini 失敗 → Claude 3 Haiku(priority 3) + └─ 特殊用途 → NVIDIA Nemotron(priority 4,tool_calling only) +``` + +**控制開關**: `USE_AI_ROUTER=true`(絞殺者模式,ADR-052) + +--- + +## 模型卡片 + +--- + +### 卡片 1:deepseek-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 + +--- + +### 卡片 2:qwen2.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 資源,高負載時互相競爭 + +--- + +### 卡片 3:nomic-embed-text + +| 屬性 | 值 | +|------|---| +| **Model ID** | `nomic-embed-text:latest` | +| **Provider** | Ollama(本地)| +| **Endpoint** | `http://192.168.0.111:11434` | +| **Priority** | 1(embedding 專用)| +| **Cost** | $0(完全離線)| + +**用途(purposes)** + +| Purpose Key | 說明 | +|-------------|------| +| `embedding` | 文字向量化(KM 搜尋、RAG 索引)| + +**特性** +- 768 維向量輸出 +- 速度快(~50ms/request),適合即時 RAG 檢索 +- 與 pgvector 整合(PostgreSQL 向量索引) + +**注意事項** +- 嵌入向量與文字模型的 embedding 不可混用 +- 若 nomic-embed-text 下線,KM 搜尋功能降級(知識庫返回空) + +--- + +### 卡片 4:qwen2.5-coder:7b + +| 屬性 | 值 | +|------|---| +| **Model ID** | `qwen2.5-coder:7b` | +| **Provider** | Ollama(本地)| +| **Endpoint** | `http://192.168.0.111:11434` | +| **Priority** | 1(code_review 專用)| +| **Cost** | $0(完全離線)| + +**用途(purposes)** + +| Purpose Key | 說明 | +|-------------|------| +| `code_review` | 程式碼審查(CI/CD Pipeline 整合)| + +**特性** +- 程式碼專用微調,理解 Python/TypeScript/YAML/Bash +- 適合靜態分析、安全掃描建議 + +--- + +### 卡片 5:Gemini 2.0 Flash + +| 屬性 | 值 | +|------|---| +| **Model ID** | `gemini-2.0-flash` | +| **Provider** | Google Gemini API(雲端)| +| **Priority** | 2(Ollama 失敗時 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 +- 網路中斷時不可用 + +--- + +### 卡片 6:Claude 3 Haiku + +| 屬性 | 值 | +|------|---| +| **Model ID** | `claude-3-haiku-20240307` | +| **Provider** | Anthropic API(雲端)| +| **Priority** | 3(Gemini 失敗或超限時 fallback)| +| **Daily Limit** | 35,000 tokens/day | +| **Cost** | 按用量計費($0.25/1M input tokens)| + +**用途(purposes)** + +| Purpose Key | 說明 | +|-------------|------| +| `rca` | 緊急 fallback(Ollama+Gemini 均失效)| +| `summary` | 緊急 fallback | + +**特性** +- Anthropic 最快、最便宜的模型 +- 35K tokens/day 作為「最後防線」使用,不應成為主力 + +**費用控制** +- 達到 Priority 3 代表 Ollama 和 Gemini 都失效,需立即告警 +- 每次使用 Claude API → Langfuse 記錄 `provider=claude` +- 月度費用報告需包含 Claude 用量 + +**限制** +- 模型知識截止日期較 GPT-4 早 +- 不含 Tool Calling 於此整合(純文字生成) + +--- + +### 卡片 7:NVIDIA 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 Calling(OpenClaw 整合)| +| `tool_calling` | 結構化函式呼叫 | + +**特性** +- 4B 小型模型,專為 Tool Calling 優化 +- 83.3% Tool Call 準確率(AIOps 場景測試) +- 整合 NVIDIA NIM 推論加速 + +**限制** +- 僅用於 `nemoclaw` / `tool_calling` purpose;RCA 不使用此模型 +- 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 為資料來源* diff --git a/docs/operations/ON-CALL-HANDBOOK.md b/docs/operations/ON-CALL-HANDBOOK.md new file mode 100644 index 00000000..dd54c038 --- /dev/null +++ b/docs/operations/ON-CALL-HANDBOOK.md @@ -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-3(P1,需審核) + +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-3(CRITICAL,必須審核) + +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-1(INFO,系統自動記錄) + +通常不需動作。若持續 > 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-1(INFO) + +```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 +# 方法 1:API 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 +``` + +### Docker(188 主機) + +```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 台北時間建立* diff --git a/docs/reference/ALERT-TAXONOMY-CATALOG.md b/docs/reference/ALERT-TAXONOMY-CATALOG.md new file mode 100644 index 00000000..e2a9cf79 --- /dev/null +++ b/docs/reference/ALERT-TAXONOMY-CATALOG.md @@ -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.py,fallback) +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_ACTION(INFO) +- **Rule 匹配**: `host_high_cpu` 規則(priority 115) + +#### `host_memory` — 記憶體不足 + +| alertname | 說明 | +|-----------|------| +| `HostOutOfMemory` | 主機可用記憶體低於 10% | +| `HighMemoryUsage` | 舊版 alias(相容保留) | +| `RedisMemoryHigh` | Redis 記憶體超過 80% | + +- **決策路徑**: NO_ACTION(INFO),建議人工清理 +- **Rule 匹配**: `host_out_of_memory` 規則(priority 110) + +#### `disk_full` — 磁碟空間耗盡 + +| alertname | 說明 | +|-----------|------| +| `HostOutOfDiskSpace` | 主機磁碟剩餘空間不足 | +| `DiskSpaceLow` | 舊版 alias(相容保留) | + +- **決策路徑**: TYPE-1(INFO),log 分析後 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-3(CRITICAL,強制人工審核) +- **禁止自動修復**: 節點問題影響全叢集,不自動 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-3(CRITICAL)→ 人工審核後 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_ACTION(INFO + 建議) + +--- + +### 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_ACTION(CI/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-1(INFO) + +#### `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-8(SLO-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條 為資料來源* diff --git a/docs/templates/POSTMORTEM-TEMPLATE.md b/docs/templates/POSTMORTEM-TEMPLATE.md new file mode 100644 index 00000000..f6bb32be --- /dev/null +++ b/docs/templates/POSTMORTEM-TEMPLATE.md @@ -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、連線池滿) +- [ ] 程式碼 Bug(logic 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 台北時間建立*