Files
group_fqcd_jr/_flows/客服_智能客服Agent专项设计方案.html
T
lzf_0626 d2aff7c129 feat: 建客服知识库(Milvus 三集合)并修复模型端点筛选缺陷
一、知识库建设
- 新增 tools/build_knowledge_chunks.py:把 knowledge/ 下文档切成可检索知识块。
  采用「叶子标题」策略(其后没有更深标题的标题即切分点),同时覆盖三种真实结构:
  带子条款的按子条款切、无子条款的条款单独成块、无小节的章整章成块。
  第一版按固定标题级别切是失败的——适当性指南的条款是 ### 而没有 ####,产品手册的
  ### 1.1 又不匹配「第X条」,两条规则互相打架,导致 4 个文件一块都没切出来。
- 新增 tools/load_knowledge_milvus.py:向量化并写入 Milvus,用 upsert 保证幂等。
  schema 按方案 §4.2 统一字段,另加 chapter/section/source_file/doc_no/visibility 五个
  检索与合规必需字段;索引 IVF_FLAT + COSINE + nlist=128;向量输入取「标题+正文」,
  标题含条款号与章节名,是比正文更干净的检索信号。
- 知识内容按业务范围裁剪:反洗钱合规操作手册不入客服知识库(业务只做公募基金、
  不涉及资金划付,且该手册标注内部机密、禁止向客户透露可疑交易信息),留给后续风控;
  高净值客户服务规范只保留「客户分层标准」与「各层级专属权益」两章,
  家族信托、资产配置流程、客户经理考核、隐私应急预案等内部管理章节不入库。
- 入库现状:fin_faq_collection 61 块、fin_product_collection 26 块、
  fin_policy_collection 73 块,合计 160 块。检索自检 5/6——未命中的一条分数 0.660
  落在中置信区间,按三档兜底策略本应提示信息可能不完整,属于预期行为。

二、embedding 端点
- 新增 tools/configure_embedding_endpoint.py:走管理 API(draft→approved→active)
  配置并激活 qwen-embedding 端点,而不是直接写库。理由是状态机与审计都要留痕,
  且 DatabaseModelGateway 只认 status='active',手工写错状态会报成与病因无关的
  「模型端点未注册或未激活」。脚本先查 endpoint_code 是否已存在,幂等可重跑。

三、修复模型端点筛选缺陷(app/service/model_gateway.py)
- 原 DatabaseModelEndpointResolver 忽略 agent_type 与 task_type、直接返回全部 active
  端点,而 ModelDispatchService 只按顺序尝试前 max_attempts(默认 2)个。两者叠加使
  「能否选到支持该任务的端点」取决于端点表顺序:实测每次 embedding 都先拿文本生成
  端点失败一次再落到向量端点(0.61s,修复后 0.42s)。
- 新增 TASK_CAPABILITY 显式映射后按能力筛选。用映射而不是同名筛选是必需的:
  memory_extraction 并不是任何端点的能力名(deepseek 声明的是 text_generation 等),
  按同名筛会得到空集、把记忆抽取打成失败关闭——这是本次修复最容易引入的回归。
- 保守兜底:未映射的 task_type、以及没有任何端点声明该能力时,都退回全部端点,
  让配置缺口表现为调用失败,而不是让上层收到「解析为空」这种与病因无关的报错。
- 验证结果:embedding→[qwen-embedding]、intent_classification→[deepseek-flash]、
  memory_extraction→[deepseek-flash]、未映射 task_type→全部;ruff 通过、
  mypy 103 文件无错、unit+contract 447 passed。

四、需求文档提取物
- 新增 _flows/:三份流程文档(智能客服 Agent 专项设计方案、投资顾问流程、基金运营流程)
  的纯文本提取,供开发期对照。原始 .docx/.html 保留在业务方目录侧。

说明:本次仅本地提交,未推送远程仓库。knowledge/ 内含公司内部制度与产品资料,
是否入远程库待确认。
2026-09-10 20:15:09 +08:00

