From 5809d3e33605df50eee195636c6c8cfe50beb56c Mon Sep 17 00:00:00 2001 From: OG T Date: Wed, 1 Apr 2026 21:11:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(ai):=20=E5=A7=94=E6=B4=BE=20Incident=20RCA?= =?UTF-8?q?=20=E7=B5=A6=20OpenClaw=20(Nemo)=20=E2=80=94=20=E6=9E=B6?= =?UTF-8?q?=E6=A7=8B=E9=90=B5=E5=BE=8B=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 架構鐵律: OpenClaw = AI 大腦,AWOOOI API 透過 HTTP 委派仲裁 修改: - openclaw.py: 加入 _call_openclaw_analyze(),在 LLM fallback 前先呼叫 OpenClaw - 04-configmap.yaml: OPENCLAW_URL 修正為 :8088 (新容器 port) - AI_FALLBACK_ORDER 改為 ["ollama","claude"] (移除 Gemini 付費 API) OpenClaw /api/v1/analyze/incident → qwen2.5:7b 本機 Ollama (Nemo) Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/openclaw.py | 84 +++++++++++++++++++++++++++++++ k8s/awoooi-prod/04-configmap.yaml | 2 +- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/apps/api/src/services/openclaw.py b/apps/api/src/services/openclaw.py index e3d752e60..ba619d434 100644 --- a/apps/api/src/services/openclaw.py +++ b/apps/api/src/services/openclaw.py @@ -255,6 +255,82 @@ class OpenClawService: } # ========================================================================= + # ========================================================================= + # OpenClaw (Nemo) 委派仲裁 — 架構鐵律 + # 2026-04-01 ogt: AWOOOI API 不直接打 LLM,委派給 OpenClaw (192.168.0.188:8089) + # ========================================================================= + + async def _call_openclaw_analyze( + self, + incident_id: str, + severity: str, + signals: list[dict], + affected_services: list[str], + expert_context: dict | None = None, + ) -> dict | None: + """ + 委派 Incident RCA 給 OpenClaw (Nemo) API + + Returns: + proposal_dict if success, None if failed (fallback to direct LLM) + """ + try: + client = await self._get_client() + payload = { + "incident_id": incident_id, + "severity": severity, + "signals": signals[:5], + "affected_services": affected_services, + "expert_context": expert_context, + } + resp = await client.post( + f"{settings.OPENCLAW_URL}/api/v1/analyze/incident", + json=payload, + timeout=httpx.Timeout(130.0, connect=5.0), + ) + resp.raise_for_status() + data = resp.json() + + # 驗證必要欄位 + if not data.get("action_title") or not data.get("risk_level"): + logger.warning("openclaw_analyze_invalid_response", incident_id=incident_id) + return None + + logger.info( + "openclaw_analyze_success", + incident_id=incident_id, + confidence=data.get("confidence", 0), + risk_level=data.get("risk_level"), + ) + + # 轉換為 AWOOOI API proposal dict 格式 + return { + "action": data.get("action_title", "AI 分析"), + "description": data.get("description", ""), + "kubectl_command": data.get("kubectl_command") or "", + "target_resource": data.get("target_resource", "unknown"), + "namespace": data.get("namespace", "awoooi-prod"), + "risk_level": data.get("risk_level", "medium"), + "reasoning": data.get("reasoning", ""), + "confidence": data.get("confidence", 0.8), + "primary_responsibility": data.get("primary_responsibility", "INFRA"), + "optimization_suggestions": data.get("optimization_suggestions", []), + "signoz_correlation": data.get("signoz_correlation", ""), + "from_cache": False, + "provider": "openclaw_nemo", + "ai_tokens": 0, + "ai_cost": 0.0, + } + + except Exception as e: + logger.warning( + "openclaw_analyze_failed", + incident_id=incident_id, + error=str(e), + reason="fallback to direct LLM", + ) + return None + # AI Provider Implementations - Enhanced with Structured Output # ========================================================================= @@ -1312,6 +1388,14 @@ Focus on: signoz_available=signoz_metrics is not None, ) + # 2026-04-01 ogt: 架構鐵律 — OpenClaw (Nemo) 是 AI 大腦,優先委派仲裁 + # AWOOOI K8s Pod 不直接打 Ollama/NVIDIA,避免並發逾時 + openclaw_result = await self._call_openclaw_analyze( + incident_id, severity, signals, affected_services, expert_context + ) + if openclaw_result is not None: + return openclaw_result, "openclaw_nemo", True + # 使用快取呼叫 LLM alert_context = { "incident_id": incident_id, diff --git a/k8s/awoooi-prod/04-configmap.yaml b/k8s/awoooi-prod/04-configmap.yaml index 47e2558f3..14b32a3fb 100644 --- a/k8s/awoooi-prod/04-configmap.yaml +++ b/k8s/awoooi-prod/04-configmap.yaml @@ -16,7 +16,7 @@ data: # 服務端點 (非機密) OLLAMA_URL: "http://192.168.0.188:11434" - OPENCLAW_URL: "http://192.168.0.188:8089" + OPENCLAW_URL: "http://192.168.0.188:8088" KALI_SCANNER_URL: "http://192.168.0.112:8080" SIGNOZ_URL: "http://192.168.0.188:3301" LANGFUSE_URL: "http://192.168.0.110:3100"