feat: enforce full AI outbound generation and reduce template replies

This commit is contained in:
2026-03-02 11:09:26 +08:00
parent 6433708597
commit 9d0276be41
5 changed files with 415 additions and 34 deletions

View File

@@ -490,23 +490,9 @@ class CustomerServiceAgent:
"""
收图阶段回复默认走 AI 改写,失败时回退到固定模板。
"""
# 首张收图先承接“我看一下”,避免机械地立刻催“发完统一报价”。
first_image_ack = "收到,我先看一下哈,稍等哈。"
if scene == "collect_ack" and len(state.pending_image_urls) == 1:
first_ack = [
"收到了,我先看一下哈,稍等哈",
"这张我收到了,我先看下,稍等我一下哈",
"收到这张了,我先过一眼,稍等哈",
"我先看这张哈,稍等我一下",
"图我收到了,我先看一眼,稍等我回你哈",
"这张先记上了,我先看下细节,稍等哈",
"收到哈,我先过一遍这张,稍等我会儿",
"我先看这张效果,稍等一下哈",
"图到了,我先看下清晰度,稍等哈",
"这张我先看着,稍等我一下就回你",
"收到这张了,我先核一下细节,稍等哈",
"我先把这张看完,稍等我一会儿哈",
]
return random.choice(first_ack)
fallback = first_image_ack
if not self.dynamic_collection_replies:
return fallback
try:
@@ -525,7 +511,7 @@ class CustomerServiceAgent:
f"客户原话: {message.msg}\n"
f"当前已收图片数: {len(state.pending_image_urls)}\n"
f"当前需求摘要: {pending_req}\n"
"输出要求: 不超过2句话像真人店主聊天。"
"输出要求: 不超过2句话像真人店主聊天;避免复用固定模板句"
)
result = await self.agent_natural_reply.run(user_prompt, deps=deps, message_history=history)
self.message_histories[message.from_id] = result.all_messages()[-30:]
@@ -695,6 +681,44 @@ class CustomerServiceAgent:
clean = msg.strip().rstrip("!?。.~")
return clean in self._COOLDOWN_PATTERNS
def _should_handle_as_meaningless_short_text(self, state: ConversationState, msg: str) -> bool:
"""
无意义短句仅在“非业务处理中”生效,避免误拦截真实推进消息。
例如:已在收图/待报价阶段时,客户发“好的/在吗”不应直接 ping。
"""
customer_text, _ = self._split_customer_text(msg or "")
text = (customer_text or "").strip()
if not _is_meaningless_short_text(text):
return False
if self._extract_image_urls(text):
return False
if (getattr(state, "pending_image_urls", None) or []):
return False
if getattr(state, "quote_phase", "idle") in {"collecting", "ready_to_quote", "waiting_result"}:
return False
return True
async def build_auto_quote_reply(self, state: ConversationState, message: CustomerMessage) -> AgentResponse:
"""
自动报价内部入口:不走 process_message避免伪造客户语句污染上下文。
"""
quote_res = await self._quote_pending_images(state, message)
reply_text = self._colloquialize_reply(quote_res.get("reply", ""))
reply_text = await self._rewrite_reply_with_ai(
message=message,
state=state,
reply=reply_text,
scene="batch_quote_reply",
)
need_transfer = bool(quote_res.get("need_transfer"))
state.last_reply_at = datetime.now()
return AgentResponse(
reply=reply_text,
should_reply=not need_transfer,
need_transfer=need_transfer,
transfer_msg=TRANSFER_MESSAGE if need_transfer else "",
)
async def process_message(self, message: CustomerMessage) -> AgentResponse:
"""处理客户消息并生成回复。"""
return await process_incoming_message(self, message)