feat(chat): NemoClaw→Claude Haiku API + 告警只由 OpenClaw 分析
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 7m20s
All checks were successful
CD Pipeline / build-and-deploy (push) Successful in 7m20s
老闆指示 (2026-04-03): 1. NemoClaw 改接 Claude API (claude-haiku-4-5),快速中文對話 2. 群組告警分析只觸發 OpenClaw,NemoClaw 不分析告警 3. OpenClaw/NemoClaw 雙向自然語言對話維持 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -144,23 +144,39 @@ class ChatManager:
|
||||
|
||||
async def _call_nemotron(self, system_prompt: str, user_message: str) -> str | None:
|
||||
"""
|
||||
呼叫 NemoClaw 對話 — NVIDIA NIM nemotron-mini-4b
|
||||
呼叫 NemoClaw 對話 — Claude API (claude-haiku-4-5)
|
||||
|
||||
2026-04-03 ogt: Ollama 188 主機負載高常超時,暫時維持 NIM
|
||||
老闆可接受慢速,timeout=120s
|
||||
2026-04-03 ogt: 老闆指示改接 Claude API,快速且中文能力強
|
||||
用 haiku 降低費用
|
||||
"""
|
||||
from src.services.nvidia_provider import get_nvidia_provider
|
||||
nvidia = get_nvidia_provider()
|
||||
try:
|
||||
full_prompt = f"{system_prompt}\n\n用戶訊息: {user_message}"
|
||||
response, success, _, _ = await nvidia.chat(
|
||||
prompt=full_prompt,
|
||||
model="nvidia/nemotron-mini-4b-instruct",
|
||||
max_tokens=300,
|
||||
)
|
||||
if success and response and "not configured" not in response and "Circuit Breaker" not in response:
|
||||
return response.strip()
|
||||
import httpx
|
||||
from src.core.config import get_settings
|
||||
settings = get_settings()
|
||||
|
||||
api_key = getattr(settings, 'CLAUDE_API_KEY', None)
|
||||
if not api_key:
|
||||
logger.warning("nemotron_chat_failed", error="CLAUDE_API_KEY not configured")
|
||||
return None
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=30.0) as client:
|
||||
resp = await client.post(
|
||||
"https://api.anthropic.com/v1/messages",
|
||||
headers={
|
||||
"x-api-key": api_key,
|
||||
"anthropic-version": "2023-06-01",
|
||||
"content-type": "application/json",
|
||||
},
|
||||
json={
|
||||
"model": "claude-haiku-4-5-20251001",
|
||||
"max_tokens": 300,
|
||||
"system": system_prompt,
|
||||
"messages": [{"role": "user", "content": user_message}],
|
||||
},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
return data["content"][0]["text"].strip()
|
||||
except Exception as e:
|
||||
logger.warning("nemotron_chat_failed", error=str(e))
|
||||
return None
|
||||
|
||||
@@ -2684,36 +2684,19 @@ class TelegramGateway:
|
||||
try:
|
||||
chat_mgr = ChatManager()
|
||||
|
||||
# 2026-04-03 ogt: 老闆指示 — 告警分析只由 OpenClaw 負責,NemoClaw 不分析告警
|
||||
openclaw_prompt = (
|
||||
f"你是 OpenClaw,AWOOOI SRE 戰情室首席 AI,精通 K8s、Prometheus、告警分析。\n"
|
||||
f"以下是一則基礎設施告警,請進行 RCA 根因分析並給出 3 點具體建議行動:\n\n"
|
||||
f"{alert_summary}"
|
||||
)
|
||||
nemo_prompt = (
|
||||
f"你是 NemoClaw,AWOOOI SRE 戰情室 AI 參謀,由 NVIDIA Nemotron 驅動。\n"
|
||||
f"以下是一則基礎設施告警,請從風險評估角度分析,指出潛在的連鎖失效點:\n\n"
|
||||
f"以下是一則基礎設施告警,請進行 RCA 根因分析並給出 3 點具體建議行動。\n"
|
||||
f"繁體中文回應,不超過 300 字:\n\n"
|
||||
f"{alert_summary}"
|
||||
)
|
||||
|
||||
# 2026-04-03 ogt: 並行執行,兩個 AI 同時分析,不互相影響(更客觀)
|
||||
openclaw_task = asyncio.create_task(
|
||||
chat_mgr._call_openclaw(
|
||||
system_prompt="你是 OpenClaw,AWOOOI SRE 戰情室首席 AI。",
|
||||
user_message=openclaw_prompt,
|
||||
)
|
||||
)
|
||||
nemo_task = asyncio.create_task(
|
||||
chat_mgr._call_nemotron(
|
||||
system_prompt="你是 NemoClaw,AWOOOI SRE 戰情室 AI 參謀。",
|
||||
user_message=nemo_prompt,
|
||||
)
|
||||
openclaw_analysis = await chat_mgr._call_openclaw(
|
||||
system_prompt="你是 OpenClaw,AWOOOI SRE 戰情室首席 AI。稱呼用戶為「老闆」。",
|
||||
user_message=openclaw_prompt,
|
||||
)
|
||||
|
||||
openclaw_analysis, nemo_analysis = await asyncio.gather(
|
||||
openclaw_task, nemo_task, return_exceptions=True
|
||||
)
|
||||
|
||||
# OpenClaw 發到群組
|
||||
if openclaw_analysis and not isinstance(openclaw_analysis, Exception):
|
||||
await self.send_as_openclaw(
|
||||
text=f"🦞 <b>OpenClaw 分析</b>\n\n{openclaw_analysis}",
|
||||
@@ -2723,16 +2706,6 @@ class TelegramGateway:
|
||||
else:
|
||||
logger.warning("trigger_group_ai_discussion_openclaw_empty")
|
||||
|
||||
# NemoClaw 發到群組(同樣 reply 告警訊息,並排出現)
|
||||
if nemo_analysis and not isinstance(nemo_analysis, Exception):
|
||||
await self.send_as_nemotron(
|
||||
text=f"🤖 <b>NemoClaw 分析</b>\n\n{nemo_analysis}",
|
||||
reply_to_message_id=alert_message_id,
|
||||
)
|
||||
logger.info("group_ai_discussion_nemo_sent")
|
||||
else:
|
||||
logger.warning("trigger_group_ai_discussion_nemo_empty")
|
||||
|
||||
logger.info("group_ai_discussion_completed", alert_message_id=alert_message_id)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
Reference in New Issue
Block a user