从0到1打造企业级AI售前机器人——实战指南二:RAG工程落地之数据处理篇🧐

欢迎大家来到从0到1完成一个企业级AI售前机器人的实战指南系列文章

我是一个十年前端程序员,也是react contributor,2022年底随着chatGPT的爆火,跟大多数开发一样,开始了AI技术的学习。

直到2023年初我发现AI技术并不是普通开发的出路,于是开始转型AI应用层设计与落地。目前已经完成了多款智能问答产品的上线、以及TOB产品的功能AI化升级。

我相信AI在未来将会是基础设施,而对于普通人而言,基础设施的机会不在基础设施本身。

本专栏将会基于我过去几年的经验,对各类AI应用落地的方案和思路积累了很多踩坑和迭代经验,进行全方位的AI产品的核心流程拆解!

本篇是该系列的第二篇,核心内容是:售前AI系统中RAG工程数据的处理和应用方案,看完本篇你将会得到全面的RAG应用方案来应对自己的行业。

为什么我们需要用RAG工程,是因为训练好的AI,不论是deepseek还是chatgpt或者其他任何模型,都不可能拥有我们的私有数据。

而这一点就是我们要用RAG工程的原因:弥补模型在数据上的不足

除了私有数据外,典型的模型在数据上存在不足的场景还有:模型训练数据截止日期后的数据即时性数据,以及模型幻觉问题

我们将会在本章完成我们售前机器人的数据处理和知识库使用,让大模型可以使用我们的私有数据,

RAG原理

RAG(Retrieve Augmented Generation),也就是检索增强生成。

通常指的是一个标准的流程,延伸出来的还有self-RAGGraphRAGRankRAG等70多种RAG流程。

  • 检索(Retrieve):拿用户 query 调用知识库检索出相关内容片段;
  • 增强(Augmented):设置提示词,把检索结果作为挂载上下文;
  • 生成(Generation):大模型回答问题,标注引用来源;

这里借用豆包的一张图来展示一下RAG工程的标准流程,中文的大家能看的明白一些:

简单来说,RAG系统分为两个步骤:

1. 离线步骤:离线把私有数据处理成向量准备好等待检索

  • 本地文档整理
  • 文档切分
  • 使用向量化模型进行向量转化
  • 把转化后的向量灌入向量数据库

2. 在线步骤:在线运行时,把用户的query处理成向量与私有化数据的向量进行检索匹配

  • 获得用户问题
  • 把用户问题向量化
  • 拿向量化后的向量去检索向量数据库
  • 将检索结果和用户问题填入 Prompt 模版
  • 用最终获得的 Prompt 调用 LLM
  • 由 LLM 生成回复

不难看出,重点在检索这一步,只有检索的准确,大模型最终的回复才准确,RAG才有意义。

对于RAG的效果判断,我们采用召回率和准确率作为标准:

召回率 = 检索到的信息 / 所有相关信息

假设用户想要找到所有提到"人工智能"的新闻文章,而数据库中实际有100篇相关的文章。如果模型检索到了80篇,那么召回率就是80%。

准确率 = 正确预测的样本数量 / 测试集总样本数量

假设测试集中有100张图片,其中猫和狗各50张。如果模型正确识别了80张图片,那么准确率就是80%。

检索

检索通常分两种:1. 关键词检索;2. 语义检索

关键词检索是根据关键词进行匹配检索,也是曾经我们常用的几种检索方式之一。

当前在RAG中更突出的是语义检索,根据两句话的语义进行在向量空间中的距离匹配,来得到语义的相近度。

可以这样理解:A: 战争 B:俄乌冲突 C:青少年打群架。 在语义的相近度上,A和B的相近度大于C。

距离:我们的向量数据库中存有战争, 那么当query输入:俄乌冲突检索出来的语义相近度就会比输入青少年打群架距离战争更近。

俄乌冲突与战争的语义相近度是0.328:

青少年打群架与战争的语义相近度是0.271:

通过语义的对比,如果我们可以更加精确的检索到与用户问题有关的内容。

这里要注意的是:语义检索一定比关键词检索好么?

不一定的,这个分场景。当我们的同质化的词汇比较多的时候,语义检索的作用就变低了。

例如在教育的场景,会有大量的同质化的名词,比如:山东大学(学校名词)的计算机专业(专业名词)多少分?

此时我们的检索逻辑在向量相似度计算上应该更注重关键词而非语义。

这也是我们在选择向量和向量之间的相似度计算方式时的策略,目前常见的有三个计算方式:欧几里得距离 (L2)、余弦距离(COSINE)、内积(IP)

  • 欧几里得距离 (L2),计算两个点再几何空间中的距离, 越小越相似;当两个向量相同时,欧几里得距离为 0,并且随着任一向量的角度(方向)或幅度(长度)的增加而增加。

