diff --git a/apps/api/src/services/chat_manager.py b/apps/api/src/services/chat_manager.py index 72d1ceb3..ca7a5fc9 100644 --- a/apps/api/src/services/chat_manager.py +++ b/apps/api/src/services/chat_manager.py @@ -85,7 +85,11 @@ class ChatManager: 2026-04-03 ogt: 老闆指示改用 Gemini,費用控管月上限 $10 USD 每次回覆附帶 token 用量與費用統計 + + 2026-04-10 Claude Code: 強制合併 OPENCLAW_PERSONA,確保字數限制與格式規範 """ + # 強制在 system_prompt 前置 persona,確保 LLM 遵守字數與格式 + system_prompt = f"{OPENCLAW_PERSONA}\n{system_prompt}" import httpx from src.core.config import get_settings settings = get_settings() @@ -153,7 +157,12 @@ class ChatManager: 2026-04-09 ogt: 改接 192.168.0.111 Ollama deepseek-r1:14b,SRE 推理能力最強 deepseek-r1 含 標籤,需過濾後才回傳 + + 2026-04-10 Claude Code: 強制合併 NEMOCLAW_PERSONA,確保字數限制與格式規範 """ + # 強制在 system_prompt 前置 persona + system_prompt = f"{NEMOCLAW_PERSONA}\n{system_prompt}" + import httpx import re diff --git a/apps/api/src/services/telegram_gateway.py b/apps/api/src/services/telegram_gateway.py index ca49026e..0e3ec1e0 100644 --- a/apps/api/src/services/telegram_gateway.py +++ b/apps/api/src/services/telegram_gateway.py @@ -3683,14 +3683,32 @@ class TelegramGateway: context = await chat_mgr.get_system_context() + def _clean_ai_reply(text: str, max_chars: int = 600) -> str: + """清理 AI 回覆:移除 Markdown 語法,截斷超長內容""" + import re + # 移除 Markdown bold/italic (**text**, *text*, __text__, _text_) + text = re.sub(r'\*\*(.+?)\*\*', r'\1', text) + text = re.sub(r'\*(.+?)\*', r'\1', text) + text = re.sub(r'__(.+?)__', r'\1', text) + text = re.sub(r'_(.+?)_', r'\1', text) + # 移除 Markdown header (#, ##, ###) + text = re.sub(r'^#{1,3}\s+', '', text, flags=re.MULTILINE) + # 移除 標籤(deepseek-r1) + text = re.sub(r'.*?', '', text, flags=re.DOTALL).strip() + # 截斷 + if len(text) > max_chars: + text = text[:max_chars].rsplit('\n', 1)[0] + '…' + return text.strip() + if mention_openclaw and not mention_nemo: # 只 OpenClaw 回應 result = await chat_mgr._call_openclaw( f"{context}\n用戶 {username} 在 SRE 戰情室問你:", clean_text, ) + body = _clean_ai_reply(result) if result else '🔴 無響應' await self.send_as_openclaw( - text=f"🦞 OpenClaw\n\n{result or '🔴 無響應'}", + text=f"🦞 OpenClaw\n\n{body}", reply_to_message_id=message_id, ) @@ -3700,8 +3718,9 @@ class TelegramGateway: f"{context}\n用戶 {username} 在 SRE 戰情室問你:", clean_text, ) + body = _clean_ai_reply(result) if result else '🔴 無響應 (NIM 超時)' await self.send_as_nemotron( - text=f"🤖 NemoClaw\n\n{result or '🔴 無響應 (NIM 超時)'}", + text=f"🤖 NemoClaw\n\n{body}", reply_to_message_id=message_id, ) @@ -3717,13 +3736,13 @@ class TelegramGateway: if oc_result and not isinstance(oc_result, Exception): await self.send_as_openclaw( - text=f"🦞 OpenClaw\n\n{oc_result}", + text=f"🦞 OpenClaw\n\n{_clean_ai_reply(oc_result)}", reply_to_message_id=message_id, ) if nemo_result and not isinstance(nemo_result, Exception): await self.send_as_nemotron( - text=f"🤖 NemoClaw\n\n{nemo_result}", + text=f"🤖 NemoClaw\n\n{_clean_ai_reply(nemo_result)}", reply_to_message_id=message_id, )