fix: disable legacy fast quote path and tighten dense-text rejection
This commit is contained in:
@@ -1342,12 +1342,19 @@ class CustomerServiceAgent:
|
|||||||
try:
|
try:
|
||||||
from utils.content_filter import should_block_customer
|
from utils.content_filter import should_block_customer
|
||||||
if should_block_customer(message.msg) or self._is_political_inquiry(message.msg):
|
if should_block_customer(message.msg) or self._is_political_inquiry(message.msg):
|
||||||
|
# 命中敏感询问时清空待报价队列,避免旧图残留污染后续会话
|
||||||
|
state.pending_image_urls.clear()
|
||||||
|
state.pending_requirements.clear()
|
||||||
|
self._sync_pending_quote_state(message.from_id, state)
|
||||||
reply = "这类不做哈,政治相关图片和人物都不接。"
|
reply = "这类不做哈,政治相关图片和人物都不接。"
|
||||||
state.last_reply_at = datetime.now()
|
state.last_reply_at = datetime.now()
|
||||||
print(f"{self.C_REPLY}[REPLY->CUSTOMER]{self.C_RESET} {reply}")
|
print(f"{self.C_REPLY}[REPLY->CUSTOMER]{self.C_RESET} {reply}")
|
||||||
return AgentResponse(reply=reply, should_reply=True, need_transfer=False)
|
return AgentResponse(reply=reply, should_reply=True, need_transfer=False)
|
||||||
except Exception:
|
except Exception:
|
||||||
if self._is_political_inquiry(message.msg):
|
if self._is_political_inquiry(message.msg):
|
||||||
|
state.pending_image_urls.clear()
|
||||||
|
state.pending_requirements.clear()
|
||||||
|
self._sync_pending_quote_state(message.from_id, state)
|
||||||
reply = "这类不做哈,政治相关图片和人物都不接。"
|
reply = "这类不做哈,政治相关图片和人物都不接。"
|
||||||
state.last_reply_at = datetime.now()
|
state.last_reply_at = datetime.now()
|
||||||
print(f"{self.C_REPLY}[REPLY->CUSTOMER]{self.C_RESET} {reply}")
|
print(f"{self.C_REPLY}[REPLY->CUSTOMER]{self.C_RESET} {reply}")
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ class QingjianAPIClient:
|
|||||||
self._agent_semaphore = asyncio.Semaphore(8)
|
self._agent_semaphore = asyncio.Semaphore(8)
|
||||||
self._pending_images: dict = {}
|
self._pending_images: dict = {}
|
||||||
self._pending_image_tasks: dict = {}
|
self._pending_image_tasks: dict = {}
|
||||||
|
# 旧版“看图即报价”快速链路(默认关闭,避免与 Agent 批量收集逻辑并发打架)
|
||||||
|
self._legacy_fast_quote_enabled = os.getenv("LEGACY_FAST_IMAGE_QUOTE", "false").lower() in ("1", "true", "yes")
|
||||||
self._system_inquiry_rules = self._load_system_inquiry_rules()
|
self._system_inquiry_rules = self._load_system_inquiry_rules()
|
||||||
self._last_reply_sent_at: dict = {} # customer_key -> monotonic ts
|
self._last_reply_sent_at: dict = {} # customer_key -> monotonic ts
|
||||||
self._inbound_log_seen: dict = {} # signature -> monotonic ts(防重复写入)
|
self._inbound_log_seen: dict = {} # signature -> monotonic ts(防重复写入)
|
||||||
@@ -600,6 +602,7 @@ class QingjianAPIClient:
|
|||||||
_cid = data.get('from_id', '')
|
_cid = data.get('from_id', '')
|
||||||
_name = self.to_chinese(data.get('from_name', '') or data.get('cy_name', ''))
|
_name = self.to_chinese(data.get('from_name', '') or data.get('cy_name', ''))
|
||||||
_plat = data.get('acc_type', '')
|
_plat = data.get('acc_type', '')
|
||||||
|
_shop_type = _get_shop_type(data.get('acc_id', ''), self.to_chinese(data.get('goods_name', '') or ''))
|
||||||
|
|
||||||
# 超大尺寸(米制)直接拒单,避免进入报价/处理流程
|
# 超大尺寸(米制)直接拒单,避免进入报价/处理流程
|
||||||
oversize_reply = self._oversize_reply_if_needed(msg_text)
|
oversize_reply = self._oversize_reply_if_needed(msg_text)
|
||||||
@@ -607,92 +610,94 @@ class QingjianAPIClient:
|
|||||||
await self.send_reply(data, oversize_reply)
|
await self.send_reply(data, oversize_reply)
|
||||||
return
|
return
|
||||||
|
|
||||||
# 消息含图片URL:累积到待处理列表,先询问要求
|
# 找图/修图店铺:统一走 Agent 的“收集需求后统一报价”流程,避免按单图快速报价
|
||||||
if self._msg_has_image_url(msg_text):
|
if self._legacy_fast_quote_enabled and _shop_type != "find_image":
|
||||||
urls = self._extract_image_urls(msg_text)
|
# 消息含图片URL:累积到待处理列表,先询问要求
|
||||||
key = self._customer_key(data)
|
if self._msg_has_image_url(msg_text):
|
||||||
self._add_pending_images(key, urls)
|
urls = self._extract_image_urls(msg_text)
|
||||||
await self.send_reply(data, "收到,我看看哈")
|
|
||||||
old = self._pending_image_tasks.get(key)
|
|
||||||
if old and not old.done():
|
|
||||||
old.cancel()
|
|
||||||
async def _delay_flush(capture_key, capture_data):
|
|
||||||
await asyncio.sleep(self._DEBOUNCE_SECONDS + 4)
|
|
||||||
# 与同客户 agent_reply 串行,避免“延迟报价”和“当前追问”并发打架
|
|
||||||
async with self._get_customer_lock(capture_key):
|
|
||||||
await self._flush_pending_images(capture_key, capture_data)
|
|
||||||
task = asyncio.create_task(_delay_flush(key, data))
|
|
||||||
self._pending_image_tasks[key] = task
|
|
||||||
return
|
|
||||||
elif self._msg_refers_images(msg_text):
|
|
||||||
urls = self._collect_recent_image_urls(_cid, data.get('acc_id', ''), max_count=6)
|
|
||||||
if urls:
|
|
||||||
key = self._customer_key(data)
|
|
||||||
self._add_pending_images(key, urls)
|
|
||||||
await self.send_reply(data, "稍等,我找找刚才那几张")
|
|
||||||
await self._flush_pending_images(key, data)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
status = self._detect_order_status(msg_text)
|
|
||||||
if status == "paid":
|
|
||||||
ack = "收到付款,我马上安排处理,有需要第一时间联系您"
|
|
||||||
await self.send_reply(data, ack)
|
|
||||||
return
|
|
||||||
elif status in ("waiting", "order"):
|
|
||||||
ack = "订单我看到了哈,方便的话请完成付款,我好安排处理"
|
|
||||||
await self.send_reply(data, ack)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
urls = self._extract_image_urls(msg_text)
|
|
||||||
if len(urls) == 1:
|
|
||||||
key = self._customer_key(data)
|
key = self._customer_key(data)
|
||||||
self._add_pending_images(key, urls)
|
self._add_pending_images(key, urls)
|
||||||
await self.send_reply(data, "收到,我看看哈")
|
await self.send_reply(data, "收到,我看看哈")
|
||||||
|
old = self._pending_image_tasks.get(key)
|
||||||
|
if old and not old.done():
|
||||||
|
old.cancel()
|
||||||
|
async def _delay_flush(capture_key, capture_data):
|
||||||
|
await asyncio.sleep(self._DEBOUNCE_SECONDS + 4)
|
||||||
|
# 与同客户 agent_reply 串行,避免“延迟报价”和“当前追问”并发打架
|
||||||
|
async with self._get_customer_lock(capture_key):
|
||||||
|
await self._flush_pending_images(capture_key, capture_data)
|
||||||
|
task = asyncio.create_task(_delay_flush(key, data))
|
||||||
|
self._pending_image_tasks[key] = task
|
||||||
return
|
return
|
||||||
else:
|
elif self._msg_refers_images(msg_text):
|
||||||
if self._msg_requests_external_contact(msg_text):
|
urls = self._collect_recent_image_urls(_cid, data.get('acc_id', ''), max_count=6)
|
||||||
reply = "这里沟通就可以哦,其他联系方式不方便"
|
if urls:
|
||||||
await self.send_reply(data, reply)
|
|
||||||
try:
|
|
||||||
from utils.wechat_chat_log import push_chat_to_wechat
|
|
||||||
asyncio.create_task(push_chat_to_wechat(
|
|
||||||
customer_name=_name,
|
|
||||||
customer_id=_cid,
|
|
||||||
acc_id=data.get('acc_id', ''),
|
|
||||||
customer_msg=msg_text,
|
|
||||||
reply_msg=reply,
|
|
||||||
goods_name=self.to_chinese(data.get('goods_name', '') or ''),
|
|
||||||
))
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
return
|
|
||||||
if self._msg_is_requirement(msg_text) or self._msg_is_price_inquiry(msg_text):
|
|
||||||
key = self._customer_key(data)
|
key = self._customer_key(data)
|
||||||
if self._pending_images.get(key):
|
self._add_pending_images(key, urls)
|
||||||
old = self._pending_image_tasks.get(key)
|
await self.send_reply(data, "稍等,我找找刚才那几张")
|
||||||
if old and not old.done():
|
await self._flush_pending_images(key, data)
|
||||||
old.cancel()
|
|
||||||
await self.send_reply(data, "稍等,我把刚才那几张一起看下")
|
|
||||||
await self._flush_pending_images(key, data)
|
|
||||||
return
|
|
||||||
if self._msg_is_price_inquiry(msg_text):
|
|
||||||
recent_urls = self._collect_recent_image_urls(_cid, data.get('acc_id', ''), max_count=6)
|
|
||||||
if recent_urls:
|
|
||||||
await self.send_reply(data, "稍等,我刚才那几张一起看下")
|
|
||||||
if len(recent_urls) == 1:
|
|
||||||
asyncio.create_task(self._analyze_single_and_reply(data, recent_urls[0]))
|
|
||||||
else:
|
|
||||||
asyncio.create_task(self._analyze_multi_and_reply(data, recent_urls))
|
|
||||||
return
|
|
||||||
status = self._detect_order_status(msg_text)
|
|
||||||
if status == "paid":
|
|
||||||
ack = "收到付款,我马上安排处理,有需要第一时间联系您"
|
|
||||||
await self.send_reply(data, ack)
|
|
||||||
return
|
return
|
||||||
elif status in ("waiting", "order"):
|
else:
|
||||||
ack = "订单我看到了哈,方便的话请完成付款,我好安排处理"
|
status = self._detect_order_status(msg_text)
|
||||||
await self.send_reply(data, ack)
|
if status == "paid":
|
||||||
|
ack = "收到付款,我马上安排处理,有需要第一时间联系您"
|
||||||
|
await self.send_reply(data, ack)
|
||||||
|
return
|
||||||
|
elif status in ("waiting", "order"):
|
||||||
|
ack = "订单我看到了哈,方便的话请完成付款,我好安排处理"
|
||||||
|
await self.send_reply(data, ack)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
urls = self._extract_image_urls(msg_text)
|
||||||
|
if len(urls) == 1:
|
||||||
|
key = self._customer_key(data)
|
||||||
|
self._add_pending_images(key, urls)
|
||||||
|
await self.send_reply(data, "收到,我看看哈")
|
||||||
return
|
return
|
||||||
|
else:
|
||||||
|
if self._msg_requests_external_contact(msg_text):
|
||||||
|
reply = "这里沟通就可以哦,其他联系方式不方便"
|
||||||
|
await self.send_reply(data, reply)
|
||||||
|
try:
|
||||||
|
from utils.wechat_chat_log import push_chat_to_wechat
|
||||||
|
asyncio.create_task(push_chat_to_wechat(
|
||||||
|
customer_name=_name,
|
||||||
|
customer_id=_cid,
|
||||||
|
acc_id=data.get('acc_id', ''),
|
||||||
|
customer_msg=msg_text,
|
||||||
|
reply_msg=reply,
|
||||||
|
goods_name=self.to_chinese(data.get('goods_name', '') or ''),
|
||||||
|
))
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
if self._msg_is_requirement(msg_text) or self._msg_is_price_inquiry(msg_text):
|
||||||
|
key = self._customer_key(data)
|
||||||
|
if self._pending_images.get(key):
|
||||||
|
old = self._pending_image_tasks.get(key)
|
||||||
|
if old and not old.done():
|
||||||
|
old.cancel()
|
||||||
|
await self.send_reply(data, "稍等,我把刚才那几张一起看下")
|
||||||
|
await self._flush_pending_images(key, data)
|
||||||
|
return
|
||||||
|
if self._msg_is_price_inquiry(msg_text):
|
||||||
|
recent_urls = self._collect_recent_image_urls(_cid, data.get('acc_id', ''), max_count=6)
|
||||||
|
if recent_urls:
|
||||||
|
await self.send_reply(data, "稍等,我刚才那几张一起看下")
|
||||||
|
if len(recent_urls) == 1:
|
||||||
|
asyncio.create_task(self._analyze_single_and_reply(data, recent_urls[0]))
|
||||||
|
else:
|
||||||
|
asyncio.create_task(self._analyze_multi_and_reply(data, recent_urls))
|
||||||
|
return
|
||||||
|
status = self._detect_order_status(msg_text)
|
||||||
|
if status == "paid":
|
||||||
|
ack = "收到付款,我马上安排处理,有需要第一时间联系您"
|
||||||
|
await self.send_reply(data, ack)
|
||||||
|
return
|
||||||
|
elif status in ("waiting", "order"):
|
||||||
|
ack = "订单我看到了哈,方便的话请完成付款,我好安排处理"
|
||||||
|
await self.send_reply(data, ack)
|
||||||
|
return
|
||||||
|
|
||||||
# 构建 CustomerMessage
|
# 构建 CustomerMessage
|
||||||
customer_msg = CustomerMessage(
|
customer_msg = CustomerMessage(
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ class ImageAnalyzer:
|
|||||||
)
|
)
|
||||||
dense_text_hint = any(
|
dense_text_hint = any(
|
||||||
kw in scene_text
|
kw in scene_text
|
||||||
for kw in ("密集文字", "大量文字", "小字", "多板块", "细字")
|
for kw in ("密集文字", "大量文字", "多板块")
|
||||||
)
|
)
|
||||||
|
|
||||||
# 校验比例合法性
|
# 校验比例合法性
|
||||||
|
|||||||
Reference in New Issue
Block a user