MVP聚技站|一文道尽RAG,为大模型提供你的私有知识

程序员有二十年 2024-08-29 12:16:46

M

点击蓝字 / 微软开发者MSDN

关注我们

作者:王豫翔 - 微软最有价值专家(MVP)

排版:Alan Wang

王豫翔

微软最有价值专家(MVP)

王豫翔,拥有20余年编程经验,Microsoft AI MVP,一直致力于分享 Azure AI 相关技术。曾在多个大型研讨会担任讲者,包含 TechEd、Tech Summit、Ignite China、Al Bootcamp 等。专注人工智能领域技术创新,尤其是自然语言对话方向的颠覆性机会。

什么是 RAG?先说一个你可能不相信的事实:RAG 是2005年提出的古老技术(论文在此 https://arxiv.org/pdf/2005.11401)。然后我们先看一个学术定义:“检索增强生成(Retrieval-augmented Generation)是指对大型语言模型输出进行优化,使其能够在生成响应之前引用训练数据来源之外的权威知识库。”转为人话就是:“因为大模型的知识是固化的,所以当我们需要大模型理解我们的私有知识时,需要自己先找到当下需要的知识片段,然后把片段提交给大模型理解、判断、推理和总结出我们需要的答案”。都说一图抵千言,我通过三张图来解释 Retrieval-augmented Generation。

大模型本质上对我们的提问不是回答,而是基于大模型自己的知识体系生成了我们需要的内容,所以大模型非常适合开放性(非预设)问题场景。由于大模型输出的内容是基于他自己的知识体系的生成,所以会出现两种结果:

生成:Generation

正确:符合我们的预期

幻觉:有两种幻觉:

完全错误的信息,无论从哪个角度看都是不可被接受使用的信息

在通常情况下信息可以被接受,但是不符合特定的细分领域(往往是企业自己的知识体系)

为解决第二种幻觉,我们需要告诉大模型企业的知识体系,所以就出现了 Augmented。

增强:Augmented

用户在提问时,同时给予大模型你自己的私域知识片段,这个过程我们叫增强,用于增强大模型的生成质量。但是要理解一个关键点,大模型不会仅仅参考你提供的私域知识片段。一旦大模型认为你给的私域知识片段不足以推理生成出用户的要求,大模型会融合自己的知识体系,或干脆放弃你的私域知识片段。

为了提供大模型私域知识片段,我们就需要用到 Retrieval 技术。

检索(召回):Retrieval

我们可以从各种不同的数据源召回大模型 Augmented 需要的信息,而这一步就是 RAG 的核心,需要解决两个问题:

数据从哪里来

如何召回正确的数据

Vector RAG

向量是高维空间中数据的数学表示。在这个空间中,每个维度对应于数据的一个特征,维度的数量从几百到数万不等,具体取决于所表示数据的复杂性。向量在此空间中的位置表示其特性。单词、短语或整个文档,以及图像、音频和其他类型的数据都可以矢量化。

这些特征向量可以使用机器学习方法从原始数据中计算出来,例如特征提取算法、词嵌入或深度学习网络。目标是使语义相似的数据项接收彼此接近的特征向量。

向量数据库、向量存储或向量搜索引擎是一种可以存储向量(固定长度的数字列表)以及其他数据项的数据库。向量数据库通常实现一个或多个近似最近邻(ANN)算法,以便可以使用查询向量搜索数据库以检索最接近的匹配数据库记录。

要记住,当我们检索向量数据库的时候,数据库返回的是最接近当前向量存储的记录。这个结果在电商推荐领域是非常好用的。我们举个栗子:系统向一个男顾客推荐男鞋,该男士之前仅浏览和购买了一双鞋。但是这双鞋的高维空间表示的特征有很多:品牌、尺码、款式,颜色,价格。现在假设我们将所有可以售卖的鞋子都编码为向量并且存储在向量库中,然后我们希望向量库返回适合推荐给这位男士的鞋子。近似最近邻算法会对向量库中所有鞋子进行排序,匹配的特征越多,排序会越靠前,可能出现的结果如下:

如果目前向量数据库中没有这位男士之前购买的鞋子的品牌、颜色、款式、尺码和价格,那么排序在最前面的就是各种鞋子。

如果向量数据库的确存在有部分符合这位男士之前购买的鞋子特征的数据,那么排序在最前面的的确是符合推荐要求的,但是我们很难预测排序前多少位之后是不适合推荐的数据。

不过,在商品推荐领域这些问题都容易解决:推荐的特征是已知的,所以我们只需分析一下排序在前的数据维度就可以知道这些商品是否符合推荐要求,因为说到底,商品推荐的特征是非开放性的。

但是到了大模型时代就不同了,由于用户的提问是开放性的,向量数据库对向量存储的排序就会复杂得多,我们会遇到很多困难。

向量近似最近邻排序结果概念图

首先,向量编码存储的信息长度如何规划?text-embedding-ada-002 ,便可以将最长 2048~8192 个字符的句子/文档转换为一个 1536 维的向量。而 HuggingFace 上的 shibing624/text2vec-base-chinese 模型可将任意长度在 512 内的中文语句编码为 768 维的向量。所以你看,对 Embedding 模型而言,无论给它多长的文本,它转换出的维度是一致的。因此如果输入的文本太长,我们就有可能丢失一些核心信息的特征(维度),而且模型本身一次性编码的字符长度也是有限的。但是如果我们编码的字符串太少,我们能确定推荐在最上面的 chunk 的确是我们需要的,但我们会丢失和这个 chunk 有关的上下文。

其次,以 text-embedding-ada-002 的 2048~8192 个字符举例,无论你如何设计 chunk 大小,一定会存在丢失核心上下文信息的可能。所以 chunk 的大小设计就非常关键。

同时,我们的文档布局非常复杂,传统的 OCR 技术几乎不能完美地把文档信息精准地提取出来,含有大量噪音的文本会严重影响 chunk 的质量。

将不同布局的文件转为纯净的文本

Vector RAG 的一个重要挑战就是将各种布局的文档转变为纯净的文本文件。这个过程目前没有太好的技术,但可以推荐一些方案:

OCR+ 布局识别。微软的 AI 智能文档服务(AI Document Intelligence,以前叫 Azure 表单识别器)是一个值得推荐尝试的工具。

多模态。多模态可以识别文档的布局、图片等信息,但是多模态依然是生成式的,它不能像 OCR 那样按字符输出,而是理解后输出。如果你需要高保真的识别,多模态就不能使用了。

本文不只讲 Vector RAG,所以对 Vector RAG 的不足如何解决,以后我们单独开一篇。

Search RAG

说出来你可能不信,我们团队最早给大模型提供模型外知识时,使用的就是 Search RAG 方式。2023年4月我和同事就使用 Azure Cognitive Search(现在改名叫 Azure AI Search)从文档中获得信息,作为提示词的一部分提交给大模型,以得到大模型的推理结果。不过 Azure Cognitive Search 的结果总是给人一种“不 AI”的感觉(很接近关键字查询),所以微软现在将 Azure Cognitive Search 升级为 Azure AI Search:

支持矢量搜索的搜索引擎

支持全文检索和混合检索索引

丰富的索引,集成了数据分块和矢量化、针对文本的词法分析,以及用于内容提取和转换的可选应用 AI

用于矢量查询、文本搜索、混合查询、模糊搜索、自动完成、异地搜索等功能的丰富查询语法

从某种角度看,你可以把 Azure AI Search 看作是微软的一种向量数据库,微软自己没有提供向量编码服务,我们依然需要使用 text-embedding-ada-002 进行向量编码预处理。但是好玩的是,微软在认知服务·计算机视觉中提供了图片向量库的服务,这样我们就可以对文档中的文本和图片进行向量检索了。除了可以将图片向量表达外,Azure AI Search 依然支持关键字搜索(全文检索),其核心依然是 Lucene 的搜索语法。

所以,在实际生产中使用向量库模式还是 Search 模式,我个人觉得是否需要进行全文检索就成为了一个非常重要的参考点。

FAQ RAG

以我的理解,Vector RAG 特别适合做开放性问答的机器人,我们只给文档集,无需预设用户可能会提哪些问题。既然是开放性场景,那么大模型生成出的回答也是不可控的。

如果我们希望大模型的输出是可控的,那意味着我们需要预设用户的提问,这就是典型的 FAQ 的场景。

FAQ RAG 有两套方案:

BERT FAQ RAG 方案

这个方案利用传统的 BERT 对用户的提问做出意图判断,然后将阈值范围内的问题和答案一起提交给大模型进行推理。

BERT FAQ RAG

Vector FAQ RAG 方案

把每一对 FAQ 作为一个 FAQ chunk 通过 embedding 进入向量库。用户提问后采用传统 Vector RAG 的方式找到合适的 FAQ chunk,然后提交给大模型。这种方式相对 BERT FAQ 来说效率高,对复杂的意图组成支持得更好,召回的信息多且结构良好。

Vector FAQ RAG

那么,为什么我们不通过大模型来进行意图判断而是需要将 FAQ List 转为 FAQ chunk 呢?因为目前实践下来,在生产环境下大模型对 FAQ 的意图判断质量低于 BERT 的意图判断,也低于 FAQ Vector。

我们实践下来发现,如果你需要对输出的控制非常高,要求一个符号都不能错,需要图文混排,那建议用 BERT FAQ RAG 方案。如果是希望召回内容丰富,或者重复使用之前投资的 FAQ Bot,那用 Vector FAQ RAG 方案是非常适合的。

Graph RAG

由于 Vector RAG 不能全局、宏观地来看知识库中的所有资料,所以人们又把目光转向了知识图谱(Knowledge Graph)。知识图谱是一种特殊的数据结构,我们叫它三元组:三元组是由三个元素组成的有序集合,分别是主体(subject)、谓词(predicate)和客体(object)。

最早我记得在2018年和微软亚研院一起合作知识图谱的工作,当时微软有一款非常棒的知识图谱产品,基于构建好的三元组,你几乎可以使用自然语言任意地进行询问。当时这款产品中构建了一个地理地标的知识图谱,机器人可以对你以下问题给出精确的回答:

中国第12高的山是哪座山

中国第5长的河是哪条河

……

这些需要对全局信息了解后,进行统计排序的问题,是 Vector RAG 非常不擅长的,所以我们非常希望 Knowledge Graph 能解决这个痛点。

基于这个知识图谱,大模型已经能够推理出我们需要的答案。

提问

大模型回答

第二长的河是哪一条

第二长的河是黄河

第五长的河是哪一条

根据提供的信息,只有四条河流的长度,所以没有第五长的河流

最短的河是哪一条

最短的河是珠江

所有河流加起来多长

所有河流加起来的长度是6300公里(长江)+5464公里(黄河)+3000公里(黑龙江)+2320公里(珠江)=17084公里。

有没有哪个省是所有河流都经过的

没有哪个省是所有这四条河流都经过的

那么哪个省被这些河流经过得最多

四川省被长江和黄河两条河流经过,是被这些河流经过的最多的省份

相对 Vector RAG,Graph RAG 优点非常明显。假设要使用 Vector RAG 做一个地理地标信息,我们会把整本中国地理大全 Chunking 后 embedding 进向量库。然后用户提问“第二长的河是哪一条”,Vector 可能将具有河和长度的 chunk 都找出来提交给大模型,这种情况下会出现几个弊端:

大模型的 Token 窗口是有限的,整本中国地理大全和河与长度有关的 chunk 的总长度可能远远超过 Token 窗口,这样大模型读取的上下文无法全局地了解整本中国地理大全和河与长度有关的信息。

每一个 chunk 块都包含了和提问无关的信息,浪费了 Token 成本也让宝贵的 Token 窗口无法装载更多信息。

长江、黄河等河流在整本中国地理大全被多次提及,每一次的提及都会召回 chunk,造成了信息的冗余。

而这些问题在 Graph RAG 就会被解决得很好:Graph RAG 的结构简单,冗余信息少,同样的 Token 窗口能装载的有效信息量更多,信息的描述更清晰有效。比如上图的 Knowledge Graph,我们可以简单地整理出如下的上下文信息:

基于下面的资料回答我的问题长度:长江:6300公里黄河:5464公里黑龙江:3000余公里珠江:2320公里途径:长江:青海、‌四川、‌西藏、‌云南、‌重庆、‌湖北、‌湖南、‌江西、‌安徽、‌江苏、‌上海黄河:青海、‌四川、‌甘肃、‌宁夏、‌内蒙古、‌山西、‌陕西、‌河南、山东黑龙江:黑龙江省、内蒙古自治区珠江:云南、‌贵州、‌广西、广东、‌湖南、‌江西

如果你已经兴奋起来了,觉得找到解决私域知识的银弹了,那我需要提醒你,Graph RAG 面临的挑战比你想象的多:

第一个挑战:为什么要用 Graph RAG

在我看来不是所有文档集都可以使用 Graph RAG 的方案,适用于 Graph RAG 的文档应该是可以被有意义地构建为三元组形式。这种文档的特征是内容里有明确可以被发现的实体以及实体的关系。比如 Person Graph、Position Graph、Device Graph 等等。

第二个挑战:Graph 的网络结构定义

我们观察下图:

这是一家医药企业的药品信息,左右两张图表示了两个 Graph 网络的构建方式:

左图的实体是药品、OTC、RX、配方信息。

右图的实体是药品,分类、君成分、臣成分。

从信息来讲,这两张图都可以描述我们的信息,但是构建角度不同,构建的复杂度也不同。不同的图我们召回给大模型的信息也不同:

以熟地黄为臣辅原材料的 OTC 药品有哪些

根据以下资料,回答我的问题

OTC:

药品1

药品3

熟地黄·

臣:

药品1

药品2

根据以下资料,回答我的问题

分类:

OTC:

药品1

药品3

臣成分:

药品1:白芍、熟地黄

药品2:熟地黄

药品3:阿胶

OTC 药品中以熟地黄为臣辅原材料的药品是药品1。

OTC 药品中以熟地黄为臣辅原材料的药品是药品1。

可以看出,大模型的推理能力是非常强大的,主要还是取决于我们提供的上下文信息。但是不同的 Graph 结构组成的 Token 是不同的。当信息量极大的时候,不同结构的 Graph 消耗的 Token 是不同的。

第三个挑战:对 Graph 的质量评估

如果直接用大模型去构建 Knowledge Graph 的三元组其质量不够精确,大模型自动生成的三元组在实体一致性、实体意义、关系描述上都有可能不符合我们预期。我们依然需要人工进行整理和审阅,一旦 Knowledge Graph 非常庞大,那人工的审阅工作量就非常大。

微软 Graph RAG 案例,每个圆圈都是一个实体(例如,一个人、一个地方或组织)

第四个挑战:Graph 的维护

因为大模型自动构建的 Graph 质量需要评估干预,所以一旦我们的知识源有更新,我们就需要大模型进行全局 Graph 重构,这样的重构极有可能对我们已经审计过的信息做出修改,所以我们需要更多干预手段对大模型进行控制。

DB RAG

当你需要全局地看企业的知识时,Graph RAG 也不是唯一的选择。Graph RAG 适合对文档知识进行梳理,但是企业经过了这么多年的信息化建设,大量的数据已经被形成结构化存储在数据库中。所以如果需要看 DB 中的数据,那 DB RAG 就是一个非常值得考虑的技术。

一般来说,凡是重要的实体数据,企业一定会投入成本构建为关系型数据库,哪怕这些实体数据原先是文档形式,因为业务需要企业也一定完成了数据转换和存储。比如我们上面假设的中药知识库,其药品的分类,配方成分都已经在数据库中存储了。因此全局地看企业数据 DB RGA 似乎就是一个可以替代 Graph RAG 的方案了。

DB RAG 有两种方式:

Chat2SQL

这种方式比较直接,将用户的提问和 Database Schema 利用大模型的能力生成出的 SQL 语句,通过 SQL 查询返回数据。然后请大模型将数据集推理为文本表达。这种方式适合于开放性提问。这个方式有几个缺点:

客户端每次都需要在提示词中包含 Database Schema,Token 成本较高

用户复杂询问生成 SQL 的质量具有风险

因为会将用户的提问直接转为 SQL 去执行,可能有 SQL 注入的风险

Chat2API

现在的 Function Call 就可以在这种方式上被很好地运用。Chat2API 方案需要我们预先构建 API,典型的预设性提问。管理员定义 Function 的 Url、参数、工具描述等,用户提问后,大模型调度对 Function Call 的使用。虽然 Chat2API 是预定义提问,但是这个方案有很多好处:

传参简单

不暴露 SQL,安全可靠

用户的提问可能被多个 Function Call 执行,可以带来更丰富的上下文数据

Internet RAG

除了企业内部的资料,外部互联网提供的数据也可以作为 RAG 的数据源。其实你有耐心看到这里,Internet RAG 你肯定不会惊讶。任何我们获得的能加工为给大模型提供上下文的手段我们都统一称为 RAG,所以从互联网上获得信息我称为 Internet RAG。

Search Engine

Baidu、Bing 和 Google 都提供了搜索 API、我们可以用这些 API 直接将用户的提问通过搜索引擎获得最有时效性的问答,比如:2024年法国奥运会的金牌排名。

但是在使用搜索引擎 API 的时候要小心,搜索引擎返回的是摘要结果,而不是真正的页面结果,比如刚才我们询问的问题:2024年法国奥运会的金牌排名。BingAPI 的结果如下:

"2024年巴黎奥运会(7月26日至8月11日)官方奖牌榜。了解哪些运动员赢得奖牌、打破纪录。

奖牌统计 - 2024年巴黎奥运会奖牌榜 - Olympics.com"

https://olympics.com/zh/paris-2024/medals

"2024年巴黎奥运会于2024年7月26日-8月11日在法国巴黎举行,央视网直播精彩奥运赛事、直击巴黎前方,推出大型原创节目,打造奥运专业数据库,提供权威、快速、独具特色的奥运报道。.

奖牌榜_2024巴黎奥运会_体育_央视网(cctv.com)

https://sports.cctv.com/Paris2024/medal_list/index.shtml

巴黎奥运会闭幕,中国登顶金牌榜!. 孙颖莎代表亚洲登台,汤姆·克鲁斯从天而降. 北京时间8月12日,. 第33届夏季奥林匹克运动会闭幕式. 在巴黎 ...

巴黎奥运会闭幕,中国登顶金牌榜!孙颖莎代表亚洲登台 ...

https://news.sina.com.cn/w/2024-08-12/doc-inciiyim9429298.shtml

2024年巴黎奥运会:中国代表团奖牌得主汇总. 截止至2024年8月11日,中国代表团在2024年巴黎奥运会上已经斩获了39金27银24铜合计90枚奖牌。. 提升您的巴黎2024体验!. 加入奥林匹克会员,免费观看资格赛直播、量身定制的最新动态以及原创系列 - 立即注册!. 🥇 ...

2024年巴黎奥运会:中国代表团奖牌得主一览 - Olympics.com

https://olympics.com/zh/news/paris-2024-team-china-medalists-overview

以上是2024年8月12日 23点14分的返回结果

所以你得到了 Bing 的搜索结果,应该通过页面的摘要判断这份摘要所在的网页是否值得你抓取,如果有必要,应该抓取网页并对网页内容进行分析,以获得真正的搜索结果。

WebPage

给定一个网页,以该网页的内容作为大模型的参考上下文。读取网页的组件有很多,读取技术本身不难。关键是一个页面上往往有很多信息,比如导航、广告、推荐位、其他链接和正文。你需要尽可能地提取正文,这时候你应该知道,如果按 HTML5 推荐标准规规矩矩写标签的前端工程师该有多可爱了吧。

Open API

对于专业信息我不喜欢用搜索引擎去找数据,比如股票价格。这些专业信息在互联网上有很多服务商提供了 API 或者 API 聚合服务,直接使用这些 API 会获得更专业的数据。

所以 Function Call 又闪亮登场,我会按不同的 API 服务建立不同的 Function Call。使用大模型对 Function Call 的调度,我可以在一个指令中调度多个 Function Call,然后将获得的信息作为上下文提交给大模型。

举个栗子,我设计了一组同事非常欢迎的 Function Call,可以对企业内数据和企业外数据联合使用,下面是我们同事常用的场景:帮我看看我还有多少年假,然后看看从后天开始,三亚、贵阳、昆明谁的天气和空气质量最好,然后安排一个黄道吉日去那里,并且给我一个3天攻略。这一条指令我们将会执行多个 Function Call,然后将返回的信息作为上下文提交给大模型,获得高质量的结果。

最后

我们快速了解了 Vector RAG、Search RAG、FAQ RAG、Graph RAG、DB RAG、Internet RAG,还包括了 Function Call 的使用。每一种 RAG 的方案都有其适合的场景和弱点。那你是否会想,能否在一个知识库中把所有的 RAG 的方案都用上呢?

RAG方案

维护成本

提问方式

主要工作

Vector RAG

中等

开放

识别文件布局精确读取内容

Search RAG

中等

开放

识别文件布局精确读取内容

FAQ RAG

中等

预设

构建 FAQ List 样本

Graph RAG

高等

开放

构建 Graph 结构和识别实体

DB RAG Chat2SQL

低等

开放

准确生成 SQL 和防止注入攻击

DB RAG Chat2API

中等

预设

构建 Function Call

Internet RAG Search engine

低等

开放

分析目标页面主要内容

Internet RAG WebPage

低等

开放

分析目标页面主要内容

Internet RAG OpenAPI

中等

预设

构建 Function Call

这个想法也不是不行,如下图:

使用 Agent 调度具体的 RAG 方案

你需要按不同的资料和场景选择合适的 RAG 方案,然后在用户提问的时候使用不同的 Agent 为大模型提供合适的数据源。此外,如果你的预算比较宽裕,可以把相同的资料使用 Vector RAG 和 Search RAG 各存储一份,当 Vector RAG 和 Search RAG 返回结果后,使用大模型对上下文做一次质量检测,将优质的内容提交给大模型做最后推理。

最后再说一下,在多路 RAG 方案中,Agent 和 Retriever 都可以使用成本相对比较低的模型,比如最近上线的 GPT4o mini。

最后的最后,几乎所有的 RAG 方案都是新瓶装旧酒,因为大模型的推理能力始终没有改变,改变的是我们获取大模型外部数据的方式。所以如果你要评判一个人是不是 NLP 的老兵,就看他对 RAG 的态度,如果他对这些技术表示:瞧瞧,这些都是我们10年前玩剩的,那你就应该肃然起敬地给他点一个赞,比如此文。

微软最有价值专家(MVP)

微软最有价值专家是微软公司授予第三方技术专业人士的一个全球奖项。31年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和经验而获得此奖项。

MVP 是经过严格挑选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的热情并乐于助人的专家。MVP 致力于通过演讲、论坛问答、创建网站、撰写博客、分享视频、开源项目、组织会议等方式来帮助他人,并最大程度地帮助微软技术社区用户使用 Microsoft 技术。

更多详情请登录官方网站:https://mvp.microsoft.com/zh-cn

微信公众号|微软开发者MSDN

新浪微博|微软中国MSDN

·END·

0 阅读:0

程序员有二十年

简介:感谢大家的关注