newtw3
This commit is contained in:
@@ -15,9 +15,18 @@ logger = logging.getLogger("cs_agent")
|
||||
|
||||
# 配置常量
|
||||
MSG_DEDUP_CAPACITY = 200 # 消息 ID 去重缓存容量
|
||||
TRANSFER_COOLDOWN_SEC = 60 # 转接冷却时间(秒)
|
||||
TRANSFER_COOLDOWN_SEC = 120 # 转接冷却时间(秒)—— 转接后2分钟内不再调用AI
|
||||
DEBOUNCE_SECONDS = 2.0 # 消息防抖延迟(秒)
|
||||
|
||||
# 转接后安抚话术池(轮换使用,避免复读)
|
||||
_TRANSFER_CALM_REPLIES = [
|
||||
"我在帮你催了哈,稍等下",
|
||||
"已经转了哈,马上就来",
|
||||
"收到,设计师在赶来了哈",
|
||||
"好的亲,稍等一下哈",
|
||||
"在催了在催了,马上哈",
|
||||
]
|
||||
|
||||
class SystemOrchestrator:
|
||||
"""
|
||||
全系统总编排:具备转接冷却、防抖合并、多消息去重、以及精准日志。
|
||||
@@ -30,8 +39,9 @@ class SystemOrchestrator:
|
||||
# 1. 消息 ID 去重
|
||||
self._processed_msg_ids = deque(maxlen=MSG_DEDUP_CAPACITY)
|
||||
|
||||
# 2. 转接冷却存储 (customer_id -> last_transfer_time)
|
||||
# 2. 转接冷却存储 (session_key -> last_transfer_time)
|
||||
self._last_transfer_time: Dict[str, float] = {}
|
||||
self._transfer_calm_idx: Dict[str, int] = {} # 安抚话术轮换索引
|
||||
|
||||
# 3. 防抖配置
|
||||
self._debounce_seconds = DEBOUNCE_SECONDS
|
||||
@@ -68,12 +78,13 @@ class SystemOrchestrator:
|
||||
# 店铺隔离:同一客户在不同店铺的对话独立处理
|
||||
session_key = f"{user_id}@{std_msg.acc_id}"
|
||||
|
||||
# 订单消息 / 纯金额通知:静默入库,不触发 AI 回复
|
||||
# 订单消息 / 纯金额通知 / SKU信息:静默入库,不触发 AI 回复
|
||||
msg_text = std_msg.content or ""
|
||||
is_order = "[系统订单信息]" in msg_text
|
||||
is_price_only = bool(re.match(r'^[\s\n]*金?额?[::]?\s*[\d.]+\s*元', msg_text.strip()))
|
||||
is_sku_only = bool(re.match(r'^[\s\n]*(备注[::]|数量[::]|款式[::])', msg_text.strip()))
|
||||
if is_order or is_price_only or is_sku_only:
|
||||
is_sku_only = bool(re.match(r'^[\s\n]*(备注[::]|数量[::]|款式[::]|定制[::])', msg_text.strip()))
|
||||
is_sku_amount = bool(re.match(r'^[\s\n]*金额[::]\s*[\d.]+元\s*●', msg_text.strip()))
|
||||
if is_order or is_price_only or is_sku_only or is_sku_amount:
|
||||
await self._handle_order_packet(platform, std_msg)
|
||||
logger.info(f"[订单消息] user={user_id} acc={std_msg.acc_id} 已入库更新状态")
|
||||
await repo.save_chat(platform, user_id, msg_text, "in", acc_id=std_msg.acc_id)
|
||||
@@ -222,22 +233,25 @@ class SystemOrchestrator:
|
||||
if all_image_urls:
|
||||
asyncio.create_task(self._analyze_images_background(session_key, all_image_urls))
|
||||
|
||||
# C. 冷却检查:如果转接冷却期内发过转接,告诉大脑"已处于转接中"
|
||||
is_in_cooldown = (time.time() - self._last_transfer_time.get(session_key, 0)) < TRANSFER_COOLDOWN_SEC
|
||||
|
||||
# D. 思考
|
||||
history = await repo.get_chat_history(user_id, limit=10, acc_id=acc_id)
|
||||
if history and history[-1].get('content') == db_content: history = history[:-1]
|
||||
# C. 冷却检查:转接成功后冷却期内,直接回安抚话术,不调AI
|
||||
last_transfer = self._last_transfer_time.get(session_key, 0)
|
||||
cooldown_elapsed = time.time() - last_transfer
|
||||
is_in_cooldown = cooldown_elapsed < TRANSFER_COOLDOWN_SEC
|
||||
|
||||
# 冷却期内:禁止再发转接指令,避免反复转接
|
||||
if is_in_cooldown:
|
||||
final_msg.content = (
|
||||
"【系统:设计师已收到转接通知正在赶来,严禁再次调用转人工工具!"
|
||||
"客户再问就回'设计师正在看了哈,稍等一下',换着说不要重复】\n"
|
||||
+ final_msg.content
|
||||
idx = self._transfer_calm_idx.get(session_key, 0)
|
||||
calm_reply = _TRANSFER_CALM_REPLIES[idx % len(_TRANSFER_CALM_REPLIES)]
|
||||
self._transfer_calm_idx[session_key] = idx + 1
|
||||
logger.info(f"[Orchestrator] 转接冷却中({cooldown_elapsed:.0f}s),直接安抚: {calm_reply}")
|
||||
std_res = StandardResponse(
|
||||
reply_content=calm_reply,
|
||||
metadata={"acc_id": acc_id, "acc_type": acc_type}
|
||||
)
|
||||
|
||||
std_res = await self.brain.think_and_reply(final_msg, history=history)
|
||||
else:
|
||||
# D. 正常流程:调用AI思考
|
||||
history = await repo.get_chat_history(user_id, limit=10, acc_id=acc_id)
|
||||
if history and history[-1].get('content') == db_content: history = history[:-1]
|
||||
std_res = await self.brain.think_and_reply(final_msg, history=history)
|
||||
|
||||
# E. 发送并记录时间
|
||||
if std_res.should_reply:
|
||||
|
||||
Reference in New Issue
Block a user