Wave 8 P3.1-T2 後續補測 + 配套: 新增測試: - test_diagnosis_aggregator_stub.py (238 行) — 15 tests · stub fixture 驗證 _collect_diagnosis_aggregator 接線 · feature flag default off 不呼叫 · timeout 邊界 / exception fail-soft 修改: - core/metrics.py +23 — 新增 DiagnosisAggregator 相關 Prometheus 指標 - sanitization_service.py +24 — 補強 prompt sanitize 邊界(vuln #4 配套) - RUNBOOK-AGENT-STEP-LATENCY.md / agent_step_latency_rules.yaml — 微調 Tests: 15 passed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
11 KiB
RUNBOOK-AGENT-STEP-LATENCY.md
Agent Step Latency — 診斷與處置 Runbook
2026-04-27 Claude Sonnet 4.6: A3 — Agent step latency observability (config A+B Wave 1)
對應告警規則: ops/monitoring/grafana/agent_step_latency_rules.yaml
快速索引
| 告警 | 嚴重度 | 章節 |
|---|---|---|
AgentStepLatencyHigh |
warning | #agentsteplatencyhigh |
AgentStepTimeoutSpike |
critical | #agentsteptimeoutspike |
DiagnoseFallbackToCloud |
warning | #diagnosefallbacktocloud |
系統背景
AWOOOI Phase 2 多 Agent 協作(ADR-082)由三個 agent 串行處理每個 Incident:
Incident 接收
│
├─ [diagnostician] 診斷分析 — 主力 Provider: openclaw_nemo (NIM @ 192.168.0.188:8088)
│ timeout: 30s(A1 拆分後)
│
├─ [solver] 決策建議 — 主力 Provider: openclaw_nemo
│ timeout: 20s
│
└─ [critic] 方案審核 — 主力 Provider: openclaw_nemo
timeout: 15s
NIM(NVIDIA Inference Microservice)實測延遲:2-27s,平均 ~10.6s。
尾巴 latency 若命中 timeout → agent 輸出 confidence=20%(degraded)→ 飛輪失能。
根因案例:INC-20260425-8D17BB / INC-20260425-3B6C39
共用 PHASE2_STEP_TIMEOUT_SEC=20.0s,NIM 27s 尾巴 latency 命中 timeout,全部 Incident 落入「待分析」。
根因鏈
flowchart TD
A[NIM GPU 高負載 / 網路抖動] --> B[step latency 尾巴 > 20-30s]
B --> C[AgentStepLatencyHigh p75 > 25s]
B --> D[agent timeout → confidence=20%]
D --> E[AgentStepTimeoutSpike > 3/min]
D --> F[DIAGNOSE fallback chain 啟動]
F --> G[openclaw_nemo → gemini]
G --> H[DiagnoseFallbackToCloud > 5/min]
H --> I[Gemini 每日配額快速耗盡]
I --> J[gemini → claude 第二段 fallback]
J --> K[費用急升 / 飛輪完全失能]
style A fill:#ff6b6b,color:#fff
style K fill:#ff6b6b,color:#fff
style C fill:#ffd93d,color:#000
style E fill:#ff6b6b,color:#fff
style H fill:#ffd93d,color:#000
AgentStepLatencyHigh
告警含義
| 欄位 | 值 |
|---|---|
| 觸發條件 | 任意 agent 的 p75 step latency > 25s,持續 10 分鐘 |
| 嚴重度 | warning |
| 代表什麼 | NIM 推理尾巴偏慢,尚未 timeout,但趨勢惡化 |
| 不代表什麼 | agent 還在正常運作,只是變慢 |
立即診斷(3 步)
步驟 1:看哪個 agent 卡
在 Grafana 查 (Prometheus 地址: http://192.168.0.110:9090):
histogram_quantile(
0.75,
sum by (agent, le) (
rate(aiops_agent_step_duration_seconds_bucket[5m])
)
)
看各 agent 的 p75 值,確認哪個 agent 最慢。
也可看 p95 了解最壞情況:
histogram_quantile(
0.95,
sum by (agent, le) (
rate(aiops_agent_step_duration_seconds_bucket[5m])
)
)
步驟 2:看 NIM 健康度
# 確認 NIM API 回應時間
curl -o /dev/null -s -w "%{time_total}s\n" http://192.168.0.188:8088/v1/models
# 確認 GPU 狀態
ssh wooo@192.168.0.188 'nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,temperature.gpu --format=csv,noheader'
| GPU 指標 | 正常 | 警戒 |
|---|---|---|
| GPU 使用率 | < 80% | > 90% |
| GPU 記憶體 | < 10GB | > 11GB |
| GPU 溫度 | < 80°C | > 85°C |
步驟 3:看 provider 路由分布
# 過去 5 分鐘各 provider 的呼叫比例
sum by (provider) (rate(ai_router_selected_provider_total[5m]))
若 openclaw_nemo 佔比大幅下降,代表 fallback 已在發生。
處置動作(3 步)
動作 1:暫時調高 timeout 環境變數(緩解)
若 NIM 只是暫時慢(< 1 小時),可調高 timeout 讓 agent 等更久:
# 確認目前設定
kubectl get deployment api -n awoooi-prod -o jsonpath='{.spec.template.spec.containers[0].env}' | python3 -m json.tool | grep -i timeout
# 暫時調高(需統帥授權才能改 ConfigMap)
# 正常路徑:修改 k8s/awoooi-prod/04-configmap.yaml 中的 PHASE2_STEP_TIMEOUT_SEC
# 緊急路徑:kubectl set env deployment/api -n awoooi-prod PHASE2_STEP_TIMEOUT_SEC=35
⚠️ 調高 timeout 不是根治,只是緩解。timeout 太長會讓 Incident 積壓。
動作 2:確認 NIM 是否需要重啟
# 檢查 NIM 服務狀態
ssh wooo@192.168.0.188 'docker ps --filter name=nim --format "{{.Status}}"'
# 若 NIM 容器 unhealthy,重啟(須確認無其他 session 在使用)
ssh wooo@192.168.0.188 'docker restart <nim_container_name>'
# 重啟後驗證
curl -s http://192.168.0.188:8088/v1/models | python3 -m json.tool
動作 3:升級統帥
若 NIM 重啟無效且 latency 仍高,Telegram 通知統帥:
- NIM 位置:192.168.0.188:8088
- 目前 p75:[從 Grafana 截圖]
- 影響範圍:diagnostician/solver/critic 全部變慢
- 建議:調查 GPU 硬體問題或考慮暫時切主力 provider 至 Gemini
AgentStepTimeoutSpike
告警含義
| 欄位 | 值 |
|---|---|
| 觸發條件 | 任意 agent timeout 速率 > 3/min,持續 5 分鐘 |
| 嚴重度 | critical |
| 代表什麼 | agent 已進入 degraded 模式(confidence=20%),飛輪失能 |
| 影響 | Incident 全部落入「待分析」,自動修復停擺 |
立即診斷(3 步)
步驟 1:確認哪個 agent 在 timeout
# 各 agent timeout 速率(/min)
sum by (agent) (
rate(aiops_agent_step_duration_seconds_count{outcome="timeout"}[5m])
) * 60
步驟 2:確認 NIM 是否已觸發 fallback
# NEMO → Gemini fallback 速率(/min)
rate(
aiops_diagnose_fallback_total{from_provider="openclaw_nemo", to_provider="gemini"}[5m]
) * 60
若 fallback > 0,代表 AI Router 已在切換,Gemini 正在被消耗。
步驟 3:確認飛輪狀態
# 確認積壓的 Incident
curl -s http://192.168.0.188:8088/api/v1/incidents?status=investigating | python3 -m json.tool | grep -c '"id"'
# 查 API log 確認 degraded 訊號
kubectl logs -n awoooi-prod deploy/api --tail=50 | grep -E "degraded|confidence=0.2|timeout"
處置動作(3 步)
動作 1:立即確認 NIM 是否可用
time curl -s -X POST http://192.168.0.188:8088/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"meta/llama-3.1-8b-instruct","messages":[{"role":"user","content":"ping"}],"max_tokens":10}'
若回應 > 30s 或 timeout:NIM 已無法使用。進行動作 2。
動作 2:強制切換主力 Provider(緊急)
AI Router 的 DIAGNOSE intent 已有 fallback chain(NEMO→GEMINI→CLAUDE)。
若需要完全跳過 NIM 嘗試,可暫時覆寫 intent override:
# 緊急設定:跳過 NEMO,直接走 GEMINI(需統帥授權)
kubectl set env deployment/api -n awoooi-prod \
DIAGNOSE_FORCE_PROVIDER=gemini \
-n awoooi-prod
⚠️ 此環境變數需 A2 代碼支援,確認 ai_router.py 是否有讀取此設定。 若無,請人工協調 SRE 直接修改 ConfigMap。
動作 3:升級統帥(必須)
critical 告警必須在 15 分鐘內升級:
- 告警觸發時間:[從 Telegram 告警中取得]
- 受影響 agent:[從步驟 1 的 Grafana 截圖]
- 積壓 Incident 數:[從步驟 3 取得]
- NIM 狀態:[可用/timeout/離線]
DiagnoseFallbackToCloud
告警含義
| 欄位 | 值 |
|---|---|
| 觸發條件 | NEMO→Gemini fallback > 5/min,持續 5 分鐘 |
| 嚴重度 | warning |
| 代表什麼 | NIM 無法服務,Gemini 正在消耗每日配額 |
| 風險 | Gemini 配額耗盡後 fallback 到 Claude(費用更高),或完全失敗 |
立即診斷(3 步)
步驟 1:查目前 fallback 速率與累積數
# 當前 fallback 速率(/min)
rate(
aiops_diagnose_fallback_total{from_provider="openclaw_nemo", to_provider="gemini"}[5m]
) * 60
# 今日累積 fallback 次數(Counter 累積值)
aiops_diagnose_fallback_total{from_provider="openclaw_nemo", to_provider="gemini"}
步驟 2:查 NIM 健康度
同 AgentStepLatencyHigh 步驟 2(nvidia-smi + NIM API 回應測試)。
步驟 3:確認 Gemini 今日配額剩餘
# Gemini 配額使用率
gemini_daily_call_count / gemini_daily_quota
若比率 > 0.8:GeminiQuotaApproaching 告警即將觸發,需立即決定是否限流。
處置動作(3 步)
動作 1:確認 fallback 是否必要(NIM 真的掛了?)
# 快速健康測試
curl -s --max-time 5 http://192.168.0.188:8088/v1/models
若 NIM 可用(回應 < 5s):可能是短暫抖動,觀察 5 分鐘是否自動恢復。
若 NIM 不可用:fallback 是正確行為,轉入動作 2 管理配額。
動作 2:估算 Gemini 配額剩餘時間
剩餘配額 = gemini_daily_quota - gemini_daily_call_count(從 Prometheus 讀取)
當前消耗速率 = 從 DiagnoseFallbackToCloud 告警值(/min)
預估耗盡時間 = 剩餘配額 / 當前速率(分鐘)
若預估耗盡時間 < 2 小時:升級統帥,考慮暫停部分 Incident 自動處理。
動作 3:升級統帥(若配額不足)
提供以下資訊:
- Gemini 配額使用率:[從 Prometheus 讀取]
- 預估耗盡時間:[計算結果]
- NIM 狀態:[離線/慢速/已恢復]
- 建議:修復 NIM 或增加 Gemini 配額
根因案例參照
INC-20260425-8D17BB
症狀:Diagnostician 信心持續降至 20%,所有 Incident 輸出「待分析」。
根因:PHASE2_STEP_TIMEOUT_SEC=20s 共用三段 agent,NIM 尾巴 latency 27s 命中 timeout。
修復:A1 拆分三段獨立 timeout(diagnostician=30s / solver=20s / critic=15s)。
教訓:不同 agent 的工作量不同,不應共用同一個 timeout 值。
INC-20260425-3B6C39
症狀:DIAGNOSE fallback 到 Ollama(CPU-only),造成 238s 二次 timeout。
根因:AI Router fallback chain 含 Ollama,Ollama CPU 推理 238s 完全不可用。
修復:A2 將 Ollama 永久移出 _diagnose_fallback_chain(NEMO→GEMINI→CLAUDE)。
教訓:fallback chain 的每個節點必須有實測延遲數據,不能假設可用。
待校準項目
以下門檻在 A1/A2 上線後,應根據實際 metric 重新校準。
目前使用 INC-20260425 實測數據(NIM 2-27s)估算。
| 告警 | 目前門檻 | 校準方式 |
|---|---|---|
AgentStepLatencyHigh |
p75 > 25s | 觀察 7d p75 基線,設為基線 × 1.5 |
AgentStepTimeoutSpike |
> 3/min | 觀察正常日的 timeout 率,應接近 0 |
DiagnoseFallbackToCloud |
> 5/min | 觀察 NIM 重啟時的 spike 幅度,設為 spike 的 30% |
校準時機:A1+A2 上線後,收集 7 天的 metric 數據再調整。