当数据中有大量的同质化的名词,检索更偏向于关键词的时候,我们更多的选择欧几里得距离

  • 余弦距离(COSINE),计算原点分别到两个点的几何空间的距离, 越大越相似;通过找到两个向量之间角度的余弦来实现的(这意味着余弦相似度不考虑大小,只考虑方向)。

当数据中的内容更倾向于语义理解的时候,我们更多的选择余弦距离

  • 内积(IP),基于向量的内积,即两个元素的对应元素相乘并求和的结果计算相似度,内积值越大相似度越高

内积是一个比较折中的方案,通常不选择使用。根据情况选择欧几里得或者余弦即可。

混合检索

"关键词和语义我都要",我知道你们老板一定是这么说的。

所以,目前我们通常是选择混合检索,然后根据个字场景来决定语义的占比大小。

这样就可以相对兼顾一下不同的场景,例如:刚才战争的那个例子,我们把语义权重调高,然后把刚才得分0.328的query俄乌冲突,分数就变成了0.656

这部分具体的设置在下面我们把数据处理完,处理知识库的时候继续解释。

接下来我们先看一下,我们要怎么利用前面讲到的这些内容来处理我们的数据:

数据处理

我们企业有那么多数据,难道要全放到知识库里?

当然不是,通常我们手中的资料按照数据内容分类会有两种:结构化的内容和非结构化的内容。

  • 非结构化的数据,可以理解为我们的产品文档、资料、等我们收集到的相关的内容。这类内容可以通过切片或者QA的形式很好的整理到知识库中。

  • 结构化数据,可以理解为我们数据库里分好标签、类型的数据,这类数据通常可以使用excel来表示,但是这类数据如果大量的放到知识库中,就会出现筛选错误 从而导致大模型在回答的时候出现幻觉。

通过过去的实战经验,得到的结论是:少量(千条以内)的结构化数据可以放到知识库中,大量(万条以上)的结构化数据,出现的幻觉概览就会大大加强。

同时需要注意的一点是:知识库最怕的不是数据多,而是数据不全! 因为知识库走的是向量检索的逻辑,任意一个query的向量去知识库中检索,都会得到一个相似度的分值,例如我们的数据中有山东XXX山西XXX,query问山西XXX的时候相似度最高的就是山西XXX,但是如果我们数据库中没有山西XXX的数据,相似度最高的可能就是山东XXX了。

所以我们知识库中的内容,对要解决的问题需要尽可能多的覆盖。

要覆盖尽可能多的问题,这里就是我们要在知识库处理开始前要做的另外一件事:搞清楚用户会提问哪些内容?

以售前场景为例,用户可能会提问的问题同时适合放到知识库中的数据有:

  1. 产品相关基本信息(基本信息、能力、规格、价格、案例)
  2. 优惠活动(折扣、活动力度)
  3. 企业资质信息
  4. 竞品对比

针对这四类信息,我们处理数据进行知识库的准备。作为售前机器人,我们的数据来源可以是:

  • 产品的说明书
  • 技术规格文档
  • 产品的白皮书
  • 定价表
  • 竞品对比表
  • 企业资质

当我们去收集这些信息的时候,我们会得到的文件形式,通常有以下几种,这里我把每一种数据我们对应的处理方案都列出来:

  1. word、txt 这两种是最基础的文档数据,先收集过来放着,一会一起处理。
  2. pdf PDF进行OCR + word转换,最终保存成word文档。
  3. excel excel数据不很多的话,直接用表头+内容转换成文档。excel数据多的话,后面我们拆分意图的时候,会拆分到意图中。
  4. 图片 有些数据会以图片的形式保存,直接OCR,保存成文档。

一定有搞过知识库demo的同学会问,为什么要全部做成文档? excel一类的文件向量数据库不是支持么?

答案是:为了提高召回率。 表头+内容组合的文档,其转化后的向量才能与用户真正提问时的query向量更匹配。

当我们准备好文档之后,要进行的就是数据清洗:

  • 由于我们收集的数据,来源于多个数据源,数据之间会存在重复与冲突,例如A文档写着价钱是8000,B文档写价钱是7000,这就出现冲突了,所以第一步,我们要把冲突的内容和重复的内容删掉
  • 收集到的文档中会有非常多的废话,可以理解为与我们场景中要解决的问题无关的内容。这部分内容要删除
  • 收集到的文档可能是曾经给某个客户的内容,里面可能会有客户的信息,这些涉及到隐私类的内容要删除
  • 文档中的emoji、多余空格、异常文本、等垃圾内容全部删除

这样我们就可以得到一批干净的数据,接下来就是对数据的应用了:

数据应用方案

常见的数据应用方案是切片QA结构化, 本系列最终的实现的售前AI机器人还应用了第三种方案:全量提示词

我们先来对比一下每个方案的优劣势:

切片经验

切片方式的知识库,我们的核心原则是:切片信息要全面

