chore(docs): docs/ 目录全面重新编号 + 重组

**重构前**(旧编号 02-11):
- docs/02-产品需求/      → 00 产品规划/PRD
- docs/03-技术架构/      → 01-05 子目录散落
- docs/04-原型设计/      → 01-02 产品设计(HTML 原型)
- docs/05-原型设计/      → screens/
- docs/06-测试素材/      → 02-E2E / 03-功能 / 04-版本测试
- docs/07-项目管理/      → 任务说明书/日报/计划
- docs/08-安全审计/      → 审计报告
- docs/09-堡垒运维/      → toolbox / deploy
- docs/10-项目管理/      → 任务说明书(重复)
- docs/11-历史归档/      → deploy-nas-archived

**重构后**(新编号 00-07,语义化):
- docs/00-产品开发流程与文档管理规范.md
- docs/00-版本迭代总览.md
- docs/01-产品文档/      (PRD/原型/认证/会话/AI 服务/坐席/集成)
- docs/02-技术文档/      (技术方案/架构图/重构记录/前端改造/实现配置)
- docs/03-测试文档/      (E2E/功能用例/版本报告/缺陷单)
- docs/04-运维文档/      (部署运维/运维指南)
- docs/05-运营文档/      (品牌推广/用户手册)
- docs/06-安全审计/      (审计报告)
- docs/07-项目管理/      (任务说明书/日报/计划/看板)

**净收益**:
- 目录编号与产品文档管理规范对齐(按文档阶段 01-07 编号)
- 消除 02-产品需求 与 10-项目管理 的编号重叠
- 子目录按文档类型分组(如 01-产品文档/00-产品规划、01-产品文档/01-认证与登录)
- 把运维/安全/项目管理从 0X 散落改为 04/06/07

