AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


绝了!这样做竟能让RAG准确率飙升至90%以上,简直开挂!
发布日期:2024-08-03 05:09:16 浏览次数: 2464 来源:运维军团



背景

自从OpenAI的ChatGPT横空出世以来,各类大语言模型(Large Language Model,简称LLM)以其丰富而强大的自然语言处理能力点燃了人们对AI的热情。无论是在教育、医疗、金融、法律还是娱乐行业,LLM的影响都在不断深化,帮助人们更有效地处理语言数据,提高工作效率,创造新的服务和产品。虽然LLM在通用知识领域表现如此出色,但是由于其训练语库(一般由普适知识、常识性知识,如维基百科、新闻、小说,和各种领域的专业知识组成)具有一定的局限性,无法覆盖到特定领域的知识,例如公共网络难以触达的企业内部文档资料,因此如何利用LLM打造垂直领域内的专属知识问答系统,特别是在ToB的场景,成为了一个很有应用潜力的课题。在过去的一段时间,我们的技术团队也在这个方向上不断尝试与探索,并取得了一些成果,希望借此机会把一些经验分享出来,跟大家一起交流和探讨。

经典RAG流程

RAG(Retrieval Augmented Generation,检索增强生成)是经典、高效的垂类大模型应用方案,就是通过自有的垂域数据库检索相关信息,然后合并成为提示模板,喂给大模型生成最终的答案。RAG对比另外两种常见的解决方案——提示词工程和微调大模型,有着其天然的优势:

  • 不需要每轮对话都带上整个知识库文本内容,每次仅需要携带跟提问相关的内容文本,效率更高,成本更少。另外,虽然现在很多通用大模型都具备了很强的长上下文能力,例如谷歌gemini 1.5、Claude3支持100万token,kimi 支持200万汉字,但是由于每次查询时无关的文档过多,大量噪声信息被引入,生成内容的质量也容易因此下降。

  • 知识时效性更强。企业知识库通常会有文章需要频繁迭代更新,如果问答要求高时效的话,微调模型很难满足要求。例如从开源社区可以看到使用 Low-Rank Adaptation of Large Language Models(LoRA)

    https://github.com/microsoft/LoRA方式微调一个模型,就需要V100显卡花费8小时才能收敛。

正因为如此,在考虑开发一个面向企业知识库的问答系统时,RAG框架往往更受青睐。然而,整套RAG流程看起来虽然不是那么复杂,但是为了达到落地的要求,实践中还需要注意很多的工程细节,一旦某个处理环节做得不够完善,最终的回答质量也会直接受到影响。下面我们就实际遇到的且认为比较关键的几个点进行阐述,看看如何才能使得RAG的效果更进一步地得到提升。

实践与思考

文档清洗

在RAG系统中,知识库构建是一个很重要的事情。一般用户的文档是零散的不同格式的文档,因此在系统实施过程中,需要有一个环节对这些数据进行处理。我们使用到OCR技术对非结构化文档进行处理;使用HTML解析方法对指定格式的HTML文档进行处理。

OCR 被用于提取非结构化文档&图片中的文字信息,然后通过深度文档理解和引用来源等能力,大大提升了知识库RAG的召回率和准确率。这样可以处理复杂文档的内容,如PDF文件中的图像和表格、还可以对文档的布局进行识别用于增强OCR的准确度。

HTML 解析技术会用于对现存结构化的HTML进行处理。使用代码对HTML进行去除无用tag、提取有用的tag的操作,进而转换成文本类的文件。这个过程中还可以对某些标签进行特殊处理,例如img标签可以特殊处理成使用OCR模型进行解析后再录入。

其中,我们着重讲一下如何利用OCR进行非结构化文档的处理,需要实现3个功能:

  1. 文档区域识别

  2. OCR 单个字符识别

  3. 表格识别(TSR)


文档区域识别

来自不同领域的文件可能有不同的布局,如报纸、杂志、书籍和简历在布局方面是不同的。只有当机器有准确的布局分析时,通过对图像中的文本区域、非文本区域以及文本的结构信息(如文本、标题、配图、表格、页头、页尾、参考引用等)进行识别,可以实现更精确的文本分割和识别。在RAG应用中,好的文档区域识别可以使得切块变得精确,也大大提升知识库的召回率和准确性。该技术的实现通常有两种方法:

  • 基于深度学习模型:性能上可能会稍微比较差,但是遇到复杂文档时候,识别适应性会更好。

  • 区域分割与字符分割:这个方式性能会比较强,但是在遇到复杂文档时候识别准确率不一定有深度学习模型好。

