05|药到病除:知识库机器人常见的三大病症与解药

你好,我是产品二姐。

这节课,我们来聊聊“消费品使用问答助手”落地过程中遇到的问题和解决方法。

在这个产品里我们核心用的技术是RAG,对于希望转型到AI产品经理的同学来说,从RAG入门会比较容易,但同时也要明白,RAG做深很难,就连OpenAI的工程师都说 “RAG比想象中难”。所以这节课,我选择先从最棘手问题入手,然后逐个分析引起这些问题的原因和方法。

我先用一张“诊断表”来列出在<消费品使用问答助手>中遇到的问题,然后逐一定位问题的成因,以及它们在RAG流程中的位置,最终制定解决方案。

图片

问题1: 明明在知识库中有答案,就是回答不出来!

下图是“消费品使用问答助手”的真实问题,当用户问,“在人机对话时,机器识别不到讲的语音怎么办”。我们肉眼可见在上传的产品说明书里有一个极其贴切的回答:“a.需要点击对话键,激活对话功能……”。然而,AI问答助手却给出了非常笼统的回答:“可能多种原因导致的,比如环境噪音……”

图片

相信这时你也会困惑。别着急,我们由表及里一项项检查。

我们知道,RAG中的内容主要由用户请求和检索到的文本块组成。所以首先要看我们期待的文本块有没有被检索出来。通过Dify里的Tracing功能我们看到,这里并没有检索出我们期待的文本块。之所以出现这种问题,一般会有两个原因:一是检索方式不合理,二是分块不合理。我们来分别排查。

图片

原因1:检索方式不合理

在第一章第三节中的RAG技术原理中,我们曾经讲过RAG中的一个环节是知识检索。好比是你去一个巨大的图书馆里快速找到你要的资料。假如这个图书馆里的书籍只能通过书名来检索,而你用作者名称检索,那么你就很难找到相应的资料。这就是所谓的“检索方式不合理”。这个问题放在RAG 流水线中处于第五步(如下图)。

图片

在RAG里,常见的检索方式有:向量检索、关键词检索、混合检索。

  • 向量检索

向量检索就是将用户问题对应的向量与知识库中文本块对应的向量进行比较,距离相近的向量会被选中,也是我们在这个案例中使用的检索方式(Dify界面中可以设置)。

举个例子,在现实生活中,你可能会觉得“桃子”与“梨”这两个词完全没有重合,但是在向量空间里,他们之间的距离是非常近的。因为词的向量化就是把一个词拆解为到几百甚至几千个维度,比如形状、大小、类型、颜色等等。

由于“桃子”与“梨”在很多维度相似,比如都是水果,因此它们在向量空间里非常接近,甚至比“梨”与“梨树”之间的距离更近,所以当我们用向量检索来寻找与“梨”接近的词时,排在第一位的可能是“桃子”,而不是“梨树”。

同理,假设用户的问题是:

在人机对话时,机器识别不到讲的语音怎么办

我们希望被检索到的块对应的文字是:

问题:在人机对话时,机器识别不到讲的语音
回答:
a.需要点击对话键,激活对话功能。在对话过程中,记住一条:当听到机器“叮”一声后,机器处于收音状态,可以开始对话。
b.机器说话时,断断续续,或者反应慢,可能是网络信号不太好,请把机器放在信号较强并稳定的区域。
c.把路由器和猫都断电,就是电源拔掉,过一会再插上。

尽管用户的问题完全被包含在文本块中,但因为文本块是作为一个整体放在向量空间里的,二者的距离就会比较远。因此当我们单纯使用向量检索时,这个文本块就不会被检索出来。

  • 关键字检索

顾名思义,就是进行关键字匹配,也是传统互联网常用的文本检索方式。这种方法就可以用“梨”来检索“梨树”,但比较死板,要求用户的问题与知识库中的文字完全匹配才行。虽然我们可以采用分词等方法将用户问题拆分为几个关键词分别检索,扩大检索范围。但关键词检索不能理解用户语义,很可能会返回完全不相关的结果,出现我们之前的“人工智障”现象。

  • 混合检索

