merge: integrate ZSY customer service and profile capabilities

This commit is contained in:
张胜宇
2026-09-11 22:31:51 +08:00
94 changed files with 7933 additions and 77 deletions
@@ -27,6 +27,7 @@ from app.core.contracts import (
RequestContext,
SourceReference,
)
from app.core.customer_service_rules import route_message
from app.core.errors import ForbiddenAgentError
from app.service.agent.base import BaseAgent
from app.service.model_gateway import DatabaseModelEndpointResolver
@@ -150,7 +151,7 @@ TOP_K = 5
MAX_ANSWER_CHARS = 1200
REFERENCE_LIMIT = 3
COMPANY = "南方科技"
COMPANY = "奶龙基金责任有限公司"
# 客服热线:正式号码确定后改这里(或改为读配置项,避免改代码)
HOTLINE = "400-XXX-XXXX"
SERVICE_HOURS = "每日 7:00-22:00"
@@ -184,7 +185,7 @@ class CustomerServiceAgent(BaseAgent):
definition = AgentDefinition(
agent_type=AGENT_TYPE,
version="1.0.0",
allowed_roles=("customer",),
allowed_roles=("visitor", "customer"),
allowed_portals=("api",),
# 代码上限:实际可用范围由发布配置的意图白名单收窄(两者取交集)
allowed_tools=(TOOL_NAME, SUITABILITY_TOOL, PROFILE_TOOL_NAME),
@@ -192,9 +193,25 @@ class CustomerServiceAgent(BaseAgent):
INTENT_FAQ, INTENT_PRODUCT, INTENT_POLICY, INTENT_SUITABILITY,
INTENT_CHITCHAT, INTENT_TRANSFER,
),
# 客服不隐式召回长期画像;已登录用户的画像查询必须显式调用受控工具。
recalls_customer_memory=False,
)
def __init__(self, definition: AgentDefinition | None = None) -> None:
"""Use the class definition for direct tests and factory-created instances alike."""
super().__init__(definition or self.definition)
async def handle(self, request: AgentRequest, context: RequestContext) -> CoreResult:
# 先执行确定性的安全与权限边界路由;这些分支不查知识库、不调用模型,
# 从根上阻断账户敏感数据、凭据泄露、诈骗和代办交易等越界请求。
safety = route_message(request.message)
if safety is not None:
return CoreResult(
text=safety.reply,
intent=IntentResult(intent=safety.intent, confidence=1.0),
transfer_required=safety.transfer_required,
transfer_reason=safety.transfer_reason,
)
# 画像问题优先处理(确定性关键词,不走意图分类):知识库答不了"我的风险等级是多少",
# 那需要读该客户的画像数据,必须走 `query_customer_profile` 工具取权威字段。
# 放在意图分发**之前**是有意的:让画像能力不依赖意图分类是否恰好给出 faq。
@@ -508,6 +525,12 @@ class CustomerServiceAgent(BaseAgent):
# ---- 出口二:闲聊(提示词走发布配置) ----
async def _chitchat(self, request: AgentRequest) -> CoreResult:
# 连续闲聊超过三轮后只做一次自然的业务引导,避免模型无限延续闲聊。
if request.metadata.chitchat_streak == 4:
return CoreResult(
text="您好呀,您是想了解基金产品、申赎规则或其他公开业务信息吗?",
intent=self._classified_intent,
)
system, template = await self._chitchat_prompt()
message = request.message[:500]
try: