diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index fcddcc69..00a8eac1 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -2663,12 +2663,12 @@ class TelegramGateway: alert_summary: str, ) -> None: """ - 觸發群組 AI 雙向討論(三頭政治核心流程) + 觸發群組 AI 並行分析(三頭政治核心流程) - 流程: - 1. @OpenClawAwoooI_Bot reply 告警訊息,輸出 RCA 分析 - 2. @NemoTronAwoooI_Bot reply OpenClaw 訊息,補充評論 - 3. 完成後停止(避免無限循環) + 流程 (2026-04-03 ogt: 統帥指示改為並行): + - OpenClaw 和 NemoClaw 同時對告警進行獨立分析 + - 兩者都 reply 同一條告警訊息 + - 並行執行,總等待時間 = max(OpenClaw, NemoClaw) 而非相加 此方法由 asyncio.create_task 非同步呼叫,失敗不影響主流程。 @@ -2677,68 +2677,62 @@ class TelegramGateway: alert_summary: 告警摘要文字(提供給 AI 分析用) """ try: - from apps.api.src.services.chat_manager import ChatManager # noqa: PLC0415 + from src.services.chat_manager import ChatManager # noqa: PLC0415 except ImportError: - try: - from src.services.chat_manager import ChatManager # noqa: PLC0415 - except ImportError: - logger.error("trigger_group_ai_discussion_failed", reason="Cannot import ChatManager") - return + logger.error("trigger_group_ai_discussion_failed", reason="Cannot import ChatManager") + return try: chat_mgr = ChatManager() - # Step 1: OpenClaw 分析告警 openclaw_prompt = ( - f"你是 OpenClaw,AWOOOI SRE 戰情室的首席 AI 分析師。\n" - f"以下是一則基礎設施告警,請進行 RCA 根因分析並給出 3 點建議行動:\n\n" + f"你是 OpenClaw,AWOOOI SRE 戰情室首席 AI,精通 K8s、Prometheus、告警分析。\n" + f"以下是一則基礎設施告警,請進行 RCA 根因分析並給出 3 點具體建議行動:\n\n" f"{alert_summary}" ) - openclaw_analysis = await chat_mgr._call_openclaw( - system_prompt="你是 OpenClaw,AWOOOI SRE 戰情室首席 AI,精通 K8s、Prometheus、告警分析。", - user_message=openclaw_prompt, - ) - - if not openclaw_analysis: - logger.warning("trigger_group_ai_discussion_openclaw_empty") - return - - openclaw_text = f"🔍 OpenClaw 分析\n\n{openclaw_analysis}" - openclaw_result = await self.send_as_openclaw( - text=openclaw_text, - reply_to_message_id=alert_message_id, - ) - - openclaw_msg_id = ( - openclaw_result.get("result", {}).get("message_id") - if openclaw_result.get("ok") - else None - ) - - logger.info("group_ai_discussion_openclaw_sent", message_id=openclaw_msg_id) - - # Step 2: NemoClaw 補充評論(回覆 OpenClaw 訊息) nemo_prompt = ( - f"你是 NemoClaw,AWOOOI SRE 戰情室的 NemoClaw AI。\n" - f"OpenClaw 剛剛對以下告警做了分析:\n\n" - f"【原始告警】\n{alert_summary}\n\n" - f"【OpenClaw 分析】\n{openclaw_analysis}\n\n" - f"請從不同角度補充你的觀點,並指出任何可能被忽略的風險點。" - ) - nemo_analysis = await chat_mgr._call_nemotron( - system_prompt="你是 NemoClaw,AWOOOI SRE 戰情室 AI,擅長補充分析與風險評估。", - user_message=nemo_prompt, + f"你是 NemoClaw,AWOOOI SRE 戰情室 AI 參謀,由 NVIDIA Nemotron 驅動。\n" + f"以下是一則基礎設施告警,請從風險評估角度分析,指出潛在的連鎖失效點:\n\n" + f"{alert_summary}" ) - if not nemo_analysis: + # 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, 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"🦞 OpenClaw 分析\n\n{openclaw_analysis}", + reply_to_message_id=alert_message_id, + ) + logger.info("group_ai_discussion_openclaw_sent") + 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"🤖 NemoClaw 分析\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") - return - - nemo_text = f"🤖 NemoClaw 補充\n\n{nemo_analysis}" - await self.send_as_nemotron( - text=nemo_text, - reply_to_message_id=openclaw_msg_id or alert_message_id, - ) logger.info("group_ai_discussion_completed", alert_message_id=alert_message_id) @@ -3155,7 +3149,7 @@ class TelegramGateway: approval_id: str, user_id: int, username: str, - message_id: int, + message_id: int, # noqa: ARG002 ) -> None: """ 執行簽核動作 (更新資料庫)