混合检索综合了关键字和向量检索的优势,这也是RAG中比较推荐的做法。

在针对这个特定问题,当我们把检索方法从向量检索改为混合检索后(Dify里可以很方便的配置检索方式),就解决了。

那么是不是检索到对应的文本块,就会完全消除这一问题呢?也不是。我们来看导致类似问题的另外一个常见原因: 分块不合理。

原因2: 分块不合理

这个原因处于RAG流水线中的第二步:分块。

图片

还是拿这个例子来说,在下图中,我们看到了匹配的检索结果,但回答仍然不准确。

图片

如果仔细看图,你就会发现,返回的文本块内容里只有问题(黄色高亮部分),没有回答内容,所以我们把文本块和用户问题都发给模型,模型也无法知道正确答案,只能胡编一个。在Dify的知识库里,我们检查对应的文本块后发现,问题和回答果然被分在了两个块里,如果把它们合在一起,就能像下图一样返回正确答案了。

图片

03课里,我们讲过RAG中的分块方式有很多种,可以说RAG中没有最好的分块方式,只有最合理的分块方式,必要的时候我们也需要进行手动修改。在类似<消费品使用问答助手>的产品中,我们就可以在Dify里手动把常见问答作为一个整体放在一个块里。

但问答场景有非常多的情况,我们不可能每个都去手动调整,还有什么方法可以弥补分块不合理导致错误呢?

  • 方法1:分块时设置一定的冗余重合内容

如下图所示,我们可以将上一个文本块的一部分内容同时也放在下一个文本块中,我们推荐重叠部分占文本块整个长度的15%左右(可以在Dify里设置)。这样,就会在一定程度上提升了文本块语义完整性、关联度,从而进一步提升准确度。

图片

  • 方法2:强制返回相邻文本块

如下图,如果知识库检索返回了文本块2,我们可以强制在代码里返回文本块2以及它相邻的文本块1和3,这样降低了语义被切断的可能性。不过这样做会将Token的消耗成本扩大2-3倍,我们明白这点后在产品中要做适当取舍。这块需要有开发同学通过代码来搞定。

图片

  • 方法3:改进分块方法

前两种方法是从使用角度改进,第三种方法就是改变分块本身。针对不同类型的文档选择不同的分块方法,原则是:尽量保持原有语义的完整度。在这里我用一个表格来列举常见的文档类型对应的分块方法以及注意事项作为参考,实际中你可以根据自身情况灵活选择。

图片

以上就是可能引发“有答案,但回答不出来” 这个问题的常见的两个原因,实际中还可能有其他原因,但无论什么原因,追溯方法都是类似的。我们总结一下解决方法。

  1. 先看检索结果,如果检索结果不对,则修正检索方法或者对检索词做一定处理。

  2. 检索结果正确的情况下,看分块内容是否完全覆盖答案。

  3. 如果分块也正确,就可以优化大语言模型的提示词,或者切换更高阶的大语言模型。

其中,最后一点更考察提示词和大语言模型本身的质量,我们在这个案例里不做详述。接下来,让我们看看其他问题。

问题2:怎么把说明书中的图片带出来回答?

在<消费品使用问答助手>这个场景中,产品说明书中经常会有类似下面的示意图。

图片

但在RAG向量化处理的时候,是无法把文本和图片放在同一向量库中的,因此我们无法像文字那样把图片也检索出来。事实上,图片和文字在向量空间的统一化表征目前还是AI的难题。

那么当我们需要在回答时展现图片该怎么操作呢?这里提供两种方法,我称之为“图文关联法”和“图文转换”法,二者可以结合使用。它们位于RAG流水线的第一步:数据提取。

图片

  • 方法1:图文关联法

在RAG中,每个文本分块都有自己的元数据(Metadata),元数据存储的是分块自身的信息,比如文本块的来源、大小、作者等。元数据里存储哪些数据是可以定制的,我们就可以增加一个ImageURL的字段,当文本块里的文字内容需要使用图片来回答时,就可以同时读取对应文本块里的ImageURL信息,将图片保留到答案中。这个过程需要由开发同学在向量数据中写入,写入后向量的meta data中就保留了对应的信息(如下图)。

