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

@@ -1,7 +1,7 @@
from __future__ import annotations
import logging
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Optional, Tuple
from core.post_ops import negotiation_strategy_reply
logger = logging.getLogger("cs_agent")
@@ -10,7 +10,43 @@ if TYPE_CHECKING:
from core.pydantic_ai_agent import AgentDeps, ConversationState, CustomerMessage, CustomerServiceAgent
def select_target_agent(agent: "CustomerServiceAgent", message: "CustomerMessage", state: "ConversationState"):
def _select_agent_by_intent(
agent: "CustomerServiceAgent",
message: "CustomerMessage",
state: "ConversationState",
) -> Tuple[Optional[Any], str]:
"""
AI 意图优先路由;识别不到时返回 (None, "intent:none"),由关键词兜底。
"""
try:
from utils.intent_analyzer import detect_intent
decision = detect_intent(message.msg or "")
intent = (decision.intent or "").strip()
source = decision.source or "none"
score = float(decision.score or 0.0)
except Exception:
intent, source, score = "", "error", 0.0
if not intent:
return None, "intent:none"
if intent in ("询价", "砍价"):
return agent.agent_pricing, f"intent:{intent}|src:{source}|score:{score:.3f}"
if intent in ("修改", "加急"):
return agent.agent_processing, f"intent:{intent}|src:{source}|score:{score:.3f}"
if intent == "售后":
return agent.agent_after_sale, f"intent:{intent}|src:{source}|score:{score:.3f}"
if intent == "转接":
return agent.agent_after_sale, f"intent:{intent}|src:{source}|score:{score:.3f}"
if intent in ("打招呼", "批量", "发图"):
target = agent.agent_after_sale if state.stage == "售后" else agent.agent
return target, f"intent:{intent}|src:{source}|score:{score:.3f}"
return None, f"intent:unmapped:{intent}|src:{source}|score:{score:.3f}"
def select_target_agent(agent: "CustomerServiceAgent", message: "CustomerMessage", state: "ConversationState") -> Tuple[Any, str]:
msg_lower = message.msg.lower()
pricing_kw = ["多少钱", "多少一张", "报价", "给个价", "几块", "价位", "能便宜点吗"]
processing_kw = ["安排", "处理一下", "开始做", "做一下", "尽快", "加急", "付款了", "已付款"]
@@ -45,18 +81,23 @@ def select_target_agent(agent: "CustomerServiceAgent", message: "CustomerMessage
"卫星地图",
]
target_agent = agent.agent_after_sale if state.stage == "售后" else agent.agent
ai_target, ai_reason = _select_agent_by_intent(agent, message, state)
if ai_target is not None:
return ai_target, ai_reason
risk_hit = any(k in msg_lower for k in risk_kw) or agent._is_political_inquiry(message.msg) or agent._is_map_inquiry(message.msg)
if risk_hit:
return agent.agent_risk
return agent.agent_risk, "keyword:risk"
if any(k in message.msg for k in order_markers):
return agent.agent_order
return agent.agent_order, "keyword:order"
if any(k in msg_lower for k in processing_kw):
return agent.agent_processing
return agent.agent_processing, "keyword:processing"
if any(k in msg_lower for k in pricing_kw):
return agent.agent_pricing
return agent.agent_pricing, "keyword:pricing"
if any(k in msg_lower for k in similar_kw):
return agent.agent_similar
return target_agent
return agent.agent_similar, "keyword:similar"
return target_agent, "fallback:default"
async def execute_ai_turn(
@@ -68,7 +109,8 @@ async def execute_ai_turn(
deps: "AgentDeps",
history: list,
) -> str:
target_agent = select_target_agent(agent, message, state)
target_agent, route_reason = select_target_agent(agent, message, state)
logger.info("[路由] %s", route_reason)
result = await target_agent.run(user_prompt, deps=deps, message_history=history)
agent.message_histories[message.from_id] = result.all_messages()[-30:]
reply_text = agent._colloquialize_reply(agent._normalize_reply_text(result.output))