fix: block leaked history content before outbound send

This commit is contained in:
2026-03-08 12:36:57 +08:00
parent 613d375845
commit 5a5bde1ba5
2 changed files with 43 additions and 0 deletions

View File

@@ -8,6 +8,28 @@ from core.schema import StandardMessage, StandardResponse
logger = logging.getLogger("cs_agent") logger = logging.getLogger("cs_agent")
_OUTBOUND_BLOCK_MARKERS = (
"【历史记录摘要】",
"【详细记录】",
"【订单摘要】",
"【订单详情】",
"<think",
"think_never_used",
'[{"name":',
)
_HISTORY_LEAK_PATTERNS = [
r'\[\d{4}-\d{2}-\d{2}[^\]]*\]\s*(客户|客服)[:]',
r'\[\d{2}:\d{2}:\d{2}\]\s*(客户|客服|我)[:]',
r'(根据|查看|查询|翻看)(历史|聊天|对话)(记录|内容)',
r'历史(记录|对话|消息)(显示|表明|中)',
r'之前的(聊天|对话|记录)(中|里|显示)',
r'\d+条(历史|对话)?消息',
r'订单号[:]\s*\d{10,}',
r'(状态|金额|数量)[:].*(状态|金额|数量)[:]',
]
class QianniuAdapter(BaseAdapter): class QianniuAdapter(BaseAdapter):
""" """
千牛适配器:支持识别消息来源(客户 vs 商家人工)。 千牛适配器:支持识别消息来源(客户 vs 商家人工)。
@@ -30,6 +52,22 @@ class QianniuAdapter(BaseAdapter):
logger.warning(f"[QianniuAdapter] 读取转接分组配置失败: {e}") logger.warning(f"[QianniuAdapter] 读取转接分组配置失败: {e}")
return self._default_group_id return self._default_group_id
@staticmethod
def _sanitize_outbound_text(content: str) -> str:
if not content:
return ""
cleaned = str(content).strip()
if "[转移会话]" in cleaned:
return cleaned
if any(marker in cleaned for marker in _OUTBOUND_BLOCK_MARKERS):
logger.warning("[QianniuAdapter] 拦截到内部内容外发,替换为安全兜底回复")
return "我在帮你看记录,稍等哈"
for pattern in _HISTORY_LEAK_PATTERNS:
if re.search(pattern, cleaned):
logger.warning(f"[QianniuAdapter] 检测到历史记录泄露模式: {pattern[:30]}...")
return "我在帮你看记录,稍等哈"
return cleaned
async def translate_inbound(self, raw: dict) -> Tuple[StandardMessage, str]: async def translate_inbound(self, raw: dict) -> Tuple[StandardMessage, str]:
""" """
返回: (标准消息, 消息方向) 返回: (标准消息, 消息方向)
@@ -81,6 +119,9 @@ class QianniuAdapter(BaseAdapter):
else: else:
content = res.reply_content content = res.reply_content
if res.msg_type == 0:
content = self._sanitize_outbound_text(content)
try: try:
logger.info( logger.info(
f"[REPLY->CUSTOMER] user={user_id} acc={acc_id} type={res.msg_type}\n{content}" f"[REPLY->CUSTOMER] user={user_id} acc={acc_id} type={res.msg_type}\n{content}"

View File

@@ -366,6 +366,8 @@ class SystemOrchestrator:
async def handle_outbound_event(self, user_id: str, platform: str, response: StandardResponse): async def handle_outbound_event(self, user_id: str, platform: str, response: StandardResponse):
if platform == "qianniu": if platform == "qianniu":
if response and response.msg_type == 0:
response.reply_content = self._sanitize_outbound_text(response.reply_content)
await self.qianniu_adapter.translate_outbound(response, user_id) await self.qianniu_adapter.translate_outbound(response, user_id)
# 全局单例 # 全局单例