# AI 客服系统全面分析与优化方案 - **日期**:2026-08-19 - **基线**:`e02be47`(两大特性已落地:联系方式驱动询盘邮件 `6860e88`;AI 职能边界三层防线 `3028685`+`9433f96`) - **质量状态**:106 项测试全绿(原始基线 17);真实 GLM 冒烟通过 - **性质**:只分析不调整。问题按七层组织,每项含现象/根因/影响;优化方案按优先级排期;最后是需要拍板的决策点。 --- ## 一、当前系统状态总览 ``` 已落地的两大能力(互相咬合的闭环): 联系方式驱动邮件: 管道确定性检测联系方式 → 秒发询盘邮件 → 更正/去重/永不锁死客户 职能边界三层防线: prompt 职能定位 → 当轮红线提醒 → 句子粒度过滤墙(打字机保留) 链路: 客户 ↔ 前端(widget/独立页/App REST) → WS/REST → ConversationManager (GLM对话+提取+评估 | 联系方式管道 | 邮件触发器 | 边界过滤) → SQLite → SMTP询盘邮件 → 销售人工承接(报价/安排) → admin后台辅助 ``` **系统当前最大的结构性事实**:核心转化链路(聊车→挖意向→收联系方式→邮件→人工)已经完整且被测试覆盖;**剩余问题集中在四个区域——安全基线、数据可靠性、前端体验、以及"上线后才知道"的观测盲区。** --- ## 二、问题清单(七层,共 30 项) ### A. 安全层(3 项 —— 上线公网前必须处理) | # | 问题 | 现象/根因 | 影响 | |---|---|---|---| | A1 | **管理后台默认密码** | `.env` 无 `ADMIN_PASSWORD` → `admin123` 生效中(本次复核确认);登录无限流无锁定;会话存内存 | 任何扫到域名的人可看全部客户对话/联系方式并删库 | | A2 | **明文 HTTP** | openresty 的 HTTPS 配置整段被注释;admin 密码/数据明文传输 | 公网嗅探风险 | | A3 | **WS 零限流 + 消息无长度上限** | 限流只挂在 REST `/api/chat/message`(30/h);`/ws/chat` 与独立页无任何限制;消息 content 不截断 | 每条消息 3 次 GLM 调用——脚本可无限烧钱;超长消息直接怼给 GLM | ### B. 数据与可靠性层(5 项) | # | 问题 | 现象/根因 | 影响 | |---|---|---|---| | B1 | **SQLite 零备份** | 全部客户线索/画像/对话就 `data/cc_ai_kefu.db` 一份文件,无备份任务、无 WAL | 磁盘坏 = 线索全灭,业务级风险 | | B2 | **GLM 调用无超时无重试** | 所有 GLM 调用不限时;挂起则该轮永远 typing(前端只重连不报错) | 客户体验死等 + 无告警 | | B3 | **SMTP 无重试队列** | 发送失败靠"下一条消息自然重试"(有意的 at-least-once);给号后沉默+首发失败=线索丢失窗口 | 低概率但真实 | | B4 | **邮件发送在请求内同步** | SMTP 握手挤占响应时间;触发频率上升后影响面变大 | 延迟抖动 | | B5 | **会话只生不死** | 决策 A 后会话永不自动结束、无超时清理;active 行无限增长 | 数据卫生(admin 列表污染、查询变慢),功能无害但持续恶化 | ### C. 前端体验层(4 项 —— 用户实测亲历) | # | 问题 | 现象/根因 | 影响 | |---|---|---|---| | C1 | **widget 刷新/翻页丢会话** | 会话只存 JS 内存、`page_token` 每次加载重新生成(widget.js:288) | 客户重聊一遍(AI 重复提问)+ 同一客户重复产生新会话(重复线索邮件放大器) | | C2 | **会话恢复了但界面空白** | 独立页 `loadHistory()` 是空函数(chat.js:182);后端历史接口存在但页面不调用 | 客户看不到自己说过什么 | | C3 | **widget 中途重连丢视觉历史** | WS 断线重连后消息列表只在内存 | 体验断裂 | | C4 | **ended 后无重开入口**(低) | 永不结束后基本不触发;但历史 completed 会话刷新即新会话 | 极低 | ### D. AI 行为质量层(5 项 —— 两大特性引入的新观测点) | # | 问题 | 现象/根因 | 影响 | |---|---|---|---| | D1 | **破防率长期趋势未知** | 第1+2层自律率、第3层拦截频率只有日志行,无聚合视图 | 无法判断防线配置是否过严/过松,也无法评估 GLM 升级收益 | | D2 | **迂回话术同质化** | 过滤器过渡话术单一池不轮换;客户一小时内反复问价会看到重复句子 | 机器人感;聪明客户可感知到"触发了什么" | | D3 | **转化流失未量化** | 价格拦截是强业务取舍——拿不到价的客户流失率、留资率变化没有任何埋点 | 无法回答"红线是否伤害转化"这个关键问题 | | D4 | **[未评估] 邮件占比未知** | 即时触发让"第1条消息就留号"的邮件带着薄上下文+未评估标签发出 | 销售对这类邮件的跟进策略缺数据支撑 | | D5 | **glm-4-flash 能力天花板** | 复杂询价理解/话术遵循/多语言均偏弱(本项目多次实测其不守规则) | 三层防线里第1+2层形同虚设的部分原因;模型升级可能显著降低第3层压力 | ### E. 转化漏斗层(5 项 —— 计划内未做) | # | 问题 | 说明 | |---|---|---| | E1 | **UI 留资卡片未做** | 表单留资转化率 > 聊天索要;判定"有意向缺联系方式"时弹卡片是转化质变手段(批次3) | | E2 | **admin 卡单筛选未做** | interested+无联系方式的人工兜底视图;卡单数据已在落库,只差筛选 UI | | E3 | **线索无生命周期** | 邮件发出后无"未跟进提醒/二次触达/关闭"管理;24h 轻提醒只覆盖再来访 | | E4 | **邮件单收件人** | `NOTIFY_EMAIL` 单一邮箱;无按国家/语种分诊(肯尼亚线和中东线分开?) | | E5 | **无数据看板** | 会话量/留资率/意向分布/破防率/邮件量——全靠 SQL 手查 | ### F. 运维观测层(4 项) | # | 问题 | 说明 | |---|---|---| | F1 | **无监控告警** | 服务挂/GLM 连续失败/SMTP 失败/磁盘满——只有日志行,无人知道 | | F2 | **无 CI** | 106 项测试只在本地跑;push 无门禁 | | F3 | **Redis 容器白跑** | compose 里运行但代码零引用;弱默认密码写在仓库 | | F4 | **杂项债务** | admin 内存会话重启掉线、admin 筛选分页 total 错误、国家映射"加拿大"笔误、IP 可被 client_info 覆盖、`AIService.chat` 死代码、邮件 From 品牌【XYH】与站点不符、openresty 静态双拷贝同步陷阱、deploy.sh 停机窗口 | ### G. 架构扩展层(3 项 —— 流量上来之前不用动) | # | 问题 | 说明 | |---|---|---| | G1 | 单进程 + SQLite | 并发写锁风险与流量成正比;当前量级完全够 | | G2 | 限流/会话存内存 | 多 worker 部署即失效(当前单 worker 无碍) | | G3 | PII 永久存储无保留策略 | 外贸业务合规盲区(低优先,知晓即可) --- ## 三、优化方案(按优先级四批) ### P0 · 上线公网前必须(约 1 天) | 序 | 动作 | 对应 | 成本 | |---|---|---|---| | 1 | .env 配置强 `ADMIN_PASSWORD` + admin 登录限流 | A1 | 0.5h | | 2 | 启用 openresty HTTPS(证书+301) | A2 | 1h | | 3 | WS 限流(session 严 60/h、IP 宽、消息级拒绝防重连风暴)+ 消息长度上限(复用 429) | A3 | 0.5 天,前后端同批 | | 4 | SQLite 定时备份(`sqlite3 .backup` cron + 保留策略 + WAL) | B1 | 1h | | 5 | GLM 调用超时(30s)+ 单次重试 + 前端明确报错 | B2 | 0.5 天 | ### P1 · 上线第一周(观测+卫生,约 2 天) | 序 | 动作 | 对应 | |---|---|---| | 1 | 超时清理任务(lifespan 周期扫描:24h 无消息的 active → abandoned) | B5 | | 2 | **破防率聚合**:每日统计 `Boundary filter` 日志行数 → 简单接口/脚本输出趋势 | D1 | | 3 | 留资率/流失埋点:admin 加统计接口(会话数、留联系方式数、[未评估]占比) | D3/D4 | | 4 | 简单告警:健康检查失败/GLM 连续失败/SMTP 失败 → 邮件或 webhook 通知 | F1 | | 5 | 邮件发送移出请求路径(asyncio.create_task + 短超时) | B4 | | 6 | F4 杂项打包:admin 分页/国家映射/删 AIService.chat/删 Redis/From 品牌改 | F4 | ### P2 · 批次 2:前端体验(约 3 天,解决你亲历的痛点) | 序 | 动作 | 对应 | |---|---|---| | 1 | widget 会话持久化(独立前缀 localStorage + 48h 过期) | C1 | | 2 | 独立页/widget 历史渲染(loadHistory 接现有历史接口) | C2/C3 | | 3 | WS 限流前端配合(P0-3 的前端侧) | A3 | ### P3 · 批次 3 + 长期:转化与质量 | 序 | 动作 | 对应 | |---|---|---| | 1 | UI 留资卡片(端点限流+校验+只弹一次) | E1 | | 2 | admin 卡单筛选 + 线索列表视图(含破防监控标签) | E2/D1 | | 3 | 过渡话术扩池轮换 | D2 | | 4 | 评估 glm-4-air/plus 对自律率的提升(换模型跑冒烟对比破防率) | D5 | | 5 | 邮件分诊(按国家路由收件人) | E4 | | 6 | 线索生命周期(跟进状态字段+超时提醒) | E3 | | 7 | 数据看板(E5)、CI(F2)、多 worker 改造(G1/G2,流量触发) | 长期 | --- ## 四、需要拍板的决策点 | # | 决策 | 选项与建议 | |---|---|---| | 1 | **上线节奏** | 两大特性现在就上(建议:核心价值已闭环,P0 做完就走),还是等 P1 观测一起? | | 2 | **超时时长**(B5) | active 会话多久算 abandoned?建议 24h(与 24h 去重窗口对齐) | | 3 | **是否保留生产基线任务** | 上线前跑一次 `baseline_stats.py` + `breach_rate.py` 存档(强烈建议,一次性机会) | | 4 | **模型升级评估要不要排期** | 如果第1+2层自律率长期很低(全靠墙),升模型可能比维护三层更省心 | | 5 | **邮件分诊需求** | 销售团队实际几人?按国家分箱是否真实需要? | --- ## 五、结论 **系统核心链路健康**:两大特性互相咬合、106 项测试护栏、真实流量冒烟通过。剩余问题没有一个是核心链路缺陷——全部集中在**安全基线(A 层 3 项)、数据可靠性(B 层 2 项)、前端体验(C 层 3 项)和观测盲区(D/F 层)**。 最短路径建议:**P0 五项(约一天)做完即可上线**,第一周做 P1 建立观测,之后按 P2/P3 消化体验与转化。A1(改密码)是零成本零风险的一项,无论如何先做。