如下是采用深度学习模型训练后,标记文档的结果。如图可以看到深度模型可以把文档里各个区域都标记出位置,同时也会标记出这个区域是什么类型的段落:

OCR文本识别

我们大多数的pdf都是使用图像呈现的内容,对于这类内容,需要使用OCR技术去提取文本内容:

表格识别(TSR)

数据表是一种常用的结构,用于表示包括数字或文本在内的数据。表的结构可能非常复杂,比如(行、列、标题、合并单元格)。在进行表格识别后,还需要把表格里面的内容生成对应HTML:

文档切块

在提取完文档信息之后,如何合理地把它分成不同的chunks,也是一个需要考虑的关键因素,因为chunks的大小会直接影响到检索和生成的效果。块大小过小或过大都会带来不同的问题和挑战,例如单个块太小了,包含的信息就比较有限,很可能无法提供足够的上下文信息;相反太大了又会带来更多冗余的信息,可能导致生成的答案过长且包含不必要的细节。

文档切块(Chunking)主要是3个层级

  1. 按字符数切块:例如按照固定的512字节,1024字节切分文章

  2. 按照段落切块:根据上面提到的文档区域识别,尽量把相同的大段落划分到同一个区块

  3. 按照语义切块:这个切块则是综合上述,把文档切分成语句级别,然后语句之间进行向量相似度判断,把可能存在同样语句的分区成一个段落

前面两种方案都是比较常规算法,下面来提及一下语义切块。

  1. 还是先简单粗暴按照句号、分号、问号、感叹号、换行符等分割文本,形成一个个的句子,用sen1、sen2、sen3、 ... senN表示

  2. 从sen1开始,以此和前后一个句子组合,形成combined_sentence,比如

    sen1+sen2=combined_sentence1,sen1+sen2+sen3=combined_sentence2,sen2+sen3+sen4=combined_sentence3,以此类推

  3. 以此计算combined_sentence1、combined_sentence2、combined_sentence3..... combined_sentenceN之间的相似度,如果相似度突然变化,那么新加入sen的语义肯定不同。这时候把上面的归位一个段落,从这个句子开始变成一个新段落


优化用户的提问

通常用户咨询的时候提出的问题都是偏口语化、相对比较短的文本,如果直接拿去知识库中搜索,结果往往会很不理想,而用户一旦发现系统无法感知他的意图,便会觉得系统不够智能(难受ing)。为了达到更好的搜索效果,我们需要对用户的提问进行一些优化。做法就是利用AI Agent 对用户的提问进行预处理,让Agent去分析用户的意图,然后帮助完善提问。这里预处理时给Agent提供的原材料包括企业内部的专用名词若干轮历史对话以及用户原问题。专用名词是为了指代消除,即解决提问中指代对象不明确的问题,例如,“MJ”在公司场景里实际指的是“Midjourney”,而不是“Michael Jackson”:

历史对话则是提供问题的上下文,从而让模型能更好地理解问题,效果就是:

注意我接着问第二个问题:

这里我只提示了“一个月”,但经过问题优化,提问就会转化成问“停车一个月花费多少”这种问法。

此外,我们还会让模型对问题进行扩展,一个问题最终会产生若干个类似的问题,从而提高了问题的语义丰富度,增大了召回相关性更强的知识的概率。类似:

原问题:公司附近有什么好吃的联想问题列表:["公司附近有什么好吃的","公司附近有哪些推荐的餐馆?","公司周边有什么美食?","公司附近有什么好吃的地方?"]

混合检索让知识召回更精准

当我们有了质量较好的提问之后,如何根据提问在知识库中召回合适的文本内容也是一个比较棘手的问题,传统的RAG应用通常采用向量(Embedding)检索。纯向量检索在很多应用场景中表现出色,但也存在一些可能的短板,例如:

  • 缺乏精确匹配:纯向量检索侧重于语义相似度,有时可能忽略了精确匹配的需求。例如,在某些法律或医学文档中,精确匹配特定术语或短语可能比语义相似度更重要。

  • 上下文处理能力有限:向量模型可以捕捉局部上下文信息,但在处理长文本或复杂语境时,可能无法完全理解和表示全局上下文。

  • 缺乏可解释性:向量检索的结果往往难以解释,因为向量空间中的相似度计算过程对用户来说是“黑箱操作”。这可能导致用户对检索结果的信任度降低,特别是在需要高透明度的应用场景中。

