114 lines
4.6 KiB
Python
114 lines
4.6 KiB
Python
"""奶龙基金智能助手:只处理一期公开客服范围。"""
|
||
|
||
from app.core.config import get_settings
|
||
from app.core.contracts import AgentDefinition, AgentRequest, CoreResult, RequestContext
|
||
from app.core.errors import RecoverableAgentError
|
||
from app.core.knowledge_contracts import KnowledgeSearchResult
|
||
from app.service.agent.base import BaseAgent
|
||
from app.service.agent.customer_service_routing import CustomerServiceIntentRouter
|
||
|
||
|
||
def _human_service_phone() -> str:
|
||
return get_settings().customer_service_phone
|
||
|
||
|
||
class CustomerServiceAgent(BaseAgent):
|
||
definition = AgentDefinition(
|
||
agent_type="customer_service",
|
||
version="1.0.0",
|
||
allowed_tools=("query_knowledge",),
|
||
allowed_roles=("visitor", "customer"),
|
||
allowed_portals=("api",),
|
||
requires_model_intent_classification=False,
|
||
supported_intents=(
|
||
"security_notice",
|
||
"account_entry",
|
||
"human_transfer",
|
||
"compliance_refusal",
|
||
"chitchat",
|
||
"public_knowledge",
|
||
"faq",
|
||
"product_inquiry",
|
||
"policy_explain",
|
||
),
|
||
)
|
||
|
||
def __init__(self) -> None:
|
||
super().__init__(self.definition)
|
||
|
||
async def handle(self, request: AgentRequest, context: RequestContext) -> CoreResult:
|
||
message = request.message.strip()
|
||
route = CustomerServiceIntentRouter.classify(message)
|
||
if route.intent == "security_notice":
|
||
return CoreResult(
|
||
text=(
|
||
"请立即停止操作,不要继续提供验证码、密码或身份证件信息,并尽快联系"
|
||
f"人工客服 {_human_service_phone()}。"
|
||
),
|
||
transfer_required=True,
|
||
transfer_reason="security_notice",
|
||
)
|
||
if route.intent == "compliance_refusal":
|
||
return CoreResult(
|
||
text=(
|
||
"我不能推荐具体产品、承诺收益或代您交易;如需进一步了解,请联系"
|
||
f"人工客服 {_human_service_phone()}。"
|
||
),
|
||
transfer_required=True,
|
||
transfer_reason="compliance_refusal",
|
||
)
|
||
if route.intent == "account_entry":
|
||
if "visitor" in context.roles:
|
||
return CoreResult(text="我无法查询账户数据,请先登录后前往“我的账户”查看相关状态。")
|
||
return CoreResult(text="我无法查询账户数据,请前往“我的账户”查看相关状态。")
|
||
if route.intent == "human_transfer":
|
||
return CoreResult(
|
||
text=(
|
||
f"您可以联系人工客服 {_human_service_phone()}(工作日 09:00-18:00)"
|
||
"进一步核实。"
|
||
),
|
||
transfer_required=True,
|
||
transfer_reason="human_transfer",
|
||
)
|
||
if route.is_chitchat:
|
||
if request.metadata.chitchat_streak == 4:
|
||
return CoreResult(text="和您聊天很开心呀。您是想了解相关的基金业务或公开信息吗?")
|
||
return CoreResult(text="您好呀,我是奶龙基金智能助手,很高兴和您聊天。")
|
||
try:
|
||
output = await self.call_tool(
|
||
"query_knowledge",
|
||
{"query": message, "intents": route.knowledge_intents, "top_k": 5},
|
||
intent="public_knowledge",
|
||
context=context,
|
||
)
|
||
result = (
|
||
output
|
||
if isinstance(output, KnowledgeSearchResult)
|
||
else KnowledgeSearchResult.model_validate(output)
|
||
)
|
||
except RecoverableAgentError:
|
||
return self._knowledge_transfer("knowledge_unavailable")
|
||
answers = [
|
||
hit.answer.strip()
|
||
for hit in result.hits
|
||
if isinstance(hit.answer, str) and hit.answer.strip()
|
||
]
|
||
if not answers:
|
||
return self._knowledge_transfer("knowledge_not_found")
|
||
return CoreResult(text=answers[0])
|
||
|
||
@staticmethod
|
||
def _knowledge_transfer(reason: str) -> CoreResult:
|
||
phone = _human_service_phone()
|
||
if reason == "knowledge_unavailable":
|
||
text = (
|
||
"您好呀,我暂时无法从公开资料中确认这个问题,请联系"
|
||
f"人工客服 {phone} 进一步核实。"
|
||
)
|
||
else:
|
||
text = (
|
||
"您好呀,我暂时没有查到匹配的公开资料,请联系"
|
||
f"人工客服 {phone} 进一步核实。"
|
||
)
|
||
return CoreResult(text=text, transfer_required=True, transfer_reason=reason)
|