图片

  • 方法2: 图文转换法

顾名思义,就是将图片信息转换为文字信息,我们可以利用高阶多模态大模型,比如Google Gemini1.5,将图片内容理解后转换为文本(如下图),将该文本块作为知识库的一部分,并将ImageURL存储为该文本块的元数据中。

图片

以上两个问题是解决“消费品产品小助手”中的功能性问题(有答案无回答,答案中带出说明书),接下来是一个成本优化的问题。

问题3:Token消耗太快了,有没有什么降低成本的方法?

我们上节课提到,对企业来说,采用AI工具有一个重要的诉求就是降低成本。如果我们降低了人力成本,但增加了大模型的调用成本,难免会让成本此消彼长。所以,我也来介绍几种降低成本的方法。这两种方法都属于RAG流水线中的第九步:LLM归纳环节。

图片

  • 方法1用问答对匹配代替RAG减少大模型调用次数

如下图中的红色部分所示,我们可以在企业售后端构建一个问答对数据库,存储用户的常见问题。当用户提问时,首先与数据库里的问题进行进行语义检索(类似RAG的混合检索方案),如果相似度大于某个阈值,则将该问题对应的答案直接返回给用户,而无需再经过大语言模型生成。


按照80-20原则,20%的问题可以覆盖到80%的用户问题,当我们将这20%的问题存储在问答对中,就能节省80%的成本。

  • 方法2:压缩提示,降低 token 量

我们知道,RAG的机制就是检索到疑似相关内容发给大模型总结,那么这里的“相关内容”往往就带有非常多的冗余信息,换句话说,提示词的压缩空间很大。目前提示词压缩方法在学术界有很多尝试,比如微软的LLMLingua可以使提示词压缩30%左右,他们在模型开源社区有demo,你可以去这个链接试试。

不过压缩提示词也意味着信息丢失,会影响最终返回的准确率。另外压缩提示词本身是通过调用小模型实现的,本身也意味着成本消耗。所以采用这个策略时不仅要多次尝试,还要多算账。

到这里我们就解决了RAG中的三个常见问题。实际中你可能还会遇到其他问题,但是你只要牢记RAG流水线的各个环节,一项项排查,总能定位发生在哪个环节,然后由这个环节出发来搜索解决方案,就会比直接由问题出发寻求解决方案会更高效。

产品复盘

好了,我们总结一下在<产品使用问答助手>这个产品中遇到实战问题以及解决方法,在开头的那张诊断表里,我们也可以圆满的写上一副“对症良方”。

图片

当然,这个产品中除了使用RAG技术实现机器人问答之外,还有两个功能是评估人工回答质量和给用户问题打标签,这两项中主要使用到的技术就是提示词技巧,也是我们下个案例中的主攻内容,在这里我们简单呈现。

评估人工回答质量的提示词如下:

你是一位优秀的客服人员,我会给你提供一组用户和客服人员的对话,你来对这个回答进行公正、严格的打分。你有以下评分标准.
## 评分标准
1. 相关度: 评价回答是否和用户问题相关。评分标准为:1分--回答与问题完全不相关;2分--回答与问题少部分相关;3分--回答与问题部分相关度;4分--回答与问题大部分相关 ;5分--回答与问题完全相关。
2. 用户满意度:评价用户是否对回答满意。评分标准为:1分--非常不满意;2分--不满意;3分--勉强接受;4分--满意 ;5分--非常满意。
## 输出格式
请严格按照以下格式输出:
{
"相关度":4 ,
"用户满意度" : 3
}


## 对话
我给你的对话是:
{对话}
##评分结果是:


给用户问题打标签提示词如下:

你是一位极具洞察力的产品设计师,我会给你提供一组用户和客服人员的对话,你从这些对话中探查用户诉求,并为他们的诉求打标签。你只能从以下标签项中选择一项或多项。


