青禾光伏智能服务平台
RAG 知识问答与智能工单分流实践
面向光伏行业客户与企业服务人员,整合 RAG 知识问答、FAQ 直出、人工客服和智能工单分流的完整业务实践。
- RAG
- FastAPI
- Milvus
- React
- BGE-M3
让清洁的阳光
照亮更多人。
Small stepsBright future.
项目目录
- 一、项目概述
- 1.1 项目背景
- 1.2 项目目标
- 1.3 技术架构
- 二、整体业务流程
- 三、RAG 核心能力
- 3.1 文档解析与知识库构建
- 3.2 Milvus 混合检索
- 3.3 FAQ 直出
- 3.4 检索策略与动态路由
- 3.5 查询改写与多轮对话
- 3.6 核心编排服务
- 四、缓存与性能设计
- 五、智能工单分流
- 5.1 转人工流程
- 5.2 BERT 与规则协同
- 5.3 紧急程度
- 六、客户端业务逻辑
- 七、员工智能工作台
- 八、权限与数据边界
- 九、项目亮点
- 9.1 不是“所有问题都做 RAG”
- 9.2 稠密与稀疏检索互补
- 9.3 答案全程可追溯
- 9.4 客户与员工双端闭环
- 9.5 本地模型与数据可控
- 9.6 生成服务故障时仍能保持核心能力
- 9.7 面向生产的缓存失效设计
- 十、Web 服务基础设施
- 十一、知识库治理与质量闭环
- 十二、RAG 基础概念:为什么它适合光伏客服
- 12.1 什么是 RAG
- 12.2 Embedding 是什么
- 12.3 为什么不能只用向量检索
- 12.4 Reranker 为什么放在召回之后
- 十三、知识入库设计
- 13.1 在线检索与离线入库分离
- 13.2 文档统一结构
- 13.3 父子分块
- 13.4 FAQ 与普通文档分集合
- 13.5 增量更新
- 十四、在线 RAG Pipeline 深入
- 14.1 为什么需要 Pipeline
- 14.2 Stage 0:输入与权限
- 14.3 Stage 1:业务路由
- 14.4 Stage 2:查询准备
- 14.5 Stage 3:FAQ 快速通道
- 14.6 Stage 4:文档混合检索
- 14.7 Stage 5:去重与重排
- 14.8 Stage 6:证据不足保护
- 14.9 Stage 7:统一输出
- 十五、Milvus 索引与过滤设计
- 15.1 双向量字段
- 15.2 HNSW 参数含义
- 15.3 中文 BM25
- 15.4 权限过滤表达式
- 十六、检索事件协议
- 16.1 为什么需要事件协议
- 16.2 事件顺序
- 十七、三级缓存实现细节
- 17.1 缓存什么
- 17.2 缓存 Key
- 17.3 TTL 策略
- 17.4 依赖故障降级
- 十八、FastAPI 服务层
- 18.1 为什么使用异步
- 18.2 路由边界
- 18.3 统一错误处理
- 18.4 启动前置校验
- 十九、工单领域模型与状态流转
- 19.1 工单核心数据
- 19.2 状态机
- 19.3 为什么客户不用注册
- 二十、智能分流算法
- 20.1 输入与输出
- 20.2 规则与模型的边界
- 20.3 可解释性
- 二十一、前端体验设计
- 21.1 客户门户
- 21.2 检索结果卡片
- 21.3 员工工作台
- 21.4 数据刷新
- 二十二、异常与降级策略
- 二十三、项目目录说明
- 二十四、典型业务使用路径
- 24.1 客户知识问答
- 24.2 转人工与智能分流
- 24.3 员工工单处理
- 24.4 内部知识库
- 二十五、完整平台能力
- 25.1 内容运营
- 25.2 检索质量
- 25.3 客服协同
- 25.4 运行治理
- 二十六、质量评估指标
- 26.1 路由指标
- 26.2 检索指标
- 26.3 回答指标
- 26.4 工单指标
- 26.5 性能指标
- 二十七、Bad Case 闭环
- 二十八、安全与隐私
- 二十九、总结
青禾光伏智能服务平台:RAG 知识问答与智能工单分流实践
一个面向光伏行业客户与企业服务人员的智能服务平台,将知识库检索、FAQ 直出、意图识别、人工客服和智能工单分流整合为完整业务闭环。

