Files
group_xinghuo_jinrong/app/utils/compliance_guard.py
T
zhanghongyu_0626 b841f68295 feat(visitor): Implement visitor chat functionality and enhance customer service interactions
- Added a new visitor chat API endpoint (`/api/chat/visitor`) to allow unauthenticated users to engage in conversations without requiring customer data.
- Introduced a visitor context dependency to manage visitor interactions seamlessly.
- Enhanced the chat API to support explicit session termination and improved response handling for customer service interactions.
- Updated the database configuration to include Redis client support for caching visitor data.
- Added a new customer note repository to persist user notes independently of the L1 profile slots.

This update significantly improves the customer service experience by enabling visitor interactions and ensuring efficient data handling for both registered and unregistered users.
2026-09-09 18:32:00 +08:00

111 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""合规护栏:违禁词扫描 + 风险提示 + 兜底话术。"""
from __future__ import annotations
import re
# ---------------------------------------------------------------------------
# 违禁词正则库
# ---------------------------------------------------------------------------
FORBIDDEN_TERMS: tuple[re.Pattern, ...] = (
# 建议买卖(允许中间 0~3 字,如「建议您买入」「建议客户加仓」)
re.compile(r"建议.{0,3}(买入|卖出|买|卖|持有|加仓|减仓|清仓)"),
re.compile(r"推荐.{0,3}(购买|买入|卖出|定投)"),
re.compile(r"(保证|承诺).{0,4}(收益|保本|盈利|赚钱)"),
re.compile(r"(一定|肯定|必定).{0,4}(涨|赚|盈利)"),
re.compile(r"稳赚|包赚|躺赚|零风险|无风险"),
re.compile(r"保本保息|刚性兑付"),
)
# ---------------------------------------------------------------------------
# 标准话术
# ---------------------------------------------------------------------------
RISK_DISCLAIMER = (
"【风险提示】以上信息仅供参考,不构成投资建议。"
"产品的风险等级、费用与赎回到账时间以官方法律文件为准,投资有风险,入市需谨慎。"
)
COMPLIANCE_REJECT = (
"抱歉,我无法提供投资建议。如需专业咨询,请转接人工客服或登录后联系理财顾问。"
)
# ---------------------------------------------------------------------------
# 分类拒绝话术(直接拒绝,不转人工)
# ---------------------------------------------------------------------------
REJECT_ADVICE = (
"抱歉,我无法提供投资建议或推荐具体产品。"
"如需专业投资咨询,建议您登录后联系专属理财顾问,或前往营业网点面询。"
)
REJECT_ACCOUNT = (
"抱歉,游客模式下无法查询个人账户信息。"
"请登录后查看您的持仓详情,如未注册可前往APP完成开户。"
)
REJECT_PREDICT = (
"抱歉,我无法预测市场走势或产品涨跌。"
"任何声称可以预测涨跌的信息都不可信,投资有风险,入市需谨慎。"
)
REJECT_COMPARE = (
"抱歉,我无法进行平台或产品间的对比评价。"
"建议您参考各平台的官方信息,做出适合自己的判断。"
)
REJECT_REALTIME = (
"抱歉,游客模式下不支持实时行情查询。"
"如需查看实时行情,请登录后使用行情功能。"
)
REJECT_GENERAL = (
"抱歉,我无法回答这个问题。"
"您可以换一种方式描述,或浏览常见问答获取帮助。"
)
# ---------------------------------------------------------------------------
# 转人工话术(仅限投诉/复杂咨询/用户主动要求/安全问题)
# ---------------------------------------------------------------------------
TRANSFER_TEXT = (
"已为您安排转接人工客服。您也可以:\n"
"- 拨打客服热线 95XXX(工作日 9:00-18:00)\n"
"- 前往最近的营业网点办理\n\n"
"如需查询个人账户、持仓信息或获取个性化投资建议,"
"请登录后联系您的专属理财顾问。\n"
"(游客模式下我无法访问任何账户数据,也无法提供投资建议,敬请谅解。)"
)
FALLBACK_TEXT = (
"抱歉,我暂时无法回答这个问题。您可以:\n"
"1. 换一种方式描述您的问题\n"
"2. 浏览常见问答帮助中心\n"
"3. 拨打客服热线 95XXX\n"
'4. 回复"转人工"联系客服人员'
)
def scan_reply(reply: str) -> tuple[bool, list[str]]:
"""扫描回复是否命中违禁词,返回 (是否命中, 命中词列表)。"""
hits: list[str] = []
for pattern in FORBIDDEN_TERMS:
match = pattern.search(reply)
if match:
hits.append(match.group())
return (len(hits) > 0, hits)
def sanitize_reply(reply: str) -> tuple[str, bool]:
"""命中违禁词则替换为拒绝话术,返回 (safe_reply, need_transfer)。"""
has_forbidden, _ = scan_reply(reply)
if has_forbidden:
return COMPLIANCE_REJECT, True
return reply, False
def should_add_disclaimer(intent: str) -> bool:
"""咨询类意图需要附带风险提示。"""
return intent in ("product_consult", "policy_interpret", "faq")