合计 494 文件 + 78495 行 / - 14076 行
This commit is contained in:
Simon
2026-08-03 18:46:55 +08:00
parent 3a44141eac
commit 44e77dcb0e
494 changed files with 78494 additions and 14075 deletions
@@ -0,0 +1,60 @@
# 术语与图标规范
> **版本**: v1.0
> **日期**: 2026-07-19
> **整合自**: PRD-v53-IT智能服务台总览-v1.2 §10
---
## 一、核心概念定义
| 术语 | 定义 | 触发者 | 接收者 | 图标 | 使用范围 |
|------|------|--------|--------|------|----------|
| **人工** | 用户呼叫坐席,请求人工服务 | H5用户端员工 | IT坐席 | 传菜铃(桌面拍铃)SVG | 用户端H5 + 坐席端(状态指示) |
| **摇人** | 主责坐席呼叫其他坐席进入群聊协助 | IT坐席 | 其他IT坐席 | 👋 招手 | 仅坐席端 |
| ~~**举手**~~ | <span style="color:red">**已取消**</span> | — | — | — | 全局移除 |
---
## 二、"人工"按钮需求
### 2.1 产品定义
**"人工"** = 用户(员工)主动呼叫IT坐席,请求人工服务。
| 属性 | 定义 |
|------|------|
| 触发者 | H5用户端员工 |
| 接收者 | IT坐席(主责坐席或系统分配坐席) |
| 图标 | 传菜铃(桌面拍铃)—— 前台/厨房放在桌面、拍一下发出"叮"声的圆形金属铃铛 |
| 区别于 | "摇人" = 坐席呼叫其他坐席 |
### 2.2 图标说明
> - ✅ **传菜铃**(正确):圆形金属铃铛,放在桌面上,从上方拍打铃面发出"叮"声。代表"我已提出问题,请人工来看一下"。
> - ❌ **摇铃** 🔔(错误):有把手的手摇铃,摇动发出声响。当前代码中使用的是此图标,需替换。
---
## 三、趣味话术体系
| 触发场景 | 话术 | 语气 | 存储方式 |
|---------|------|------|---------|
| 点击呼叫人工坐席按钮 | 已为您呼叫人工坐席,请稍等! | 亲切 | 配置表 |
| 关键词触发转人工 | 已为您呼叫人工坐席,请稍等! | 稍正式 | 配置表 |
| 排队等待(30秒无人接单) | 人还在路上,别急别急~ | 安抚 | 配置表 |
| 坐席接入 | 坐席正在查看您的信息,请等待处理回复! | 明确交接 | 配置表 |
| 等待超时(2分钟) | 坐席都在忙,不过AI还在呢,要不先聊聊? | 降级安抚 | 配置表 |
| VIP员工(自动切换) | 这就帮您安排专家,请稍候 | 正式 | 配置表 |
> **话术确定方式**: 代码默认值 + 数据库动态配置
> - 默认值定义在 `backend/app/services/funny_phrase_service.py` 的 `DEFAULT_PHRASES`
> - 线上实际话术以数据库 `funny_phrases` 表配置为准(支持后台修改)
> - 话术更新记录见 `CHANGELOG.md`
---
## 四、关联文档
- 原始文档: `PRD-v53-IT智能服务台总览-v1.2.md` §10
- 整合自: `PRD-增量-人工按钮与术语统一.md`
@@ -0,0 +1,235 @@
# IT智能服务台 — 产品规划总览
> **版本**: v1.0
> **日期**: 2026-07-19
> **维护人**: 产品经理
> **类型**: 产品规划
---
## 一、产品概述
### 1.1 项目背景
税友集团内部 IT 支持渠道分散(企微群、电话、走访),缺乏统一 SLA 追踪。本项目构建一个 **AI + 人工坐席协作** 的智能服务台:
- **员工端**H5):企微 OAuth2 免登,AI 自动回复 + 人工兜底,支持「呼叫人工坐席」
- **坐席端**(Web):三栏工作台,会话分配/抢单/协作/转接,实时 WebSocket 推送
- **AI 层**:接入 RAGFLOW/Dify 知识库,自动回复常见 IT 问题
**核心指标**:AI 自助解决率 55%(实际 1-5月已达 70.2%
### 1.2 产品目标
1. **提高AI首答率**: 通过消息路由层强制新会话先走AI,将AI筛选比例提升至80%以上
2. **统一对话体验**: 员工从AI对话到人工服务在同一窗口无缝流转
3. **构建AI-人工协作闭环**: 建立坐席标注→知识库迭代的正向循环
### 1.3 角色体系
| 角色 | 标识 | 说明 | 访问路径 |
|------|------|------|----------|
| 普通员工 | `user` | 提交IT问题、查看进度、评价满意度 | `/itdesk/` |
| IT坐席 | `agent` | 处理会话、AI辅助、快速回复 | `/itagent/` |
| 管理员 | `admin` | 系统配置、坐席管理、数据看板 | `/itadmin/` |
---
## 二、核心系统架构
```
员工端(H5) ←→ 后端服务 ←→ 坐席端(Web)
AI层(RAGFlow/Dify)
```
| 组件 | 技术 |
|------|------|
| 后端 | FastAPI + Redis + PostgreSQL |
| 前端 | Vue3 + Element Plus / Vant4 |
| AI | RAGFlow + Dify + 千问 |
| 部署 | Docker |
---
## 三、五阶段演进路径
| 阶段 | 目标 | 员工端 | 坐席端 |
|------|------|--------|--------|
| 阶段一 | 转人工改H5+坐席工作台MVP | H5 登录+转人工 | 会话列表+聊天+快速回复 |
| 阶段二 | 智能咨询集成 | H5 全流程 + 呼叫人工坐席 + 评分 | 三栏工作台 + AI建议 |
| 阶段三 | 坐席辅助回复/判断 | H5 体验优化 | AI Wingman(草稿+摘要+知识) |
| 阶段四 | 日志标准+知识库迭代 | H5 跨平台扩展 | 绩效看板 + 知识库自动迭代 |
| 阶段五 | 自动/辅助审核开单结单 | H5 一站式 | 待办面板 + AI填单 + AI审核 |
---
## 四、版本迭代记录
| 版本 | 状态 | 日期 | 主要内容 |
|------|------|------|----------|
| v1.0 | ✅ 已上线 | 2025-07 | 企微SSO、MFA、RBAC |
| v1.1 | ✅ 已上线 | 2025-xx | 敏感词检测、token修复、扫码登录优化 |
| v1.2 | ✅ 已上线 | 2026-07-04 | 知识库迭代修复、生产痛点缓解 |
| v2.0 | ✅ 已上线 | 2026-07-10 | 综合版:审批卡片、模板卡片、知识库迭代 |
| v2.2 | ✅ 已上线 | 2026-07-10 | 审批卡片改造:12种/18流程 |
| v2.3 | ✅ 已上线 | 2026-07-17 | ITSM工单跳转交互优化 |
---
## 五、已上线功能清单
### M1 阶段
| ID | 功能 | 状态 |
|----|------|------|
| P1-01 | 会话标记系统 | ✅ 已实现 |
| P1-02 | 会话列表排序 | ✅ 已实现 |
| P1-03 | VIP标记自动匹配 | ✅ 已实现 |
| P1-04 | 举手标记 | ✅ 已实现 |
| P1-05 | 需介入标记 | ✅ 已实现 |
| P1-06 | 情绪标记(规则版) | ✅ 已实现 |
| P1-07 | 紧急度评分 | ✅ 已实现 |
| P1-08 | 置顶/代办 | ✅ 已实现 |
| P1-09 | 企微入口 SSO | ✅ 已实现 |
| P1-10 | MFA 双因素认证 | ✅ 已实现 |
| P1-11 | RBAC 角色管理 | ✅ 已实现 |
| P1-12 | 敏感词检测 | ✅ 已实现 |
| P1-13 | 扫码登录优化 | ✅ 已实现 |
| P2-06 | 企微模板卡片消息 | ✅ 已完成 |
---
## 六、产品功能规划
### 6.1 近期必补短板(1-2个月)
| 优先级 | REQ编号 | 改造项 | 现状 | 目标 | 对应PRD |
|--------|---------|--------|------|------|---------|
| P0 | REQ-知识-001 | **知识库真可用** | P2-01标注"已完成"实为桩实现,API未挂载 | 知识建议→训练师审批→入库→AI引用,全闭环 | `PRD-REQ-知识-001-知识库闭环-v1.0.md` |
| P0 | REQ-用户-001 | **群聊双模式** | PRD已完整定义,代码未实现 | H5底部弹出 + 坐席就地展开,参与者缩略/展开切换 | `PRD-REQ-用户-001-群聊双模式-v1.0.md` ✅ |
| P0 | REQ-用户-002 | **文件上传** | P1-23 待开发,员工无法发截图 | 支持图片/文档/日志上传,为多模态铺路 | `PRD-REQ-用户-002-文件上传-v1.0.md` |
| P1 | REQ-AI-002 | **置信门控** | P2-02 待开发,AI不分难易硬答 | 低置信度问题自动转人工,减少"AI答非所问"的负面体验 | `PRD-REQ-AI-002-置信度门控-v1.0.md` |
**改造逻辑**:这4项是"让现有系统真正可用"的基础。知识库假完成是最严重的信任危机——员工用过几次发现AI答不准,就不信任了,再推广就难了。文件上传是多模态的前置条件,没有文件上传,多模态理解就是空中楼阁。
### 6.2 中期体验跃迁(3-4个月)
| REQ编号 | 改造项 | 价值 | 对应PRD |
|---------|--------|------|---------|
| REQ-通用-001 | **前端全套优化** | 三端视觉统一,体验跃升 | `PRD-REQ-通用-001-前端设计系统-v1.0.md` |
| REQ-AI-003 | **多模态视觉理解** | 员工发截图→AI自动识别错误码/蓝屏/弹窗 | `PRD-REQ-AI-003-多模态视觉理解-v1.0.md` |
| REQ-坐席-003 | **坐席代答** | AI推荐答案→坐席一键发送,效率翻倍 | `PRD-REQ-坐席-003-坐席代答-v1.0.md` |
| REQ-推广-001 | **内推广** | 让全员知道、会用、爱用 | (运营文档) |
### 6.3 远期智能闭环(5-8个月)
| REQ编号 | 改造项 | 价值 | 对应PRD |
|---------|--------|------|---------|
| REQ-知识-002 | ~~训练师审批~~ → 已合并至 REQ-知识-001 | 已合并至知识库闭环 v1.1 | `PRD-REQ-知识-001-知识库闭环-v1.0.md` |
| REQ-用户-003 | **自助服务门户** | 员工不用找坐席也能查进度/搜知识/看审批 | `PRD-REQ-用户-003-自助服务门户-v1.0.md` |
| REQ-集成-003 | **SLA仪表盘** | 管理层实时看到SLA达成率、超时预警 | `PRD-REQ-集成-003-SLA仪表盘-v1.0.md` |
| REQ-集成-004 | **自动化闭环** | 自动分诊→自动升级→自动回访 | `PRD-REQ-集成-004-自动化闭环-v1.0.md` |
---
## 七、待开发功能
### P1 系列
| ID | 功能 | 状态 | 优先级 |
|----|------|------|--------|
| P1-20 | 邀请功能-历史消息共享 | 待开发 | P1 |
| P1-21 | 邀请功能-部门批量邀请 | 待开发 | P1 |
| P1-22 | 邀请功能-系统消息广播 | 待开发 | P1 |
| P1-23 | 文件上传 | 待开发 | P1 |
### P2 系列
| ID | 功能 | 说明 | 状态 |
|----|------|------|------|
| P2-01 | 知识库自动迭代 | 从假完成修复为真可用 | 待开发 |
| P2-02 | 分诊式置信门控 | 缓解信息过载 | 待开发 |
| P2-03 | 坐席代答 | 坐席直接回答AI问题 | 待开发 |
| P2-04 | 多模态视觉理解 | 截图/照片理解 | 待开发 |
| P2-05 | 训练师内联审批 | 知识库审核 | 待开发 |
---
## 八、知识库迭代五大生产痛点
| 痛点 | 描述 |
|------|------|
| 1 | 员工不信任 AI |
| 2 | 信息过载 |
| 3 | 坐席输入质量差 |
| 4 | 流程不可审计 |
| 5 | 坐席与训练师工作重叠 |
---
## 九、PRD需求清单汇总
| 序号 | REQ编号 | 需求名称 | 优先级 | 阶段 | 状态 |
|------|---------|----------|--------|------|------|
| 1 | REQ-知识-001 | 知识库闭环 | P0 | 近期 | ⏳ 待创建 |
| 2 | REQ-用户-001 | 群聊双模式 | P0 | 近期 | ✅ 已存在 |
| 3 | REQ-用户-002 | 文件上传 | P0 | 近期 | ⏳ 待创建 |
| 4 | REQ-AI-002 | 置信度门控 | P1 | 近期 | ⏳ 待创建 |
| 5 | REQ-通用-001 | 前端设计系统 | P1 | 中期 | ⏳ 待创建 |
| 6 | REQ-AI-003 | 多模态视觉理解 | P2 | 中期 | ⏳ 待创建 |
| 7 | REQ-坐席-003 | 坐席代答 | P2 | 中期 | ⏳ 待创建 |
| 8 | REQ-知识-002 | 训练师审批 | P2 | 远期 | ✅ 已合并至 REQ-知识-001 |
| 9 | REQ-用户-003 | 自助服务门户 | P2 | 远期 | ⏳ 待创建 |
| 10 | REQ-集成-003 | SLA仪表盘 | P2 | 远期 | ⏳ 待创建 |
| 11 | REQ-集成-004 | 自动化闭环 | P2 | 远期 | ⏳ 待创建 |
| 12 | REQ-集成-002 | 邀请功能 | P1 | 近期 | ✅ 已创建 `PRD-REQ-集成-002-邀请功能-v1.0.md` |
---
## 十、执行优先级总览
```
本周 → 群聊双模式开发启动(PRD已就绪)
2周内 → 知识库真可用修复(REQ-知识-001)
1个月内 → 文件上传(REQ-用户-002+ 置信门控(REQ-AI-002
1-2个月 → 近期4项全部完成
2-3个月 → 前端全套优化(REQ-通用-001)
3个月 → CG视频制作 + 宣传文案定稿
3-4个月 → 多模态(REQ-AI-003+ 坐席代答(REQ-坐席-003
5-8个月 → 远期智能闭环
```
---
## 十一、关联文档
| 文档 | 位置 |
|------|------|
| 术语与图标规范 | `01-产品文档/00-术语与图标规范-v1.0.md` |
| 会话管理 PRD | `01-产品文档/02-会话管理/PRD-REQ-会话-xxx.md` |
| AI服务 PRD | `01-产品文档/03-AI服务/PRD-REQ-AI-xxx.md` |
| 坐席工作台 PRD | `01-产品文档/04-坐席工作台/PRD-REQ-坐席-xxx.md` |
| 用户端H5 PRD | `01-产品文档/05-用户端H5/PRD-REQ-用户-xxx.md` |
| 审批与待办 PRD | `01-产品文档/06-审批与待办/PRD-REQ-审批-xxx.md` |
| 知识库 PRD | `01-产品文档/07-知识库/PRD-REQ-知识-xxx.md` |
| 集成生态 PRD | `01-产品文档/08-集成生态/PRD-REQ-集成-xxx.md` |
| 技术架构 | `docs/02-技术文档/` |
| 运营文档 | `docs/05-运营文档/` |
---
## 十二、变更日志
| 版本 | 日期 | 变更内容 |
|------|------|----------|
| v1.0 | 2026-07-19 | 初始版本:合并 v1.2精简版 + v2.0精简版 + 全套改造建议产品功能层面 |
---
> **核心信息**:先把基础打牢(知识库真可用+群聊双模式+文件上传),再做体验跃迁(前端全套优化),最后推广上线。顺序不能反——推广一个半成品只会透支信任。
> **源文档**
> - `PRD-v53-IT智能服务台总览-v1.2-精简版.md`(已归档)
> - `PRD-v53-IT智能服务台总览-v2.0-精简版.md`(已归档)
> - `全套改造建议-产品功能层面-v1.0.md`(已归档)
@@ -0,0 +1,269 @@
# IT 智能服务台 AI 化战略路线图
> **版本**: v1.0
> **日期**: 2026-07-28
> **作者**: 宋献
> **状态**: 草案 v1.0(待评审)
> **范围**: 工具层面 AI 化 + 组织层面 AI 化(双轨)
> **关联任务**: REQ-通用-004 敏感词检测 v1.2(首个 AI 化抓手)
---
## 1. 战略背景
### 1.1 现实压力
| 维度 | 现状 | 风险 |
|------|------|------|
| **AI 技术成熟度** | LLM 推理能力 / Agent 协作框架已成熟 | 错过窗口期 = 失去竞争力 |
| **组织变革周期** | 传统管理变革 1-3 年 | 已无过渡时间 |
| **业务复杂度** | IT 服务台工单 / 审批 / 坐席管理 / 资产管理... 持续膨胀 | 纯人肉无法应对 |
| **员工期望** | 80 后员工已习惯 AI 辅助 | 不提供 AI 工具 = 留不住人 |
### 1.2 核心判断
> **没有"从传统管理过渡到 AI 运营"的时间窗**,必须**直接进入 AI 智能运营**。
### 1.3 关键认知
| 误区 | 真相 |
|------|------|
| "AI 化 = 替代人" | AI 化 = **AI + 人**协作,人聚焦决策与例外 |
| "AI 化 = 一蹴而就" | AI 化 = **持续演进**,从工具 AI 化到组织 AI 化 |
| "AI 化 = 全自动" | **保留人工最终审核**是合规与业务连续性底线 |
| "AI 化 = 高成本" | 多数场景成本可控(GPT-4o-mini ¥0.001/次) |
---
## 2. 现状评估(IT 服务台已具备的 AI 能力)
### 2.1 已落地 AI 能力
| 能力 | 实现位置 | 状态 |
|------|----------|------|
| **Dify AI 客服** | `yw-dify.dc.servyou-it.com` | ✅ 已上线 |
| **Dify 分诊意图** | Dify app `z3S9AEUUAVPbtR2rioxpiIvp` | ✅ 已上线 |
| **Dify 审批意图** | Dify app `7jkRkAzvX4QM9v9SM3P8mMEO` | ✅ 已上线 |
| **Dify 主对话** | Dify app `8f0f3d62-f63d-4cf3-815e-b10529c66f1d` | ✅ 已上线 |
| **企微 JS-SDK 语音转文字** | 百度 ASR | ✅ 已上线 |
| **RAGFlow 知识库** | `10.80.0.85:8080` | ✅ 已上线 |
| **AI Wingman(敏感词检测 v0.7.1** | 后端 content_moderation_service | ✅ 已上线 |
| **快速回复规则(置信度 0.85 阈值)** | D1 路由 | ✅ 已上线 |
| **多智能体协作(软件团队)** | software-company 专家 | 🟡 实验性 |
### 2.2 现状能力评估
| 维度 | 评分 | 说明 |
|------|------|------|
| **AI 基础设施** | ⭐⭐⭐⭐ | Dify / RAGFlow / 多智能体框架齐备 |
| **数据资产** | ⭐⭐⭐⭐ | 工单 / 消息 / 审批 / 知识库 数据完整 |
| **业务规则数字化** | ⭐⭐⭐ | 路由规则 / 审批规则已结构化,敏感词仍人肉 |
| **运营自动化** | ⭐⭐ | 部分自动(路由/审批),多数仍人肉 |
| **决策智能化** | ⭐ | 几乎全部人工决策 |
**总评**:**基础设施已就绪**,但**运营/决策智能化是短板**。
---
## 3. AI 化愿景
### 3.1 愿景陈述
> **从"人驱动 AI"演进为"AI 驱动 + 人监督",最终达成"AI 自主运营 + 人聚焦例外"。**
### 3.2 三阶段演进
| 阶段 | 名称 | 时间 | 特征 |
|------|------|------|------|
| **v1.x**(工具 AI 化) | **AI 辅助运营** | 2026 H2 | AI 替代人肉运营,人审核 |
| **v2.x**(决策 AI 化) | **AI 协同决策** | 2027 H1 | AI 参与决策,人终审 |
| **v3.x**(组织 AI 化) | **AI 自主运营** | 2027 H2+ | AI 全链路自主,人聚焦例外 |
### 3.3 阶段目标量化
| 指标 | 当前 | v1.x | v2.x | v3.x |
|------|------|------|------|------|
| 工单自动化率 | 30% | 50% | 70% | 85% |
| 人工审批环节 | 8 个 | 6 个 | 3 个 | 1 个(合规) |
| 运营人肉任务占比 | 60% | 30% | 15% | < 5% |
| 异常响应延迟 | 30min | 5min | 1min | 实时 |
---
## 4. 核心场景(双轨:工具层 vs 组织层)
### 4.1 工具层面 AI 化(v1.x 重点)
| 场景 | 当前痛点 | AI 化方案 | 优先级 |
|------|----------|----------|--------|
| **敏感词维护** | 运营人肉发现新词 | AI 自动发现 + 推荐 | ✅ **首个抓手 v1.2** |
| **知识库更新** | 运营人肉整理 FAQ | AI 自动挖掘高频问题 → 草拟 FAQ | P0 |
| **工单分诊** | 人工分配 | AI 智能分诊(已部分实现) | 增强 |
| **审批流程** | 人工审批 | AI 预审 + 人工复核 | P0 |
| **坐席绩效** | 人工统计 | AI 自动出报表 + 异常告警 | P1 |
| **员工满意度** | 人工抽样 | AI 全量分析 + 情感识别 | P1 |
| **资产盘点** | 人工核对 | AI 智能识别异常 | P2 |
| **故障预测** | 被动响应 | AI 预测 + 主动推送 | P2 |
### 4.2 组织层面 AI 化(v2.x / v3.x
| 场景 | 当前痛点 | AI 化方案 | 阶段 |
|------|----------|----------|------|
| **跨部门协调** | 人工拉群 / 拉会 | AI Agent 自动协调 | v2.x |
| **资源调度** | 经理人工分配 | AI 智能调度(基于负载/技能/优先级) | v2.x |
| **风险预警** | 事后审计 | AI 实时预警 + 处置建议 | v2.x |
| **战略决策** | 管理层会议 | AI 智能分析 + 决策辅助 | v3.x |
| **流程优化** | 流程办人工梳理 | AI 自动发现瓶颈 + 优化建议 | v3.x |
| **组织诊断** | 年度咨询 | AI 实时诊断 | v3.x |
---
## 5. 路线图
### 5.1 v1.22026 H2)—— AI 辅助运营试水
| 月份 | 任务 | 抓手 |
|------|------|------|
| 7 月 | 敏感词检测 v1.2 | REQ-通用-004 |
| 8 月 | 知识库 AI 自动更新 v1.0 | REQ-知识-002 |
| 9 月 | 审批 AI 预审 v1.0 | REQ-审批-003 |
| 10 月 | 工单分诊 AI 增强 | REQ-会话-005 |
| 11 月 | 坐席绩效 AI 自动报表 | REQ-运营-001 |
| 12 月 | AI 化基础设施(agent 协作框架) | REQ-基础设施-001 |
**v1.2 收尾时(12 月)目标**
- 5 个核心场景已 AI 辅助
- 运营人肉任务占比 60% → 30%
- Dify 工作流 ≥ 10 个
- AI 智能体 ≥ 3 类协同工作
### 5.2 v2.x2027 H1)—— AI 协同决策
| 月份 | 任务 |
|------|------|
| 1-2 月 | 跨部门协调 Agent |
| 3-4 月 | 资源调度 AI |
| 5-6 月 | 风险预警 AI |
**目标**
- 决策环节 AI 参与 50%
- 人工审批从 8 个环节 → 3 个
- AI 智能体 ≥ 6 类协同
### 5.3 v3.x2027 H2+)—— AI 自主运营
| 季度 | 任务 |
|------|------|
| Q3 2027 | 战略决策辅助 |
| Q4 2027 | 流程自动优化 |
| Q1 2028 | 组织实时诊断 |
**目标**
- 工单自动化率 ≥ 85%
- 异常响应延迟 ≤ 1min
- AI 自主处理 95% 常规事务
---
## 6. 资源与组织
### 6.1 团队配置建议
| 角色 | 当前 | v1.2 建议 | v2.x 建议 |
|------|------|-----------|-----------|
| AI 工程师 | 0 | 1(专注 Dify 工作流) | 2+ Agent 开发) |
| 产品经理 | 1(宋献) | 1(不变) | 1 + 1(业务侧) |
| 后端 | 1 | 1(不变) | 2 |
| 前端 | 1 | 1(不变) | 1 |
| 运营 | 1 | 0.5(解放至 AI 训练) | 0.3 |
| 外部专家 | 0 | 0.2(顾问) | 0.5 |
### 6.2 基础设施投入
| 项 | v1.2 | v2.x |
|----|------|------|
| Dify 工作流 | ≤ 15 个 | ≤ 30 个 |
| AI Agent 框架 | LangGraph 评估 | LangGraph + AutoGen |
| LLM 成本 | ≤ ¥500/月 | ≤ ¥2000/月 |
| 数据存储 | 不变 | + 向量库扩展 |
### 6.3 跨部门协同
| 部门 | 协同内容 |
|------|----------|
| **HR** | AI 化对岗位的影响 / 培训计划 |
| **财务** | AI 成本预算 / 节省人力成本测算 |
| **合规** | 数据隐私 / 审计 / 决策保留边界 |
| **安全** | LLM 输入数据安全 / 模型本身安全 |
---
## 7. 风险与边界
### 7.1 风险清单
| 风险 | 等级 | 缓解措施 |
|------|------|----------|
| **合规风险**(AI 自动决策违反监管) | 🟠 高 | 保留人工最终审核(决策保留) |
| **数据隐私风险**(喂 LLM 数据泄露) | 🟠 高 | 数据脱敏前置 + 不喂敏感字段 |
| **AI 误判风险**(绕过场景识别错误) | 🟡 中 | 人工 review 必做 + 灰度发布 |
| **成本失控风险**(LLM 调用成本爆炸) | 🟡 中 | 配额 + 监控 + 自动降级 |
| **员工抵触风险**(怕被替代) | 🟡 中 | 明确"AI + 人"定位,强调聚焦例外 |
| **业务连续性风险**(AI 故障 = 服务中断) | 🟡 中 | 自动降级 + 灰度开关 |
### 7.2 决策保留(与 AI 化原则相关)
| 决策 | 内容 | 来源 |
|------|------|------|
| **人工最终审核** | 所有 AI 推荐需人工最终确认 | 2026-07-28 AI 化讨论 |
| **命中动作 WARN** | 敏感词命中仍 WARN(不 BLOCK | 2026-07-08 决策保留 |
| **脱敏前置** | 喂 LLM 前必须脱敏 | 2026-07-28 AI 化讨论 |
### 7.3 边界
| 不做 | 原因 |
|------|------|
| 完全无人化决策 | 合规底线 |
| 训练私有模型 | 成本不划算,GPT-4o-mini 足够 |
| 替代所有坐席 | 业务连续性 + 人文关怀 |
| 跨部门强推 AI 化 | 各部门节奏不同,工具层先跑 |
---
## 8. 关联文档
| 文档 | 位置 | 关联点 |
|------|------|--------|
| **敏感词 v1.2 PRD** | `01-产品文档/00-产品规划/PRD-REQ-通用-004-敏感词检测-v1.2-AI辅助.md` | **首个 AI 化抓手** |
| 敏感词 v1.0 PRD | `01-产品文档/00-产品规划/PRD-REQ-通用-004-敏感词检测-v1.0.md` | 基础功能 |
| 敏感词 v1.1 任务说明书 | `07-项目管理/任务说明书/` | v1.1 实施记录 |
| 软件团队主理人 SOP | `~/.workbuddy/plugins/.../software-company/` | 多智能体协作框架 |
| Dify 应用清单 | `02-技术文档/实现配置/dify_dsl/` | 工作流清单 |
---
## 9. 评审待确认议题
| 议题 | 决策人 | 时间 |
|------|--------|------|
| v1.2 投入:1 个 AI 工程师 / 8.5 天 | 宋献(产品) + 财务(预算) | 本周 |
| 工具 vs 组织双轨是否同步启动 | 宋献(战略) | 本周 |
| AI 化预算上限(v1.2 ≤ ¥500/月) | 财务 | 本周 |
| 数据脱敏规则是否符合合规 | 安全 / 合规 | 下周 |
| 跨部门协同计划(HR/财务/合规/安全) | 各部门负责人 | 下周 |
---
## 10. 变更日志
| 版本 | 日期 | 变更 | 变更人 |
|------|------|------|--------|
| v1.0 | 2026-07-28 | 首次起草:基于敏感词 v1.2 PRD 启动契机 | 宋献 |
---
> **核心论点**
> - **没有"传统过渡到 AI 化"的时间窗**,直接进入 AI 智能运营
> - **首个抓手**:敏感词检测 v1.2(v1.2 草案已完成)
> - **双轨**:工具层(v1.x+ 组织层(v2.x/v3.x
> - **保留底线**:人工最终审核(决策保留)
@@ -0,0 +1,284 @@
# PRD - 前端设计系统
> **REQ编号**: REQ-通用-001
> **版本**: v1.1
> **优先级**: P1
> **阶段**: 中期(3-4个月)
> **作者**: 宋献
> **日期**: 2026-07-19v1.1 补充 2026-07-27
---
## 一、问题陈述
**用户问题**
- H5、坐席、管理后台三端视觉风格割裂
- 缺乏统一的 Design Tokens
- 品牌感弱,除绿色外没有独特视觉符号
**业务目标**
- 建立统一的 IT 智能服务台设计系统
- 三端视觉风格一致,提升产品辨识度
- 提升用户体验和品牌感知
---
## 二、需求范围
### 2.1 核心功能
| 功能 | 描述 |
|------|------|
| Design Tokens | 统一的色彩、字体、间距、圆角、阴影、动效 |
| 组件规范 | 按钮、输入框、卡片、弹窗等组件规范 |
| 图标库 | 统一使用 Lucide 图标库 |
| 深色模式 | 完整的深色模式适配 |
### 2.2 非目标
- 不包含完整的设计系统文档网站
- 不包含组件库的实现(仅定义规范)
---
## 三、用户故事
| 角色 | 用户故事 | 验收标准 |
|------|----------|---------|
| 前端开发 | 有统一的 Design Tokens 可复用 | 三端使用统一的 CSS 变量 |
| 设计师 | 有完整的组件规范文档 | 设计产出符合规范 |
| 员工 | 三端视觉风格一致 | H5、坐席、后台看起来像同一产品 |
---
## 四、功能详情
### 4.1 Design Tokens 定义
**色彩系统**
| Token | 值 | 用途 |
|-------|-----|------|
| --color-primary | #07C160 | 主色(企微绿) |
| --color-primary-light | #E8F5E9 | 主色浅背景 |
| --color-primary-dark | #056739 | 主色深色 |
| --color-secondary | #3b82f6 | 辅助色-蓝 |
| --color-accent | #FF9800 | 强调色-橙 |
| --color-success | #10B981 | 成功 |
| --color-warning | #F59E0B | 警告 |
| --color-danger | #EF4444 | 危险 |
| --color-info | #6B7280 | 信息 |
**灰阶**
| Token | 值 | 用途 |
|-------|-----|------|
| --gray-50 | #F9FAFB | 页面背景 |
| --gray-100 | #F3F4F6 | 卡片背景 |
| ... | ... | ... |
| --gray-900 | #111827 | 主标题 |
**排版系统**
| Token | 值 | 用途 |
|-------|-----|------|
| --font-family | PingFang SC, Microsoft YaHei | 字体 |
| --font-size-xs | 12px | 辅助文字 |
| --font-size-sm | 13px | 标签 |
| --font-size-base | 14px | 正文 |
| --font-size-lg | 16px | 小标题 |
| --font-size-xl | 20px | 页面标题 |
| --font-size-2xl | 24px | 大标题 |
**间距系统**4px 基准):
- 4, 8, 12, 16, 20, 24, 32, 48, 64
**圆角系统**
| Token | 值 | 用途 |
|-------|-----|------|
| --radius-sm | 4px | 标签 |
| --radius-md | 6px | 按钮 |
| --radius-lg | 8px | 卡片 |
| --radius-xl | 12px | 大组件 |
| --radius-full | 999px | 圆形 |
**阴影系统**
| Token | 值 | 用途 |
|-------|-----|------|
| --shadow-sm | 0 1px 2px rgba(0,0,0,0.04) | 悬浮态 |
| --shadow-md | 0 2px 8px rgba(0,0,0,0.06) | 卡片 |
| --shadow-lg | 0 4px 16px rgba(0,0,0,0.08) | 弹窗 |
**动效系统**
| Token | 值 | 用途 |
|-------|-----|------|
| --duration-fast | 150ms | hover/press |
| --duration-normal | 200ms | 展开/收起 |
| --duration-slow | 300ms | 弹窗/过渡 |
### 4.2 组件规范
**按钮**
- 主按钮:主色填充,白色文字,6px 圆角
- 次按钮:边框主色,主色文字,透明背景
- 文字按钮:无背景,无边框,主色文字
**输入框**
- 默认:灰色边框,14px 圆角
- 聚焦:主色边框,显示阴影
- 错误:红色边框,显示错误提示
**卡片**
- 白色背景,8px 圆角,轻微阴影
- 可选:边框样式(细灰线)
### 4.3 图标规范
- 统一使用 Lucide 图标库
- 风格:线框风格(outline
- 尺寸:16px(辅助)、20px(常规)、24px(强调)
---
## 四、用户交互反馈规范(补充)
> **补充日期**: 2026-07-24
> **补充原因**: 2026-07-24 H5选项交互消息重复Bug反思——产品设计文档中缺失「用户交互反馈」定义
### 4.4 交互反馈设计原则
**核心原则**:所有涉及后端异步响应的用户操作,前端应优先通过**UI状态变化**反馈结果,而非**临时消息**。
| 场景 | 不推荐做法 | 推荐做法 |
|------|-----------|---------|
| 用户点击AI选项 | 立即显示一条"待确认"消息,等后端返回后删除或保留 | 按钮立即禁用 + 高亮选中态,静默发WS,等后端返回后再添加正式消息 |
| 用户发送消息 | 本地先添加消息,等后端返回确认后再决定是否显示 | 按钮禁用 + 发送中状态,后端返回后添加正式消息 |
| 用户上传文件 | 先显示"上传中..."的临时消息 | 进度条 + 按钮禁用,上传完成后显示正式消息 |
### 4.5 交互状态定义
每一种用户操作都应定义以下状态:
| 状态 | 视觉表现 | 说明 |
|------|---------|------|
| **正常态** | 按钮可点击,无特殊样式 | 用户可以执行操作 |
| **处理中态** | 按钮禁用 + 加载指示器 | 后端正在处理,不允许重复点击 |
| **成功态** | 恢复正常,可能有短暂高亮反馈 | 操作成功完成 |
| **失败态** | 按钮恢复可用 + 错误提示 | 操作失败,需要用户重试 |
### 4.6 消息添加时机原则
**技术设计原则**:前端不应在收到后端确认前添加消息到消息列表。
```
┌─────────────────────────────────────────────────────────────────┐
│ 推荐的消息添加流程 │
├─────────────────────────────────────────────────────────────────┤
│ 1. 用户触发操作(如点击选项) │
│ 2. 前端:UI状态变为「处理中」(按钮禁用) │
│ 3. 前端:发送请求到后端(WS或HTTP) │
│ 4. 后端:处理完成,返回确认消息 │
│ 5. 前端:收到后端确认后,添加到消息列表 │
│ 6. 前端:UI状态恢复「正常」或变为「成功」 │
└─────────────────────────────────────────────────────────────────┘
```
**为什么这样设计**
1. 避免消息ID不一致导致的重复显示问题
2. 用户通过UI状态变化就能感知操作已被接收,不需要"假消息"来确认
3. 后端失败时,前端只需要恢复UI状态,不需要处理消息的"撤回"
### 4.7 Element Plus 深色主题适配规范(v1.1 补充 2026-07-27
> **补充原因**BUG-通用-001(管理后台 el-table 白底白字)暴露了设计系统在 Element Plus 落地时的具体应用规则缺失。本节明确设计 Tokens 在 Element Plus 组件上的覆盖要求。
#### 4.7.1 适用范围
- 所有使用 `<el-table>` 的视图(管理后台核心列表页)
- 后续扩展到 `<el-dialog>` / `<el-tag>` / `<el-form>` / `<el-pagination>` 等深色主题相关组件
#### 4.7.2 el-table 三层覆盖规则
Element Plus 的 `<el-table>` 在 DOM 上有三层结构:
```
<td> ← td 层(外层)
<div class="el-table__cell"> ← cell 层(内层 div
<!-- 文字 --> ← 内容
</div>
</td>
```
**核心规则**:必须覆盖到 **cell 层 + fixed-column 层**,否则白底白字。
```css
/* 主体单元格(普通 + 固定列)—— 必须在 cell 层覆盖 */
.el-table .el-table__body td,
.el-table .el-table__body td.el-table__cell,
.el-table .el-table__body td.el-table-fixed-column--left,
.el-table .el-table__body td.el-table-fixed-column--right {
background-color: var(--bg-secondary) !important; /* ⚠️ 必须 !important */
color: var(--text-primary);
}
/* 斑马纹行(偶数行) */
.el-table .el-table__row--striped td, ... {
background-color: var(--bg-tertiary) !important;
}
/* hover 状态 */
.el-table .el-table__body tr:hover > td, ... {
background-color: rgba(59, 130, 246, 0.15) !important;
}
```
#### 4.7.3 实施原则
| 原则 | 说明 |
|------|------|
| **全局覆盖** | 在 `src/<前端项目>/src/styles/global.css` 统一配置,不在每个视图写 scoped 样式 |
| **必须 !important** | Element Plus 固定列选择器优先级高,不加 !important 无法胜出 |
| **覆盖完整 3 层** | td / td.el-table__cell / td.el-table-fixed-column--left/--right,缺一不可 |
| **覆盖完整状态** | 普通 / 斑马纹 / hover,缺一就有半清半不清 |
#### 4.7.4 验收清单(每个 el-table 视图必须通过)
- [ ] 普通行(无 striped)背景深、文字浅 → 清晰
- [ ] 偶数行(striped)背景更深一档、文字浅 → 清晰
- [ ] 固定列(`fixed="left"``fixed="right"`)与同行普通列颜色一致
- [ ] hover 时整行变蓝透 → 文字仍可读
- [ ] 表格头(thead)背景与全站风格一致
- [ ] WCAG 对比度 ≥ 4.5:1
#### 4.7.5 教训(来自 BUG-通用-001
1. **不要在视图里加 scoped `:deep()`**:治标,每个表都得改;scoped 选择器优先级也不够
2. **必须用 !important**Element Plus 的 `.el-table-fixed-column--left/--right` 优先级很高
3. **3 层都要覆盖**:第 1 次只覆盖 td(用户反馈"半清半不清"),第 2 次加 cell(用户反馈"偶数行不清"),第 3 次加 !important + fixed-column 才彻底修复
4. **完整 Skill 沉淀**`~/.workbuddy/skills/element-plus-dark-table/SKILL.md`(下次遇到可直接调用)
#### 4.7.6 关联文档
- 缺陷单:`03-测试文档/05-缺陷单/BUG-通用-用户角色分配表格看不清-001.md`
- 故障案例:`04-运维文档/部署运维/00-标准故障排查手册.md` CASE-20260727-02
- Skill`~/.workbuddy/skills/element-plus-dark-table/SKILL.md`
---
## 五、指标设计
| 指标 | 目标 | 测量方式 |
|------|------|---------|
| 设计系统覆盖率 | 100% | 三端组件使用 Design Tokens 的比例 |
| 三端视觉一致性 | ≥ 90% | 用户调研评分 |
---
## 六、技术方案
- 使用 CSS Custom Properties 实现 Design Tokens
- 抽离为独立 CSS 文件,三端引入
- 深色模式通过 CSS 变量覆盖实现
---
## 七、关联文档
- 技术文档: `02-技术文档/前端改造/前端改造建议-v1.1.md`
@@ -0,0 +1,231 @@
# PRD - 快速回复规则后台管理
> **需求编号**: REQ-通用-002
> **版本**: v1.2
> **状态**: [已评审]
> **作者**: Simon
> **日期**: 2026-07-27(初版) / 2026-07-28v1.2 变更)
> **关联文档**:
> - 原型图:`01-产品文档/01-02产品设计/快速回复规则后台管理-原型图.html`
> - 技术方案:`02-技术文档/技术方案-REQ-通用-002-快速回复规则后台管理.md`
> - 任务说明书:`07-项目管理/任务说明书/任务说明书-131-快速回复规则后台管理.md`
> - 测试用例:`03-测试文档/03-功能测试用例/TC-通用-002-快速回复规则后台管理.md`
> - 部署文档:`04-运维文档/快速回复规则后台管理-部署文档-v1.0.md`
> - 整改记录:`04-运维文档/部署运维/00-文档规范化整改记录.md`
---
## 1. 需求描述
### 1.1 背景
当前AI回复的快速规则(打招呼、业务路由、发送名片)全部硬编码在Python代码中,存在以下问题:
- **维护不便**:修改关键词需要改代码、部署
- **无法运营**:运营人员无法自主配置规则
- **灵活性差**:无法快速响应业务变化
### 1.2 目标
建立后台可编辑的快速规则管理系统,将硬编码的规则配置迁移到数据库,支持运营人员在管理后台灵活配置。
同时考虑未来扩展性:系统既要支持**人工快速维护**,也要为**智能体自动优化**(AI Agent 自动分析消息、调整规则)保留接口能力。
### 1.3 范围
| 规则类型 | 当前实现 | 目标 |
|---------|---------|------|
| 打招呼关键词 | `ai_handler.py` 硬编码 | 数据库 + 管理页面 |
| 业务路由关键词 | `routing_service.py` 硬编码 | 数据库 + 管理页面 |
| 路由目标配置 | `routing_service.py` 硬编码 | 数据库 + 管理页面 |
---
## 2. 用户故事
### 2.1 运营人员
| 优先级 | 用户故事 |
|--------|---------|
| P0 | 作为运营人员,我希望在管理后台增删改查打招呼关键词,无需每次修改代码 |
| P0 | 作为运营人员,我希望在管理后台维护业务路由关键词,及时响应业务变化 |
| P1 | 作为运营人员,我希望修改规则后立即生效,无需重启服务 |
| P1 | 作为运营人员,我希望看到规则的启用/禁用状态,快速调整规则 |
### 2.2 开发人员
| 优先级 | 用户故事 |
|--------|---------|
| P0 | 作为开发人员,我希望规则数据存储在数据库,支持多环境配置 |
| P1 | 作为开发人员,我希望规则加载有缓存,减少数据库查询压力 |
---
## 3. 功能需求
### 3.1 数据库设计
新建 `quick_rules` 表:
| 字段 | 类型 | 说明 |
|------|------|------|
| id | SERIAL | 主键 |
| rule_type | VARCHAR(50) | 规则类型:greeting/routing_prefilter/routing_target |
| category | VARCHAR(50) | 业务分类(行政/人力/财务/法务/物业) |
| keyword | TEXT | 关键词内容 |
| priority | INTEGER | 优先级(越大越优先) |
| response_template | TEXT | 回复模板(可选) |
| is_active | BOOLEAN | 是否启用 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |
**rule_type 枚举**:
- `greeting` - 打招呼规则
- `routing_prefilter` - 路由预过滤关键词
- `routing_target` - 路由目标配置
> **注意**: BYOD功能涉及员工岗位校验、资产领取状态查询、补贴历史年限等复杂API,暂不纳入快速规则管理,后续可在智能服务模块中实现。
### 3.2 管理API
| 接口 | 方法 | 说明 |
|------|------|------|
| `/api/admin/quick-rules` | GET | 列表查询(支持筛选) |
| `/api/admin/quick-rules` | POST | 创建规则 |
| `/api/admin/quick-rules/{id}` | PUT | 更新规则 |
| `/api/admin/quick-rules/{id}` | DELETE | 删除规则 |
| `/api/admin/quick-rules/batch` | POST | 批量导入 |
| `/api/admin/quick-rules/refresh` | POST | 热刷新缓存 |
| `/api/admin/quick-rules/export` | GET | 批量导出(JSON/Excel |
| `/api/admin/quick-rules/batch-delete` | POST | 批量删除(按ID列表) |
| `/api/admin/quick-rules/agent-update` | POST | 智能体专用更新(带置信度) |
| `/api/admin/quick-rules/audit-log` | GET | 规则修改审计日志 |
| `/api/admin/quick-rules/stats` | GET | 规则统计(命中率、误判率) |
### 3.3 前端管理页面
新建 `/quick-rules` 路由,包含3个子页面:
| 子页面 | 路径 | 功能 |
|--------|------|------|
| 打招呼配置 | `/quick-rules/greeting` | 管理打招呼关键词 |
| 路由关键词 | `/quick-rules/routing` | 管理业务路由关键词 |
| 路由目标 | `/quick-rules/targets` | 管理路由目标(kfid |
### 3.4 规则加载服务
创建 `QuickRuleService`
- 启动时加载所有规则到内存缓存
- 提供 `get_greeting_keywords()``get_byod_keywords()` 等方法
- 支持热刷新API,修改后刷新缓存
---
## 4. 验收标准
### 4.1 功能验收
| 编号 | 验收条件 | 测试方式 |
|------|---------|---------|
| AC1 | 可以在管理后台新增打招呼关键词 | 页面操作验证 |
| AC2 | 可以在管理后台修改业务路由关键词 | 页面操作验证 |
| AC3 | 管理后台快速回复规则页面不再展示顶部 3 张规则统计卡片,规则计数信息由标签导航上的徽标呈现 | 页面加载后检查标签导航及徽标 |
| AC4 | 修改规则后无需重启即可生效 | 修改后发送消息验证 |
| AC5 | 禁用规则后立即不生效 | 禁用后发送消息验证 |
| AC6 | 规则列表支持分页和搜索 | 页面操作验证 |
| AC7 | 底部统计卡片删除后,路由切换、筛选、批量删除、编辑、启停开关、分页、搜索功能完全保持不变 | 页面回归验证 |
### 4.2 性能验收
| 编号 | 验收条件 | 目标 |
|------|---------|------|
| PC1 | 规则加载时间 | < 100ms(缓存命中) |
| PC2 | 规则查询响应时间 | < 200ms |
| PC3 | 页面加载时间 | < 2s |
### 4.3 兼容性验收
| 编号 | 验收条件 |
|------|---------|
| CC1 | 与现有功能(欢迎与引导、快速回复)无冲突 |
| CC2 | 历史数据(硬编码规则)可迁移到数据库 |
---
## 5. Non-goals
- 不支持正则表达式匹配(仅支持简单关键词)
- 暂不提供规则版本历史回滚
- 暂不提供规则导入/导出功能
---
## 6. 技术约束
- 使用现有数据库PostgreSQL
- 前端使用现有Vue3 + Element Plus技术栈
- 规则匹配保持简单子串匹配
- 需要兼容现有硬编码规则的默认值
---
## 7. 风险与依赖
| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| 规则迁移可能影响线上服务 | 中 | 渐进式迁移,新旧页面并行 |
| 缓存与数据库不一致 | 中 | 热刷新机制 + 缓存过期策略 |
| 智能体自动修改规则引入风险 | 高 | 置信度阈值 + 人工审核 + 审计日志 |
---
## 8. 扩展规划(v2.0 智能体自动优化)
### 8.1 为什么需要智能体自动优化
随着业务消息量增长,仅靠人工维护规则会出现:
- 规则更新滞后:新业务术语、词汇无法及时识别
- 误判漏判:缺乏闭环反馈机制
- 优化效率低:人工分析大量日志成本高
### 8.2 双重维护模式
| 维度 | 人工快速维护 | 智能体自动优化 |
|------|------------|---------------|
| 触发方式 | 管理后台手动操作 | 定时任务触发 |
| 修改范围 | 单条/批量 | 批量 |
| 审核机制 | 人工审核 | 置信度阈值(>0.8 自动,<0.8 人工) |
| 回滚能力 | 手动 | 自动(命中率下降时回滚) |
| 审计追溯 | updated_at | 审计日志表 |
### 8.3 智能体专用接口
- `POST /api/admin/quick-rules/agent-update` - 智能体提交建议
- 请求参数附带:置信度、修改原因、建议依据
- 返回值:是否应用、警告信息
- `GET /api/admin/quick-rules/audit-log` - 审计日志
- 记录:操作人/agent、修改前后值、置信度、修改时间
- `GET /api/admin/quick-rules/stats` - 规则统计
- 命中率、误判率、规则有效性分析
### 8.4 批量导入导出
- `POST /api/admin/quick-rules/import` - 支持 JSON/Excel 批量导入
- `GET /api/admin/quick-rules/export` - 支持 JSON/Excel 批量导出
- 用途:备份、跨环境同步、智能体配置同步
### 8.5 期望效果
- 人工运维效率提升 50%
- 规则误判率下降 30%
- 业务响应速度提升(无需开发介入)
---
## 9. 变更记录
| 日期 | 版本 | 变更内容 | 变更人 | 变更原因 | 影响范围 |
|------|------|---------|-------|----------|----------|
| 2026-07-27 | v1.0 | 初始版本 | Simon | 快速回复规则后台管理需求建立 | 管理后台及快速规则服务 |
| 2026-07-27 | v1.1 | 新增第8章 扩展规划(智能体自动优化 + 导入导出) | Simon | 补充后续智能化扩展规划 | 产品规划与相关接口设计 |
| 2026-07-28 | v1.2 | 删除快速回复规则管理后台顶部 3 张重复统计卡片,仅保留标签导航;补充关联文档链接 | Simon | 信息冗余 | 管理后台 /quick-rules 页面 |
@@ -0,0 +1,150 @@
# PRD - 管理后台表格可读性优化
> **需求编号**: REQ-通用-003
> **版本**: v1.0
> **状态**: 草稿
> **作者**: 宋献
> **日期**: 2026-07-27
> **关联文档**: 无
> **优先级**: P2-Medium
---
## 1. 需求描述
### 1.1 背景
管理后台「角色管理 → 用户角色分配」表格的 **"员工账号 / 姓名 / 分配者 / 分配时间"** 四列内容存在严重的可读性问题,影响运营人员日常工作。
经排查,根因为 `Roles.vue:940-943` 强制把表格行背景设为浅色 `#fafafa`,但文字色仍继承深色主题变量 `var(--text-primary) = #f1f5f9`(接近白色),形成 **白底白字** 的视觉灾难,对比度几乎为 0。
### 1.2 目标
1. 修复用户角色分配表的颜色冲突,恢复文字可读性
2. 为长文本列添加 `show-overflow-tooltip`,避免内容被截断
3. 关键标识列(员工账号、姓名)固定左侧,横向滚动时不会丢失上下文
4. 提供简单搜索框,方便运营人员快速定位某个员工/分配者的记录
5. 形成可复用的"管理后台表格可读性"规范,避免类似问题在其他页面复发
### 1.3 范围
| 改动项 | 涉及文件 | 范围 |
|--------|---------|------|
| 修复颜色冲突 | `src/frontend-admin/src/views/Roles.vue` | 仅 `.user-roles-table` 选择器 |
| 添加 tooltip + fixed 列 | `src/frontend-admin/src/views/Roles.vue` | 表格 8 列全部调整 |
| 添加搜索过滤 | `src/frontend-admin/src/views/Roles.vue` | `filteredUserRoles` computed |
| 复用性规范 | `src/frontend-admin/src/styles/global.css` | 注释(无功能改动) |
**不在范围**
- 不改动后端 API
- 不改动其他表格(如"自动映射规则"表——目前问题不严重)
- 不重做整个表格组件(如换成 vxe-table)
---
## 2. 用户故事
### 2.1 运营人员
| 优先级 | 用户故事 |
|--------|---------|
| P0 | 作为运营人员,我希望表格文字清晰可读,能直接看到员工账号、姓名、分配者、分配时间 |
| P1 | 作为运营人员,我希望长员工姓名/分配者被截断时,鼠标悬停能看到完整内容 |
| P1 | 作为运营人员,我希望横向滚动表格时,左侧的"员工账号/姓名"列不消失 |
| P2 | 作为运营人员,我希望能搜索员工姓名/账号,快速过滤出我关心的记录 |
### 2.2 前端开发
| 优先级 | 用户故事 |
|--------|---------|
| P1 | 作为前端开发,我希望这套样式修复能复用,避免后续其他表格再犯同样错误 |
---
## 3. 功能需求
### 3.1 样式修复(核心)
**当前代码(Roles.vue:940-943**
```css
.user-roles-table :deep(.el-table__body td) {
background-color: #fafafa; /* 浅灰白背景 */
color: var(--text-primary); /* #f1f5f9 白色文字 = 白底白字 */
}
```
**目标代码**
```css
.user-roles-table :deep(.el-table__body td) {
background-color: var(--bg-secondary); /* #1e293b 与全站深色主题一致 */
color: var(--text-primary); /* #f1f5f9 浅色文字,深底浅字对比清晰 */
}
.user-roles-table :deep(.el-table__row--striped td) {
background-color: var(--bg-tertiary); /* 斑马纹 #334155 */
}
.user-roles-table :deep(.el-table__body tr:hover > td) {
background-color: rgba(59, 130, 246, 0.15) !important;
}
```
### 3.2 列属性优化
| 列名 | 当前 | 调整后 |
|------|------|--------|
| 员工账号 | `min-width="120"` | `min-width="120" fixed="left" show-overflow-tooltip` |
| 姓名 | `min-width="100"` | `min-width="100" fixed="left" show-overflow-tooltip` |
| 角色 | `min-width="100"` | `min-width="100"` |
| 来源 | `min-width="100"` | `min-width="100" show-overflow-tooltip` |
| 分配者 | `min-width="100"` | `min-width="120" show-overflow-tooltip` |
| 分配时间 | `min-width="160"` | `min-width="160" show-overflow-tooltip` |
| 过期时间 | `min-width="160"` | `min-width="160" show-overflow-tooltip` |
| 操作 | `width="100" fixed="right"` | 保持不变 |
### 3.3 搜索框
在表格上方添加简易搜索输入框,按 `employee_id` / `employee_name` / `assigned_by` 任一字段做模糊匹配(大小写不敏感)。
**实现**:复用 `filteredUserRoles` computed,新增 `searchKeyword` ref + watcher/计算属性。
---
## 4. 验收标准
### 4.1 功能验收
| 编号 | 验收项 | 通过标准 |
|------|--------|----------|
| AC-1 | 文字可读 | 「员工账号/姓名/分配者/分配时间」四列文字清晰可见(对比度 ≥ 4.5:1,WCAG AA |
| AC-2 | 溢出提示 | 长员工姓名被截断时,鼠标悬停显示完整内容 |
| AC-3 | 固定列 | 横向滚动表格时,"员工账号/姓名"两列保持可见 |
| AC-4 | 搜索 | 输入员工姓名/账号关键词,列表实时过滤 |
| AC-5 | 主题一致 | 表格样式与全站深色科技风一致,无突兀色块 |
| AC-6 | 斑马纹 | 偶数行/奇数行有可辨识的背景区分 |
### 4.2 回归验收
| 编号 | 验收项 | 通过标准 |
|------|--------|----------|
| AC-7 | 现有功能 | 分配角色 / 撤销角色 / 搜索员工对话框 全部正常使用 |
| AC-8 | 其他表格 | 「自动映射规则」表样式不受影响 |
| AC-9 | 其他页面 | 角色概览卡片网格样式不受影响 |
| AC-10 | 移动端响应式 | 视口宽度 < 1280px 时表格仍可用 |
---
## 5. 关联信息
- **关联缺陷**: BUG-通用-001
- **关联代码文件**: `src/frontend-admin/src/views/Roles.vue`
- **关联样式文件**: `src/frontend-admin/src/styles/global.css`
- **关联测试**: 手动验收(详见 `BUG-通用-001` 验证清单)
---
## 6. 变更记录
| 日期 | 版本 | 变更内容 | 变更人 |
|------|------|----------|--------|
| 2026-07-27 | v1.0 | 创建 PRD,记录表格可读性问题与修复方案 | 宋献 / Duckula |
@@ -0,0 +1,276 @@
# PRD - 敏感词检测
> **需求编号**: REQ-通用-004
> **版本**: v1.0
> **状态**: [已上线/部分达标]
> **作者**: 宋献
> **日期**: 2026-07-28
> **关联任务**: 项目主文档 #81v0.7.1 已上线)
> **关联文档**:
> - 技术方案:`02-技术文档/技术架构/技术方案-REQ-通用-004-敏感词检测-v1.0.md`
> - 测试用例:`03-测试文档/03-功能测试用例/TC-通用-004-敏感词检测.md`
> - 看板验真测试报告(历史基线):`03-测试文档/04-版本测试报告/看板验真-测试报告-20260707.md`
> - 内容审核服务源码:`src/backend/app/services/content_moderation_service.py`
> - 内容审核测试源码:`src/backend/tests/test_content_moderation.py`
---
## 1. 需求描述
### 1.1 背景
IT 智能服务台坐席在工作过程中会发送大量文字消息(回复员工、推送通知、催办等),存在两类内容风险:
| 风险类别 | 典型场景 | 后果 |
|----------|----------|------|
| **服务态度风险** | 坐席使用轻视/推诿/反问式语气("你爱找谁找谁"、"自己不会百度吗") | 员工投诉,IT 服务台品牌受损 |
| **隐私泄露风险** | 坐席误发员工手机号、身份证号、银行卡号、个人邮箱 | 公司合规风险,员工个人隐私暴露 |
历史经验表明,**人工巡检难以 100% 覆盖**。需要在坐席发送消息**前**做一次内容审核,给出风险提示。
### 1.2 目标
建立坐席发送消息的**内容审核机制**,做到:
1. **覆盖风险面**:敏感服务用语(脏话/不当推诿/反问)+ 隐私字段(手机/身份证/银行卡/个人邮箱)
2. **低干扰**:命中后**仅警告不阻断**WARN 策略,2026-07-08 决策),保留坐席自主权
3. **可扩展**:词库/规则**可运营**(理论上可由管理后台维护,当前 v1.0 为写死基线)
### 1.3 范围
| 范围项 | v1.0 状态 | 说明 |
|--------|----------|------|
| 敏感服务用语检测 | ✅ 已实现 | wordfilter 库 + 自定义词库(写死 4 条) |
| 隐私字段检测 | ✅ 已实现 | 正则匹配手机/身份证/银行卡/邮箱 |
| 命中动作 | ✅ 维持 WARN | 不阻断发送,仅提示 |
| 修改建议 | ✅ 已实现 | 按分类返回固定建议文案 |
| 词库运营管理 | ❌ 未实现 | 当前写死,PRD §6 数据需求中已规划 |
| 后台配置 UI | ❌ 未实现 | 运营需改代码发布 |
| 命中动作可配置 | ❌ 未实现 | 当前固定 WARN,无法升级为 BLOCK |
### 1.4 Non-goals
| 不做 | 原因 |
|------|------|
| 图像/附件内容审核 | 仅做文本审核;图片走企微原生反垃圾 |
| AI 实时生成建议 | 当前为固定文案模板;AI 改写后续再评估 |
| 阻断(BLOCK)动作 | 2026-07-08 决策:维持 WARN,避免误伤业务 |
| 员工端(H5)输入审核 | 员工端走企微原生反垃圾 + AI Wingman |
---
## 2. 用户故事
### 2.1 坐席
| 优先级 | 用户故事 |
|--------|----------|
| P0 | 作为坐席,我希望发送"自己不会百度吗"前收到警告,知道这不合适 |
| P0 | 作为坐席,我希望看到具体哪些词被命中(matched_words |
| P0 | 作为坐席,我希望能继续发送(不被强制阻断),由我自己判断 |
| P1 | 作为坐席,我希望看到修改建议(suggestion),学习如何更专业 |
| P1 | 作为坐席,我希望知道为什么被警告(category:脏话/隐私/... |
### 2.2 运营人员
| 优先级 | 用户故事 |
|--------|----------|
| P1 | 作为运营,我希望能调整词库(添加/删除敏感词),无需改代码 |
| P2 | 作为运营,我希望能调整隐私正则(如新增"军官证号"),支持业务扩展 |
| P2 | 作为运营,我希望能查看词库命中统计(高频误判词/低频词) |
### 2.3 管理员
| 优先级 | 用户故事 |
|--------|----------|
| P1 | 作为管理员,我希望命中动作可配置(WARN/BLOCK),应对合规升级 |
| P2 | 作为管理员,我希望审核日志可追溯(谁发了什么被警告) |
---
## 3. 功能需求
### 3.1 敏感词检测(写死词库)
| 字段 | 规格 |
|------|------|
| 检测范围 | 坐席发送的所有文本消息(员工消息不审) |
| 词库来源 | `content_moderation_service.py::ContentModerationService.__init__` 写死 4 条 |
| 词库当前值 | `["投诉我", "你爱找谁找谁", "自己不会百度吗", "这点小事"]` |
| 匹配算法 | `wordfilter` 库(基于 DFA 的 Aho-Corasick 变体) |
| 分类 | 当前仅支持 profanity(脏话),其它分类保留扩展位 |
| 命中动作 | `ModerationAction.WARN`(固定) |
### 3.2 隐私字段检测
| 字段 | 规格 |
|------|------|
| 检测项 | phone / id_card / bank_card / personal_email |
| 手机号正则 | `(?<!\d)1[3-9]\d{9}(?!\d)`**已修复**:用数字边界替代 `\b`,修复 Python3 re 中文失效) |
| 身份证正则 | `(?<!\d)\d{17}[\dXx](?!\d)` |
| 银行卡正则 | `(?<!\d)\d{16,19}(?!\d)` |
| 个人邮箱正则 | 排除 `servyou-it.com``servyou.com.cn` 后缀 |
| 返回值 | 命中的字段描述列表(如 `["phone", "id_card"]` |
| 命中动作 | `ModerationAction.WARN`(隐私检测暂未接入 moderate 主流程,仅提供独立方法) |
### 3.3 提示与建议
| 字段 | 规格 |
|------|------|
| 提示形式 | 坐席端发送按钮上方黄色提示条 |
| 提示内容 | "⚠️ 检测到敏感词:[xxx] 建议修改为:xxx" |
| 阻断行为 | 无(坐席可继续发送) |
| 审计日志 | 当前未写审计日志(v1.0 限制) |
### 3.4 词库管理(v1.0 留接口,未实现 UI)
| 字段 | 规格 |
|------|------|
| 数据存储 | 计划存 `system_config` 表(key=sensitive_words, value=JSON 数组) |
| 加载时机 | 服务启动时一次性加载到内存(`Wordfilter.addWords` |
| 热更新 | 未实现(v1.0 限制;改词库需重启后端) |
| 增删 API | `service.add_custom_word(word)` / `service.remove_custom_word(word)` 已有,未挂载到路由 |
| 后台 UI | ❌ 未实现(PRD §6 数据需求规划) |
### 3.5 命中动作分级(v1.0 限制)
| 分类 | v1.0 动作 | 后续规划 |
|------|----------|----------|
| profanity | WARN | 可配置为 BLOCK |
| politics | WARN(理论) | 应升级为 BLOCK |
| porn | WARN(理论) | 应升级为 BLOCK |
| ad | WARN(理论) | 可配置 |
| privacy | WARN(理论) | 应升级为 BLOCK |
| other | WARN(理论) | 可配置 |
> **决策记录**2026-07-08 项目评审决定 v1.0 维持 WARN,不升级 BLOCK。理由:避免误伤业务(WARN 已经能让坐席知道问题,且坐席有最终决策权)。
---
## 4. 非功能需求
| 维度 | 要求 |
|------|------|
| 性能 | 单次审核 < 5mswordfilter DFA 算法,已实测) |
| 可用性 | 不阻塞主流程:审核失败不阻断消息发送(v1.0 异常吞掉) |
| 可维护性 | 词库/正则集中在一个 service,修改影响范围可控 |
| 可测试性 | 13 个单元测试用例,覆盖率 ≥ 85% |
| 兼容性 | Python 3.11+ / FastAPI / PostgreSQL / Redis(与现有架构一致) |
| 国际化 | 当前仅中文(敏感词库和提示文案) |
---
## 5. 接口需求
### 5.1 服务层 API(已实现)
| 方法 | 签名 | 返回 |
|------|------|------|
| `moderate(text)` | `str -> ModerationResult` | 审核结果(action/category/matched_words/suggestion |
| `check_privacy_leak(text)` | `str -> List[str]` | 命中的隐私字段名 |
| `add_custom_word(word)` | `str -> None` | 动态加词(v1.0 未挂路由) |
| `remove_custom_word(word)` | `str -> None` | 动态删词(v1.0 未挂路由) |
### 5.2 路由层 API(计划中)
| 接口 | 方法 | 说明 | 状态 |
|------|------|------|------|
| `/api/admin/sensitive-words` | GET | 词库列表 | ❌ 未实现 |
| `/api/admin/sensitive-words` | POST | 添加词 | ❌ 未实现 |
| `/api/admin/sensitive-words/{id}` | DELETE | 删除词 | ❌ 未实现 |
| `/api/admin/sensitive-words/test` | POST | 测试输入文本(不入库) | ❌ 未实现 |
| `/api/admin/privacy-patterns` | GET/POST | 隐私正则管理 | ❌ 未实现 |
| `/api/admin/moderation-config` | GET/PUT | 命中动作配置(WARN/BLOCK | ❌ 未实现 |
> **现状**v1.0 仅服务层可用,无 HTTP API 暴露。
---
## 6. 数据需求
### 6.1 词库存储(v1.0 写死,v1.1 计划入库)
| 字段 | 规格 |
|------|------|
| 表名 | `sensitive_words`v1.1 计划新建) |
| 字段 | id / word / category / severity / is_active / created_at / updated_at |
| severity | 1=低(仅 WARN/ 2=中(WARN+审计)/ 3=高(BLOCK |
| 初始化 | 通过 Alembic 迁移 + init SQL 导入基础词库 |
| 缓存 | 服务启动时全量加载到 `Wordfilter` 实例 |
### 6.2 隐私正则存储(同上)
| 字段 | 规格 |
|------|------|
| 表名 | `privacy_patterns`v1.1 计划新建) |
| 字段 | id / name / pattern / description / is_active / created_at |
| 名称示例 | phone / id_card / bank_card / personal_email |
| 初始化 | 同上,Alembic + init SQL |
### 6.3 命中审计日志(v1.1 计划)
| 字段 | 规格 |
|------|------|
| 表名 | `moderation_logs` |
| 字段 | id / message_id / agent_id / matched_words / category / action / created_at |
| 用途 | 追溯谁发了什么被警告 |
---
## 7. 风险与约束
| 风险 | 等级 | 缓解措施 |
|------|------|----------|
| 命中仅 WARN,违规坐席可忽略 | 🟡 中 | PRD §3.5 已记录决策;后续可配置 |
| 词库写死,运营无法调整 | 🟡 中 | v1.1 计划入库(PRD §6 |
| 隐私正则覆盖有限(未含军官证/护照/车牌) | 🟢 低 | v1.1 计划扩展正则集合 |
| 误报(正常消息触发 WARN) | 🟡 中 | 词库极小(4 条),v1.1 后由运营调整 |
| 漏报(新敏感词未及时入库) | 🟡 中 | 依赖运营定期 review |
| 后台 UI 缺失 | 🟡 中 | v1.1 计划开发(参考通用-002 快速回复规则后台管理) |
---
## 8. 验收标准
### 8.1 必达项(v1.0 已实现)
- [x] `moderate("你爱找谁找谁")` 返回 WARNmatched_words 含该词
- [x] `moderate("您好,电脑无法开机")` 返回 PASS
- [x] `check_privacy_leak("电话13800138000")` 返回 `["phone"]`
- [x] `check_privacy_leak("身份证11010119900307123X")` 返回 `["id_card"]`
- [x] 命中动作固定为 WARN,不 BLOCK
- [x] 自定义词库包含 4 条基础词
- [x] 隐私正则使用数字边界(修复 Python3 中文失效)
### 8.2 已知不达标项(v1.0 接受,v1.1 解决)
- [ ] 命中动作可配置(v1.0 固定 WARN)
- [ ] 词库可数据库化(v1.0 写死)
- [ ] 后台管理 UIv1.0 无)
- [ ] 命中审计日志(v1.0 无)
- [ ] 隐私正则可扩展(v1.0 仅 4 类)
---
## 9. 关联文档
| 文档 | 位置 | 关联点 |
|------|------|--------|
| 看板验真测试报告 | `03-测试文档/04-版本测试报告/看板验真-测试报告-20260707.md` | 历史基线测试(11/13 通过) |
| 项目状态看板 #81 | `07-项目管理/任务说明书/IT智能服务台-项目管理主文档.md` | v0.7.1 已上线 |
| 快速回复规则后台管理 PRD | `01-产品文档/00-产品规划/PRD-REQ-通用-002-快速回复规则后台管理-v1.2.md` | 同类功能(运营后台词库管理),可复用架构 |
| 知识库迭代技术方案 §4 代答排除规则 | `02-技术文档/技术架构/技术方案-REQ-知识-001-知识库迭代-v1.0.md` | 关键词匹配机制可参考 |
| 内容审核服务源码 | `src/backend/app/services/content_moderation_service.py` | 当前实现 |
| 内容审核测试源码 | `src/backend/tests/test_content_moderation.py` | 13 用例基线 |
---
## 10. 变更日志
| 版本 | 日期 | 变更 | 变更人 |
|------|------|------|--------|
| v1.0 | 2026-07-28 | 首次整理:v0.7.1 上线内容回溯为正式 PRD | 宋献 |
---
> **备注**:本文档是对 v0.7.1 已上线功能的**回溯性 PRD 化**,用于补全项目文档体系。功能本身已在生产稳定运行(命中即 WARN 是已接受的产品决策)。
@@ -0,0 +1,419 @@
# PRD - 敏感词检测 v1.2AI 辅助运营)
> **需求编号**: REQ-通用-004
> **版本**: v1.2(基于 v1.1 升级)
> **状态**: 草案 v1.0(待评审)
> **作者**: 宋献
> **日期**: 2026-07-28
> **前置版本**: PRD-REQ-通用-004-敏感词检测-v1.0v0.7.1 上线),v1.1DB化+后台 UI+审计日志,2026-07-28 上线)
> **关联文档**:
> - 前置 PRD`01-产品文档/00-产品规划/PRD-REQ-通用-004-敏感词检测-v1.0.md`
> - 前置技术方案:`02-技术文档/技术架构/技术方案-REQ-通用-004-敏感词检测-v1.0.md`
> - 关联战略:`01-产品文档/00-产品规划/IT服务台AI化战略路线图-v1.0.md`
---
## 1. 需求描述
### 1.1 背景(v1.1 回顾)
v1.12026-07-28 上线)实现了:
- 词库入库(`sensitive_words` / `privacy_patterns`
- 后台管理 UI4 Tabs
- 命中审计日志
- 灰度开关
**v1.1 仍然依赖人肉运营**
- 新敏感词需运营**逐条人工发现并加入**
- 词库命中规则**写死 4 条** + 运营手动扩展
- 绕过场景(如"自己不会百度嘛"加语气词)**无法识别**
- 词库命中率/误判率**无人系统分析**
### 1.2 v1.2 升级动机
**业务压力**:组织正经历 AI 技术冲击,**没有时间从"人肉维护"过渡到"AI 维护"**,敏感词检测 v1.2 必须**直接进入 AI 辅助运营阶段**。
### 1.3 v1.2 目标
| 目标 | 描述 |
|------|------|
| **G1 自动化运营** | 词库发现 / 分类 / 调整由 AI 完成,人工仅最终审核 |
| **G2 绕过场景覆盖** | 引入 AI 语义级检测,**替代 wordfilter** 主路径 |
| **G3 反馈闭环** | 误判自动反馈 → AI 学习 → 自动加白名单 |
| **G4 数据驱动** | 命中率/误判率/绕过模式可量化分析 |
### 1.4 范围
| 范围项 | v1.2 状态 | 说明 |
|--------|----------|------|
| AI 敏感词发现引擎 | ✅ P0 必做 | Dify 工作流:历史 messages + 工单 → LLM 提取 |
| AI 审核工作台 | ✅ P0 必做 | 运营一键 approve / reject |
| AI 误判反馈闭环 | ✅ P0 必做 | 坐席 WARN 后"非命中"反馈 → AI 学习 → 白名单建议 |
| **AI 语义级检测** | ✅ **P0 主路径** | **替代 wordfilter**(用户决策 2026-07-28 确认) |
| AI 自动构造测试用例 | 🟡 P1 | 对抗样本自动生成 |
| AI 智能日报 | 🟡 P1 | 每日违规模式自动分析 |
| AI 自动审批(无人审核) | ❌ P2 不做 | 与 2026-07-08 决策冲突,保留人工最终审核 |
| AI 自动变更 severity | ❌ P2 不做 | 需配套审计,待评审 |
### 1.5 Non-goals
| 不做 | 原因 |
|------|------|
| 完全无人化(AI 全自动) | 决策保留:所有 AI 推荐需人工最终确认 |
| 多语言支持 | 业务尚未确认 |
| 跨租户词库隔离 | 当前单租户架构,无 SaaS 化需求 |
| 组织级 AI 化变革 | 独立任务(见 AI 化路线图),v1.2 仅做工具自身 AI 化 |
---
## 2. 用户故事
### 2.1 运营人员
| 优先级 | 用户故事 |
|--------|----------|
| P0 | 作为运营,我希望看到 AI 自动推荐的新词候选,一键加入词库 |
| P0 | 作为运营,我希望 AI 自动判定分类(profanity/privacy)和 severity,无需我手动选 |
| P0 | 作为运营,我希望 AI 自动分析"非命中"反馈,给出白名单建议 |
| P1 | 作为运营,我希望看到每日违规分析报告(高频词/高频坐席) |
| P1 | 作为运营,我希望 AI 自动生成对抗样本测试,验证词库覆盖率 |
### 2.2 坐席
| 优先级 | 用户故事 |
|--------|----------|
| P0 | 作为坐席,我希望 AI 能识别"自己不会百度嘛"等绕过的语气(不被精确匹配绕过) |
| P0 | 作为坐席,我希望误报时一键标记"非命中",系统记住我的反馈 |
| P0 | 作为坐席,我希望继续保留最终发送权(不被 AI 强制阻断) |
### 2.3 管理员
| 优先级 | 用户故事 |
|--------|----------|
| P1 | 作为管理员,我希望所有 AI 推荐/审核记录可追溯 |
| P1 | 作为管理员,我希望 AI 引擎可灰度启用(如先 1 个部门试运行) |
| P2 | 作为管理员,我希望 AI 引擎可关闭,回到 v1.1 模式 |
---
## 3. 功能需求
### 3.1 AI 敏感词发现引擎(P0
| 字段 | 规格 |
|------|------|
| 输入数据 | 1) 历史 messages(最近 30 天)<br>2) 工单投诉内容<br>3) 审计日志(被 WARN 的文本)<br>4) 运营白名单(已知非敏感词) |
| AI 处理 | Dify 工作流:<br>① 数据采样(按时间+部门)<br>② LLM 推理(提取风险词 + 判定分类 + 判定 severity<br>③ 去重(与现有词库 diff<br>④ 输出"待审核"队列 |
| 触发时机 | 每日凌晨 03:00 自动跑(cron<br>运营可手动触发(按钮) |
| 输出 | `ai_pending_words` 表(待审核队列) |
| 数据量 | 30 天 messages 约 1 万条,LLM 处理 ≈ 30 秒 |
### 3.2 AI 审核工作台(P0
| 字段 | 规格 |
|------|------|
| 位置 | `/sensitive-words` 管理后台 → 新增 Tab"AI 推荐" |
| 展示 | 待审核词列表:word / category / severity / AI 置信度 / 来源 / 推荐时间 |
| 操作 | 1) approve → 写入 `sensitive_words` 表<br>2) reject → 标记"已拒绝",不再推荐<br>3) 编辑 → 修改 word/category/severity 后 approve |
| 批量 | 支持批量 approve(多选) |
| 审计 | 所有操作写 `ai_word_review_logs` 表 |
### 3.3 AI 误判反馈闭环(P0
| 字段 | 规格 |
|------|------|
| 坐席侧 | WARN 提示条增加"非命中"按钮 |
| 后端 | 接收反馈 → 写入 `false_positive_feedback` 表(text / agent_id / timestamp |
| AI 处理 | 每日分析"非命中"反馈:<br>① 提取频繁被标记的词/短语<br>② LLM 判定"确为误报" → 自动加白名单<br>③ LLM 判定"需复审" → 入 AI 审核队列 |
| 白名单存储 | 新增 `whitelist` 表(phrase / category / source / created_at |
| 检测逻辑 | 审核时:先查白名单 → 命中则直接 PASS |
### 3.4 AI 语义级检测(P0 主路径)
| 字段 | 规格 |
|------|------|
| **替代目标** | **替代 wordfilter** 作为主检测引擎 |
| 实现方式 | Dify LLM 调用(GPT-4o-mini 或国产模型) |
| 输入 | 坐席消息文本 |
| 输出 | `{action, category, matched_concepts, confidence, suggestion}` |
| 响应时间 | < 2sP95 |
| 成本 | ¥0.001 / 次(GPT-4o-mini<br>按日均 1 千条消息 ≈ ¥1/天 |
| 降级策略 | Dify 不可用时 → 降级为 wordfilterv1.1 引擎)<br>降级日志:ERROR + 计数 |
| 决策动作 | 仍维持 WARN2026-07-08 决策保留) |
| 旁路 | wordfilter 仍作为快速预筛(命中则直接 WARN,不调 AI)<br>未命中 → 调 AI 语义 |
### 3.5 AI 自动构造测试用例(P1)
| 字段 | 规格 |
|------|------|
| 触发 | CI 流水线 / 运营手动 |
| 生成 | LLM 自动生成 100 条对抗样本(语气词 / 同义词 / 拼音化) |
| 跑测 | 自动跑 pytest 报告 |
| 输出 | 覆盖率报告:词库覆盖 / AI 语义覆盖 / 遗漏点 |
### 3.6 AI 智能日报(P1
| 字段 | 规格 |
|------|------|
| 触发 | 每日 08:00 自动生成 |
| 内容 | 1) 命中总数(按 action / category 分布)<br>2) 高频违规坐席(Top 10<br>3) 高频违规部门(按部门聚合)<br>4) 命中时段分布(小时级热力图)<br>5) AI 语义命中 vs wordfilter 命中(覆盖率对比)<br>6) 误报率("非命中"反馈占比) |
| 推送 | 管理员企微消息卡片 |
| 存储 | `daily_reports` 表(30 天滚动) |
---
## 4. 数据需求
### 4.1 新增表
#### `ai_pending_words`AI 推荐词队列)
```sql
CREATE TABLE ai_pending_words (
id SERIAL PRIMARY KEY,
word VARCHAR(100) NOT NULL,
category VARCHAR(50) NOT NULL,
severity SMALLINT NOT NULL,
confidence DECIMAL(3,2) NOT NULL, -- 0.00~1.00
source VARCHAR(50) NOT NULL, -- message_sample / complaint / audit_log
sample_text TEXT, -- 原始样本(前 200 字)
status VARCHAR(20) DEFAULT 'pending', -- pending / approved / rejected
reviewed_by INTEGER REFERENCES users(id),
reviewed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(word, status)
);
CREATE INDEX idx_pending_status ON ai_pending_words(status, created_at);
```
#### `false_positive_feedback`(误判反馈)
```sql
CREATE TABLE false_positive_feedback (
id BIGSERIAL PRIMARY KEY,
agent_id INTEGER NOT NULL REFERENCES agents(id),
original_text TEXT NOT NULL,
matched_word VARCHAR(100),
category VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_fp_agent ON false_positive_feedback(agent_id, created_at);
```
#### `whitelist`(白名单)
```sql
CREATE TABLE whitelist (
id SERIAL PRIMARY KEY,
phrase VARCHAR(200) NOT NULL UNIQUE,
category VARCHAR(50),
source VARCHAR(50), -- ai_auto / manual / fp_feedback
created_at TIMESTAMP DEFAULT NOW(),
expires_at TIMESTAMP -- 可选:临时白名单
);
```
#### `ai_word_review_logs`AI 推荐审核记录)
```sql
CREATE TABLE ai_word_review_logs (
id BIGSERIAL PRIMARY KEY,
pending_id INTEGER REFERENCES ai_pending_words(id),
reviewer_id INTEGER REFERENCES users(id),
action VARCHAR(20) NOT NULL, -- approve / reject / edit
original_word VARCHAR(100),
final_word VARCHAR(100),
notes TEXT,
created_at TIMESTAMP DEFAULT NOW()
);
```
#### `daily_reports`(每日报告)
```sql
CREATE TABLE daily_reports (
id SERIAL PRIMARY KEY,
report_date DATE UNIQUE NOT NULL,
payload JSONB NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
```
### 4.2 `sensitive_words` 表扩展
```sql
-- 新增字段
ALTER TABLE sensitive_words ADD COLUMN source VARCHAR(50) DEFAULT 'manual';
-- source 取值: manual / ai_recommend / imported / migrated_from_v07
ALTER TABLE sensitive_words ADD COLUMN confidence DECIMAL(3,2);
-- 仅 ai_recommend 来源的词有置信度
```
### 4.3 Alembic 迁移
- 新建:`alembic/versions/057_add_ai_moderation_tables.py`
---
## 5. 接口需求
### 5.1 新增后端 API11 端点)
| 接口 | 方法 | 说明 | 权限 |
|------|------|------|------|
| `/api/admin/ai-pending-words` | GET | 列表查询 | admin |
| `/api/admin/ai-pending-words/{id}/approve` | POST | 审核通过 | admin |
| `/api/admin/ai-pending-words/{id}/reject` | POST | 审核拒绝 | admin |
| `/api/admin/ai-pending-words/batch-approve` | POST | 批量通过 | admin |
| `/api/admin/ai-pending-words/trigger` | POST | 手动触发 AI 发现 | admin |
| `/api/admin/false-positive-feedback` | POST | 坐席提交反馈 | agent |
| `/api/admin/false-positive-feedback` | GET | 查询反馈 | admin |
| `/api/admin/whitelist` | GET/POST/PUT/DELETE | 白名单 CRUD | admin |
| `/api/admin/whitelist/auto-suggest` | POST | AI 基于反馈生成建议 | admin |
| `/api/admin/daily-reports/latest` | GET | 最新日报 | admin |
| `/api/admin/daily-reports/{date}` | GET | 指定日期日报 | admin |
### 5.2 改造现有 API
| 接口 | 变更 |
|------|------|
| `POST /admin/sensitive-words/test` | 增加 AI 语义模式(`mode=ai` |
| `GET /admin/moderation-config` | 增加 `ai_engine_enabled` 字段 |
| `PUT /admin/moderation-config` | 增加 AI 引擎开关 |
### 5.3 Dify 工作流(3 个)
| 工作流 | 用途 |
|--------|------|
| `sensitive_word_discovery` | 输入 messages → 输出风险词列表 |
| `false_positive_analyzer` | 输入 fp_feedback → 输出白名单建议 |
| `daily_report_generator` | 输入审计日志 + 命中数据 → 输出日报 |
### 5.4 配置项(v1.2 新增)
```python
# config.py
AI_MODERATION_ENABLED = False # 总开关
AI_DISCOVERY_CRON_HOUR = 3 # 每日 AI 发现执行时间
AI_DAILY_REPORT_HOUR = 8 # 日报推送时间
DIFY_DISCOVERY_APP_ID = "..." # 复用现有 Dify app
DIFY_API_KEY = "..." # 从 .env 读
WHITELIST_ENABLED = True # 白名单开关
```
**配置同步铁律**:新增 6 个配置项时需同步:
1. `config.py` 字段
2. `docker-compose.yml``backend.environment`
3. `.env.example` 模板
---
## 6. 数据隐私合规(重要)
### 6.1 LLM 输入数据合规
| 数据类型 | 合规要求 |
|----------|----------|
| 历史 messages | 喂 LLM 前**脱敏**:移除手机号/身份证/邮箱/姓名 |
| 工单投诉内容 | 同样脱敏 |
| 审计日志 | 已脱敏(v1.1 仅存 text_excerpt 100 字) |
### 6.2 脱敏规则
```python
# content_moderation_service.py 新增 _sanitize_for_ai()
def _sanitize_for_ai(text: str) -> str:
"""喂 AI 前脱敏"""
text = re.sub(r'(?<!\d)1[3-9]\d{9}(?!\d)', '[PHONE]', text)
text = re.sub(r'(?<!\d)\d{17}[\dXx](?!\d)', '[ID_CARD]', text)
text = re.sub(r'(?<!\d)\d{16,19}(?!\d)', '[BANK]', text)
text = re.sub(r'[\w.-]+@[\w.-]+\.[\w]+', '[EMAIL]', text)
text = re.sub(r'[\u4e00-\u9fa5]{2,4}(?=先生|女士|老师|经理|总)', '[NAME]', text)
return text
```
### 6.3 合规审计
| 审计项 | 实施 |
|--------|------|
| LLM 调用日志 | `ai_llm_calls` 表:app_id / 输入 hash / 输出 / 延迟 / 成本 |
| 数据脱敏校验 | 单元测试:确保喂 LLM 前已脱敏 |
| 运营 review 记录 | 所有 AI 推荐审核写入 `ai_word_review_logs` |
| 错误监控 | Sentry / 日志告警:Dify API 失败率 > 5% |
---
## 7. 风险与降级
| 风险 | 等级 | 降级措施 |
|------|------|----------|
| Dify API 不可用 | 🟡 中 | 自动降级为 wordfilterv1.1 引擎) |
| AI 推荐质量低 | 🟡 中 | 置信度 < 0.7 不入"待审核"队列 |
| 脱敏不彻底泄露隐私 | 🟠 高 | 脱敏失败时**不调 LLM**,直接降级 wordfilter |
| AI 误判高(绕过场景也误报) | 🟡 中 | 人工 review 必须;自动阈值兜底 |
| 审计日志爆炸 | 🟢 低 | 7 天前的旧 fp_feedback 自动清理 |
| AI 引擎与决策冲突 | 🟡 中 | **保留人工最终审核**(决策保留 2026-07-08 |
---
## 8. 验收标准
### 8.1 必达项(v1.2 P0
- [ ] AI 发现引擎每天 03:00 自动跑,生成 ≥ 1 个推荐词(基于历史数据)
- [ ] AI 审核工作台:运营可一键 approve / reject / 批量 approve
- [ ] AI 误判反馈闭环:坐席"非命中"按钮 → 24h 内 AI 自动分析
- [ ] **AI 语义级检测作为主路径**Dify 不可用时降级 wordfilter
- [ ] AI 语义覆盖"自己不会百度嘛"等语气绕过场景
- [ ] 数据脱敏:喂 LLM 前已移除 PII
- [ ] 所有 AI 推荐均经人工最终确认
- [ ] 命中动作仍为 WARN(决策保留)
- [ ] 白名单生效:白名单词命中 WARN 时直接 PASS
- [ ] 灰度开关:`AI_MODERATION_ENABLED=false` 时回到 v1.1 行为
### 8.2 非必达(v1.2 P1 / P2
- [ ] AI 自动构造测试用例(P1
- [ ] AI 智能日报推送(P1
- [ ] AI 自动审批(不做)
- [ ] AI 自动变更 severity(不做)
---
## 9. 实施路线
| 阶段 | 内容 | 工作量 |
|------|------|--------|
| **D1** | Dify 工作流(3 个)开发 + 测试 | 2 天 |
| **D2** | 后端:5 新表 + 11 API + 现有 API 扩展 | 2 天 |
| **D3** | 前端:AI 审核工作台 + 误报反馈按钮 + 白名单 UI | 2 天 |
| **D4** | AI 语义级检测集成 + 降级逻辑 | 1 天 |
| **D5** | 数据脱敏 + 合规审计 | 0.5 天 |
| **D6** | 部署 + 灰度发布(先 1 个坐席试运行 24h) | 1 天 |
| **总计** | | **8.5 天** |
---
## 10. 关联文档
| 文档 | 位置 | 关联点 |
|------|------|--------|
| 前置 PRD v1.0 | `01-产品文档/00-产品规划/PRD-REQ-通用-004-敏感词检测-v1.0.md` | 基础功能 |
| 前置技术方案 v1.0 | `02-技术文档/技术架构/技术方案-REQ-通用-004-敏感词检测-v1.0.md` | 实现参考 |
| 前置测试用例 | `03-测试文档/03-功能测试用例/TC-通用-004-敏感词检测.md` | 测试基线 |
| **关联战略** | `01-产品文档/00-产品规划/IT服务台AI化战略路线图-v1.0.md` | **v1.2 是战略落地的第一个抓手** |
| Dify 应用清单 | `02-技术文档/实现配置/dify_dsl/` | 新增 3 工作流 |
| 看板验真测试报告 | `03-测试文档/04-版本测试报告/看板验真-测试报告-20260707.md` | 历史基线 |
---
## 11. 变更日志
| 版本 | 日期 | 变更 | 变更人 |
|------|------|------|--------|
| v1.0 | 2026-07-28 | 首次整理:v0.7.1 上线内容回溯为正式 PRD | 宋献 |
| v1.1 | 2026-07-28 | DB化 + 后台 UI + 审计日志 + 灰度开关 | 宋献 |
| **v1.2 草案 v1.0** | **2026-07-28** | **AI 辅助运营:AI 语义级检测纳入 P0 替代 wordfilter** | **宋献** |
---
> **关键决策记录**
> - 2026-07-08:命中动作固定 WARNv1.0 决策)
> - 2026-07-28v1.1 上线(DB化)
> - **2026-07-28v1.2 启动,AI 语义级检测作为主路径,AI 辅助运营为定位**
@@ -0,0 +1,178 @@
# PRD - 选项选择持久化
> **REQ 编号**: REQ-通用-005
> **版本**: v1.0
> **日期**: 2026-07-29
> **作者**: 许清楚(PM+ 宋献(Simon
> **状态**: ✅ 已批准
> **关联**:
> - 技术方案:docs/02-技术文档/技术架构/技术方案-REQ-通用-005-选项选择持久化-v1.0.md(待架构师出)
> - 测试用例:docs/03-测试文档/03-功能测试用例/TC-REQ-通用-005-选项选择持久化-v1.0.md(待 QA 出)
> - 代码真相:src/backend/app/api/ws.py + src/backend/app/services/h5_ai_task.py
> - 相关 PRDPRD-REQ-用户-006-智能推荐重构-v1.0.md(衍生关系)
---
## 1. 问题陈述
Dify 工作流可输出 quick reply / 选择题形式的“选项消息”。AI 选项消息已以 `msg_type="ai_structured"``extra_data.options` 持久化,但用户点选后,后端 `_handle_option_select` 当前故意不写 `messages` 表,仅进行瞬时 WebSocket 广播并将 `option_label` 传给 Dify`src/backend/app/api/ws.py:277-281`)。坐席端的 `selectedOptionLabels` 又是纯内存集合,重连即失效,导致选择动作无法追溯。
| 优先级 | 业务影响 | 真实场景 | 可量化后果 |
|---|---|---|---|
| P0 | 合规与审计留痕缺失 | 金融/政府客户复盘“员工选择了哪一项”时,管理端无记录 | 操作链不完整,无法满足可追溯要求 |
| P0 | 坐席分诊效率下降 | 紧急报修员工已选“网络中断”,坐席进会话后看不到,只能重问 | 会话时长预计增加约 20%,存在 SLA 风险 |
| P1 | AI 推荐反馈闭环断裂 | 智能推荐卡 A/B/C 中用户选 C,但系统无结构化选择数据 | A/B/C 效果不可归因,AI 投入 ROI 难评估 |
| P1 | 会话连续性中断 | 员工刷新或退出 H5 后,历史中缺少已选内容 | 断点续聊上下文不完整,Dify 将选择误识别为普通发言 |
| P2 | 员工体验不一致 | 员工看不到“我之前选了什么” | 重复操作、降低信任感 |
**目标**:以零数据库迁移方式,将每次选择作为 `employee` 消息持久化,并在 H5、坐席、管理审计、Dify 反馈链和转人工上下文中形成一致、可追溯的数据闭环。
---
## 2. 用户故事
| 角色 | 现状 | 期望用户故事 |
|---|---|---|
| 员工 H5 | 刷新/退出后已选内容消失 | 作为员工,我希望每次选择都进入消息历史,以便刷新或续聊时仍能确认我选过什么 |
| 坐席 PC | 仅实时内存可见,进入晚或重连后不可见 | 作为坐席,我希望实时及历史消息中看到“✓ 选项”,并识别最新选择,以便无需重复询问即可分诊 |
| 管理端 | 无选择记录可供审计、复盘 | 作为管理员,我希望按会话追溯选择时间、题目和选项,以便满足合规审计和投诉复盘 |
| AI 训练/运营 | 选择被当作普通自然语言,且缺少选项归属 | 作为 AI 训练人员,我希望获得带 `question_id``option_id``feedback_type` 的反馈,以便准确评估推荐效果 |
---
## 3. 范围
### 3.1 In-scopev1.0 MVP
| # | 范围项 | 优先级 |
|---|---|---|
| 1 | `_handle_option_select` 插入 `msg_type="option_select"` 的员工消息(`src/backend/app/api/ws.py:270-281` | P0 |
| 2 | 选择成功后使用标准 `new_message` 事件广播(`src/backend/app/api/ws.py:284-293` | P0 |
| 3 | 坐席 `MessageBubble.vue` 渲染“✓ {content}”灰色徽标,最新选择高亮(`src/frontend-agent/src/components/chat/MessageBubble.vue:52-77` | P0 |
| 4 | H5 `sendOptionSelect` 补齐来源消息、客户端幂等及题目/选项标识(`src/frontend-h5/src/stores/conversation.ts:1486` | P0 |
| 5 | 客户端生成 UUID,服务端按会话与客户端消息 ID 执行 5 秒去重 | P0 |
| 6 | 回归“发送→点选→坐席实时→坐席重连→REST 历史仍可见”完整链路 | P0 |
| 7 | Dify inputs 注入 `feedback_type=option_select` | P1 |
| 8 | 转人工时注入 `selected_options` 快照 | P1 |
| 9 | 选项展示遵循敏感信息中间四位脱敏 | P0 |
### 3.2 Out-of-scope
- 方案 B:新增 `conversation_selections` 表及数据库迁移。
- 方案 C:仅向 `ai_structured.extra_data` 追加 `selected_options`
- 多卡嵌套、父子题、条件题等复杂语义编排。
- 跨会话选择聚合、BI 看板与推荐效果报表。
---
## 4. 功能需求
### 4.1 后端落库 Schema
服务端收到合法选择后,必须先完成幂等判断,再向现有 `messages` 表追加一行;不得覆盖原选项消息或历史选择。实现位置为 `_handle_option_select``src/backend/app/api/ws.py:270-281`)。
| 字段 | 类型/示例 | 必填 | 规则 |
|---|---|---:|---|
| `msg_type` | `"option_select"` | 是 | 新增文档化取值;现有字段 `String(20)`,零迁移 |
| `sender_type` | `"employee"` | 是 | 表示员工操作 |
| `content` | `"网络中断"` | 是 | 保存原始 `option_label`,展示时再脱敏 |
| `extra_data.option_value` | `"network_down"` | 是 | 传给业务/Dify 的选项值 |
| `extra_data.selected_from_message_id` | 消息 ID | 是 | 关联产生选项的 `ai_structured` 消息 |
| `extra_data.client_msg_id` | UUID | 是 | 幂等键 |
| `extra_data.question_id` | `"fault_type"` | 是 | 题目稳定标识,支持跨卡归属 |
| `extra_data.option_id` | `"network_down"` | 是 | 选项稳定标识,禁止仅靠 label 归属 |
持久化成功后,REST 历史接口必须按现有消息排序规则返回该记录;失败时不得向 Dify提交“已成功选择”的假状态。
### 4.2 WS 事件改造
当前瞬时专用广播必须改为标准 `new_message` 事件(`src/backend/app/api/ws.py:284-293`),事件 payload 应复用持久化后的消息对象,至少包含消息 ID、会话 ID、发送方、消息类型、内容、`extra_data`、创建时间。坐席实时态与重连后的 REST 历史态必须使用同一数据模型。
### 4.3 坐席端渲染规范
- `src/frontend-agent/src/components/chat/MessageBubble.vue:52-77` 必须增加 `msg_type === "option_select"` 分支。
- 徽标位于员工消息流原选择发生的时间位置,文案为 `✓ {mask(content)}`,采用灰色次要信息样式,不渲染为普通气泡。
- 同一 `question_id` 多次选择全部保留;当前最新一条使用主色描边或浅色背景高亮,旧选择降级为灰色。
- 最新判定按服务端消息时间与消息 ID 稳定排序,不依赖 `selectedOptionLabels` 内存集合。
### 4.4 H5 端字段补全
`sendOptionSelect``src/frontend-h5/src/stores/conversation.ts:1486-1518`)必须发送:`option_label``option_value``selected_from_message_id``client_msg_id``question_id``option_id``client_msg_id` 在首次点击时生成 UUID;同一次请求重试必须复用,用户主动重选必须生成新 UUID。
### 4.5 幂等与去重规则
- 服务端幂等键:`(conversation_id, client_msg_id)`
- 去重窗口:首次受理后 5 秒;窗口内重复请求只返回首次成功结果,不新增消息、不重复广播、不重复调用 Dify。
- 5 秒后相同 ID 仍不得被客户端主动复用;服务端可记录告警并拒绝,以避免历史重复。
- 不同 `client_msg_id` 即视为撤回后的重选/再次选择,追加新行。
### 4.6 Dify 集成
传入 Dify Workflow 的 inputs 必须新增 `feedback_type="option_select"`,并同时传递 `question_id``option_id``option_value`、脱敏后的 `option_label`;接入点由技术方案基于现有 Dify 调用链定位(当前调用见 `src/backend/app/tasks/h5_ai_task.py:1505-1514`,任务入口见 `src/backend/app/tasks/h5_ai_task.py:1617-1624`)。Dify 必须据此区分“用户选择了 X”与“用户自然语言说了 X”,且不破坏现有普通文本消息链路。
### 4.7 转人工快照
触发转人工时,系统必须按每个 `question_id` 取最新一条有效选择,组成 `selected_options` 注入坐席上下文;每项至少包含 `question_id``option_id`、脱敏 label、选择消息 ID、选择时间。快照仅用于快速接续,审计真相仍以 `messages` 表全部追加记录为准。
### 4.8 敏感词 Mask
选项含账号、身份证号等敏感数字串时,数据库保存原始值以满足审计权限场景;H5、坐席普通视图、WS 普通 payload、Dify inputs 和转人工快照必须将数字串中间连续四位替换为 `****`。不足 4 位的敏感值全部掩码;脱敏不得改变 `question_id``option_id` 的匹配与最新选择判定。
---
## 5. 验收标准
| 编号 | 对应需求 | 验收用例与通过标准 |
|---|---|---|
| AC-01 | 4.1 | 点选后 `messages` 新增 1 行:`msg_type=option_select``sender_type=employee`5 个 `extra_data` 字段完整;REST 重拉仍存在 |
| AC-02 | 4.1 | 连续重选两次形成两行,不覆盖首次记录,均可按时间追溯 |
| AC-03 | 4.2 | 坐席在线时收到标准 `new_message`;断线重连后从 REST 得到相同消息 ID 与内容 |
| AC-04 | 4.3 | 坐席显示“✓ 选项”灰色徽标;同一 `question_id` 仅最新一条高亮,旧记录仍可见 |
| AC-05 | 4.4 | H5 每次主动选择生成合法 UUID,并携带来源消息、题目、选项标识;重试复用 UUID |
| AC-06 | 4.5 | 5 秒内用相同 `(conversation_id, client_msg_id)` 重发 3 次,仅落库、广播、调用 Dify 各 1 次 |
| AC-07 | 4.6 | Dify 收到 `feedback_type=option_select` 及题目/选项字段;普通文本仍沿用原语义 |
| AC-08 | 4.7 | 员工选择后立即转人工,坐席上下文包含各 `question_id` 最新选择;坐席无需重问 |
| AC-09 | 4.8 | 选项包含账号/身份证示例时,各普通展示及 Dify 输入中间四位为 `****`,数据库审计原值不变 |
| AC-10 | 全链路 | 完成“AI 发选项→员工点选→坐席实时 ✓→坐席重连→REST 历史仍可见”,全程无重复记录 |
---
## 6. 边界场景
| 场景 | 产品规则 | 预期结果 |
|---|---|---|
| 撤回/重选 | 不改旧行,使用新 `client_msg_id` 追加记录 | 全历史可见;同题最新一条高亮并进入快照 |
| 弱网重发 | 同一请求复用 `client_msg_id`,5 秒窗口去重 | 只落库、广播、调用 Dify 一次 |
| 跨卡归属 | 必须联合 `question_id + option_id`,label 不作为唯一键 | 多卡存在同名 label 时仍准确归属 |
| 敏感词 | 存储原值,展示与外发链路 mask 中间四位 | 审计可追溯,普通使用方不暴露敏感值 |
| 转人工 | 每题取最新选择生成 `selected_options` | 人工坐席获取完整断点上下文,历史行不丢失 |
---
## 7. 非目标
1. 不新增选择专表、不执行 Alembic 迁移。
2. 不把选择状态回写到原 `ai_structured.extra_data`,避免撤回/重选语义丢失。
3. 不建设选项编辑、撤销按钮;v1.0 的“撤回”通过再次选择表达。
4. 不定义多卡嵌套题、跨题依赖和选择有效期。
5. 不建设跨会话 BI、推荐转化率报表或模型自动训练流水线。
6. 不改造所有历史 `recommend_event` 数据,仅保证新链路兼容。
---
## 8. 风险
| 风险点 | 等级 | 说明 | 缓解/验证 |
|---|---|---|---|
| `ws_manager` 单例状态依赖 | 高 | 单进程内存去重或广播状态在重启后丢失 | 幂等以消息持久化查询为准,内存仅作加速;补充重启回归 |
| 多 worker 并发竞态 | 高 | 两个 worker 同时处理同一 UUID,5 秒内可能双写 | 技术方案必须定义原子去重策略;并发压测验证仅生成一条消息 |
| Dify 反馈链语义变化 | 中 | 新增 `feedback_type` 后,旧工作流节点可能忽略或误用字段 | 字段向后兼容、灰度开启;验证普通文本和选项两条链 |
| `recommend_event` 兼容性 | 中 | 现有智能推荐事件仍可能依赖旧 payload 或 label | 保留旧必要字段,新增字段只增不删;覆盖单卡、多卡与转人工回归 |
---
## 9. 变更记录
| 版本 | 日期 | 变更内容 | 变更人 | 变更原因 |
|---|---|---|---|---|
| v1.0 | 2026-07-29 | 创建 PRD,固化方案 A、6 项产品决策与 MVP 验收范围 | 许清楚、宋献 | 修复选项选择不落库导致的数据完整性问题 |
@@ -0,0 +1,202 @@
# PRD(增量草案) — 选项选择持久化 v1.1
> **REQ 编号**: REQ-通用-005
> **版本**: v1.1-**DRAFT**(草案,待用户确认范围,不替代 v1.0)
> **日期**: 2026-08-02
> **作者**: 许清楚(PM
> **状态**: 🟡 草案(v1.0 已批准,v1.1 仅增不删)
> **基线**: v1.0 PRD179 行,9 章节,已批准)+ v1.0 技术方案(523 行,11 章节)+ v1.0 测试用例(35 条)+ Dify v3 DRAFT
> **关联**:
> - 基线 PRD`docs/01-产品文档/00-产品规划/PRD-REQ-通用-005-选项选择持久化-v1.0.md`
> - 基线技术方案:`docs/02-技术文档/技术架构/技术方案-REQ-通用-005-选项选择持久化-v1.0.md`
> - 基线测试用例:`docs/03-测试文档/03-功能测试用例/TC-REQ-通用-005-选项选择持久化-v1.0.md`
> - Dify v3 DRAFT`docs/02-技术文档/实现配置/dify_dsl/itdesk_main_v3_feedback-vars_DRAFT.yml`
> - 原型:无(v1.0 暂无独立原型;UX 调整需重开)
---
## 1. 增量背景(Why v1.1
v1.0 已部署并通过 35 条测试用例验收,但 2026-08-02 用户实测暴露 3 个持续 Bug + 1 个新需求,**Dify v3 工作流(用户尚未导入)** 仍未落地,导致"AI 跟进选项"语义无法端到端验证。
| 触发事件 | 观察 | 业务影响 |
|---|---|---|
| 2026-08-02 17:45 用户反馈 | **Bug 4**:员工提问后看到 AI 回答,坐席端实时收单,但**员工端需刷新才显示** | 员工体感卡顿,怀疑"卡死" |
| 2026-08-02 17:45 用户反馈 | **Bug 5**:选选项后,**先看到 AI 思考占位 → 后同时出现"答案 + 上一个选择"** | 时序错位,破坏确定性信任 |
| 2026-08-02 17:45 用户问询 | **Bug 6**:曾发生"**页面刷新后选择消失**",询问是否真解决 | 会话连续性 + 审计可追溯 |
| 2026-08-02 17:45 用户强调 | **Req 7**:员工选选项后,**效果实时同步到坐席端(< 100ms)** | 紧急报修场景坐席分诊效率 |
**v1.1 目标**:在不动 v1.0 6 项产品决策(前缀:撤回/重选、幂等键、跨卡归属、敏感词、Dify 语义、转人工快照)的前提下,修复时序与持久化体感问题,并验证 v1.0 的"刷新保留"是否真达成。
---
## 2. 与 v1.0 的差异(What Changed
| 编号 | v1.0 内容 | v1.1 增量 | 优先级 |
|---|---|---|---|
| **Bug 4** | (v1.0 无) | 员工端 AI 回答延迟显示:消息已落库 + WS 已广播坐席端,但**员工端需刷新才显示** | **P0** |
| **Bug 5** | (v1.0 无) | 选选项时序错位:先 AI 思考占位 → 后同时出现"答案 + 上一个选择" | **P1** |
| **Bug 6** | v1.0 §4.1 / AC-01 已要求"落库 option_select + REST 仍可见" | 显式写入"刷新后必须保留选择历史"作为**P0 验收**;消除 v1.0 隐含歧义 | **P0** |
| **Req 7** | v1.0 §4.2 + §3.1 #2 仅要求"坐席可实时可见" | **新增显式时延指标**:坐席端 < 100ms 同步;坐席不在线时恢复后立即可见 | **P0**(用户强调) |
> v1.0 的 6 项产品决策(撤回/重选、5 秒 UUID 幂等、跨卡归属、敏感词 4 位中间 mask、Dify 5 字段 inputs、转人工 selected_options 快照)**全部不变**。
---
## 3. 增量 PRD:详细功能需求
### 3.1 Bug 4 — 员工端 AI 回答延迟显示(**P0**)
| 字段 | 内容 |
|---|---|
| **现象** | 员工提问 → AI 思考 → 答案已落库 + WS 已广播到坐席(坐席端实时可见)→ **员工端界面不更新**,刷新后才行 |
| **现状根因候选** | 员工端 `message-store``processedMessageIds` 已包含该 message_id(之前 WS 收到过 chunk 阶段 ID),导致 `new_message` 完整事件被 `if (processedMessageIds.has(data.message_id)) return` 静默丢弃(`src/frontend-h5/src/stores/conversation.ts:474-477` |
| **期望** | 员工端 AI 回答 < 1 秒内显示(不需要刷新) |
| **验收** | 员工端提问 → 2 秒内看到 AI 回答气泡(不强求同步打字机,但气泡必须出现) |
| **建议修复方向**(待架构师确认) | 区分"中间 chunk 的 message_id"与"最终 message_id";或把最终 `new_message` 事件直接接收,不去重 |
| **关联基线** | v1.0 §4.2 WS 事件;`conversation.ts:474-477``conversation.ts:1404-1407` |
### 3.2 Bug 5 — 选选项时序错位(**P1**)
| 字段 | 内容 |
|---|---|
| **现象** | 员工选选项 → UI 立即显示:AI 思考占位 + 上一个选择气泡 → 几秒后**同时出现"新答案 + 上一个选择"**(时序错位) |
| **现状根因候选** | H5 `sendOptionSelect` 触发 `process_h5_ai_reply` → 思考占位立刻 push 到 `messages.value``h5_ai_task.py:1574` WS 推送 `ai_thinking`)→ 但**上一个 option_select 消息尚未回流**到 store → 答案到达时**上一条 option_select 一起渲染** |
| **期望** | 选选项后 UI 顺序:① 已选气泡(✓)→ ② AI 思考占位 → ③ AI 答案气泡 |
| **验收** | 选选项后 3 个 UI 元素**按时间顺序独立出现**,不同时弹出 |
| **建议修复方向**(待架构师确认) | `sendOptionSelect` 同步把已选消息 push 到本地 store(不依赖 WS 回流),或后端先 ack 再触发 Dify |
| **关联基线** | v1.0 §4.4 H5 字段补全;`conversation.ts:1640-1710` |
### 3.3 Bug 6 — 刷新后选择消失(**P0**,需确认 v1.0 是否真解决)
| 字段 | 内容 |
|---|---|
| **现象** | 员工选选项后能看到 ✓ 气泡 → 刷新页面 → ✓ 气泡**消失** |
| **现状调研** | 见 §7 本节根因分析 |
| **调研结论** | H5 REST 端点 `h5.py:964-1029` **未实现 v1.0 §4.8 mask 要求**(存安全漏洞),但**未发现"消失"的代码缺陷**。理论上:DB 存原值 → REST 返回原值 → `mapMessage` 保留 `msg_type``MessageBubble.vue:174` 渲染 ✓ 模板 → 选项应可见 |
| **可能的"消失"根因** | ① 默认 `limit=50`,长会话(>50 条)历史选项被分页(P1 修复);② 浏览器缓存被清除(H5 应有 fallback);③ DB 该行因 WS 关闭或事务回滚未落库 |
| **v1.1 期望** | 显式写入"刷新后**所有历史选项气泡按时间顺序显示**"作为 P0 验收;不再依赖隐含理解 |
| **验收** | ① 员工选选项 → 刷新 → ✓ 气泡依然可见;② 选项按 server_timestamp 升序;③ 选项时间戳对应的 AI 题目卡片也应可见 |
| **建议修复方向** | ① 在 AC-01 加 P0 子项 AC-01-2"刷新后仍可见";② H5 端点在 `limit=50` 不够时支持 `before` 翻页验证;③ 紧急 P0 验证步骤必须包含实际操作 |
| **关联基线** | v1.0 §4.1 + AC-01`h5.py:964-1029` |
### 3.4 Req 7 — 实时同步到坐席端(**P0**,用户强调)
| 字段 | 内容 |
|---|---|
| **现象** | 员工选选项后,**坐席端是否立即看到**?用户担心存在 < 1s 延迟 |
| **现状** | v1.0 §4.2 已实现 `ws_manager.broadcast({"type": "new_message", "data": ...})`(坐席端有新事件后 MessageBubble 渲染 ✓),链路已稳定 |
| **v1.1 期望** | **显式时延指标**:员工点击选项 → 坐席端 < 100ms 内看到"已选:xxx ✓" |
| **验收** | ① 在线坐席端 < 1s 看到新消息事件;② 坐席不在线 → 重新加载时 REST 历史含同样 message_id;③ 弱网或 502 时降级为 3s 轮询可见 |
| **建议实施** | **无需新代码**——v1.0 §4.2 已实现。建议架构师出具 `E2E` 验收日志(WS 广播时间戳 + 坐席端 MessageBubble 渲染时间戳差值)证明 < 100ms |
| **关联基线** | v1.0 §4.2、AC-03、AC-10`ws.py:407-421` |
---
## 4. 与 v1.0 兼容性(What Stays
| 维度 | v1.0 决策 | v1.1 是否变动 |
|---|---|---|
| 撤回/重选语义 | 追加新行、不更新旧行(§4.1) | ❌ 不变 |
| 5 秒 UUID 幂等 | `(conversation_id, client_msg_id)` + 5s 窗口(§4.5 | ❌ 不变 |
| 跨卡归属 | `question_id + option_id` 联合,label 不作主键(§6) | ❌ 不变 |
| 敏感词 mask | 16 位数字中间 4 位 `****`(§4.8 | ❌ 不变 |
| Dify 5 字段 inputs | `feedback_type/question_id/option_id/option_value/option_label`(§4.6 | ❌ 不变 |
| 转人工快照 | `selected_options` 每题最新(§4.7) | ❌ 不变 |
| 5 重 UUID 守卫(V0-C 修复) | WS 在线 + 5 题内 + 5s 内 + 同题 + 未陈旧(`conversation.ts:1662-1675` | ❌ 不变,**作为 v1.1 Bug 5 修复的"前提"** |
---
## 5. 风险与依赖
| 风险 | 等级 | 缓解/验证 |
|---|---|---|
| **Dify v3 未导入** → 修复 Bug 4/5/6 后,**用户感知不到 Bug 真实修复**(因 AI 回答本身没变) | 高 | v1.1 落地**前提**:先确认 Dify v3 导入时间表;建议 2026-08-09 前完成 |
| 实时同步依赖后端 `ws_manager` 单进程 | 中 | v1.0 已固定 `--workers 1`v1.1 沿用 |
| 坐席端 before 翻页未断言 | 中 | v1.0 TC-004 已覆盖;v1.1 沿用 |
| 长会话 limit=50 可能漏显 | 中 | Bug 6 验证;若发现,v1.1 引入翻页 |
| H5 端点 mask 缺失(`h5.py:1025` | 高 | v1.0 §4.8 已要求,v1.1 修复(顺手) |
| 浏览器缓存丢失 | 低 | 现有 fallback `getMessages` API |
---
## 6. 待用户确认(5 个问题)
1. **Bug 4 / 5 / 6 的优先级排序**是否合理?(当前:Bug 4=Bug 6=P0 / Bug 5=P1
2. **Req 7 是否属于 v1.1 范围**?(用户强调"如果没有技术问题,希望实现"——倾向属于 v1.1)
3. 是否同意新增"**刷新后必须保留选择历史**"作为 v1.1 P0 验收(AC-01-2 增项)?
4. **Dify v3 何时导入**?(影响 AI 能否"基于选项的跟进",进而影响 Bug 4/5 是否真验收)
5. 是否需要拉原型?如需 UI 调整(坐席侧徽标位置、员工端选项视觉等),需 UX 重新设计
---
## 7. Bug 6 根因分析(基于代码 + Git 现状)
> 用户问"之前发生过页面刷新后选择消失问题,是否真解决"——下面给出**基于代码证据**的判断。
### 7.1 代码调研(5 个关键点)
| # | 调研点 | 代码位置 | 结论 |
|---|---|---|---|
| 1 | 后端持久化 | `ws.py:374-385` `Message(msg_type="option_select", content=option_label, ...)` + `db.add()` + `commit` | ✅ 落库 |
| 2 | H5 REST 端点是否返回 option_select | `h5.py:964-1029` `select(Message).where(conversation_id==...)`**无 msg_type 过滤** + `MessageResponse.model_validate(m).model_dump()` | ✅ 应返回 |
| 3 | H5 端点是否 mask option_select | `h5.py:1025` **直接 dump,无 mask**(违反 v1.0 §4.8 | ❌ **存安全漏洞**,但**与"消失"无关** |
| 4 | 前端字段映射 | `api/conversation.ts:234-249` `mapMessage``msg_type: raw.msg_type` 直接透传 | ✅ 保留 |
| 5 | UI 渲染分支 | `MessageBubble.vue:174-179` `<template v-else-if="msg.msg_type === 'option_select'">✓ {{ msg.content }}</template>` | ✅ 渲染分支存在 |
| 6 | 缓存 + 合并 | `conversation.ts:62-82` + `85-97` + `117-119` `mergeMessages``message_id` 去重 | ✅ 应保留 |
| 7 | 限分页 | `h5.py:999` `limit(limit)` 默认 50 | ⚠️ 长会话会被分页 |
### 7.2 根因判定(确定性)
**基于代码,`Bug 6 "刷新后选择消失" 在当前 v1.0 应不应发生**?——**不应发生**。但有以下 3 个潜在触发场景:
| 场景 | 当前是否根因 | 概率 |
|---|:---:|:---:|
| **A. H5 端点未 mask**`h5.py:1025`) | 否(是安全 bug,不是"消失" | 高 |
| **B. 默认 limit=50,长会话历史选项被分页** | **是**(超过 50 条之后,刷新只显示最新 50 条) | 中 |
| **C. 浏览器缓存被清除 + step 3 异步 fetch 失败** | **是**(无网络时,UI 不会显示选项气泡) | 中 |
| **D. 消息真正未落库**(DB 事务回滚) | 否(v1.0 §3.1 #1 已 P0 验收,PG advisory lock 已避免) | 极低 |
| **E. 字段映射丢失**`msg_type` 被过滤) | 否(`mapMessage` 直接透传) | 极低 |
### 7.3 结论
**Bug 6 在 v1.0 当前实现下大概率已被解决**——代码层面:
- 后端 ✅ 落库
- API ✅ 返回
- 字段映射 ✅ 保留
- UI ✅ 渲染分支存在
**但有 2 个**潜在根因未被 v1.0 显式覆盖:
1. **H5 端点 limit=50 未分页验证**(场景 B
2. **H5 端点 mask 缺失**(场景 A,与"消失"无关但是安全漏洞)
**v1.1 建议**
- 把"刷新后保留"显式写入 PR v1.1 验收(AC-01-2
- 顺手修复 H5 端点 mask 漏洞(§3.1 修复的同时)
- 增加 `E2E` 验收步骤:选选项 → 刷新 → 截图选项气泡
---
## 8. 附录:v1.1 增量范围 vs 完整 PRD
| 范围 | 是否在 v1.1 增量草案 | 备注 |
|---|:---:|---|
| Bug 4 / 5 / 6 修复 | ✅ 草案 | 待用户确认优先级 |
| Req 7 实时同步验收 | ✅ 草案 | 显式时延指标 |
| v1.0 6 项决策 | ❌ 不再重复 | 见 v1.0 原 PRD |
| Dify v3 变更 | ❌ 不再重复 | 见 Dify v3 CHANGELOG |
| 测试用例增量 | ⏳ 下一步 | 待 QA 在 v1.1 范围确认后增量 |
| 完整 PRD(含组件图、时序图、API 变更) | ❌ 不出 | 用户明确"先写草案" |
---
## 9. 变更记录
| 版本 | 日期 | 变更内容 | 变更人 | 变更原因 |
|---|---|---|---|---|
| v1.0 | 2026-07-29 | 创建 PRD,固化方案 A、6 项产品决策与 MVP 验收范围 | 许清楚、宋献 | 修复选项选择不落库 |
| **v1.1-DRAFT** | **2026-08-02** | **增量草案:3 Bug + 1 Req + Bug 6 根因分析 + 5 待确认问题** | **许清楚** | **用户实测反馈 + 询问刷新保留是否真解决** |
---
> **下一步**:等待用户对 §6 五个问题的回复 → 确认 v1.1 范围 → 由架构师出 v1.1 技术方案 → 由 QA 补 v1.1 测试用例增量。