## 标签选项
1. 运输不当:和快递相关的问题,比如物流太慢,包装破损、简陋、有污渍,发错货。
2. 操作不便:和产品操作相关的问题,比如操作不方便,操作流程复杂。
3. 质量问题:产品到货后不能开机,无法使用。
4. 新功能诉求:比如希望能支持新内容,新功能等。


## 输出格式
请严格按照以下格式输出:
{
"运输不当","操作不便"  
}


## 对话
我给你的对话是:
{对话}
##标签:


到这里,我们的第一个实战案例就结束了。我们重点讲述RAG在产品中的应用和常见问题。相信通过实践,你会对RAG有了更深的理解和体会。

那么AI上层建筑中的另外两项技术,提示词和Agent又可以应用在哪些场景呢?除了我们最常见的对话机器人形态,还会有哪些产品形态呢?

在下一节中,我们就会重点利用提示词工程来做一个文本数据提取分析工具,ta可以帮助用户从文本数据中提取有效信息,并对这些信息进行分析、洞察。在这里我也顺便给你出一个简单的题目预习、热身一下提示词工程。请你写一段提示词来识别用户所说时间。要求是:

给定一个描述时间点的短语和参照时间,按照YYYY-MM-DD HH:MM:SS格式输出这个短语对应的时间。比如: 
描述时间点的短语是:“昨天这个时候”
参照时间是:“2024-08-08 12:34:12”
输出:{"time": 2024-08-07 12:34:12}

我给你的时间短语有:

明天
昨天
下周
上个月
两天前
三小时后
去年同一天
下个月的这个时候
两周后
上周二
明年夏天
去年冬天
在午夜
大约中午
几分钟后
半小时前
到今天结束时
一大早
再过100小时

在下节课开始之前,你先感受一下吧。

思考题

下次你家再买电子消费品的时候,要不要把对应的电子说明书改成“智能说明书”呢?你甚至还可以在Coze或者Dify里搭建完之后发布在微信小号上,放在家庭群里,这样就有个家电消费品小助手啦。

欢迎分享你的小助手,在留言区和我交流搭建、使用心得。如果觉得有所收获,也可以把课程分享给更多的朋友一起学习。我们下节课见!

>>戳此加入课程交流群

精选留言

  • kxydoublek

    2024-10-09 13:45:04

    太棒了,尤其是对于RAG回答质量不高的针对性说明。学到了很多,比如检索方式、分块方式
    作者回复

    🙌

    2024-10-10 06:38:30

  • 末日,成欢

    2025-03-04 18:33:36

    ##需求描述
    你需要进行将短语转化为时间
    依据时间基准是:“2024-08-08 12:34:12”

    ##参考
    如果我给与的是昨天这个时间,
    输出:{"time": 2024-08-07 12:34:12}


    ## 任务
    将下述所有的时间短语转化为具体时间
    明天
    昨天
    下周
    上个月
    两天前
    三小时后
    去年同一天
    下个月的这个时候
    两周后
    上周二
    明年夏天
    去年冬天
    在午夜
    大约中午
    几分钟后
    半小时前
    到今天结束时
    一大早
    再过100小时
  • Geek_fd900e

    2025-04-25 19:21:33

    ## 需求描述
    你需要进行将短语转化为时间 依据时间基准是:“2025-04-08 12:34:00”

    ## 参考
    如果我给的是“昨天这个时间”, 输出:{"time": 2025-04-07 12:34:00}
    如果我给的是“去年这个时间”, 输出:{"time": 2024-04-08 12:34:00}
    如果我给的是“上周这个时间”, 输出:{"time": 2025-04-01 12:34:00}

    ## 任务
    将下述所有的时间短语转化为具体时间
    明天这个时间
    下周这个时间
    两天前
    三小时后
    下个月的这个时候
    两周后
    上周二
    半小时前
    到今天结束时
    再过100小时
  • Quotient

    2024-10-18 15:16:52

    您好~关于处理图片那块,能否提供包含相关的数据,可以跟着实践操作一下
    作者回复

    如果实践, 可以下载任何一个带图片的产品说明书哈。 这里关于图片的内容更多的是讲了解决思路。

    2024-10-21 16:39:39