一、项目概述
1.1 项目背景
光伏设备涉及组件、逆变器、储能系统、并网设备等多类产品。客户在使用过程中会产生大量专业咨询,例如设备参数查询、告警代码解释、安装规范、功率衰减、质保政策和售后申请等。
传统客服模式主要面临以下问题:
- 产品资料分散在不同手册中,人工查找效率低;
- 客户描述不规范,同一个问题可能有多种表达方式;
- 普通问题和紧急故障混在一起,工单依赖人工判断;
- 客户转人工后,客服需要重新理解上下文;
- 企业内部制度和客户产品资料权限边界不清晰;
- 大模型直接回答容易产生无依据内容,缺少来源追踪。
青禾光伏智能服务平台围绕“知识优先解决,复杂问题智能转人工”的思路,构建客户门户与员工工作台两个业务端。
1.2 项目目标
项目重点实现两个核心能力:
- RAG 知识库检索:基于企业授权资料回答光伏产品和内部制度问题,并展示答案来源、问题分类、置信度和处理耗时。
- 智能工单分流:客户提交人工咨询后,自动识别问题类型、情绪倾向和紧急程度,为员工提供辅助判断。
1.3 技术架构
| 层级 | 技术方案 | 主要职责 |
|---|---|---|
| 前端 | React、TypeScript、Vite、TanStack Query | 客户门户、员工工作台、状态轮询与交互 |
| 后端 | FastAPI、SQLAlchemy、异步接口 | 用户会话、RAG 服务、工单与权限接口 |
| 数据库 | PostgreSQL | 员工、会话、工单、消息和缓存命名空间 |
| 向量数据库 | Milvus | BGE-M3 稠密向量与内置 BM25 稀疏检索 |
| 缓存 | 进程内缓存、Redis、PostgreSQL | 热点数据、检索结果和版本失效控制 |
| AI 模型 | BGE-M3、BGE Reranker、本地 BERT | 向量化、重排序、意图分类与情绪识别 |
| RAG 生态 | LangChain、LangChain Milvus | 文档对象、向量库适配与检索编排 |
二、整体业务流程
平台不是把所有问题都直接送入向量数据库,而是先路由,再决定最合适的处理链路。
flowchart TD
A[客户输入问题] --> B[业务领域与意图路由]
B -->|无关问题| C[直接提示业务范围]
B -->|标准高频问题| D[FAQ 精确/语义匹配]
B -->|专业知识问题| E[RAG 混合检索]
D --> F[返回标准答案]
E --> G[生成有来源的回答]
F --> H[展示分类、来源库、置信度]
G --> H
H --> I{是否需要人工}
I -->|否| J[继续多轮咨询]
I -->|是| K[填写人工咨询描述]
K --> L[BERT + 业务规则分析]
L --> M[生成分类、情绪与紧急程度]
M --> N[进入员工工单队列]
N --> O[客服接单并回复]
O --> P[客户在我的咨询查看消息]
这条链路体现了三个业务原则:
- 能拦截的不检索:天气、闲聊等无关问题在第一层结束,避免无意义召回。
- 能直出的不生成:高频标准问题优先走 FAQ,速度更快、答案更稳定。
- 需要检索的必须可追溯:专业问题使用知识库回答,并携带来源信息。
三、RAG 核心能力
3.1 文档解析与知识库构建
产品手册、FAQ 和企业内部制度先转换为统一文档对象,并保留标题、章节路径、页码、知识库类型和文档编号等元数据。
文档切分采用父子块结构:
- 父块保留较完整的章节语义;
- 子块用于精确检索,降低无关上下文;
- 检索命中子块后,可以通过父块补充完整语境;
- 内容哈希用于识别文档变化并避免重复入库。
知识库按业务权限分为两类:
- 产品知识库:产品参数、故障处理、安装维护、售后与质保资料;
- 企业内部制度库:入职流程、内部服务规范和企业管理制度。
客户只能检索产品知识库,员工登录后才能访问两个知识库。
3.2 Milvus 混合检索
单独使用向量检索擅长理解语义,但对型号、告警码和精确参数不一定敏感;单独使用关键词检索能够匹配专有名词,却难以理解用户的自然表达。
平台在 Milvus 中同时建立:
- Dense 稠密向量:由 BGE-M3 生成,负责语义召回;
- Sparse 稀疏向量:使用 Milvus 内置 BM25,负责关键词、型号和告警码匹配。
检索采用加权混合策略,将两路结果融合。权重以语义检索为主,同时保留关键词检索对设备型号和故障码的敏感度。
flowchart LR
Q[用户问题] --> D[BGE-M3 Dense 向量]
Q --> S[Milvus BM25 Sparse 向量]
D --> R[加权融合]
S --> R
R --> T[候选文档]
T --> X[BGE Reranker 精排]
X --> C[高相关上下文]
C --> A[答案生成与来源引用]
3.3 FAQ 直出
FAQ 与普通文档使用独立检索集合。问题进入知识链路后先判断是否可以命中高置信度 FAQ:
- 命中时直接返回经过审核的标准答案;
- 不命中时再进入普通产品文档检索;
- FAQ 返回仍携带分类、来源库和置信度;
- 标准答案不依赖生成模型,即使生成服务暂时不可用也能稳定工作。
例如“逆变器报警代码含义”可直接命中 FAQ,而“QH-620 组件额定功率是多少”则进入产品手册检索。
3.4 检索策略与动态路由
平台为三种典型问题建立了不同的处理路径:
| 问题类型 | 示例 | 处理方式 |
|---|---|---|
| 无关问题 | 今天天气怎么样? | 领域路由直接拦截,不访问知识库 |
| FAQ 问题 | 逆变器报警代码含义 | FAQ 高置信度直出 |
| 知识检索问题 | QH-620 组件额定功率是多少? | Dense + BM25 混合检索 |
路由结果同时决定知识库范围。客户查询固定限制为产品资料;员工可以选择产品知识库、企业内部制度库或全部授权知识库。
3.5 查询改写与多轮对话
真实用户可能只输入“这个怎么处理”“还有其他要求吗”等不完整问题。多轮对话需要结合上一轮主题补足当前问题,再进入检索。
平台通过查询准备链路完成:
- 清洗用户输入;
- 识别是否依赖历史上下文;
- 补全产品型号和问题对象;
- 生成适合检索的标准查询;
- 保留原始问题用于最终回答。
3.6 核心编排服务
RAG 服务负责统一编排:
- 校验用户角色和知识库权限;
- 执行业务领域与意图路由;
- 查询缓存;
- 并行检索 FAQ 与普通文档;
- 合并、去重并重排候选结果;
- 计算检索置信度;
- 组织回答和参考来源;
- 返回问题分类、来源库、处理耗时与检索过程。
前端通过事件协议接收运行状态,依次展示“开始处理、问题路由、知识检索、答案生成、处理完成”等阶段,避免长时间等待时页面没有反馈。
四、缓存与性能设计
平台围绕知识检索建立三层缓存治理:
- L1 进程内缓存:短时间保存知识库命名空间版本,减少重复查询数据库;
- L2 Redis 检索缓存:缓存 FAQ、文档和向量结果,降低重复检索开销;
- L3 PostgreSQL 版本控制:持久化知识库缓存 Epoch,负责跨进程一致失效。
缓存 Key 不直接保存用户问题明文,而是结合查询哈希、用户角色、知识库范围、模型版本、资料版本和命名空间版本生成。
当知识库更新时,系统提升对应知识库的 Epoch。旧缓存无需全量扫描删除,因为新请求会自然生成新的 Key;如果失效过程失败,当前进程会阻止继续使用可能过期的缓存。
平台只缓存检索结果,不缓存最终生成答案,避免不同用户上下文之间发生答案串用。
五、智能工单分流
5.1 转人工流程
客户点击“联系人工客服”后,需要描述设备型号、故障现象和当前影响。系统创建工单时自动完成分析,然后把工单放入员工工作台。
sequenceDiagram
participant C as 客户
participant API as 服务平台
participant AI as BERT与规则引擎
participant S as 客服人员
C->>API: 提交人工咨询
API->>AI: 意图、情绪、紧急程度分析
AI-->>API: 分类结果与置信度
API-->>C: 返回咨询编号
API->>S: 工单进入待接单队列
S->>API: 接单并回复
API-->>C: 我的咨询展示最新消息
5.2 BERT 与规则协同
纯模型分类可能受到短文本、口语表达和训练数据规模影响,因此工单分流采用“BERT 辅助信号 + 业务规则”的组合方式。
- BERT 识别客户意图;
- 情绪模型判断积极、中性、负向或强烈负向;
- 规则识别“停机、冒烟、起火、多次故障”等紧急词;
- 业务规则结合产品类型确定分类和建议部门;
- 低置信度结果标记为需要人工复核。
员工端重点展示情绪识别置信度,而不是把较低的意图分类分数作为醒目的业务指标。
5.3 紧急程度
工单按普通、高、紧急三个等级进入队列。涉及安全风险、设备停机或强烈负向情绪的问题会得到更高优先级,帮助客服先处理影响更大的问题。
六、客户端业务逻辑
客户门户采用匿名会话,不要求用户注册账号,降低咨询门槛。
核心功能包括:
- 产品知识智能问答;
- 三类典型问题覆盖不同路由;
- 检索过程实时展示;
- 问题分类、来源库、置信度和耗时展示;
- 参考来源展开查看;
- 联系人工客服并提交咨询;
- “我的咨询”持续查看客服回复。
匿名身份通过浏览器 HttpOnly Cookie 保存。只要客户继续使用同一浏览器,就可以看到此前咨询和员工回复,同时避免在前端直接保存敏感身份信息。
七、员工智能工作台