我们需要根据内容的不同来设计切片,需要保证切片上下文信息的完整性。

  • 例如:文档名称是【X产品介绍】小标题【价格】, 为了防止切片后丢失X产品信息就需要补充为【X产品介绍价格】
  • 例如:为了确保信息的完整性,使用总结性的文案作为切片。而不是使用原文简单的切片

目前在实战中最新的切片方案就是:利用大模型对每个文档中的内容进行分组提炼,提炼出多份相关内容,然后把每份内容都作为切片进行入库。

这样的好处是,每个切片的信息都是相对完整的。如此便能弥补切片方案的不足。

QA结构化经验

QA结构化方式的知识库,我们的核心原则是覆盖全面的场景问题

就像前面优劣势对比一样,QA的处理成本相对更高一些,目前的实战经验,就是要通过企业过去的日志、用户调研、专家访问等手段来尽可能的了解到所需要覆盖的场景。

然后使用人工+AI的方式进行Q的提取和补充,力求全面覆盖场景问题。

全量提示词

第三种方案,全量提示词的方案,也是我们本次AI售前机器人采用的一种方案。这个方案完全是实战中解决问题总结出来的方案:

当我们的流程执行意图判断后,针对某类意图进行回答的时候,此时我们已经能够精确到某一部分文档了,这时候我们就可以把这类完整的文档作为提示词提供给AI。

目前AI的能力对几千上万字的文档处理是完全没问题的,还能避免上面切片和QA两种方式的弊端。

你可能会问:这得浪费多少tokens?

首先我给你算个账:在这个场景我们不需要使用v3这样的模型,通常doubao-1.5就够了,费用是输入tokens 2元/百万。

我们假设我们的提示词+资料每次消耗一万tokens,每次消耗2分钱。每一百次是2元,一百万次2万。

这个成本是非常非常低的,而且后面我还会教大家tokens的缓存方案,大约能省75%,最终每百万次也就几千的成本。

结语

RAG工程的内容有些多,怕大家看着太累,还是决定分成两个部分发。

本文我们了解了RAG的原理、数据的处理方案、以及实战中的数据应用方案。

但是在生产环境使用的话,目前的RAG工程依然存在以下几个问题:

  1. 只能进行文本回复,无法提供相关的图片、视频等能力。
  2. 如果用户query不标准,问题不全,我们的知识库可能匹配不到内容。
  3. 知识库中的内容仍然存在匹配错误的情况。例如:用户问A产品的价钱,我们知识库筛选出了B产品的价钱,然后回复给了用户。
  4. 经典的中文二义性问题。用户的问题可以用A来回答,也可以用B来回答,怎么办?

所以下一篇,我们将会完成RAG工程,来解决上述四个问题。

同时为了方便大家,下一篇会将相关代码贴上。😎😎

希望这个系列能够打造成各位落地AI产品时的实战手册!

大家在自己公司中会有什么业务场景需要用到RAG呢?如果你不确定你的业务场景是否需要RAG,也可以留言大家一起讨论一下。

☺️你好,我是华洛,如果你对程序员转型AI产品负责人感兴趣,请给我点个赞。

你可以在这里联系我👉www.yuque.com/hualuo-fztn...

已入驻公众号【华洛AI转型纪实】,欢迎大家围观,后续会分享大量最近三年来的经验和踩过的坑。

专栏文章

# 从0到1打造企业级AI售前机器人------实战指南一:根据产品需求和定位进行agent流程设计🧐

# # 聊一下MCP,希望能让各位清醒一点吧🧐

# 实战派!百万PV的AI产品如何搭建RAG系统?

# 团队落地AI产品的全流程

# 30行代码,随时进行云端大模型能力评估!

# 5000字长文,AI时代下程序员的巨大优势!

相关推荐
编程猪猪侠3 分钟前
Tailwind CSS 自定义工具类与主题配置指南
前端·css
qhd吴飞7 分钟前
mybatis 差异更新法
java·前端·mybatis
YGY Webgis糕手之路29 分钟前
OpenLayers 快速入门(九)Extent 介绍
前端·经验分享·笔记·vue·web
患得患失94931 分钟前
【前端】【vueDevTools】使用 vueDevTools 插件并修改默认打开编辑器
前端·编辑器
ReturnTrue86832 分钟前
Vue路由状态持久化方案,优雅实现记住表单历史搜索记录!
前端·vue.js
UncleKyrie37 分钟前
一个浏览器插件帮你查看Figma设计稿代码图片和转码
前端
遂心_40 分钟前
深入解析前后端分离中的 /api 设计:从路由到代理的完整指南
前端·javascript·api
你听得到111 小时前
Flutter - 手搓一个日历组件,集成单日选择、日期范围选择、国际化、农历和节气显示
前端·flutter·架构
风清云淡_A1 小时前
【REACT18.x】CRA+TS+ANTD5.X封装自定义的hooks复用业务功能
前端·react.js
@大迁世界1 小时前
第7章 React性能优化核心
前端·javascript·react.js·性能优化·前端框架