为了改善这个问题,我们采取混合检索的方式,即结合向量检索的语义能力和传统的全文检索方式,借助关键词匹配带来的精准度提高,在一定程度上弥补纯向量检索的短处,从而提高整体检索的精确度和召回率。

向量存储结构

通常Embedding的做法都是一个文本块对应一个向量,但其实还有改进的空间——多向量的使用。这里我们向量的存储采用两种数据库,向量存放在PostgresSQL中,用它的PG Vector插件作为向量检索器(也可以替换成其他流行的向量数据库或引擎,如milvus,chroma,或者ES);MongoDB用于存储原始文本内容。MongoDB的dataset.datas表中,会存储向量原数据的信息,同时有一个indexes字段,会记录其对应的向量ID,这是一个数组,也就是说,一个文本块可以对应多个向量。

对于向量的表示,内容的长度和语义的丰富度通常是矛盾的,上下文越长,语义就可能损失越多。我们使用一些策略能够平衡这种矛盾,例如:

  • 文本分段处理:将文章按段落分割,每个段落生成一个向量。

  • 滑动窗口:使用滑动窗口技术,将文本分成多个重叠的片段,每个片段生成一个向量。

通过这种多向量的方式,数据的完整性和语义的丰富度得到保障,只要有其中一个向量被检索到,该数据也将被召回。

混合检索+RRF

前面我们通过问题优化会得到一系列相似的问题,它们都会一起参与到检索中,从而增强了语义的丰富度,提高了召回的命中率。向量的检索利用向量引擎或数据库默认支持的相似度匹配算法即可,PG Vector使用的是HNSW算法。而全文检索这里选择采用BM25算法,BM25是一种用于文本信息检索的算法,是BM(Best Matching)系列中的一员,在信息检索领域中广泛应用,尤其是搜索引擎场景。

在并行执行混合检索方式后,对于问题列表我们会得到两种渠道的检索结果,接着通过 RRF 公式进行两个搜索结果合并,一般情况下搜索结果会更加丰富准确。RRF(Ranked Retrieval Fusion,也称为 Reciprocal Rank Fusion,倒数排名融合)是一种用于信息检索系统的融合算法,基本思想是将来自不同检索器的排名结果进行融合,以生成一个综合排名,从而提高检索的准确性和鲁棒性。

搜索过滤

按照传统设计,每次检索的结果最多取top k,但实践发现,这种方式可能因不同知识块的大小差异很大,导致最终的结果不稳定,因此改用tokens数的方式来进行引用上限的控制。

Prompt模板设计

当召回知识后,我们需要将匹配到的知识和用户的提问填充到预先设定的Prompt模板上,构成一个完整的Prompt,然后提供给LLM。一个好的Prompt能更好地激发大模型的潜能,设计的得当与否也会直接影响到最终回答的质量,甚至有人将它定义为AI应用的最后一公里。我们需要根据实际的业务场景来设置不同的回应策略,例如当Top K 匹配不到时,可以直接返回特殊的语言标记,比如”知识库找不到问题相关的信息“,或者直接让LLM使用通用知识作答;又比如产品应用需要提供多轮对话,即拥有上下文联想功能时,我们还需要将历史会话记录整理后一起拼接到提示词中。在此基础上,我们可以进一步利用一些Pormpt的技巧,比如零样本提示(Zero-shot Prompting)、少量样本提示(Few-shot Prompting)、思维链提示(Chain-of-Thought Prompting)等,来充分释放LLM的能力,近似达到”微调“的效果。

结语

以上就是我们团队在过去这段时间里针对RAG实现企业知识问答系统的一些实践与思考,虽然取得了一些成果,但随着LLM技术的日新月异,以及LLM应用潜能的逐步释放,未来还有很多工作需要进一步展开,例如常用工具在RAG链路上的集成,探究多Agent如何重塑日常工作流,以及研究微软研究院在RAG的新突破——基于知识图谱的GraphRAG,希望本文可以起到一个抛砖引玉的作用,同时也非常欢迎各个团队的同学一起交流大模型技术!



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询