RAG实践技巧:这次还做不好AI客服,那我也没办法了...
AI训练营6期,12月16日开班,欢迎咨询
就近两年的实践经验,各个公司最常见的AI需求有以下四类:
一、工作流类AI
这个可以解决很多确实的问题,但AI含量很低,不到20%(通常10%左右):
二、简单AI知识库-AI客服
这是最常用也是公司体系真正能降本增效的应用,而且多数时候实现不难:
三、简单AI知识库-AI内容生成
这也是相对常见的项目类型,比如帮助写公文,就是根据已有模板生成符合要求的内容:
四、AIGC-文生图
今年下半年以来的话,文生图、文生视频相关的需求逐渐旺盛,甚至已经超过了AI客服相关需求,这块商业机会巨大,比如AI漫收益很高:
每种项目类型都有其固有的方法论、成本结构、技术卡点,其中简单AI知识库是一套体系(大同小异),也就是我们常说的RAG系统,只不过当前很多同学对RAG这个东西是懵逼的,其中包括我的一些学员。
他们是打开书了然,关了书茫然,但是真的回归工作场景又一定会遇到RAG系统,所以我们这里很有必要再将这个RAG再拉出来连续鞭尸!
RAG的效果问题
首先,这个是我必须连续强调再强调的部分,很多同学用RAG很粗暴。比如他们拿着知识库直接丢进 Coze/Dify 自动切片,完了一下午搞了两下提示词,一个聊天机器人就出来了,这种效果能好就奇了...
我们这里说的还是简单AI知识库,甚至你非要说他是AI搜索都行,这种产品特性是一锤子买卖,衡量指标到底出没出想要的内容:
用户提问 -> 检索操作 -> 返回结果。如果检索返回的都是不相关的垃圾信息,整个流程就宣告失败;甚至返回了想要的内容,但是其中垃圾信息较多,也不能算成功。
而取决于这次搜索的核心有两点:
第一是用户输入,这东西是不可控的,所以问题或者说拿去检索的关键词一定会被转写和优化; 第二是一定要保证在输入(用去搜索那个关键词)没问题的情况下一定要能得到正确的结果,这一块就要求最初的数据处理了;
我们这里先说为什么要改写用户查询,其中会慢慢涉及最烦躁的数据入库处理:
查询改写
其实无论对于Agent的Tools调用,还是做RAG系统,都会遭遇相同的问题,这也是稳定Workflow难以解决的部分:用户语言太模糊,他具有多意图,泛化能力要求极高,这东西只有模型能够解决。
还是那句话:用户无限的意图需要被有限的工具所收敛、对应着用户的无限问题需要被知识库做边界。
比如用户一句话可能有多个问题,但我们需要处理的只能是知识库里面有的问题,如果没有那么就无需处理。
综上,重写查询,相当于在检索前做一轮语义收束,会大大提升检索精确度,当前常见的策略是查询分解,偶尔会用到HyDE:
查询分解的核心思维是分而治之,将复杂或多意图查询拆分为独立的原子子问题;
HyDE (假设文档嵌入)属于先脑补,后检索,让LLM基于问题生成一份“假设答案”,用其丰富语义去检索;
大家肯定没听懂,这里我们用个案例详细展开:
案例详解查询改写
用户:我入职 8 个月了,想请 3 天病假,需要走什么流程?病假工资怎么算?
这一问题同时包含了请假流程和病假工资计算两个意图。每个子问题对应一个明确的意图:
子问题1: “需要走什么流程?” – 询问病假请假流程的意图。
子问题2: “病假工资怎么算?” – 询问病假工资计算方法的意图。
这里会涉及到输入Query整理前的第一个知识点:问题分类表。
一、问题分类表(Intent)
模型是不可能当场理解业务的,所以稳定检索不能只依赖模型能力,在做RAG前,就必须说清楚一件事情:你的系统到底要完成哪些问题,比如我在做个人卖课AI客服时候就有一套:
这种问题分类也就是我们之前所说的收敛:把无限问题收敛成有限类型,只要跟我需要解决的问题有关,管你用户说得天花乱坠都不需要关注。
再回归用户关于HR规则的询问,我们需要为每个意图指定一个问题类型(Intent),用于指导后续流程:
Intent 1: 请假流程咨询。用户询问请病假的具体流程和手续。 Intent 2: 病假工资计算咨询。用户询问病假期间工资如何计算。
他应该映射到HR领域的一张问题分类表(作用是用于收敛):
| 请假管理 请假与休假办理、审批规则、证明材料、销假/续假;考勤记录与异常更正(补卡/漏打卡)、迟到早退等出勤异常处理。 | 2)请 3 天病假需要什么证明? 3)我忘记打卡了,怎么补卡? |
| 薪资规则 计薪口径与发放周期;扣款/补发规则;补贴、加班费、绩效奖金发放;与出勤/请假相关的计薪规则(如病假工资)。 | 2)这个月工资少了,扣的是什么? 3)加班费怎么算?周末和节假日一样吗? |
| 社保公积金 参缴条件、基数比例、增减员;断缴/补缴/转移;商业保险与福利报销类事项的办理要求。 | 2)社保断缴了怎么办,能补缴吗? 3)商业保险怎么报销,需要什么材料? |
| 入职、转正 入职手续与资料;试用期与转正流程;工龄口径;员工信息变更;在职/收入等证明开具。 | 2)工龄怎么计算?影响年假吗? 3)在职证明/收入证明怎么开? |
| 离职 离职申请与通知期;交接要求;离职证明;最后工资/补偿结算;社保公积金停缴/转移;未休假期结算。 | 2)离职证明怎么开?什么时候能拿? 3)最后一个月工资怎么结算? |
| 制度查询 制度入口与版本;条款解释与适用范围;例外情形;违纪处理;保密/竞业等合规边界说明。 | 2)某条规定怎么解释,有没有例外? 3)这个做法合规吗?有红线吗? |
二、数据处理
好,在清楚用户的查询输入后(用户的问题会被模型尽量的引导到问题类别),所以在做知识检索的时候更多的是在做简单语义识别,甚至这里不用向量库,用小模型也行:
这也是最常见的微调场景,我们一般用小模型微调后,处理问题类型判断,最终抽取问题类别(intent)标签
因为只要确定问题类别,那么相关的知识就一定能被搜出来。在这里也终于涉及到了我们知识库到底该长什么样的问题了?
如上所述,因为收敛的方式是以问题类别为主,那么知识库的排布也需要如此,这里给一个简单案例,首先每份文档前面需要加一段“摘要”,而后才是具体内容:
module_id:如HR.Payroll
覆盖范围:能回答哪些问题
先决信息(Required Context):回答前通常需要的关键背景(不是全量槽位,强调“最小关键”)
缺失追问(Clarifying Questions):缺关键背景时,问用户的 1–2 句追问模板
检索提示(Retrieval Hints):该模块常用关键词、优先命中的制度文档名称/章节
版本与适用范围:制度分地区/分用工类型时怎么处理
为了方便各位进一步了解,这里给一个模型判断问题类别和具体知识库文档长什么样的样例:
你是一个专业的HR助手,负责对用户问题进行意图分类。
请严格按照下面的分类体系进行分析:
## 问题分类表
1. **请假管理**:请假与休假办理、审批规则、证明材料、销假/续假;考勤记录与异常更正
......
6. **制度查询**:制度入口与版本;条款解释与适用范围;例外情形;违纪处理
## 处理规则
1. 只识别上述6类问题,其他问题回复"抱歉,这个问题超出我的处理范围"
2. 一个问题可能涉及多个类别,输出所有相关类别
3. 具体处理流程...此处省略1000字...
4. 输出格式:{"intents": ["类别1", "类别2"], "reasoning": "简要分析原因"}
## 示例
用户:我入职8个月了,想请3天病假,需要走什么流程?病假工资怎么算?
输出:{"intents": ["请假管理", "薪资规则"], "reasoning": "问题包含请假流程(请假管理)和病假工资计算(薪资规则)两个意图"}
然后是一个具体的文档案例:
# 模块ID:HR.Leave.Medical
# 版本:xxx
# 适用范围:省事员工
## 摘要
本模块涵盖病假申请全流程及相关政策,包括:
1. 病假申请步骤(线上系统操作、材料要求)
2. 病假期间工资计算规则(基于司龄和当地政策)
3. 常见问题(证明材料、审批节点、异常处理)
## 覆盖问题范围
- 如何请病假?
- 病假需要什么证明材料?
......
## 先决信息(Required Context)
- 员工司龄(影响病假天数上限和工资比例)
- 所在地区(影响最低工资标准)
- 请假天数(影响审批层级)
## 缺失追问模板
1. "请问您的司龄是多久?这将影响病假工资的计算比例。"
2. "您计划请几天病假?不同天数的审批流程不同。"
......
## 检索提示(Retrieval Hints)
关键词:病假、医疗期、病假工资、医疗证明、病假申请、病假流程
相关文档:《员工手册-考勤篇》第3章、《薪酬福利制度》第5.2节
常用别名:医疗假、带薪病假、病休
## 具体内容
### 一、病假申请流程
1. **线上申请**
- 登录HR系统 → 请假申请 → 选择"病假"
- 填写:起止时间、病因简述、上传证明材料
- 提交至直接上级审批
......
其实这套逻辑肯定没问题,但是数据整理真的很烦,比如你想把自己的所有零散文章(比如公众号)整理成这种知识库,那就要费大劲。
三、HyDE(假设文档)
其实在简单业务场景下,上述的逻辑已经很清晰了,先意图路由(收敛)→ 再在对应模块检索,这种准确率是奇高的;
但是,在稍微复杂点的业务下,收敛只能解决去哪搜的问题,却不能解决搜得准的问题,因为就算同一类别也可能有很多内容,最典型的场景就是某个类别的文件特别长,被切割成了数十块,而每块的摘要都是类似的,这就会搜出大量内容。
更常见的场景是,即使我们收敛到“请假管理”这个意图,知识库中可能有:
病假申请流程(3种不同情况) 年假申请流程 事假规定 ...
用户问“病假流程”,但知识库中可能有:
《员工手册》第3章:通用请假流程 《考勤制度》附件2:病假特殊规定 ...
甚至条款间内容是冲突的都有可能,后面的覆盖前面的,特殊的覆盖普通的...
综上,意图收敛只是第一层筛选,后续仍需要精确匹配。
于是,HyDE在这里的作用就出来了,对于意图2(病假工资),HyDE可以生成类似:
根据公司规定,员工病假工资计算通常基于司龄、基本工资和当地最低工资标准。
对于司龄不满1年的员工,病假期间工资按基本工资的60%发放,但不得低于当地最低工资标准的80%...
这个“假设答案”包含了:
关键变量:司龄、基本工资、最低工资标准 具体数值:60%、80% 专业术语:基本工资、当地最低工资标准
用这个向量去检索,更容易命中《薪酬制度》中具体的计算条款,而非泛泛的薪酬介绍,这里还是给个案例:
我有点不舒服,想休息几天,工资怎么算?
意图识别:请假管理+薪资规则(可能有歧义)
查询改写(HyDE):
子查询1:“轻微不适短期休息请假流程,是否需要医生证明”
子查询2:“短期病假工资计算规则,非住院病假待遇”
查询效果评估
到这里就进入一个关键环节了,如何评价每次查询的质量,这个也是非常经典的面试题。常见的评估指标有:
检索召回率(Recall@k):改写后的查询,能否在 top-k 个检索结果中命中正确答案的文档; 查询意图保持度:人工抽样检查,改写是否歪曲了用户原意; 下游任务准确率提升:最终答案的准确率是否因改写而显著提升;
也有通俗一点的说法:
没召回(入库/切分/索引问题) 召回了没选对(重排问题) 选对了答歪(提示词/生成约束问题) 本来就不该答(范围外问题/需要工具调用/需要人工)
但是每次我以为说清楚了,都还是有同学没明白,所以这里还需要进一步说细点:
首先,评估查询质量要细化到每个链条,这里依次是:
路由正确 - 问题是否分到对的意图模块; 召回可靠 - 关键证据有没有被找到; 排序合理 - 正确证据是否排在前列; 回答可证 - 答案是否严格基于证据; 边界清晰 - 不该答的是否恰当处理;
然后接下来就是具体的标准,这东西还不能一蹴而就,是个逐渐加强的过程:
一、弱标准
弱标准成本低,甚至普通测试就能做判断。他只需要判断整体好坏,几乎凭感觉,适合项目初期做快速验证。
具体工作的话是只标注答案正确与否,是否需要追问,是否胡说等,这里要注意,每个环节都需要有测试数据集。
二、过渡标准
一般是在系统快上线时候需要做的测试,这个时候需要业务专家加入做判断了,一般测试只能做协助工作;
业务专家需要标注问题对应的文档到底该什么,相当于他会给出文档级别的正确答案,比如病假流程问题 → 《员工手册》第3章+《考勤制度》附件2;
这里就一定要做成测试数据集,以后每次就跑自动化脚本看看类似问题对不对。
三、强标准
从这里开始,就要求就比较高了,需要专家精确标注到具体段落,偶尔还要定义错误处理策略,比如冲突处理规则;
因为成本较高,所以实际操作时候,只对高频+高风险问题做强标注,必定20%问题决定80%体验嘛。
四、数据集问题
其实,在做模型评估的时候,有两个难点:
第一是建立评估点,到底哪些地方需要评估; 第二就是每个地方的数据集怎么来;
按之前的做法,在上线前让专家准备一部分,在上线后要做好日志,从日志拿数据,比如:每周从线上日志抽取100-200个真实问题。
这里要注意的是,除了错误的案例,这里还需要收集一些正确的案例,这些对于数据集的多样性是有帮助的。
然后对专家的依赖是无法避免的,但要尽量降低他的压力,直接让他做选择题,比如对错,然后到底该哪个文档,这里最好做一套系统让他用...
最后给个简单案例表,大家体验下就行:
| 路由错 | ||
| 搜不到 | ||
| 搜到但没排上来 | ||
| 证据对但回答错 | ||
| 边界处理错 | 不该答还答 |
结语
今天又浪费5小时,折腾这个,生怕有哪里说不清楚,到现在也不知道能不能把简单AI知识库(RAG)为什么难、难在哪、该怎么做”讲清楚。
RAG是公司必定会遭遇的课题,要做好需要一条完整的链路,而不是一股脑搞进去,RAG这东西其实成本挺高的:
好了,文章篇幅很大了,就不多说了,希望对各位有用。
点击上方卡片关注叶小钗公众号,查看下方二维码,添加我个人微信:
往期推荐
《LangChain、 Dify、 n8n、 Coze:四大AI框架怎么选?》