员工登录后进入统一工作台,页面由三部分组成:
- 左侧工单队列:显示工单状态、紧急程度、问题摘要和分类;
- 中间对话区:查看客户原始描述、沟通记录并回复;
- 右侧智能分析:展示客户意图、问题分类、情绪倾向、置信度和处理建议。
员工还可以在产品知识库与企业内部制度库之间切换,在回复客户前快速查找有来源的标准答案。
八、权限与数据边界
平台采用“匿名客户 + 授权员工”两类身份:
| 能力 | 匿名客户 | 授权员工 |
|---|---|---|
| 产品知识库检索 | 支持 | 支持 |
| 企业内部制度库检索 | 不支持 | 支持 |
| 创建人工咨询 | 支持 | 不适用 |
| 查看工单 | 仅限当前浏览器创建的咨询 | 可查看工作台工单 |
| 回复与处理工单 | 不支持 | 支持 |
员工会话通过安全 Cookie 维护,接口层再次校验身份,不能只依赖前端隐藏菜单实现权限控制。

九、项目亮点
9.1 不是“所有问题都做 RAG”
系统先判断问题是否属于业务范围,再区分 FAQ 与知识检索。无关问题不检索,标准问题不生成,真正需要专业资料的问题才进入完整 RAG 链路。
9.2 稠密与稀疏检索互补
BGE-M3 理解自然语言语义,Milvus BM25 捕获型号、告警码和精确关键词,两者融合后更适合光伏设备场景。
9.3 答案全程可追溯
用户不仅看到答案,还能看到问题分类、答案来自哪个知识库、置信度、处理耗时和具体资料来源。
9.4 客户与员工双端闭环
项目不止实现一个知识问答页面,还打通了“智能回答—转人工—自动分流—员工接单—持续回复—客户查询进度”的完整业务流程。
9.5 本地模型与数据可控
向量模型、重排序模型、意图模型和情绪模型均可在本地运行,知识库权限由后端控制,适合对内部资料安全有要求的企业场景。
9.6 生成服务故障时仍能保持核心能力
FAQ、混合检索、来源返回、工单分流和本地模型识别不依赖外部大模型。生成服务正常时负责组织自然语言答案;生成服务异常时,系统基于检索证据返回结构化摘要。
9.7 面向生产的缓存失效设计
缓存 Key 同时绑定知识版本、模型版本、角色和知识范围;知识更新通过 Epoch 实现跨进程失效,避免员工和客户命中越权或过期缓存。
十、Web 服务基础设施
后端采用 FastAPI 异步服务,对外提供:
- 匿名客户与员工会话接口;
- 知识检索同步接口;
- 检索事件流接口;
- 工单创建、列表、详情、接单、回复和解决接口;
- 健康检查和统一异常响应。
前端使用 React 和 TypeScript 构建,TanStack Query 负责接口状态与缓存,Vite 在开发环境中将 /api 请求代理到后端服务。
十一、知识库治理与质量闭环
RAG 系统不仅需要“能检索”,还必须持续保证知识质量。平台建立以下治理能力:
- 文档版本管理与增量入库;
- 重复、冲突和失效内容检测;
- FAQ 审核与发布时间管理;
- Bad Case 自动沉淀;
- 无答案率、命中率、来源正确率和响应耗时评估;
- 根据评估结果校准路由阈值、召回数量和混合检索权重。
flowchart LR
A[线上咨询] --> B[收集低置信度与失败问题]
B --> C[Bad Case 数据集]
C --> D[分析路由、检索与答案问题]
D --> E[更新资料/FAQ/阈值]
E --> F[回归评估]
F --> G{达到质量门槛}
G -->|是| H[发布新知识版本]
G -->|否| D
十二、RAG 基础概念:为什么它适合光伏客服
12.1 什么是 RAG
RAG(Retrieval-Augmented Generation,检索增强生成)可以理解为“先查资料,再组织答案”。与直接让大模型根据参数记忆回答不同,RAG 会先从企业授权知识库中找出相关材料,再把材料作为回答依据。
一个最小 RAG 系统包括四个部分:
- 知识源:产品手册、FAQ、安装规范、售后政策和内部制度;
- Embedding 模型:把文字转换成可以计算相似度的向量;
- 向量数据库:保存向量、原文和元数据,并完成相似内容召回;
- 回答服务:组合用户问题与检索材料,生成最终回答。
对于光伏客服,RAG 的价值尤其明显。组件型号、逆变器告警码、额定功率、工作电压等信息具有很强的产品依赖性,不能只依靠通用语言模型猜测。回答必须来自对应型号的正式资料,并向用户展示出处。
12.2 Embedding 是什么
Embedding 会把一段文字映射为高维数值向量。语义相近的文本,其向量在空间中的距离通常更近。
例如:
- “逆变器出现 E021 告警”;
- “设备提示绝缘监测异常”;
- “逆变器绝缘故障怎么处理”。
三句话表面关键词并不完全相同,但表达了相近的问题。经过 BGE-M3 向量化后,它们可以在语义空间中彼此接近,从而召回同一份故障处理资料。
12.3 为什么不能只用向量检索
语义检索并不擅长所有情况。像 QH-620、E021、52.4V 这类字符串,对业务非常重要,但在向量空间里未必能获得足够高的区分度。
因此项目同时使用 BM25:
- BGE-M3 负责“意思相近”;
- BM25 负责“词语精确”;
- Reranker 负责“在候选中再次精排”。
这三步形成“广泛召回—互补融合—精细排序”的检索漏斗。
12.4 Reranker 为什么放在召回之后
Embedding 检索需要在大量数据中快速找候选,适合使用 Bi-Encoder:问题和文档分别编码,文档向量可以预先保存。
Reranker 通常采用 Cross-Encoder 思路,把问题和候选文档放在一起判断相关性,精度更高但计算成本也更高。因此它只处理召回后的少量候选,而不是遍历全部知识库。
全部知识库
↓ Dense + BM25 快速召回
候选 Top K
↓ Reranker 精细排序
最终上下文 Top N
↓ 答案组织
有依据的回复
十三、知识入库设计
13.1 在线检索与离线入库分离
知识库系统包含两条性质完全不同的链路:
- 离线链路负责读取、清洗、切分、向量化和写入知识库;
- 在线链路负责接收用户问题、路由、检索和回答。
两条链路必须分离。入库通常耗时较长,还可能遇到文件损坏、表格解析失败、模型资源不足等问题;在线查询则要求稳定且快速,不能在用户每次提问时重新读取和切分全部文档。
13.2 文档统一结构
进入向量库的每个 Chunk 不只保存文本,还保存可用于过滤、展示和治理的元数据:
{
"document_id": "product/inverter",
"title": "QH-100K 逆变器故障与运维手册",
"knowledge_scope": "product",
"source_type": "doc",
"heading_path": "故障处理 / E021",
"page_number": 12,
"parent_chunk_id": "product/inverter:p08",
"content_hash": "...",
"corpus_owner": "solar-demo-v2"
}
这些字段分别解决不同问题:
knowledge_scope控制客户与员工能够检索的资料范围;source_type区分 FAQ 和普通文档;heading_path帮助回答展示具体章节;content_hash用于增量更新与去重;corpus_owner防止同一 Milvus 实例中的不同项目数据互相影响。
13.3 父子分块
文档切分需要在“召回精度”和“上下文完整度”之间平衡。
Chunk 太大时,一个段落可能同时包含多个主题,向量表达被稀释;Chunk 太小时,虽然命中精确,但答案缺少前置条件和完整步骤。
项目采用父子分块思路:
- 子块较短,用于检索;
- 父块保留完整章节;
- 子块命中后,通过父块恢复完整语境;
- 标题路径与页码跟随 Chunk 保存。
对于光伏手册,这种方式可以避免只召回“请断开设备”一句,却遗漏前文中的适用型号、安全条件和后续检查步骤。
13.4 FAQ 与普通文档分集合
FAQ 和普通文档的业务意义不同。
FAQ 是经过审核的标准问答,目标是高置信度直出;普通文档是大段知识材料,目标是为复杂问题提供上下文。因此项目将两者保存到独立 Collection:
solar_demo_faq_v2:高频问答;solar_demo_documents_v2:产品与制度正文。
分集合后可以分别配置召回数量、阈值和缓存时间,也便于统计 FAQ 命中率。
13.5 增量更新
服务启动或知识发布时,会计算当前语料版本:
语料版本 = 项目标识
+ Embedding 模型版本
+ Reranker 模型版本
+ 全部文档内容摘要
系统比较当前知识块 ID 与 Milvus 中已有 ID:
- 新 ID 执行新增;
- 已存在且未变化的 ID 保留;
- 已删除文档对应的旧 ID 清理;
- 模型或语料版本变化后,缓存 Key 自动变化。
这样避免每次启动都清空并重建全部集合,也不会删除同一 Milvus 中不属于本项目的数据。
十四、在线 RAG Pipeline 深入
14.1 为什么需要 Pipeline
在线问答不是一个“搜索函数”,而是由多个阶段组成的业务流水线。Pipeline 的价值是让每个阶段只有一个明确职责,并可以单独观察、替换和降级。
青禾平台可以抽象为以下阶段:
flowchart TD
S0[Stage 0 输入校验与身份范围] --> S1[Stage 1 业务领域路由]
S1 -->|无关| OUT[业务范围提示]
S1 --> S2[Stage 2 查询准备]
S2 --> S3[Stage 3 FAQ 检索]
S3 -->|高置信命中| FAQ[标准答案直出]
S3 -->|未命中| S4[Stage 4 普通文档混合检索]
S4 --> S5[Stage 5 融合、去重与重排]
S5 --> S6[Stage 6 上下文与答案构建]
S6 --> S7[Stage 7 引用、置信度与统一响应]
14.2 Stage 0:输入与权限
入口首先校验:
- 问题不能为空且不能超过长度限制;
- 当前身份是匿名客户还是员工;
- 客户请求强制限制为
product; - 员工请求可以使用
product、internal或all; - 请求 ID、开始时间和事件通道已建立。
权限范围在检索前写入过滤条件,而不是检索后再删结果。这样内部制度内容不会先被召回到客户请求的内存上下文中。
14.3 Stage 1:业务路由
路由是整个系统最重要的成本控制点。
对于“今天天气怎么样”这类问题,如果直接执行 RAG,向量库总能找到某些表面相关的词,例如文档中的“现场天气”,最终产生看似有来源但答非所问的结果。
正确方式是在第一层判断它是否属于光伏产品、安装、故障、售后或制度范围。无关问题直接返回可解释提示,并明确说明没有执行知识检索。
14.4 Stage 2:查询准备
用户问题可能包含口语、错别字和上下文指代。查询准备阶段负责:
- 去除无意义空白与重复符号;
- 标准化设备型号;
- 保留告警码、功率和电压等关键实体;
- 必要时根据历史问题补全指代;
- 生成适合 Dense 与 BM25 的查询文本。
多轮查询改写将历史问题、当前指代和关键实体合并为独立可检索的问题,同时保留原始输入用于回答展示。
14.5 Stage 3:FAQ 快速通道
FAQ 快速通道承担确定性回答。命中后可以跳过普通文档检索和生成模型:
用户问题
→ FAQ 缓存
→ FAQ 混合检索
→ 阈值判断
→ 标准答案 + FAQ 来源
它的业务优势是低延迟、低成本、可审核和可预测。
14.6 Stage 4:文档混合检索
未命中 FAQ 后,服务并行执行 Dense 与 BM25 检索。Milvus 使用加权 Ranker 合并结果,Dense 与 Sparse 权重分别为 0.55 和 0.45。
Dense 权重略高,是因为客户问题多为自然语言;Sparse 仍保持较高比例,是因为光伏场景包含大量型号、数字和故障码。
14.7 Stage 5:去重与重排
不同检索通道可能召回同一段内容。系统以文档 ID、父块 ID 和内容摘要识别重复结果,避免同一来源在上下文中出现多次。
随后由 Reranker 对“问题—文档”对进行精排,最终只选择高相关内容进入答案上下文。
14.8 Stage 6:证据不足保护
向量数据库总能返回“最相近”的结果,但最相近不等于足够相关。因此系统必须设置证据阈值。
当没有可靠资料时,回答应明确表示:
当前授权知识库中未找到可靠依据。请补充产品型号、故障码或具体问题,也可以转人工咨询。
这比利用低相关文档拼凑答案更符合企业客服要求。
14.9 Stage 7:统一输出
无论走无关路由、FAQ 直出还是普通文档检索,最终都转换成统一响应:
{
"answer": "...",
"question_classification": {
"category": "设备故障"
},
"knowledge_bases": ["产品FAQ库"],
"retrieval_confidence": 0.95,
"processing_time_ms": 14.1,
"pipeline": "FAQ direct answer",
"sources": []
}
统一契约让前端不必为每条路线实现完全不同的页面。
十五、Milvus 索引与过滤设计
15.1 双向量字段
Milvus Collection 同时维护:
dense:BGE-M3 向量;sparse:BM25 内置函数产生的稀疏向量;text:原始 Chunk;- 动态元数据字段:知识范围、标题、父块等。
Dense 字段使用 HNSW 索引,适合近似最近邻搜索;Sparse 字段使用 BM25 索引。
15.2 HNSW 参数含义
项目使用:
M = 16
efConstruction = 200
查询 ef = 64
M决定图中节点连接数量,越大通常召回更好,但占用更多内存;efConstruction影响建索引质量和耗时;- 查询
ef控制搜索范围,越高通常召回越好,但延迟也会上升。
这些参数不是固定真理,生产环境需要根据知识规模、并发量和 Recall@K 评测结果调整。
15.3 中文 BM25
BM25 依赖分词。Collection 使用中文分析器,让“逆变器报警代码”“额定功率”等中文词组能够参与稀疏检索。
与在应用层自行维护另一套稀疏向量相比,Milvus 内置 BM25 可以让数据写入、索引和混合搜索在一个系统中完成,减少双库同步复杂度。
15.4 权限过滤表达式
检索时构造类似下面的过滤条件:
corpus_owner == "solar-demo-v2"
and knowledge_scope in ["product"]
员工查询全部授权资料时,范围可以扩展为:
knowledge_scope in ["internal", "product"]
过滤值必须经过转义,并且只能来自服务端白名单,不能直接拼接任意用户输入。
十六、检索事件协议
16.1 为什么需要事件协议
RAG 请求可能涉及模型加载、向量化、两路召回、重排和答案构建。如果前端只有一个旋转图标,用户无法判断系统是否正在工作。
平台为检索定义结构化事件:
| 事件 | 含义 | 前端表现 |
|---|---|---|
start |
请求已接收 | 建立当前回答卡片 |
status |
当前处理阶段变化 | 展示路由、检索、生成进度 |
token |
产生部分回答内容 | 逐步追加文本 |
end |
最终结果完成 | 展示元数据和参考来源 |
error |
请求失败 | 显示可读错误并结束等待 |
16.2 事件顺序
sequenceDiagram
participant UI as React 客户端
participant API as FastAPI
participant RAG as RAG Service
UI->>API: 建立检索事件连接
API-->>UI: start
API->>RAG: query(message, scope, role)
RAG-->>UI: status:意图路由
RAG-->>UI: status:知识检索
RAG-->>UI: status:答案生成
RAG-->>UI: token:部分文本
RAG-->>UI: end:答案、来源、置信度
异常也必须转换成 error 事件并正常收口,避免前端一直停留在“正在检索”。
十七、三级缓存实现细节
17.1 缓存什么
平台缓存 FAQ、文档检索结果和可复用向量,不缓存最终自然语言答案。
最终答案可能受到用户角色、对话上下文和回答策略影响;盲目缓存答案容易造成串话、过期回答或权限泄漏。检索结果更稳定,也更容易通过版本进行治理。
17.2 缓存 Key
缓存 Key 由稳定 JSON 序列化后计算 SHA-256 摘要,参与计算的字段包括:
- 缓存种类;
- 问题哈希;
- 授权知识范围;
- 用户角色;
- 语料和模型版本;
- 各知识范围的 Epoch。
同一个问题由客户查询和员工查询会产生不同的 Key,从缓存层继续保持权限隔离。
17.3 TTL 策略
不同数据的变化频率不同:
| 缓存对象 | 示例 TTL | 原因 |
|---|---|---|
| FAQ 检索 | 30 分钟 | 标准答案稳定、重复率高 |
| 普通文档检索 | 15 分钟 | 兼顾命中率与资料更新 |
| Embedding | 60 分钟 | 计算成本高、相同文本结果稳定 |
| L1 Epoch | 3 秒 | 快速感知失效,同时降低数据库压力 |
17.4 依赖故障降级
Redis 不可用不应该让知识问答整体不可用。缓存读取异常按 Miss 处理,系统继续访问 Milvus;同时清理进程内 Epoch,避免使用不确定状态。
如果知识失效写入 PostgreSQL 失败,对应 Scope 会被当前进程暂时阻止使用缓存,优先保证一致性。
十八、FastAPI 服务层
18.1 为什么使用异步
RAG 请求包含大量 I/O:
- 访问 PostgreSQL;
- 访问 Redis;
- 访问 Milvus;
- 等待模型或生成服务;
- 向前端推送事件。
FastAPI 的异步模型可以在一个请求等待外部服务时处理其他连接,提高并发利用率。对于本地模型推理这类阻塞任务,项目通过工作线程执行,避免阻塞主事件循环。
18.2 路由边界
接口按领域拆分:
/api/auth:匿名会话、员工登录和会话查询;/api/knowledge:同步知识问答;- 检索事件接口:向前端输出阶段状态;
/api/tickets:客户创建和查看本人咨询;/api/staff/tickets:员工查看、接单、回复和解决;/api/health:服务健康检查。
18.3 统一错误处理
后端不会把数据库异常堆栈或模型路径直接返回浏览器,而是转换为统一、可读的错误结构。每个请求保留 Request ID,方便后续关联日志。
18.4 启动前置校验
服务启动时执行以下前置检查:
- 环境变量是否完整;
- PostgreSQL、Redis 和 Milvus 是否可连接;
- Collection 是否存在或允许初始化;
- 本地 BGE 与 BERT 模型目录是否完整;
- 员工初始密码是否仍为默认值;
- 知识库语料是否为空。
平台提供模型资源检查与初始化脚本,避免服务启动后第一次请求才发现模型缺失。
十九、工单领域模型与状态流转
19.1 工单核心数据
一张工单不仅保存客户描述,还包含:
- 业务编号;
- 匿名客户会话;
- 问题摘要与类别;
- 当前状态;
- 紧急程度;
- 客户意图与模型置信度;
- 情绪标签与情绪置信度;
- 分流依据和建议部门;
- 是否需要人工复核;
- 创建时间和消息记录。
19.2 状态机
stateDiagram-v2
[*] --> 待接单: 客户创建咨询
待接单 --> 处理中: 员工接单
处理中 --> 处理中: 客户/员工发送消息
处理中 --> 已解决: 员工标记解决
已解决 --> [*]
后端校验状态转换。例如未接单工单不能直接以“处理中员工”的身份回复,已解决工单不能继续追加普通消息。
19.3 为什么客户不用注册
为了降低咨询门槛,客户身份默认使用匿名浏览器会话:
- 首次访问自动创建会话;
- 会话 ID 保存在 HttpOnly Cookie;
- 客户接口只返回该会话创建的工单;
- 员工回复后,客户刷新“我的咨询”即可查看。
匿名会话还可以绑定手机号、订单号或企业客户账号,在保持低门槛的同时支持跨设备查询。
二十、智能分流算法
20.1 输入与输出
分流输入是客户原始问题,输出不仅是一项类别,而是一组业务信号:
{
"category": "设备故障",
"department": "技术支持",
"urgency": "urgent",
"intent": "product_quality_issue",
"emotion": "strong_negative",
"emotion_confidence": 0.81,
"needs_review": false,
"reason": "识别到设备停机与强烈负向情绪"
}
20.2 规则与模型的边界
BERT 适合识别自然语言类别和情绪,但企业规则更适合处理强确定性的业务条件。
例如:
- 出现“起火、冒烟、触电”时,安全规则应直接提升优先级;
- 出现“设备已停机、多次无法发电”时,不应只依赖情绪分数;
- 模型置信度低时,规则可以给出保守分类并标记复核;
- 用户语气激烈但问题只是进度催促时,情绪和业务分类应分别保存。
20.3 可解释性
员工工作台不只展示“AI 判定紧急”,还展示判定依据。客服可以根据原始描述、情绪标签和业务规则做最终判断。
AI 在这里承担辅助决策,而不是绕过员工自动做不可逆业务操作。
二十一、前端体验设计
21.1 客户门户
客户首页采用清洁能源与地球视觉,主区域聚焦一个问题输入框。用户不需要理解 RAG、向量库或模型,只需要知道“可以查询产品使用、安装维护和故障排查”。
三个预设问题分别覆盖典型路由:
- 无关问题展示路由能力;
- FAQ 问题展示标准答案直出;
- 产品参数问题展示知识库检索。
21.2 检索结果卡片
答案卡片分为四层:
- 首层是自然语言答案;
- 第二层是问题分类、来源库、置信度和耗时;
- 第三层是本次处理 Pipeline;
- 第四层是可以展开的参考来源。
这种结构兼顾阅读效率和结果核验:用户先读答案,需要核验时再查看来源。
21.3 员工工作台
员工页面强调信息密度:
- KPI 快速了解待接单、处理中和已解决数量;
- 队列按优先级定位问题;
- 中间区域专注沟通;
- 右侧 AI 面板提供判断依据;
- 产品知识库和内部制度库通过侧边栏切换。
21.4 数据刷新
工单列表使用低频增量轮询同步队列状态,轮询过程中通过写入锁和 Revision 防止员工正在回复时旧请求覆盖新状态;会话消息使用 WebSocket 推送,减少无变化请求并保证客服与客户之间的实时沟通。
二十二、异常与降级策略
企业 AI 应用不能只考虑“所有依赖都正常”的路径。
| 故障场景 | 平台策略 |
|---|---|
| 生成模型服务不可用 | 使用 FAQ、检索摘要与本地模型维持核心服务 |
| Redis 不可用 | 缓存按 Miss 处理,继续访问检索服务 |
| Milvus 不可用 | 返回明确的 RAG 环境不可用提示 |
| BERT 模型不可用 | 使用业务规则完成保守分流 |
| 检索证据不足 | 不生成确定性答案,引导补充信息或转人工 |
| 员工未登录 | 后端拒绝内部知识库和员工工单接口 |
| 事件流异常 | 输出 error 事件,前端结束加载状态 |
降级原则是:可以降低智能程度,但不能伪造高置信度、泄露权限范围或让页面无限等待。
二十三、项目目录说明
qinghe-solar-service-platform/
├─ apps/
│ ├─ api/ # FastAPI 服务、RAG 与工单接口
│ │ ├─ src/solar_api/
│ │ │ ├─ auth/ # 匿名与员工会话
│ │ │ ├─ core/ # 配置、数据库、异常
│ │ │ ├─ demo/ # 工单与智能分流
│ │ │ ├─ demo_documents/ # 产品资料与内部制度示例
│ │ │ ├─ rag_service/ # Milvus 混合检索
│ │ │ ├─ rag_cache.py # 三级缓存治理
│ │ │ └─ rag_events.py # 检索事件协议
│ │ └─ tests/
│ └─ web/ # React 客户端与员工端
├─ packages/
│ ├─ ml_runtime/ # 本地模型资源注册与加载
│ └─ rag_core/ # 文档切分与模型 Provider
├─ scripts/ # 初始化、模型检查与接口导出
├─ docs/ # 设计文档和博客图片
├─ docker-compose.yml # 基础服务编排
├─ .env.example # 安全环境变量模板
└─ README.md
二十四、典型业务使用路径
以下使用路径能够串联平台的全部核心能力。
24.1 客户知识问答
- 打开客户门户;
- 点击“今天天气怎么样?”;
- 说明无关问题在入口被拦截,没有执行检索;
- 点击“逆变器报警代码含义”;
- 展示 FAQ 直出、95% 置信度和来源库;
- 点击“QH-620 组件额定功率是多少?”;
- 展示混合检索结果、资料来源与处理耗时。
24.2 转人工与智能分流
输入:
我的逆变器持续报警,已经重启多次仍然无法正常发电,现场设备已停机,请尽快处理。
提交人工咨询后,展示咨询编号和“我的咨询”页面。
24.3 员工工单处理
- 登录员工工作台;
- 查看刚创建的紧急工单;
- 展示问题分类、情绪倾向和情绪置信度;
- 接单并回复;
- 回到客户页面查看回复;
- 员工标记工单已解决。
24.4 内部知识库
员工进入企业内部知识库,查询“新人入职流程”,展示员工权限可以访问内部制度,而客户不能访问。
二十五、完整平台能力
平台围绕内容、检索、客服协同和运行治理形成四组完整能力。
25.1 内容运营
- 建立文档上传与审核后台;
- 支持 PDF、Word、Markdown 和结构化表格;
- 建立产品、型号、版本和适用区域元数据;
- 制定 FAQ 负责人和有效期。
25.2 检索质量
- 建立真实问题评测集;
- 分别统计 FAQ 命中、文档召回和答案质量;
- 校准不同问题类别的检索阈值;
- 加入多轮查询改写和实体识别;
- 建立 Bad Case 周期。
25.3 客服协同
- 接入企业员工账号;
- 支持客服组、技能组与排班;
- 增加工单 SLA、超时提醒和升级;
- 引入 WebSocket 实时消息;
- 增加服务评价和质检。
25.4 运行治理
- 完善日志、指标和链路追踪;
- 增加限流、熔断、超时与重试;
- 建立知识库灰度发布和回滚;
- 对敏感信息进行脱敏;
- 完成备份、恢复和容量评估。
二十六、质量评估指标
RAG 系统不能只凭“看起来回答得不错”验收。
26.1 路由指标
- 无关问题拦截准确率;
- FAQ 路由准确率;
- 知识库范围选择准确率;
- 应转人工问题的召回率。
26.2 检索指标
- Recall@K:正确资料是否出现在前 K 个结果中;
- MRR:正确资料首次出现的位置;
- 型号与告警码命中率;
- 不同知识库的越权召回数;
- 无答案问题的错误召回率。
26.3 回答指标
- 答案是否由来源支持;
- 引用是否指向正确文档;
- 关键参数是否准确;
- 信息不足时是否正确拒答;
- 回答完整性与可操作性。
26.4 工单指标
- 分类准确率;
- 紧急问题召回率;
- 情绪识别准确率;
- 人工复核比例;
- 首次响应时间;
- 工单解决时长。
26.5 性能指标
- FAQ P50/P95 延迟;
- 文档检索 P50/P95 延迟;
- 缓存命中率;
- 模型加载时间;
- 并发请求成功率;
- 外部依赖降级成功率。
二十七、Bad Case 闭环
线上低置信度、用户转人工和客服纠正结果都是高价值数据。
Bad Case 处理流程:
- 自动记录问题、路由结果、召回文档和最终答案;
- 判断错误发生在路由、检索、重排还是回答阶段;
- 由业务人员补充正确分类和正确资料;
- 决定修复 FAQ、文档、规则、阈值或模型;
- 将案例加入回归数据集;
- 新版本发布前重新执行评估。
不能把所有失败都归因于模型。很多问题来自资料缺失、Chunk 边界错误、元数据不完整或阈值配置不合理。
二十八、安全与隐私
客户咨询可能包含电话、地址、设备序列号和现场照片。正式系统需要:
- 在输入区域提示不要提交不必要的敏感数据;
- 日志中避免记录完整 Cookie、密码和 Token;
- 客户接口按匿名会话隔离工单;
- 内部制度检索强制员工鉴权;
- 缓存 Key 包含角色与知识范围;
- 上传资料经过类型、大小和恶意文件检查;
- 对导出、分享和删除操作保留审计记录。
本项目的权限边界从检索前开始执行,并贯穿数据库查询、缓存和结果返回,而不是只通过前端菜单控制。
二十九、总结
青禾光伏智能服务平台的核心价值,不是简单地接入一个大模型,而是把企业知识、检索策略、权限控制和客服业务真正连接起来。
对于客户,它提供了更低门槛、更快且有依据的产品咨询服务;对于员工,它减少了查找资料和判断工单的时间;对于企业,它建立了一套可持续治理、可追溯、可扩展的智能服务基础。
平台完整覆盖真实文档上传、知识库后台管理、WebSocket 实时消息、客服自动分配、服务评价、数据统计与生产环境部署,并通过质量评估和 Bad Case 闭环持续优化业务效果。