Files
group_fqcd_jr/app/service/agent/customer_service_agent.py
T

114 lines
4.6 KiB
Python
Raw Normal View History

2026-09-10 19:51:08 +08:00
"""奶龙基金智能助手:只处理一期公开客服范围。"""
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)