From 100e4d9b89eefae47e6baad6e939d04d3a95b5af Mon Sep 17 00:00:00 2001 From: OG T Date: Fri, 10 Apr 2026 21:26:15 +0800 Subject: [PATCH] =?UTF-8?q?fix(chat):=20AI=20=E5=9B=9E=E8=A6=86=E6=88=AA?= =?UTF-8?q?=E6=96=B7=E5=95=8F=E9=A1=8C=20=E2=80=94=20=E5=BC=B7=E5=88=B6=20?= =?UTF-8?q?persona=20+=20Markdown=20=E6=B8=85=E7=90=86=20+=20600=E5=AD=97?= =?UTF-8?q?=E4=B8=8A=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 問題: OpenClaw/NemoClaw 回覆 Markdown 語法 + 超長,Telegram 顯示截斷 修正: 1. chat_manager: _call_openclaw/_call_nemotron 強制前置 persona (含不超過300字規範) 2. telegram_gateway: _clean_ai_reply() 移除 **bold** *italic* # header 語法 移除 deepseek-r1 標籤,截斷 > 600 字並在段落邊界截 Co-Authored-By: Claude Sonnet 4.6 --- apps/api/src/services/chat_manager.py | 9 ++++++++ apps/api/src/services/telegram_gateway.py | 27 +++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) 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, )