1664 lines
73 KiB
HTML
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.
智能客服Agent专项设计方案
目录
- 0. 文档说明与评审指引
- 0.1 定位与范围
- 0.2 依据文件(优先级从高到低)
- 0.3 合规基线速览(本文档反复引用)
- 0.4 评审关注点(读前提示)
- 1. 定位与设计目标
- 1.1 一句话定位
- 1.2 服务对象与边界
- 1.3 业务目标与度量指标
- 1.4 合规红线(客服 Agent 视角)
- 1.5 AI 接入前后的工作流程对比
- 2. 整体流程闭环
- 2.1 闭环流程图
- 2.2 七步拆解(与统一执行骨架对齐)
- 2.3 关键决策点:置信度与三档兜底
- 2.4 三集合路由代码与 Milvus 关键概念(带详细中文注释)
- 3. 细分流程(按意图类型)
- 3.0 意图体系总览(5 类)
- 3.1 账户与交易查询(持仓 / 收益 / 交易记录)
- 3.2 产品信息咨询(一般性介绍)
- 3.3 费率与收益计算
- 3.4 赎回与到账时效
- 3.5 投诉与情绪安抚
- 3.6 风险揭示与合规禁答
- 3.7 各意图数据流向图(汇总)
- 4. 知识库清单
- 4.1 三集合总览
- 4.2 字段结构(建议统一 schema)
- 4.3 更新频率与数据来源
- 4.4 知识运营机制
- 4.5 FAQ 示例(fin_faq_collection 内容样例)
- 5. 人工审核机制
- 5.1 转人工触发条件(分级)
- 5.2 事后复核与质检(兜底保障)
- 5.3 升级路径
- 5.4 国标对齐检查(《顾客联络服务 人工与智能客户服务协同要求》,2026-09-01 实施)
- 6. 回复策略
- 6.1 标准回复模板(分场景)
- 6.2 语气与措辞规范
- 6.3 必备风险提示与免责声明
- 6.4 拒答与兜底话术
- 6.5 负面词清单(7 个,零容忍)
- 7. 数据与状态流转 / 接口与异常
- 7.1 接口约定
- 7.2 会话状态机
- 7.3 异常处理表
- 8. 度量与验收(双轨评测)
- 9. 完善方向与最终交付要求
- 9.0 差距总览(一页速览)
- 9.1 功能完整性
- 9.2 用户体验
- 9.3 性能优化
- 9.4 错误处理
- 9.5 安全性
- 9.6 代码可读性
- 9.7 最终交付要求(上线门禁 Go/No-Go 清单)
- 10. 附录
- 10.1 参考来源清单
- 10.2 需核实项清单
文档:智能财富管家系统 · 智能客服 Agent 专项设计方案
版本:v1.3
日期:2026-09-07
状态:内部方案评审稿
智能客服 Agent 专项设计方案(内部评审稿)
0. 文档说明与评审指引
0.1 定位与范围
本文档是《智能财富管家系统-业务与技术全景设计说明书》中「智能客服 Agent」的深化专项设计,聚焦对外客户服务入口这一条链路(用户提问 → 意图识别 → 知识检索 → 答案生成 → 合规校验 → 人工转接 → 结果反馈),供内部方案评审使用。
范围边界:只覆盖智能客服 Agent(自然语言问答 / FAQ / 产品一般性介绍 / 政策解读 / 转人工)。投顾助手、风控监测、数据分析三个 Agent 不在本文档范围(详见全景说明书 §5.3/§5.4/§5.5)。
设计原则:所有结论都落到项目实际内容(意图、集合、阈值、表、接口),并对照主流平台真实落地做法标注来源;信息不确定处标注「需核实」,不做臆测。
0.2 依据文件(优先级从高到低)
优先级 |
文件 |
作用 |
1 |
需求文档-修改版.html |
需求基线:四大 Agent、合规定位(不代客交易)、分阶段需求、评分标准 |
2 |
统一执行骨架_七步模板方法与职责边界.html |
执行骨架权威:七步模板方法与基类/子类职责边界 |
3 |
功能设计文档.html(v1.5) |
意图体系、推理范式、工具清单(注意:其「业务操作 Agent / NL2API」已被修改版下线) |
4 |
智能财富管家系统-业务与技术全景设计说明书.md |
全景说明书:置信度阈值、三集合路由、数据表、架构 |
0.3 合规基线速览(本文档反复引用)
红线 |
要求 |
依据 |
不代客交易 |
AI 不得代替客户执行申购/赎回/转账,不触及资金与下单环节 |
需求文档-修改版合规定位 |
适当性 |
客户 C1-C5 ↔ 产品 R1-R5 匹配,取最严口径 |
全景说明书 A4 |
负面词 |
7 个零容忍:保本 / 稳赚 / 无风险 / 保证收益 / 预期收益率 / 年化收益率 / 安全 |
全景说明书 §14 |
免责声明 |
面向客户的输出末尾必须附固定话术 |
全景说明书 B3 |
留痕 |
客户沟通记录保存 ≥ 20 年 |
《证券基金经营机构信息技术管理办法》〔S15〕 |
0.4 评审关注点(读前提示)
- §2 闭环流程中「合规校验」是否应前置到「答案生成」之前(当前为生成后置校验 + 二次打回)。
- §3.3「费率与收益计算」的收益口径:字段名 expected_return,对外一律表述「业绩比较基准」并附测算依据,不得出现「预期收益率」。
- §5 转人工阈值(意图 0.6、RAG 混合判定)是否需按业务容忍度二次校准。
- §6 回复话术的「负面词 7 个」是否要扩充(如「零风险」「稳赚不赔」等变体)。
1. 定位与设计目标
1.1 一句话定位
智能客服 Agent 是系统的唯一对外自然语言入口,负责把「客户想问的」映射到「合规能答的」,答不了的果断转人工——价值在于 7×24 秒回标准问题,边界在于绝不越合规红线。
1.2 服务对象与边界
服务对象 |
可问范围 |
权限边界 |
游客(未登录) |
仅公开产品信息、一般性介绍 |
不涉及任何账户数据 |
零售客户 |
客服咨询、产品一般性介绍、政策解读、持仓查询、投资分析报告(带免责声明) |
仅本人资产与持仓 |
高净值客户 |
同上,且可触发「AI 初筛 + 投顾人工审核」闭环 |
仅本人数据 |
1.3 业务目标与度量指标
指标 |
目标值 |
度量来源 |
高频意图回答准确率 |
≥ 90% |
会话归档 + RAG 判定日志(对标天弘智能客服公开的 94%〔S6〕) |
首响时长 |
< 3 s |
埋点 |
转人工率 |
≤ 20% |
工单统计 |
违规话术次数 |
0(负面词后置校验拦截率 100%) |
后置校验日志 |
适当性违规 |
0 起 |
安全审计日志 |
1.4 合规红线(客服 Agent 视角)
客服 Agent 的职责是「信息提供」,因此它只读不写、只答不荐、只解释不下结论:
允许 |
不允许 |
产品一般性介绍、政策规则解读(适当性、反洗钱、销售办法) |
承诺收益、使用「保本/稳赚/安全/预期收益率」等违规表述 |
持仓/收益查询(本人数据) |
代客申购/赎回/转账 |
风险等级客观转述(R1-R5) |
主观评价「这个产品风险很低」 |
转人工引导 |
对低置信问题「硬答」 |
行业对标:华云天下提出的金融 AI 客服「十条铁律」首条即「不能承诺收益」——任何含「左右/大约/预期」的收益数字都不允许〔S13〕。招商基金总经理级口径强调「AI 不能代替信任、责任与人文关怀」〔S7〕,与本项目「不代客交易」定位同源。
1.5 AI 接入前后的工作流程对比
本节用两张流程对比图说明:AI 智能客服解决了什么问题、在哪些环节提升了效率。量化结论见 §1.3 度量指标。
1.5.1 未接入 AI 智能客服时的工作流程
flowchart TD
A[用户有问题] --> B[电话/邮件/线下网点求助]
B --> C[排队等待人工客服]
C --> D{人工客服在线?}
D -- 否(夜间/节假日) --> E[等到工作日再处理]
E --> C
D -- 是 --> F[人工逐条答疑口径依赖个人经验]
F --> G{能解决?}
G -- 是 --> H[解决 + 人工记录]
G -- 否 --> I[转资深客服/持证投顾]
I --> F
H --> J[人工汇总工单/报表易遗漏]
痛点:响应慢(排队 + 非工作时间无人值守)、口径不一致(靠个人经验)、重复劳动高、留痕靠人工易遗漏。
1.5.2 接入 AI 智能客服后的工作流程
flowchart TD
A[用户提问] --> B[AI 7×24 秒级响应]
B --> C{意图识别 + 置信度}
C -- 标准问题 --> D[三集合检索 → 秒回]
C -- 低置信/情绪/投诉 --> E[自动转人工携带完整上下文]
D --> F[合规校验负面词 + 免责声明]
F --> G[结果反馈 SSE]
E --> H[人工接管聚焦复杂问题]
G --> I[自动归档 + 脱敏留痕]
H --> I
1.5.3 两者对比(AI 解决了什么 / 在哪提升效率)
环节 |
未接入 AI 的痛点 |
接入 AI 后 |
效率提升 |
响应时效 |
排队等待、非工作时间无人 |
7×24 秒级响应标准问题 |
首响分钟级 → <3s |
标准问题 |
人工重复回答 |
FAQ 直返 / RAG 秒回 |
高频意图准确率 ≥90% |
口径一致性 |
各客服口径不一 |
统一话术 + 来源引用 |
违规话术 0 次 |
转人工 |
靠用户自己找入口 |
智能触发 + 上下文无缝传递 |
转人工率 ≤20%,且不复述 |
留痕与合规 |
人工整理、易遗漏 |
全量自动归档(脱敏) |
100% 留痕 ≥20 年 |
人力投入 |
大量重复劳动 |
人力聚焦复杂/高价值问题 |
释放约 40% 重复人力(对标天弘〔S6〕) |
2. 整体流程闭环
2.1 闭环流程图
flowchart TD
A[用户提问] --> B[① 输入接收与校验鉴权]
B --> B1{鉴权通过?}
B1 -- 否 --> B2[返回登录引导]
B1 -- 是 --> C[② 记忆召回读 Redis 短期会话]
C --> D[③ 意图路由qwen-turbo 分类·阈值0.6]
D --> D1{置信度>=0.6?}
D1 -- 否 --> D2[澄清提问]
D2 --> D3{仍无法识别?}
D3 -- 是 --> H[转人工]
D3 -- 否 --> D
D1 -- 是 --> E[④ 知识检索Milvus 三集合路由]
E --> F[⑤ 答案生成temperature 0.3 + 来源引用]
F --> G[⑥ 合规校验负面词后置 + 免责声明注入]
G --> G1{命中负面词?}
G1 -- 是 --> G2[打回重生成]
G2 --> G3{二次仍命中?}
G3 -- 是 --> G4[返回安全话术 + 告警]
G3 -- 否 --> F
G1 -- 否 --> I[⑦ 结果反馈 SSE 流式]
I --> J{需转人工?}
J -- 是 --> H
J -- 否 --> K[数据沉淀:写回会话+归档脱敏]
H --> K
K --> L[事件广播:命中敏感意图 publish suspicious_intent]
2.2 七步拆解(与统一执行骨架对齐)
步 |
名称 |
输入 → 输出 |
归属 |
① |
输入接收与校验鉴权 |
session_id/user_id/message → JWT 解析画像标签 |
基类 |
② |
记忆召回 |
读 Redis 会话(List,TTL 30min,最长 24h,超 4096 token 截断旧消息) |
基类 |
③ |
意图路由 |
消息 + 上下文 → 5 类意图 + 置信度(qwen-turbo,阈值 0.6) |
基类调用、子类给分类器 |
④ |
核心逻辑 |
意图 → Milvus 三集合检索 → 混合判定 |
子类唯一实现 |
⑤ |
结果生成 |
检索结果 → LLM 生成(temperature 0.3)+ 来源引用 + 负面词后置校验 + 免责声明注入 |
基类 |
⑥ |
数据沉淀 |
写回会话、归档(脱敏)、记录 tool_calls |
基类(强制) |
⑦ |
事件广播 |
命中转账/敏感意图 → publish event:suspicious_intent |
基类(强制) |
对齐说明:⑥⑦ 由基类强制,防止「某个 Agent 忘了归档/忘了广播」——这是合规留痕与跨 Agent 协作的结构性保障〔全景说明书 §8〕。
2.3 关键决策点:置信度与三档兜底
决策点 |
规则 |
结果 |
意图置信度 |
< 0.6 → 澄清提问;澄清后仍无法识别 → 转人工 |
不硬答 |
RAG 混合判定 |
绝对阈值 AND(相对间隙 OR 分布优势) |
三档:高/中/低 |
高置信 |
— |
直接回答 |
中置信 |
— |
回答 + 「以上信息可能不完整…」提示 |
低置信 |
— |
兜底话术 + 建议转人工 |
2.4 三集合路由代码与 Milvus 关键概念(带详细中文注释)
§2.1 的流程图里多次出现「Milvus 三集合路由」——这里给出对应工程模块(tool/milvus_tool.py,与本文档 §0.2 / §4.1 引用一致)的完整代码与逐行中文注释,方便评审时逐字段、逐分支核对。
阅读顺序:先看 2.4.1 概念与原理(建立直觉)→ 2.4.2 三级路由职责速查 → 2.4.3 Milvus 概念速查(扫盲)→ 2.4.4 完整代码(带注释的实现)→ 2.4.6 操作类查询规划。
2.4.1 三集合路由的概念与原理(先看懂,再看代码)
一句话定义:三集合路由 = 把知识库分成三个「书架」(FAQ / 产品 / 政策),用户每问一个问题,系统先判断「该去哪个/哪几个书架找」,再去对应书架里用「语义相似度」找出最相关的资料。
用一个图书馆的类比理解:
概念 |
图书馆类比 |
本项目 |
collection(集合) |
一个书架 |
fin_faq / fin_product / fin_policy |
路由(routing) |
图书管理员判断「去哪个书架找」 |
_step1_route_intent |
向量检索 |
按「内容像不像」找书,而非按书名精确匹配 |
_step2_search_in_collection |
重排 |
从几个书架找到的书里挑最好的几本 |
_step3_rerank_and_merge |
为什么需要「路由」而不是一个大集合:如果把 FAQ、产品、政策全塞进一个大集合,问「赎回费怎么算」时,可能把「反洗钱政策」也检索出来,干扰答案。分成三个集合 + 路由,等于先缩小查找范围,再精确定位——既快又准。
原理(三步走):
flowchart LR
A[用户问题] --> B[意图识别这是哪类问题?]
B --> C{路由决策去哪个集合}
C -- 高频问答 --> D1[fin_faq_collection]
C -- 产品咨询 --> D2[fin_product_collection]
C -- 政策解读 --> D3[fin_policy_collection]
D1 & D2 & D3 --> E[集合内向量检索找最相关的 topK 条]
E --> F[重排去重输出最终素材]
注意:这里的「路由」不是网络路由器(转发数据包),而是「按问题类型分发检索目标」的业务路由——两者同名,含义完全不同。
2.4.2 三级路由职责速查表
级别 |
名称 |
干啥的 |
代码位置 |
第一级 |
意图路由 |
决定「去哪个/哪几个集合」找资料 |
ThreeCollectionRouter._step1_route_intent |
第二级 |
集合内检索 |
在选定的集合里做「向量相似度」搜索,取 topK 条 |
ThreeCollectionRouter._step2_search_in_collection |
第三级 |
重排与融合 |
把多个集合的候选合并、去重、排序,输出最终素材 |
ThreeCollectionRouter._step3_rerank_and_merge |
「三集合路由」= 在三个 Milvus collection(fin_faq / fin_product / fin_policy)之间,按用户意图选集合,再在集合内做向量检索。写入路径另有 upsert_document(往集合里塞新数据/更新旧数据)。
2.4.3 Milvus 关键概念速查(给不熟悉 Milvus 的同学)
概念 |
一句话解释 |
在本项目对应 |
collection 集合 |
Milvus 的「表」,存一类数据 |
三个:fin_faq / fin_product / fin_policy |
field 字段 |
表里的列 |
id、content、embedding、effective_date 等 |
primary key 主键 |
唯一标识一条记录的字段 |
每个集合的 id 字段(VARCHAR,max=64) |
vector field 向量字段 |
专门存 embedding(文本的数学表示)的字段,类型 FLOAT_VECTOR |
每个集合的 embedding 字段,维度 VECTOR_DIM |
scalar field 标量字段 |
非向量的普通字段(VARCHAR/INT 等),可用于精确过滤 |
tags、product_code、effective_date、expire_date |
partition 分区 |
集合内部的「子文件夹」,可按维度划分,搜索时指定分区可大幅缩范围 |
产品集合按 product_type 分区(股票/混合/债券) |
segment 段 |
Milvus 内部把数据切成的小块(存盘+加载的单位),对使用者透明 |
Milvus 自动管理 |
index 索引 |
为向量字段建的「加速查找结构」,常见 IVF_FLAT、HNSW、DISKANN |
本项目用 IVF_FLAT(nlist=128) |
ANN |
Approximate Nearest Neighbor 近似最近邻——速度极快、不要求 100% 精确 |
搜索的本质目标 |
topK |
返回相似度最高的 K 条记录 |
FAQ 取 3、其余取 5 |
metric_type 距离度量 |
向量之间「像不像」的衡量方式 |
COSINE 余弦相似度(最常用,忽略长度只看方向) |
hybrid search 混合检索 |
向量检索 + 标量过滤(如过期过滤) |
用 expr 参数实现 |
load() |
把集合从磁盘加载到内存(不加载不能搜,Milvus 是「磁盘省钱、内存才快」) |
初始化时调用一次 |
upsert |
插入或更新(Milvus 用 upsert,不用 insert+update) |
写入路径统一用 upsert |
flush |
把内存里的数据真正落盘+建索引(较重,高频写可批量) |
写入后调用 |
2.4.4 完整代码(带详细中文注释)
下面的代码可直接保存为 tool/milvus_tool.py。每一行 # 后的中文注释都对不熟悉 Milvus / RAG 的读者做了通俗解释。
# -*- coding: utf-8 -*-
"""
milvus_tool.py
==============
智能客服 Agent 的「三集合路由」核心模块。
【三集合路由的定义和作用】
智能客服 Agent 回答用户问题时,需要先在「知识库」里找到相关资料。
我们的知识库分成了三个独立的 Milvus 集合(你可以理解为三张表),
分别存放不同类型的资料:
1. fin_faq_collection —— 高频操作类问答(如「怎么重置密码」)
2. fin_product_collection —— 产品说明书、费率、风险等级
3. fin_policy_collection —— 监管法规、适当性规则、销售办法
为什么要分三个?
- 不同类型资料的「更新频率」不同(FAQ 周更,政策即时更新)
- 不同意图需要「检索不同的内容」(问政策就不该去产品表里找)
- 权限/审计可以按集合隔离
【三级路由的协作流程】
用户提问 → 意图分类器判定意图 →
第一级(意图路由)→ 决定去哪些集合 →
第二级(集合内检索)→ 每个集合内做向量相似度搜索 →
第三级(重排与融合)→ 合并多集合候选 → 输出最终 topK
写入路径(更新/新增知识):upsert_document() → 写入对应 collection
"""
from __future__ import annotations # 让类型注解在 Python 3.9 之前也能用
import time # 用 time.strftime 取当前日期
import hashlib # 用 md5 做内容指纹(去重用)
from typing import List, Dict, Any, Optional # 类型注解,让代码可读性更强
from dataclasses import dataclass # 用装饰器快速定义「数据类」(只装数据的简单类)
# 下面这行是 pymilvus 的官方 SDK(Milvus 团队维护的 Python 客户端)。
# 如果项目里还没装,请先:pip install pymilvus
from pymilvus import (
connections, # 用来连 Milvus 服务(建立网络连接)
Collection, # 集合对象 = 指向 Milvus 某张「表」的引用
CollectionSchema, # 集合的「表结构」= 字段列表
FieldSchema, # 单个字段的「列定义」
DataType, # 字段类型枚举:VARCHAR / FLOAT_VECTOR / INT64 ...
utility, # 工具函数:判断 collection 是否存在、查版本等
)
# ============================================================
# 一、常量区:把会变的配置集中起来(单一真相源)
# ============================================================
# 「单一真相源」= 全项目只有这一处定义这个值,避免散落各处导致改一处忘改另一处。
# 比如你想把端口换了,只改这里就行。
# Milvus 服务器地址。本地开发用 standalone,集群用 cluster 地址。
MILVUS_HOST = "127.0.0.1"
MILVUS_PORT = "19530"
# 三个集合的名字(= 三张「表」)。改这里就够了,不要在代码里到处写字符串字面量。
FAQ_COLLECTION = "fin_faq_collection"
PRODUCT_COLLECTION = "fin_product_collection"
POLICY_COLLECTION = "fin_policy_collection"
ALL_COLLECTION_NAMES = [FAQ_COLLECTION, PRODUCT_COLLECTION, POLICY_COLLECTION]
# 意图 → 集合 的映射关系(= 「第一级路由」的配置表)
# 含义:用户问的是这个意图时,去这几个集合里找资料。
# 用列表而不是单个字符串,是允许「一个意图跨多个集合」的灵活设计。
INTENT_TO_COLLECTIONS: Dict[str, List[str]] = {
"faq": [FAQ_COLLECTION], # 高频问题只在 FAQ 表
"product_inquiry": [PRODUCT_COLLECTION], # 产品咨询去产品表
"policy_explain": [POLICY_COLLECTION], # 政策解读去政策表
"chitchat": [], # 闲聊不去任何表(走 LLM 自由生成)
"transfer_human": [], # 转人工也不查表
# 兜底:意图分类没把握时,三个集合都查,取并集后再重排
"low_confidence": [FAQ_COLLECTION, PRODUCT_COLLECTION, POLICY_COLLECTION],
}
# 每个集合检索时取 topK 条候选。TopK 越大召回越全但越慢。
COLLECTION_TOPK: Dict[str, int] = {
FAQ_COLLECTION: 3, # FAQ 是「一问一答」标准答案,取 3 条够用
PRODUCT_COLLECTION: 5, # 产品信息需要更多候选让 LLM 选
POLICY_COLLECTION: 5, # 政策条款同理
}
# 向量维度。要和 embedding 模型输出一致(如 Qwen Embedding 通常 1024 或 1536 维)。
# 「维度」= 一个向量有多少个数字。文本越长不一定维度越高,是模型决定的。
VECTOR_DIM = 1024
# 向量距离度量。COSINE = 余弦相似度(最常用,忽略向量长度只看方向)。
# 选 COSINE 而不是 L2(欧氏距离),因为我们关心「语义方向」而不是「距离绝对值」。
METRIC_TYPE = "COSINE"
# ============================================================
# 二、三个集合的「表结构」定义(schema)
# ============================================================
# Milvus 的 schema 就像建表语句:定义有哪些字段、各自什么类型。
# 用工厂函数(返回对象的函数)生成,方便统一管理 + 后续扩展。
def build_faq_schema() -> CollectionSchema:
"""FAQ 集合的表结构:高频问答。"""
fields = [
# 主键:用 md5(question) 做主键,保证同一问题只有一条记录
FieldSchema("id", DataType.VARCHAR, max_length=64, is_primary=True),
FieldSchema("question", DataType.VARCHAR, max_length=512), # 标准问法
FieldSchema("answer", DataType.VARCHAR, max_length=2048), # 标准答案
FieldSchema("tags", DataType.VARCHAR, max_length=256), # 标签,JSON 字符串
FieldSchema("effective_date",DataType.VARCHAR, max_length=32), # 生效日期 "2026-01-01"
FieldSchema("expire_date", DataType.VARCHAR, max_length=32), # 失效日期,空=长期有效
# 向量字段:把 question 文本转成 embedding 存进来
FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=VECTOR_DIM),
]
# description 给这个集合写个说明,方便在 Milvus 管理界面(Attu)里辨认
return CollectionSchema(fields, description="FAQ 集合:高频操作类问答")
def build_product_schema() -> CollectionSchema:
"""产品集合的表结构:产品说明书/费率/风险等级。"""
fields = [
FieldSchema("id", DataType.VARCHAR, max_length=64, is_primary=True),
FieldSchema("product_code", DataType.VARCHAR, max_length=32), # 产品代码,如 "000001"
FieldSchema("product_name", DataType.VARCHAR, max_length=128),
FieldSchema("product_type", DataType.VARCHAR, max_length=32), # 股票/混合/债券
FieldSchema("risk_level", DataType.VARCHAR, max_length=8), # R1-R5
FieldSchema("content", DataType.VARCHAR, max_length=4096), # 文档片段原文
FieldSchema("source_url", DataType.VARCHAR, max_length=512),
FieldSchema("effective_date", DataType.VARCHAR, max_length=32),
FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=VECTOR_DIM),
]
return CollectionSchema(fields, description="产品集合:产品说明书/费率/风险")
def build_policy_schema() -> CollectionSchema:
"""政策集合的表结构:监管法规/适当性/销售办法。"""
fields = [
FieldSchema("id", DataType.VARCHAR, max_length=64, is_primary=True),
FieldSchema("doc_id", DataType.VARCHAR, max_length=64), # 法规文号,如 "银发2016261号"
FieldSchema("title", DataType.VARCHAR, max_length=256),
FieldSchema("content", DataType.VARCHAR, max_length=4096),
FieldSchema("issuing_org", DataType.VARCHAR, max_length=64), # 发文机构:银保监会 / 证监会 ...
FieldSchema("effective_date", DataType.VARCHAR, max_length=32),
FieldSchema("embedding", DataType.FLOAT_VECTOR, dim=VECTOR_DIM),
]
return CollectionSchema(fields, description="政策集合:监管法规/适当性/销售办法")
# schema 字典:集合名 → schema 工厂函数
SCHEMA_FACTORIES: Dict[str, Any] = {
FAQ_COLLECTION: build_faq_schema,
PRODUCT_COLLECTION: build_product_schema,
POLICY_COLLECTION: build_policy_schema,
}
# ============================================================
# 三、检索结果的数据类(让返回值有结构,方便后续处理)
# ============================================================
# @dataclass 装饰器自动生成 __init__ / __repr__ / __eq__ 等方法,代码更短。
@dataclass
class Hit:
"""单条检索命中结果。相当于「一行记录」+「相似度分」。"""
collection: str # 来自哪个集合
doc_id: str # 该集合内的主键
score: float # 相似度分(越大越像;范围约 0~1)
content: str # 文本内容(问题/答案/产品/政策原文)
metadata: Dict[str, Any] # 其他元数据(tags、product_code、raw_distance 等)
@dataclass
class RoutePlan:
"""第一级路由的输出:决定去哪些集合、每个取多少条。"""
target_collections: List[str] # 要去查的集合名列表
per_collection_topk: Dict[str, int] # 每个集合分别取 topK
# ============================================================
# 四、三集合路由器(核心类)
# ============================================================
class ThreeCollectionRouter:
"""
三集合路由器的核心类。
一个实例 = 一个 Milvus 客户端连接。
设计要点:复用连接、缓存 collection 句柄,避免每次检索都重新建连。
"""
def __init__(self, host: str = MILVUS_HOST, port: str = MILVUS_PORT):
# 1. 连 Milvus 服务
self._connect(host, port)
# 2. 懒加载:集合句柄按需获取(用 self.get_collection(name) 时才建),
# 避免启动时全部加载占内存。
# 「懒加载」= 用到时再加载,不用时不加载。
self._collection_cache: Dict[str, Collection] = {}
# ---------- 连接与初始化 ----------
def _connect(self, host: str, port: str) -> None:
"""连 Milvus 服务。alias='default' 是默认连接名,后面 Collection 用默认连接。"""
connections.connect(alias="default", host=host, port=port)
# 用一个轻量调用确认连接成功(get_server_version() 返回类似 "v2.4.x")
if not utility.get_server_version():
# 抛异常而不是静默失败,让上层知道出问题了
raise RuntimeError(f"无法连接 Milvus 服务 {host}:{port}")
def get_collection(self, name: str) -> Collection:
"""
获取一个集合的句柄(带缓存)。
Collection 对象 = 指向 Milvus 某张「表」的引用,搜索/写入都要用它。
缓存的好处:第二次拿同一集合不用重新查 Milvus,省一次 RPC。
"""
# 第一步:先看缓存里有没有
if name not in self._collection_cache:
# 第二步:缓存里没有,检查 Milvus 里有没有这个集合
if not utility.has_collection(name):
# 都没有 → 首次启动,自动建表
self._create_collection(name)
# 第三步:拿句柄
coll = Collection(name)
# 第四步:load() 把集合从磁盘加载到内存,否则搜索会报「collection not loaded」
# Milvus 是「磁盘省钱、内存才快」的设计,不 load 就搜不了
coll.load()
# 放进缓存,下次直接拿
self._collection_cache[name] = coll
return self._collection_cache[name]
def _create_collection(self, name: str) -> None:
"""首次启动时创建集合(建表 + 建索引)。"""
# 用 schema 工厂拿表结构定义
schema = SCHEMA_FACTORIES[name]()
# 创建集合:参数 = 名字 + 表结构
Collection(name, schema=schema)
# 为向量字段建索引。
# IVF_FLAT:常用索引,简单稳;HNSW 更精确但费内存;DISKANN 大数据量省钱。
coll = Collection(name)
coll.create_index(
field_name="embedding", # 给哪个字段建索引
index_params={
"metric_type": METRIC_TYPE, # 用余弦相似度(前面常量区定义的)
"index_type": "IVF_FLAT",
# nlist:聚类中心数。越大越精确但越慢;128 是常用起点
"params": {"nlist": 128},
},
)
# ---------- 写入路径:往集合里塞一条新数据 / 更新旧数据 ----------
def upsert_document(
self,
collection_name: str,
doc_id: str,
text: str,
embedding: List[float],
extra_fields: Optional[Dict[str, Any]] = None,
) -> None:
"""
写入或更新一条文档。
调用时机:运营上传新知识、费率变更、政策更新时。
参数:
collection_name: 写入哪个集合(faq / product / policy)
doc_id: 主键(自己生成,md5 或雪花 ID 都行)
text: 文本内容
embedding: text 转成的向量(调用 embedding 模型得到)
extra_fields: 其他字段(product_code、effective_date 等)
"""
coll = self.get_collection(collection_name)
# 拼装一行数据。Milvus 要求:字段顺序和 schema 一致,且值都是列表(支持批量)。
row = {
"id": [doc_id],
"content": [text], # 简化:假设 schema 都有 content 字段
"embedding": [embedding],
}
# 把额外字段补进去(如果 schema 里有)
if extra_fields:
for k, v in extra_fields.items():
row[k] = [v]
# upsert:存在则更新、不存在则插入(Milvus 用 upsert 统一两种操作)
coll.upsert(row)
# 写完刷一下:让数据立即可见、开始建索引。
# flush 较重(要写盘),高频写入场景可以用 flush_buffer 批量刷
coll.flush()
# ---------- 读取路径:三集合路由的核心(对外入口) ----------
def query(
self,
intent: str,
query_text: str,
query_embedding: List[float],
user_id: Optional[int] = None,
partition_name: Optional[str] = None,
) -> List[Hit]:
"""
三级路由的对外入口——客服 Agent 每次问问题,都会调这个函数。
参数:
intent: 意图分类的结果("faq" / "product_inquiry" / "policy_explain" / "low_confidence")
query_text: 用户的原始问题(中文)
query_embedding: query_text 经 embedding 模型转成的向量(长度 = VECTOR_DIM)
user_id: 当前用户 ID(用于权限过滤,例如只让看本人产品)
partition_name: 可选——只查某个分区的数据(产品集合可按 product_type 分区)
返回:经过三级路由后的候选结果列表(已重排)
"""
# ============ 第一级:意图路由 → 决定去哪些集合 ============
route_plan = self._step1_route_intent(intent, query_text)
# 如果第一级判定不需要查表(闲聊/转人工),直接返回空,让上层走别的逻辑
if not route_plan.target_collections:
return []
# ============ 第二级:集合内检索(多集合可并行)============
# 多个集合之间没有依赖关系,可以并行查。这里用 for 串行演示;真实环境用线程池/异步并行。
per_collection_hits: Dict[str, List[Hit]] = {}
for coll_name in route_plan.target_collections:
# 每个集合的 topK 从 route_plan 里取
topk = route_plan.per_collection_topk.get(coll_name, 3)
hits = self._step2_search_in_collection(
coll_name=coll_name,
query_embedding=query_embedding,
top_k=topk,
user_id=user_id,
partition_name=partition_name,
)
per_collection_hits[coll_name] = hits
# ============ 第三级:重排与融合 → 输出最终 topK ============
final_hits = self._step3_rerank_and_merge(
per_collection_hits=per_collection_hits,
query_text=query_text,
)
return final_hits
# ---------- 第一级:意图路由 ----------
def _step1_route_intent(self, intent: str, query_text: str) -> RoutePlan:
"""
第一级路由:决定去哪些集合、每个集合取多少条。
决策逻辑:
1. 查 INTENT_TO_COLLECTIONS 配置,看该意图默认对应哪些集合
2. 如果意图不在配置里 → 走兜底:三个集合都查
"""
# 默认配置里的目标集合列表
targets = INTENT_TO_COLLECTIONS.get(intent)
# 没找到意图配置 → 兜底:全集合都查
if targets is None:
# list() 是为了拷贝一份,避免后面修改时改了常量
targets = list(ALL_COLLECTION_NAMES)
# 构造每个集合的 topK 配置
per_topk: Dict[str, int] = {}
for name in targets:
# 用 COLLECTION_TOPK 配置表查每个集合的 topK,找不到默认 3
per_topk[name] = COLLECTION_TOPK.get(name, 3)
return RoutePlan(target_collections=targets, per_collection_topk=per_topk)
# ---------- 第二级:集合内检索 ----------
def _step2_search_in_collection(
self,
coll_name: str,
query_embedding: List[float],
top_k: int,
user_id: Optional[int],
partition_name: Optional[str] = None,
) -> List[Hit]:
"""
第二级路由:在某一个集合内做「向量相似度检索」。
流程:
1. 构造过滤表达式(标量过滤,比如「未过期」+「本人可见」)
2. 用 embedding 向量在该集合内搜 topK(向量化最近邻)
3. 把 Milvus 返回的原始结果转成 Hit 对象
"""
coll = self.get_collection(coll_name)
# 构造标量过滤条件(标量 = 非向量字段)。
# 语法类似 SQL 的 WHERE 条件。含义:expire_date 为空 OR expire_date > 今天
today = time.strftime("%Y-%m-%d")
expr = f'expire_date == "" OR expire_date > "{today}"'
# 产品集合再加权限过滤(简化示意:实际应该是 OR 公开产品 OR user_id 匹配)
if coll_name == PRODUCT_COLLECTION and user_id is not None:
expr += f' OR user_id == "{user_id}"'
# 向量搜索参数:
# nprobe:搜索时探查的聚类数,越大越精确但越慢
search_params = {"metric_type": METRIC_TYPE, "params": {"nprobe": 16}}
# 准备 partition_names 参数(如果指定了 partition)
# 搜索时指定 partition 可以大幅缩范围、提速
search_kwargs: Dict[str, Any] = {
"data": [query_embedding], # 查询向量,外层是列表因为支持一次查多个
"anns_field": "embedding", # 用哪个向量字段做相似度
"param": search_params, # 搜索参数
"limit": top_k, # topK
"expr": expr, # 标量过滤条件
"output_fields": ["id", "content"], # 这些标量字段也一起返回
}
if partition_name:
# 如果传了分区名,只在该分区内搜(产品集合可按 product_type 分区)
search_kwargs["partition_names"] = [partition_name]
# 执行搜索(anns_field = Approximate Nearest Neighbor Search field)
results = coll.search(**search_kwargs)
# 解析结果。results 是 [[Hit1, Hit2, ...]],外层列表是因为可以一次查多个 query
hits: List[Hit] = []
for query_hits in results:
for h in query_hits:
# h.distance 是距离(越小越像)。
# 余弦距离 = 1 - 余弦相似度,所以 score = 1 - distance
# 我们把 score 统一成「越大越像」,方便后续按相似度排序
score = 1.0 - h.distance
hits.append(Hit(
collection=coll_name,
doc_id=h.id, # 命中记录的主键
score=score, # 相似度分(0~1)
content=h.entity.get("content", ""), # 命中的文本内容
metadata={"raw_distance": h.distance}, # 保留原始距离方便排查
))
return hits
# ---------- 第三级:重排与融合 ----------
def _step3_rerank_and_merge(
self,
per_collection_hits: Dict[str, List[Hit]],
query_text: str,
) -> List[Hit]:
"""
第三级路由:把多个集合的结果合并、重排、去重。
策略:
1. 把所有集合的 hits 合并到一个列表
2. 按 score 降序排(相似度高的排前面)
3. 简单去重:内容前 100 字相同的视为重复
4. 截断到最终 topK(这里固定 5,可改为参数)
进阶:可以接 rerank 模型(如 bge-reranker)做精排,这里简化。
"""
# 1. 合并:把所有集合的 hits 展平成一个列表
all_hits: List[Hit] = []
for hits in per_collection_hits.values():
all_hits.extend(hits)
# 2. 按相似度分数降序排(lambda h: h.score 意思是「取 h 的 score 作为排序键」)
all_hits.sort(key=lambda h: h.score, reverse=True)
# 3. 去重(用内容前 100 字符的 md5 做指纹)
# 为什么要去重?因为同一个答案可能在 FAQ 和产品集合里都出现(比如关于费率的说明)
seen: set = set()
deduped: List[Hit] = []
for h in all_hits:
# md5(内容前100字符) → 32 位字符串指纹
fingerprint = hashlib.md5(h.content[:100].encode("utf-8")).hexdigest()
if fingerprint in seen:
continue # 见过这个指纹了,跳过
seen.add(fingerprint)
deduped.append(h)
# 4. 截断到最终 topK(这里固定 5,可改为参数或按业务调整)
return deduped[:5]
# ============================================================
# 五、demo:怎么用
# ============================================================
# 下面是「怎么调用路由器」的最小示例。
# 真实 Agent 里:query_text 先送意图分类器(拿到 intent),再送 embedding 模型(拿到 vector),
# 然后调 router.query(...) 拿到候选 hits。
if __name__ == "__main__":
# 1. 初始化路由器(自动连 Milvus、自动建表、自动 load)
router = ThreeCollectionRouter()
# 2. 模拟一次用户提问
intent = "policy_explain" # 假设意图分类器说这是「政策解读」
query_text = "什么叫冷静期?" # 用户原话
# 真实场景:query_embedding = embedding_model.encode(query_text)
# 这里用全 0 占位(真实项目必须用真实 embedding,否则相似度全为 0)
query_embedding = [0.0] * VECTOR_DIM
# 3. 三级路由检索
hits = router.query(
intent=intent,
query_text=query_text,
query_embedding=query_embedding,
user_id=10001, # 当前用户 ID(用于权限过滤)
# partition_name="股票型", # 可选:只查「股票型」分区
)
# 4. 打印结果
for i, h in enumerate(hits, 1):
print(f"[{i}] 集合={h.collection} 分数={h.score:.3f}")
print(f" 内容: {h.content[:80]}...")
print()
2.4.5 三级路由协作时序(一句话总结)
用户提问 ──► 意图分类 ──► 第一级(去哪个集合)
──► 第二级(在集合里找 topK)
──► 第三级(合并去重排序)
──► 交给 LLM 生成最终回复
写入路径(与读取路径独立):upsert_document() 在运营/系统需要更新知识时调用,往指定 collection 塞一条或更新一条;不参与用户问问题的实时链路。
2.4.6 操作类查询的现状与实施规划(客户端未完成,暂缓)
本节回应一个常见疑问:为什么现在只有三个「知识类」集合,没有「操作类」(账户/持仓/交易查询)的向量库?
关键澄清:知识类 vs 操作类
类型 |
问的是 |
数据来源 |
是否依赖客户端 |
现在能做吗 |
知识类(当前三集合) |
「赎回费怎么算」「适当性规则是什么」 |
文档(说明书/法规/FAQ) |
否(文档已有) |
✅ 现在就能做 |
操作类(账户/持仓/交易查询) |
「我的持仓有哪些」「这笔交易到账了吗」 |
客户真实账户数据(账户系统) |
是(需客户端 + 账户系统产生数据) |
❌ 暂缓 |
为什么操作类暂缓:操作类查询需要「客户真实账户数据」,而这些数据由客户端(前端)+ 账户系统在真实业务运行中产生。客户端尚未开发完成,账户数据还不存在,因此现在无法实现操作类查询。
重要修正——操作类本质不是「向量库」:账户/持仓/交易查询是「精确查询」(查"我"的具体持仓、具体流水),应当通过 API 直连账户系统实现,而不是用向量库做「语义模糊检索」。向量库只服务于「答案散落在文档里的知识问答」。因此:
- 知识类(FAQ/产品/政策)→ 用 Milvus 向量库(本项目三集合)
- 操作类(账户/持仓/交易)→ 用账户系统 API 精确查询(待客户端完成后接入)
分阶段规划:
阶段 |
前置条件 |
实施内容 |
Phase 1(当前) |
仅需文档(已具备) |
知识类三集合路由(FAQ/产品/政策)+ RAG 问答 |
Phase 2(客户端完成后) |
客户端 + 账户系统 + 真实账户数据 |
接入操作类查询:账户/持仓/交易记录 API,与知识类问答打通(如「我的 XX 基金盈亏」→ API 查数) |
Phase 3(可选,视需求) |
操作类 API 稳定后 |
若出现「操作指引类」高频问题(如"如何修改定投"),可沉淀进 FAQ 知识类集合,不必新建操作类向量库 |
对 §3.1 账户与交易查询的影响:§3.1 将该场景列入 6 条业务路径,但当前其「可答范围」需标注为「Phase 2 待实现」——现阶段用户问账户问题,客服应引导转人工或说明「该功能即将上线」。
3. 细分流程(按意图类型)
3.0 意图体系总览(5 类)
意图 |
集合 |
TopK |
处理方式 |
product_inquiry 产品信息咨询 |
fin_product_collection |
5 |
RAG + LLM 生成 + 来源引用 |
policy_explain 政策解读 |
fin_policy_collection |
5 |
RAG + 解释 |
faq 常见问题 |
fin_faq_collection |
3 |
检索直返标准答案 |
chitchat 闲聊 |
— |
LLM 引导业务话题 |
transfer_human 转人工 |
— |
转接消息 + 生成转接工单 |
本方案将 5 类「技术意图」按业务场景细分为 6 条处理路径(§3.1-§3.6),便于评审时逐条核对;faq/product_inquiry/policy_explain 是检索主路径,chitchat/transfer_human 是控制路径。
3.1 账户与交易查询(持仓 / 收益 / 交易记录)
维度 |
内容 |
判定条件 |
命中「持仓、收益、交易记录、份额、到账」等实体 + 本人数据查询意图 |
可答范围 |
本人持仓明细、收益概览、在途交易、历史交易记录(只读) |
禁答范围 |
他人账户数据;未完成身份验证时的账户信息 |
处理路径 |
鉴权 → JWT 画像标签 → 只读查询 → 脱敏输出(mask_tool)→ 回复 |
转人工条件 |
涉及账户异常、冻结、司法冻结、到账失败、无法自助解释的账务问题 |
合规要点 |
完整敏感字段(卡号/身份证号)不回显,仅显示掩码;查询前必须完成身份验证〔S16〕 |
⚠️ 实施状态:本场景属「操作类」查询,依赖客户端 + 账户系统产生真实账户数据,当前为 Phase 2 待实现(客户端尚未完成)。现阶段用户问账户问题,客服应引导转人工或说明「该功能即将上线」。详见 §2.4.6。
参考做法:天天基金智能客服对「什么时候能看到基金份额」这类账务问题,直接给出「T+1 工作日确认,[我的]→持仓查看,未确认的在[在途交易]查看」的标准流程答案〔S3〕。富途帮助中心以「我的 > 我的客服 > 全部问题搜索 → 仍未解决再转电话/在线」的三步式自助+兜底〔S8〕。
3.2 产品信息咨询(一般性介绍)
维度 |
内容 |
判定条件 |
命中基金名称/代码 + 「是什么、怎么样、投资方向、基金经理、规模」等介绍类问法 |
可答范围 |
产品要素客观转述(类型、投资范围、风险等级 R1-R5、费率结构、开放状态) |
禁答范围 |
「这只基金适不适合我」「值不值得买」等个性化推荐(应转投顾流程,客服不越界) |
处理路径 |
意图 product_inquiry → 检索 fin_product_collection → 生成 + 来源引用 |
转人工条件 |
用户追问「该买哪个」「给我推荐」→ 引导至风险测评 + 转投顾/人工 |
合规要点 |
风险等级只做客观转述,不做「风险很低」主观评价〔S13 铁律三〕 |
参考做法:招商基金智能客服对「基金下跌怎么办」分析净值下跌 4 个原因(市场变化、分红、折算、转型)并提示异常可查公告〔S6〕——只解释现象、不给结论,与本项目「只答不荐」一致。华夏基金「机智小牛智能体」主打「会倾听、能共情、懂陪伴」,同样止步于陪伴与解答〔S7〕。
3.3 费率与收益计算
维度 |
内容 |
判定条件 |
命中「费率、手续费、申购费、赎回费、管理费、收益、赚多少、年化」等计算类问法 |
可答范围 |
费率结构与计算规则(申购/赎回/管理费率、前端/后端收费)、业绩比较基准及测算依据 |
禁答范围 |
任何收益数字承诺(含「左右/大约/预期」);「预期收益率/年化收益率」表述 |
处理路径 |
费率计算器(三维计算模型)→ 客观输出费率;收益类 → 检索产品文档 + 附「业绩比较基准 + 过往业绩不代表未来表现」 |
转人工条件 |
用户要求测算「到期能拿回多少钱」等个性化金额 → 转投顾(需画像与风评) |
合规要点 |
字段 expected_return 对外一律称「业绩比较基准」;提及收益必附风险提示〔S16〕 |
参考做法:百度智能云证券基金方案内置「申购费/赎回费/管理费三维费率计算器,支持前端/后端收费切换」〔S15〕。华云天下铁律一给出的标准应答为「根据产品说明书,该产品的业绩比较基准为 XX%。过往业绩不代表未来表现,投资有风险,请您仔细阅读产品说明书」〔S13〕——本项目固定免责话术与之同构。
3.4 赎回与到账时效
维度 |
内容 |
判定条件 |
命中「赎回、卖出、到账、多久到账、T+N」等时效类问法 |
可答范围 |
分类型到账时效规则(货币/债券/混合/股票/QDII)、T+N 确认规则 |
禁答范围 |
承诺「最快几秒/当天必到」等确定性时效(实际以产品为准) |
处理路径 |
意图 faq → 检索 fin_faq_collection → 直返标准答案 + 「具体以产品为准」 |
转人工条件 |
用户到账异常、超时未到账、金额不符 → 转人工核查 |
合规要点 |
时效表述必须带「具体以产品为准」,不做绝对承诺 |
参考做法:天天基金「基金吧答疑」对「基金赎回多久到账」给出分类型标准答案:货币 1-2 工作日、债券 2-4、混合/股票 2-4、QDII 4-13 工作日(具体以产品为准)〔S3〕。这正是本项目 fin_faq_collection 标准答案的组织范式——高频规则类问题固化为标准话术直返。
3.5 投诉与情绪安抚
维度 |
内容 |
判定条件 |
命中「投诉、差评、举报、生气、不满意」等情绪/投诉词,或情绪识别触发 |
可答范围 |
情绪共情 + 投诉渠道引导 + 受理承诺 |
禁答范围 |
对纠纷事实自行定性、承诺赔偿/退款(必须人工确认) |
处理路径 |
情绪识别 → 共情话术 → 生成投诉工单 → 自动转人工 |
转人工条件 |
情绪激烈、涉及投诉/纠纷/资金争议 → 无条件转人工 |
合规要点 |
涉及退款/赔偿/合同变更,AI 只解释规则、收集材料、生成工单,最终确认由人工或规范化流程完成〔S11〕 |
参考做法:捷通华声明确「涉及投诉/纠纷关键词」纳入转人工触发条件,「宁可早转,不可硬撑」〔S14〕。国标《顾客联络服务 人工与智能客户服务协同要求》明确「感知到客户负面情绪…系统应自动转接人工」〔S11〕。
3.6 风险揭示与合规禁答
维度 |
内容 |
判定条件 |
命中「保本、稳赚、零风险、绝对安全、保证收益、预期收益率」等违规词,或监管敏感问题 |
可答范围 |
风险揭示话术(非保本浮动收益、可能损失本金)、引导阅读产品说明书 |
禁答范围 |
任何合规禁答内容(见 §6.5 负面词清单) |
处理路径 |
负面词后置校验命中 → 打回重生成;二次仍命中 → 返回安全话术 + 告警 |
转人工条件 |
监管敏感问题(如「有没有内部消息」「能不能代持」)→ 转合规/法务 |
合规要点 |
命中负面词零容忍;告警留痕备查 |
参考做法:华云天下铁律四标准应答「理财产品是非保本浮动收益产品,您的本金和收益可能会因市场波动而产生损失」〔S13〕。蚂蚁财富《智能理财助理服务协议》明确「输出可能出现错误或遗漏…不构成投资建议/推介/要约」〔S1〕——本项目的免责声明与「AI 生成内容风险提示」双保险与此对齐。
3.7 各意图数据流向图(汇总)
下图把 §3.1-§3.6 的六类业务场景,映射回 §3.0 的五类技术意图,展示不同意图下数据从「提问」到「结果」的完整流转路径。账户/持仓/交易查询(操作类)当前为 Phase 2 待实现(见 §2.4.6),图中以虚线标出。
flowchart TD
U[用户提问] --> A[① 输入接收与校验鉴权]
A --> B[② 记忆召回:读 Redis 会话]
B --> INT{③ 意图路由qwen-turbo · 阈值0.6}
INT -- faq 高频问答 --> F1[检索 fin_faq_collection · TopK=3]
F1 --> F2[直返标准答案]
INT -- product_inquiry 产品咨询 --> P1[检索 fin_product_collection · TopK=5]
P1 --> P2[RAG + LLM 生成 + 来源引用]
INT -- policy_explain 政策解读 --> PL1[检索 fin_policy_collection · TopK=5]
PL1 --> PL2[RAG + 解释]
INT -- chitchat 闲聊 --> C1[不查集合LLM 引导业务话题]
INT -- transfer_human 转人工 --> T1[生成转接工单携带完整上下文]
T1 --> T2[运营/投顾后台接管]
INT -- 置信度 L1[澄清提问 → 仍低则转人工]
O1[账户/持仓/交易查询Phase 2 · API 直连账户系统] -.-> G
F2 --> G[⑤ 合规校验负面词 + 免责声明]
P2 --> G
PL2 --> G
C1 --> G
T2 --> G
L1 --> G
G --> H[⑥ 数据沉淀:归档 + 脱敏]
H --> I[⑦ 事件广播:敏感意图 → 风控]
H --> J[结果反馈 SSE]
各意图数据路径说明:
意图 |
数据从哪来 |
经过什么处理 |
到哪去 |
faq |
fin_faq_collection |
检索直返(不经 LLM) |
用户 |
product_inquiry |
fin_product_collection |
RAG + LLM 生成 + 来源引用 |
用户 |
policy_explain |
fin_policy_collection |
RAG + 解释 |
用户 |
chitchat |
无(不查集合) |
LLM 直接生成 |
用户 |
transfer_human |
会话上下文 |
生成转接工单 |
运营/投顾后台 |
账户/持仓/交易查询(操作类) |
账户系统 API(Phase 2) |
精确查询 |
用户(暂缓,见 §2.4.6) |
4. 知识库清单
4.1 三集合总览
集合 |
内容范围 |
TopK |
数据来源 |
fin_faq_collection |
高频操作类标准问答(开户/绑定/赎回时效/密码/换卡) |
3 |
客服历史工单 + 帮助中心 + 人工审校 |
fin_product_collection |
产品说明书、招募说明书、费率结构、风险等级、业绩比较基准 |
5 |
产品系统 + 官方法律文件 |
fin_policy_collection |
监管法规、适当性规则、销售办法、反洗钱政策、平台规则 |
5 |
监管原文 + 法务审校 |
4.2 字段结构(建议统一 schema)
字段 |
说明 |
示例 |
doc_id |
唯一标识 |
FAQ-0001 / PROD-001 / POL-2016-261 |
title |
标题 |
「基金赎回多久到账」 |
content |
正文(按条款完整性切分,例外与主条款同片段) |
— |
tags |
意图/主题标签 |
["faq", "redeem"] |
effective_date |
生效日期 |
2026-01-01 |
expire_date |
失效日期(过期自动下线) |
null / 2027-01-01 |
source_url |
来源链接 |
产品说明书 URL |
version |
版本号 |
v2.1 |
reviewer |
审校人 |
客服运营 / 法务 |
embedding |
向量 |
Qwen Embedding 生成 |
字段设计依据:阿里云开发者社区强调「知识条目需标注生效日期与适用范围,费率/期限/政策调整时旧条目及时下线,避免过期信息被检索命中」〔S16〕;富途微藤 AI 提供「知识库健康度检查」能力,识别并更正知识库瑕疵〔S9〕。
4.3 更新频率与数据来源
知识类型 |
更新频率 |
更新机制 |
FAQ |
周更新(高频新问题入池) |
从历史工单提取真实问法 → 人工审校 → 入库〔S9 FAQ 抽取〕 |
产品要素 |
产品变更即时同步 |
产品系统更新 → 触发知识库重建 → Agent 自动拉取(自动化同步管道)〔S14〕 |
费率/政策 |
变更即时下线旧条目 |
规则引擎 + 生效/失效日期控制〔S16〕 |
监管法规 |
法规发布后 N 个工作日内 |
法务审校后入库 |
参考做法:招商基金智能在线客服「集成招商银行小招X引擎及知识库」,并将「文字聊天记录生成工单内容总结、自动匹配受理产品和渠道」,实现知识沉淀的自动化〔S5〕。富途微藤 AI 的「语料智能扩写」可在冷启动阶段快速丰富语料〔S9〕。
4.4 知识运营机制
- 设立专职知识运营岗位,明确更新责任与频率——「上线后无人维护」是金融产品知识库快速失效的头号原因〔S16〕。
- 同义问法补充:从历史工单提取真实表达(用户说「到期能拿回多少钱」而非「现金价值」),作为同义问法补充进知识条目与意图示例〔S16〕。
- 按条款完整性切分:把「同一条款的适用条件与例外情况」放在同一片段,避免拆散导致回答不准〔S16〕。
4.5 FAQ 示例(fin_faq_collection 内容样例)
下表给出 fin_faq_collection 的典型问答对示例,覆盖不同意图类型。实际入库时按 §4.2 字段结构存储(question / answer / tags / effective_date / expire_date / embedding)。
类别 |
用户问法 |
标准答案要点 |
是否可直返 |
开户/注册 |
怎么开通账户? |
邮箱验证码注册 → 填写风险测评问卷 → 后台人工审核 → 邮件通知激活 |
是 |
账户绑定 |
怎么换绑定的银行卡? |
进入「我的」-「账户设置」-「银行卡」按提示操作(本功能 Phase 2 上线) |
是 |
密码重置 |
忘记密码怎么办? |
登录页点击「忘记密码」→ 邮箱验证 → 重置 |
是 |
风险测评 |
风险测评多久有效? |
有效期按监管要求;过期需重新测评(具体以系统提示为准) |
是 |
赎回时效 |
赎回多久到账? |
货币 1-2 工作日 / 债券 2-4 / 混合·股票 2-4 / QDII 4-13,具体以产品为准 |
是 |
费率 |
申购费怎么收? |
按产品费率表执行,前端/后端收费按合同约定;以产品说明书为准 |
是 |
适当性 |
我能买什么风险等级的基金? |
先完成风险测评得 C1-C5,再匹配 R1-R5;系统会校验是否匹配 |
是 |
收益 |
这个基金能赚多少? |
不能承诺收益;请参考「业绩比较基准」及产品说明书,过往业绩不代表未来 |
是(合规话术) |
投诉 |
我要投诉! |
共情安抚 → 登记投诉工单 → 转人工跟进 |
否(转人工) |
转人工 |
立即生成工单转人工 |
否(转人工) |
说明:「是否可直返」= 是否走「检索直返标准答案」路径(faq 意图)。涉及投诉/转人工的,直接走 transfer_human 意图,不检索 FAQ。
5. 人工审核机制
5.1 转人工触发条件(分级)
级别 |
触发条件 |
响应 |
P0 自动转 |
用户明确要求转人工;情绪激烈/投诉/纠纷关键词;涉人身财产安全/信息安全紧急场景;监管敏感问题 |
立即转人工,同步上下文 |
P1 兜底转 |
意图置信度 < 0.6 且澄清后仍无法识别;RAG 混合判定低置信;连续 2 轮未解决 |
兜底话术 + 建议转人工 |
P2 人工引导 |
涉及资金争议、个性化推荐诉求、大额操作意愿 |
生成工单 + 引导至投顾/运营人工 |
触发条件整合了项目既有设计(全景说明书场景 2 的四条件)与国标/行业要求:国标明确「交互失败达到设定阈值、感知负面情绪、涉信息安全人身安全紧急场景时自动转接人工」〔S11〕;捷通华声「连续 2 轮未理解意图、涉及投诉/纠纷关键词、客户主动要求人工」〔S14〕。
5.2 事后复核与质检(兜底保障)
即使 AI 未触发转人工,仍设事后质检:
质检项 |
规则 |
动作 |
负面词命中 |
后置校验拦截记录 |
告警 + 安全话术兜底 |
高风险表述 |
涉及收益/风险/推荐 |
抽检人工复核 |
低置信已答 |
中置信档回答 |
纳入质检池,定期回看 |
投诉关联会话 |
后续产生投诉的历史会话 |
全量复核 |
参考:金融 AI 客服「双轨评测」——一条测业务准确率、一条测合规通过率,任何一条不通过不发布〔S14〕;监管要求客户沟通记录保存 ≥ 20 年且不得含诱导性表述,传统录音抽检覆盖率不足 5%,AI 全量留痕可支撑 100% 质检〔S15〕。
5.3 升级路径
一线客服(运营/客户经理接管)
↓ 无法解决或涉合规
高级坐席(持证投顾/资深客服)
↓ 涉监管敏感、法律、重大投诉
合规/法务(合规官)
参考做法:招商基金「金谘机构」投顾服务强调「从『顾』到『投』再到『顾』的闭环」,高净值客户「AI 初筛 + 投顾人工审核」正是分级升级的实践〔S4〕。富途按「在线客服 7×24 / 电话人工交易日 24h / 紧急交易柜台」分层〔S8〕。
5.4 国标对齐检查(《顾客联络服务 人工与智能客户服务协同要求》,2026-09-01 实施)
国标要求 |
本项目对齐情况 |
转人工入口便捷、衔接顺畅 |
✅ 对话中固定「转人工」入口 + 关键词触发 |
切换后同步客户信息且不重复询问 |
✅ 转接工单携带 session_id 完整历史 + 意图 + 置信度 + 已引用来源 |
支持关键词/菜单/按键/语音多种切换 |
✅ 关键词 + 菜单(语音为后续扩展,需核实) |
AI 回复保留显著 AI 生成标识 + 风险提示 |
✅ 免责声明强制注入(AI 生成标识建议补充,见 §0.4 评审点) |
涉及退款/赔偿/合同变更最终确认由人工 |
✅ §3.5 投诉处理路径 |
不以「AI 回答不代表公司立场」拒履行承诺 |
✅ 将智能+人工视为完整服务〔S12〕 |
6. 回复策略
6.1 标准回复模板(分场景)
场景 A:产品信息 / 风险等级客观转述
「XX 基金为【股票型/混合型/债券型】基金,风险等级为 R【1-5】(【低/中低/中/中高/高】风险),适合【风险等级】及以上投资者。您可以在完成风险测评后查看是否匹配。」〔S13 铁律三模板〕
场景 B:费率 / 业绩比较基准
「根据产品说明书,该产品的【申购费率/赎回费率/管理费率】为 X%。该产品的业绩比较基准为 X%,过往业绩不代表未来表现,投资有风险,请您仔细阅读产品说明书。」〔S13 铁律一模板〕
场景 C:风险揭示(非保本)
「理财产品/基金是非保本浮动收益产品,您的本金和收益可能会因市场波动而产生损失,请在充分了解风险后做出决策。」〔S13 铁律四模板〕
场景 D:到账时效
「【货币 1-2 / 债券 2-4 / 混合·股票 2-4 / QDII 4-13】个工作日到账,具体以产品为准。」〔S3〕
场景 E:情绪安抚 + 投诉受理
「非常理解您的心情,很抱歉给您带来不好的体验。我已为您登记并转接人工专员跟进处理,稍后会有专人联系您。」
6.2 语气与措辞规范
规范 |
说明 |
共情优先 |
投诉/情绪场景先安抚、后解决(对标华夏「机智小牛」的情感计算〔S7〕) |
客观中性 |
只陈述事实与规则,不做主观判断与收益暗示 |
简洁明确 |
标准问题直返答案,不绕弯 |
主动引用 |
关键结论附来源引用,增强可信 |
6.3 必备风险提示与免责声明
固定免责声明(基类强制注入,子类不得绕过):
「本内容仅为投资分析参考,不构成任何直接投资建议,不构成对任何产品的收益承诺,据此操作风险自负,请谨慎对待。」
AI 生成标识(建议补充,见 §0.4 评审点 4):对 AI 生成的开放式回答,前置「本回答由 AI 生成,仅供参考」,对齐国标「保留显著 AI 生成标识和风险提示」〔S11〕。
6.4 拒答与兜底话术
情形 |
话术 |
低置信兜底 |
「抱歉,我暂时无法准确回答您的问题,建议您转接人工客服获取更准确的帮助。」 |
负面词命中(安全话术) |
「根据监管要求,我不能对收益做出任何承诺。本产品为非保本浮动收益产品,请以产品说明书为准。」 |
合规禁答 |
「非常抱歉,该问题涉及的内容我无法回答,为您转接人工客服。」 |
个性化推荐越界 |
「我无法为您推荐具体产品。您可以先完成风险测评,了解自己的风险承受能力后,咨询持证投顾为您提供服务。」 |
6.5 负面词清单(7 个,零容忍)
# |
负面词 |
合规原因 |
1 |
保本 |
资管新规后非保本 |
2 |
稳赚 |
误导性表述 |
3 |
无风险 |
绝对化表述 |
4 |
保证收益 |
禁止刚兑承诺 |
5 |
预期收益率 |
《理财销售办法》明文禁止 |
6 |
年化收益率 |
监管处罚点名措辞 |
7 |
安全 |
绝对化表述 |
评审建议:可将「零风险」「稳赚不赔」「躺着赚」「坐享收益」等变体纳入模糊匹配规则(见 §0.4 评审点 4)。
7. 数据与状态流转 / 接口与异常
7.1 接口约定
// POST /api/chat/customer 请求
{ "session_id": "...", "user_id": 10001, "message": "..." }
// 响应(统一信封)
{ "code": 200, "message": "success", "trace_id": "uuid",
"data": { "reply": "...", "source_references": [...], "intent": "faq",
"confidence": 0.86, "tool_calls": [...], "suggestions": [...] } }
7.2 会话状态机
状态 |
说明 |
迁移条件 |
idle |
空闲 |
收到消息 → processing |
processing |
处理中 |
意图清晰 → answering;需澄清 → clarifying |
clarifying |
澄清中 |
澄清后仍无法识别 → transferring |
answering |
回答 |
完成 → idle |
transferring |
转人工中 |
工单生成 → idle(会话交人工) |
7.3 异常处理表
异常 |
策略 |
检索无结果 / 低分 |
三档兜底(不硬答) |
Milvus 超时(>2s)/故障 |
降级 MySQL LIKE 关键词检索 |
LLM 失败 |
退避重试 1s/2s/4s ×3 → 备用模型 → 预设兜底话术 |
命中负面词 |
打回重生成;二次仍命中则返回安全话术 + 告警 |
Redis 故障 |
会话降级为进程内字典;画像直连 MySQL |
8. 度量与验收(双轨评测)
轨道 |
用例 |
通过标准 |
业务准确率 |
高频意图回答正确性、来源引用完整性 |
高频意图准确率 ≥ 90% |
合规通过率 |
负面词命中率、免责声明缺失率、适当性越界、越权查询 |
全部为 0 |
参考:捷通华声「上线前必须跑满合规用例,任何一条不通过都不发布」〔S14〕;百度智能云分层目标「试点期意图识别准确率 ≥85%、推广期多轮完成率 ≥70%、成熟期 NPS ≥40」〔S15〕。
9. 完善方向与最终交付要求
本章按六大维度逐项指出当前差距 → 完善标准(可量化)→ 交付要求,作为评审后的迭代排期依据。每条完善标准都对应可验收的量化门槛;文末给出上线门禁(Go/No-Go)清单作为最终交付要求。
9.0 差距总览(一页速览)
维度 |
关键差距(Top) |
完善标准(量化) |
优先级 |
功能完整性 |
闲聊无边界、澄清槽位缺失、同义问法缺失、suggestions 空转、转人工会话未回收、跨 Agent 联动未定义 |
闲聊 ≤3 轮引导;澄清 ≤2 轮;top20 问法各 ≥5 同义句;转人工会话 24h 内回收 |
P0 |
用户体验 |
无 SSE 流式、情绪识别后置、无首屏建议问题、引用不可点击、多端未适配 |
首 token <800ms;负面情绪直通安抚通道;引用可跳转原文 |
P0 |
性能优化 |
三段串行、FAQ 无缓存、无 rerank、截断策略粗糙、无并发限流 |
端到端 P95 <3s;热点缓存命中 ≥80%;意图与检索并行 |
P1 |
错误处理 |
无熔断/半开、无幂等、trace_id 未贯穿、兜底话术硬编码、无灰度回滚 |
熔断 N 次触发;同 trace_id 幂等;话术可热更新 |
P1 |
安全性 |
无提示词注入防护、检索层行级过滤未强制、脱敏清单未定、反诈触发词未列、审计字段未定 |
注入红队 0 穿透;越权查询 0;敏感字段 100% 脱敏 |
P0 |
代码可读性 |
常量散落、意图分类器硬编码、单测覆盖未定义、命名未固化、文档代码脱节 |
常量单一来源;核心逻辑覆盖率 ≥80%;合规用例 100% |
P1 |
9.1 功能完整性
改进点 |
现状差距 |
完善标准 |
交付要求 |
闲聊意图边界 |
chitchat 仅写「LLM 引导业务话题」,无话题边界与轮次上限,可被闲聊无限消耗资源 |
闲聊 ≤3 轮后强制引导业务;引导后仍无业务意图 → 转人工或静默结束 |
闲聊状态机 + 引导话术模板 + 轮次计数单测 |
澄清机制槽位 |
状态机有 clarifying 态,但未定义澄清追问的槽位(产品名/时间范围等)与次数上限 |
澄清 ≤2 轮;每轮追问 1 个关键槽位;澄清失败 → 转人工 |
槽位定义表 + 澄清话术 + 澄清失败转人工用例 |
同义问法/口语纠错 |
用户问法与官方术语差距大(「到期能拿回多少钱」vs「现金价值」)〔S16〕 |
高频意图 top20 问法各配置 ≥5 个同义问法;拼写/口语纠错 |
同义问法词表(历史工单提取)+ 纠错规则 |
suggestions 空转 |
接口有 suggestions 字段但无生成逻辑 |
每条回答附带 2-3 个关联建议问题,点击率埋点 |
建议问题生成规则 + 埋点 |
转人工会话回收 |
全景说明书提到「解决后提取摘要并回收对话」,客服专项未细化 |
转人工会话解决后 24h 内生成摘要,回收入 FAQ 候选池 |
摘要提取流程 + FAQ 沉淀机制 |
跨 Agent 联动 |
客服识别「高净值/大额意愿/敏感话题」后的联动规则未定义 |
三类联动触发词清单 + 事件发布契约(suspicious_intent 等) |
联动触发规则表 + 事件契约文档 |
9.2 用户体验
改进点 |
现状差距 |
完善标准 |
交付要求 |
流式输出(SSE) |
接口返回完整 JSON,长答案首字延迟高 |
首 token 延迟 <800ms;SSE 流式输出 |
SSE 改造 + 首字延迟监控 |
情绪识别前置 |
情绪识别在转人工判定时才做,负面情绪客户先在兜底话术打转 |
意图路由前做情绪预判;负面情绪直通「安抚+转人工」,不绕检索 |
情绪预判前置 + 负面情绪快速通道 |
首屏建议问题 |
对标天天基金「猜你想问」、支小宝「大家都在问」〔S2〕,本项目无首屏引导 |
首屏提供 top 高频问题 + 按画像的个性化建议 |
首屏问题推荐模块 |
引用可点击 |
来源引用格式未定义,长答案无分点 |
长答案分点/分段;来源引用可点击跳转原文 |
回答格式化模板 + 引用跳转 |
多端适配 |
未说明 APP/H5/网页端差异 |
三端统一会话(session 跨端)与展示适配 |
多端适配方案 |
9.3 性能优化
改进点 |
现状差距 |
完善标准 |
交付要求 |
三段串行链路 |
意图分类 → RAG 检索 → LLM 生成串行 |
意图分类与 RAG 检索并行;端到端 P95 <3s |
并行化改造 + 压测报告 |
FAQ 热点缓存 |
FAQ 直返未做缓存,重复计算 |
热点 FAQ 缓存命中率 ≥80%;缓存 TTL 10min |
Redis 缓存层 + 命中率监控 |
检索重排 rerank |
TopK=5 直接送 LLM,无精排 |
引入 rerank,top1 准确率相对基线提升 ≥5pp |
rerank 模型接入 + 离线评测 |
上下文截断策略 |
超 4096 token 截断旧消息,丢失关键信息 |
改为「摘要 + 近期原文」混合;按意图选择性保留 |
上下文压缩策略 + 效果对比 |
并发限流削峰 |
高峰并发无保护 |
令牌桶/滑动窗口限流;QPS 阈值;降级预案 |
限流配置 + 压测 |
9.4 错误处理
改进点 |
现状差距 |
完善标准 |
交付要求 |
熔断与半开恢复 |
只有超时降级,无熔断器 |
Milvus/LLM 连续失败 N 次熔断,半开探测恢复 |
熔断器 + 恢复策略 |
幂等性 |
重复提交/重试无幂等 |
同一 trace_id 幂等 |
幂等键设计 |
trace_id 全链路 |
接口有 trace_id,未说明贯穿到 Milvus/LLM 调用日志 |
一次请求一个 trace_id 贯穿所有下游调用 |
全链路日志规范 + 示例 |
兜底话术硬编码 |
安全话术/兜底话术硬编码在代码 |
话术配置化(独立配置/知识条目),可热更新 |
话术配置中心 |
灰度与回滚 |
新模型/新知识库上线失败无回滚 |
模型/知识库版本化,一键回滚 |
版本管理 + 回滚预案 |
9.5 安全性
改进点 |
现状差距 |
完善标准 |
交付要求 |
提示词注入防护 |
用户消息可夹带「忽略之前的指令」 |
输入侧注入检测 + 输出侧越界拦截;红队 0 穿透 |
注入防护规则 + 红队测试用例 |
检索层权限过滤 |
客服「仅本人数据」,但检索/SQL 层是否强制行级过滤未明确 |
数据访问在检索层强制 + 服务层二次校验(纵深防御) |
行级过滤设计 + 越权用例 |
脱敏字段清单 |
mask_tool 已提但字段清单未定 |
身份证/卡号/手机号全脱敏;日志/回显均脱敏 |
脱敏字段清单 + 脱敏时机 |
反诈敏感意图触发词 |
suspicious_intent 事件已提但触发词未列 |
反诈关键词(转账/验证码/安全账户)+ 实时预警 |
触发词清单 + 与风控联动 |
审计留痕完整性 |
留痕 ≥20 年已提但字段未定义 |
完整记录(人/时/问/答/意图/置信度/来源/工具调用) |
审计日志字段规范 |
9.6 代码可读性
改进点 |
现状差距 |
完善标准 |
交付要求 |
常量散落 |
阈值/负面词/免责声明可能散落在子类 |
唯一常量源(对标 SUITABILITY_MATRIX 单一来源) |
常量集中管理(config/constants) |
意图分类器硬编码 |
意图集 + 阈值配置化 |
配置化 + 文档 |
单元测试覆盖 |
未定义测试覆盖率 |
核心逻辑覆盖率 ≥80%;合规用例 100% 通过 |
单测 + 双轨评测 |
命名与目录规范 |
已有 api/service/tool 但未固化规范 |
统一命名 + 分层依赖规则 |
编码规范文档 |
文档代码同步 |
方案 vs 代码可能脱节 |
关键阈值/话术/集合在代码中有单一真相源,文档引用该源 |
文档-代码同步机制 |
9.7 最终交付要求(上线门禁 Go/No-Go 清单)
以下为必须全部满足才可进入联调/上线的硬性门禁;任一未达标即 No-Go。
功能门禁(Must)
# |
交付项 |
验收标准 |
F1 |
5 类意图 + 三集合路由可运行 |
每类意图至少 1 条端到端用例通过 |
F2 |
三档兜底(高/中/低置信) |
低置信 100% 不硬答,触发兜底/转人工 |
F3 |
转人工工单携带完整上下文 |
session_id + 历史 + 意图 + 置信度 + 来源一次传递 |
F4 |
负面词 7 个后置校验 |
命中率 0(拦截率 100%) |
F5 |
免责声明强制注入 |
面向客户的输出 100% 附固定话术 |
安全与合规门禁(Must)
# |
交付项 |
验收标准 |
S1 |
不代客交易 |
客服 Agent 无任何交易写接口 |
S2 |
适当性不越界 |
C1×R2+ 推荐 0 起(客服不荐,越界转投顾) |
S3 |
越权查询防护 |
本人数据之外查询 0 起 |
S4 |
敏感字段脱敏 |
身份证/卡号/手机号日志与回显 100% 脱敏 |
S5 |
留痕可追溯 |
全量会话归档,保存 ≥20 年 |
质量门禁(Must)
# |
交付项 |
验收标准 |
Q1 |
高频意图准确率 |
≥90% |
Q2 |
首响时长 |
<3s(SSE 首 token <800ms) |
Q3 |
转人工率 |
≤20% |
Q4 |
合规用例通过 |
双轨评测合规轨道 100% 通过 |
Q5 |
核心逻辑单测覆盖率 |
≥80% |
交付物清单(最终交付要求)
类别 |
交付物 |
代码 |
customer.py(5 意图 + 三档兜底)、rag_service.py、milvus_tool.py、mask_tool.py、memory_service.py + 常量集中管理模块 |
配置 |
意图阈值、负面词清单、免责声明话术、兜底话术、限流参数、熔断参数(全部配置化) |
数据 |
三集合知识库(FAQ/产品/政策)初始版本 + 同义问法词表 |
文档 |
本方案 v1.1 + 编码规范 + 接口契约 + 审计日志字段规范 + 联调测试用例 |
测试 |
单元测试(覆盖率 ≥80%)+ 双轨评测集(业务 + 合规) |
10. 附录
10.1 参考来源清单
编号 |
来源 |
要点 |
S1 |
蚂蚁财富《智能理财助理服务协议》〔render.alipay.com〕 |
「蚂小财」大模型局限免责、不构成投资建议/推介/要约、95188 人工热线 |
S2 |
天天基金研究(AI 客服「小天」/支小宝界面)〔ima.qq.com〕 |
常见问题、选基金/持仓分析/产品评测功能 |
S3 |
天天基金「基金吧答疑」〔guba.eastmoney.com〕 |
联系客服路径、赎回到账分类型时效、折算解释 |
S4 |
招商基金「懂投资更懂你」(金谘机构)〔cmfchina.com〕 |
7×24 在线机器人、持仓诊断、基金体检 |
S5 |
招商基金「数字金融建设」〔sohu.com/a/969419069〕 |
小招X引擎+知识库、AI 工单总结、营销知识图谱、DeepSeek R1+QWQ-32b |
S6 |
证券时报「沉浸式体验基金智能客服 九大趋势」〔stcn.com〕 |
招商/富国基金智能客服对「基金下跌」的回答差异、天弘 94% 准确率 |
S7 |
华夏基金李一梅「AI 时代的能力者」〔cet.com.cn〕 |
「机智小牛智能体」、情感计算、人机边界 |
S8 |
富途官方「7×24 小时服务」〔futunn.com〕 |
帮助中心三步、智能客服 7×24、人工分层时段 |
S9 |
富途 2024 年报〔newsfile.futunn.com〕 |
ContactBot(TextBot/VoiceBot)、微藤 AI:语料扩写/FAQ 抽取/文档问答/知识库健康度检查 |
S10 |
腾讯新闻「6000 次实测基金公司」〔so.html5.qq.com〕 |
国泰 84%、嘉实 42%、建信 31% AI 解答率;15 家仅 3 家周末有人工 |
S11 |
新华网《顾客联络服务 人工与智能客户服务协同要求》〔news.cn〕 |
国标转人工规则、切换同步不重复询问、AI 标识+风险提示 |
S12 |
人民论坛「新国标整治 AI 客服躲猫猫」〔rmlt.com.cn〕 |
不以「AI 回答不代表公司立场」拒履行承诺 |
S13 |
华云天下「金融 AI 客服十条合规铁律」〔huayunworld.com〕 |
不能承诺收益/推荐/风险评价/刚兑、三道防线、标准应答模板 |
S14 |
捷通华声「金融客服智能体可控比聪明更重要」〔sohu.com〕 |
置信度阈值转人工、连续 2 轮/投诉关键词、双轨评测 |
S15 |
百度智能云「智能客服赋能证券基金」〔cloud.baidu.com〕 |
留痕 ≥20 年、合规引擎 200+ 规则、分层落地指标 |
S16 |
阿里云开发者社区「AI 客服金融落地实践」〔developer.aliyun.com〕 |
生效日期标注、条款完整性切分、同义问法、脱敏、知识运营岗位 |
S17 |
嘉实基金「亮相世界人工智能大会」〔jsfund.cn〕 |
与浦发共建 AI 财富数字人联合实验室 |
10.2 需核实项清单
# |
待核实内容 |
说明 |
1 |
天天基金智能客服响应时效 ≤30 秒 |
来源为第三方(叩富网)引用「天天基金统计数据」,非官方口径,需核实 |
2 |
招商基金部署模型「QWQ-32b」具体版本 |
搜狐报道原文,模型名拼写需核实 |
3 |
蚂蚁财富「蚂小财」的意图分类体系与转人工阈值 |
未公开,需向平台方或公开资料核实 |
4 |
国泰/嘉实/建信 AI 解答率实测数据 |
为第三方媒体抽样测试,非官方披露,仅作行业参照 |
5 |
各平台知识库字段结构 |
均为非公开信息,本方案 §4.2 为设计建议,需按本项目实际数据核实 |
6 |
语音切换人工(§5.4 国标对齐) |
本项目当前仅文本,语音为后续扩展,需排期确认 |