diff --git a/core/pydantic_ai_agent.py b/core/pydantic_ai_agent.py index aa7be2e..7f82fa5 100755 --- a/core/pydantic_ai_agent.py +++ b/core/pydantic_ai_agent.py @@ -515,6 +515,10 @@ class CustomerServiceAgent: try: from image.image_analyzer import image_analyzer result = await image_analyzer.analyze(image_url) + if result.get("feasibility") == "no" or result.get("risk") == "high": + return "该图风险高或不可做:不报价,建议换图或转人工评估。" + if not result.get("success", False): + return "图片识别异常:先不报价,建议客户重发更清晰图片。" p = result.get("price_suggest", 20) try: st = self._get_conversation_state(ctx.deps.from_id) diff --git a/core/websocket_client.py b/core/websocket_client.py index a6e4d2e..bf2a9a6 100755 --- a/core/websocket_client.py +++ b/core/websocket_client.py @@ -587,7 +587,8 @@ class QingjianAPIClient: pass reply = f"这张按{p}元,满意再拍" else: - reply = "这张我看了,先按20元给你做" + # 识别失败时不做兜底报价,避免把未识别图片误判为可做 + reply = "这张我这边暂时识别不稳定,先不乱报价。你可以换一张更清晰的,我再给你准报价。" await self.send_reply(data, reply) except Exception: pass @@ -792,13 +793,6 @@ class QingjianAPIClient: await asyncio.sleep(0.8) logger.info(f"Agent 回复: {response.reply}") await self.send_reply(data, response.reply) - # 记录客服回复 - if _cid: - try: - _chat_log(_cid, response.reply, "out", customer_name=_name, - acc_id=data.get('acc_id', ''), platform=_plat) - except Exception: - pass # 推送到企微:客户消息+AI回复成对 try: from utils.wechat_chat_log import push_chat_to_wechat @@ -840,6 +834,25 @@ class QingjianAPIClient: tasks = [image_analyzer.analyze(u) for u in urls] results = await asyncio.gather(*tasks, return_exceptions=True) + # 先做风险分流:多图中只要出现不可做/高风险,不进入报价 + unsafe = [] + dense_text_reject = [] + for i, r in enumerate(results, 1): + if isinstance(r, dict) and r.get("success", False): + if r.get("feasibility") == "no" or r.get("risk") == "high": + unsafe.append(f"图{i}") + note = str(r.get("note", "") or "") + if "文字内容过于密集" in note or "密集文字" in note: + dense_text_reject.append(f"图{i}") + + if unsafe: + if dense_text_reject and len(dense_text_reject) == len(unsafe): + reply = "这类文字太密的图我们这边不接单,抱歉哈。你要是简化后再发我可以继续看。" + else: + reply = f"这批里{'、'.join(unsafe)}处理风险较高,我这边先不直接接,建议转人工评估更稳。" + await self.send_reply(data, reply) + return + pairs = [] for u, r in zip(urls, results): if isinstance(r, dict) and r.get("success", False): @@ -862,7 +875,7 @@ class QingjianAPIClient: except Exception: pass if not pairs: - await self.send_reply(data, "这组图我看了,先按20元一张给你做") + await self.send_reply(data, "这组图我这边暂时识别不稳定,先不乱报价。你可以换清晰图再发我。") return composite = _detect_composite_request() composite_fee = 5 if composite else 0 @@ -879,7 +892,7 @@ class QingjianAPIClient: except Exception as e: logger.error(f"多图分析失败: {e}") try: - await self.send_reply(data, "这组图我看了,先按20元一张给你做") + await self.send_reply(data, "这组图我这边暂时识别异常,先不乱报价。你可以稍后再发我。") except Exception: pass def _msg_requests_external_contact(self, msg: str) -> bool: @@ -1321,11 +1334,6 @@ class QingjianAPIClient: } await asyncio.sleep(0.5) await self.send_reply(fake_data, response.reply) - try: - _chat_log(customer_id, response.reply, "out", - acc_id=acc_id, platform=acc_type) - except Exception: - pass logger.info(f"[Workflow] AI 通知已发送: {response.reply}") except Exception as e: logger.error(f"[Workflow] AI 通知生成失败: {e}") diff --git a/utils/wechat_chat_log.py b/utils/wechat_chat_log.py index b9b1bab..607b137 100755 --- a/utils/wechat_chat_log.py +++ b/utils/wechat_chat_log.py @@ -83,11 +83,17 @@ async def push_chat_to_wechat( # 附带近期对话,保持连贯 recent = _get_recent_conversation(customer_id, acc_id, last_n=8) + last_line = None for m in recent: role = customer_id if m.get("direction") == "in" else "客服" msg = _truncate((m.get("message") or "").strip(), 120) if msg: - lines.append(f"{role}:{msg}") + line = f"{role}:{msg}" + # 防止日志中的重复记录在企微里连续刷屏 + if line == last_line: + continue + lines.append(line) + last_line = line # 当前回复(可能已在 recent 中有客户消息,客服回复是新的) lines.append(f"客服:{reply_msg or '(无回复)'}")