PingCAP 王琦智:下一代 RAG,tidb.ai 使用知识图谱增强 RAG 能力

导读

随着 ChatGPT 的流行,LLMs(大语言模型)再次进入人们的视野。然而,在处理特定领域查询时,大模型生成的内容往往存在信息滞后和准确性不足的问题。如何让 RAG 和向量搜索技术在实际应用中更好地满足企业需求?如何在向量之上构建全链路 RAG 服务,提升开发者效率,降低成本?本文整理自 TiDB 生态系统架构师及高级开发者 Advocate 王琦智在墨天轮数据库沙龙的分享:《下一代RAG,tidb.ai 使用知识图谱增强 RAG 能力》,以下为演讲实录。

Graph RAG(Graph Retrieval-Augmented Generation)是一种结合知识图谱和信息检索技术的方法。为了更好地理解它,我们可以用一个形象的例子来说明:在商场门口有一个抽奖箱,你把手伸进去抽出一张小纸条,上面写着一二三等奖的奖项及相应的绕口令。你需要念出绕口令才能拿到奖品。这个过程很像 Graph RAG 的工作原理:你在一个"黑盒子"里接收到一段信息,然后使用这些信息进行相应的操作。

但我们发现,在某些情况下,抽到的奖项越高反而可能带来一些问题。例如,若口才不佳,抽到高奖项可能会让人难以应对,从而无法获得任何实际的奖励。这种现象在某些游戏场景中尤为明显。然而,在 RAG 场景中,我们希望能获得更好的回答。那么,如何解决这一问题呢?一种解决方案是,当抽取奖项时,同时抽取与之关联的其他奖项。例如,当抽到二等奖时,同时抽出相应的一等奖和三等奖。这种方法可以借助知识图谱来增强 RAG 能力。

今天,我们就来探讨如何使用知识图谱来提高 RAG 表现。

tidb.ai是什么

首先,让我们介绍一下 tidb.ai 它是什么。其实很简单,就是一个了解 TiDB 知识的 AI 问答机器人。在使用 tidb.ai 的过程中,可能会有一些常见的问题。例如,TiDB 中的 TiKV 和 TiFlash 有什么区别?实际上,这是指两种存储引擎,TiKV 是行存储,而 TiFlash 是列存储。但是,对于一个 TiDB 新手来说,可能会不知道这些区别,因此会产生疑问。这正是我们使用知识图谱生成的一些档案所解决的问题。

在我们使用 tidb.ai 之前,存在一些问题。首先,我们缺乏技术支持的人力。以前我们有一个轮班的小组来回答社区成员提出的问题,但人力一直不足,所以导致技术支持的间隔时间较长。如果问题提得不够清楚,没有一次性把所有问题提完,就需要几轮沟通,从而延长了技术回答的时间。其次,我们的文档丰富,但会导致用户不知道从哪里开始。 通过 tidb.ai,我们可以帮助用户查阅文档、编写代码、回答问题,从而解放技术支持工程师的人力,实现零延迟的回答,并且不需要等待多轮对话。

简单RAG的实现方案

首先,简单介绍一下我们在一年之前是如何实现的简单的 RAG。最初的实验方案是基于 Plain RAG(云原生 RAG)。下面是具体的实现步骤,如图所示,分别为:

文档切分与向量化:

◦ 从左边开始,我们首先有一些文档,将其切分成文本块(text chunk)。

◦ 这些文本块会被输入到 OpenAI 或其他模型中进行向量化处理,生成相应的向量。

◦ 这些向量与对应的文本块会被存储在 TiDB 中。

建立向量索引:

◦ 向量与文本块存储在同一行中,这样我们可以为这些向量建立索引(vector index),使服务能够使用这些向量进行快速检索。

用户问题向量化与检索:

◦ 当用户提出问题(例如"什么是 TiDB?"),我们使用相同的模型将问题向量化。

◦ 然后,我们通过一个 SQL 查询在向量索引中检索,使用一个称为 X 的函数来比较两个向量之间的余弦距离。

◦ 通过这个函数,我们可以找到与用户问题最接近的三个向量(Top Three Nearest Neighbors)。

生成回答:

◦ 找到最接近的向量后,我们可以获取相应的文本块。

◦ 最后,使用 OpenAI 模型生成答案,并将其返回给用户。

RAG(Retrieval-Augmented Generation)是一种开创性的技术 ,解决了多个问题。首先,它降低了大模型的幻觉现象 。大模型有时会生成不准确或无根据的回答,而 RAG 通过检索相关文档,提供额外的支持,减少了这种现象。其次, RAG 能够给予大模型额外的知识支持 ,通过检索相关信息,增强模型的回答质量和准确性。最后, RAG 突破了上下文窗口限制 。大模型的上下文窗口通常有限,例如 1024 个 token,虽然现在扩展到 2048、4096,甚至 8K、16K,但传递所有上下文依然成本高昂且不经济。

为什么需要Rerank?

在有了 RAG 之后,我们为什么还需要 Rerank 或其他增强操作呢?Rerank 是对检索到的文档进行重新排序的过程,其重要性在于提高检索的准确性。余弦相似性在比较文本时,往往忽略了语言间的关系。例如,问题"你吃饭了吗?"最相似的文本可能是"你吃饭了吗?"本身,而不是"我吃了"或"我没吃"。这种文本之间的相似性无法捕捉到实际回答的意图。

Rerank 通过重新排序,帮助我们找到最相关的回答。就像推荐系统中,在召回之后进行重新排序一样,Rerank 能进一步提升检索结果的相关性和准确性。通过这种方式,我们可以更好地理解文档与问题之间的交互关系,提高回答的准确性和用户体验。Rerank 加 RAG 就能解决所有问题吗?其实不然,它也无法一次性解决所有问题。

举个例子,比如在索引阶段(indexing),即构建 Vector index 的过程中,会遇到上下文窗口的限制。文字可能会在不该被截断的地方被截断,造成问题。举个例子,有一句话是"王叔叔夸我作业做得好,于是抱起了我妈妈,然后 token 没了",结果 GPU 运行超载,大模型 GPU 直接开始冒烟,显然需要处理这些问题。这个例子仅仅展示了 indexing 阶段上下文窗口限制所导致的问题 ,除此之外,Rerank+RAG 还会造成 Chunks 之间没有关联,忽略文档结构关系等问题 。

知识图谱助力RAG

基于以上的问题,我们提出了一个使用知识图谱来增强 RAG(Retrieval-Augmented Generation)模型的解决方案。这个方案能够有效解决 RAG 的问题,提升模型的回答质量和准确性。

1、理论基础 如图是微软发布的一篇关于知识图谱的论文。大家可以参考这篇论文了解更多细节。我们在初始阶段基于这篇论文的实现思路进行开发,后续进行了改良和优化。

2、简易架构 用户提出问题后,我们首先找到几个最近邻的节点。不论使用哪种方法,找到一个或多个 Top n 节点后,对这些节点进行扩展。图中,我们扩展了一个度,蓝色箭头表示扩展路径,绿色节点是扩展后触达的节点。最后,我们将这些节点及其关系全部提取出来,生成最终的回答。这个架构简单但有效,通过这种方式,我们能够显著提高模型的回答准确性和相关性。

在前面我们提到知识图谱,大家可能对它有了一个初步的认识。实际上,建立好的知识图谱看起来就像一个星云,有些人觉得它更像是我们的神经元。我们的知识被存储在一个个小球和它们之间的连线上,看起来非常壮观。刚刚展示的图也显示了知识图谱中包含的大量节点及其复杂的关联。

3、构建方式 有人可能会问,这么多的节点是否是手工构建的?显然不是。我们是一家小型数据库公司,没有那么多人力去完成这个任务。接下来就分别与大家讨论下构建的四个步骤

丰富的文档及社区问答 社区中英文 Markdown 文档为 1276 篇,中文 Markdown 文档为 1098 篇,而且这都不是 AI 翻译的,我们这个文档是有一个专门的团队去进行维护,每一个文档都跟随着版本发布而作出对应的调整与更新。

使用LLM 进行知识图谱构建 我们提出了一个利用 LLM 抽取知识图谱的可行方案,解决了我们人力不足的问题。具体来说,我们使用了 DSPy 库进行知识图谱的自动化构建。如果你对代码实现感兴趣,可以查看我们提供的 demo,扫描二维码即可访问。

在具体实现上,我们采用了 DSPy 库来定义和抽取知识图谱中的节点和边。我们生成的图谱是一种汇总图谱(Summary graph),而不是实例图谱(instance graph)。 这两种图谱有以下区别: • 实例图谱(Instance Graph):这种图谱更干净,准确率更高,泛用性更好,但其维护成本也更高。 • 汇总图谱(Summary Graph):这种图谱维护成本低,不需要频繁的人工维护。由于我们的人力有限,只能实现汇总图谱的程度。

•存入 TiDB Serverless 集群

尽管汇总图谱的精度和泛用性不如实例图谱,但其维护成本更低,并且在性能上明显优于不使用知识图谱的 RAG 版本。因此,我们选择了汇总图谱。由于知识图谱的数据量非常大,我们需要一个合适的数据库进行存储。这个数据库不仅需要支持大规模数据存储,还要支持向量操作和高效检索。TiDB Serverless 不仅支持大规模数据存储和向量检索,还能应对高并发的查询需求 ,基于此我们选择了 TiDB Serverless 来解决这些问题。

•检索时使用 Vector Search 和知识图谱

检索时首先会使用 Vector Search 在集群中搜索最近邻的 Top N 节点,随后使用这些节点扩散 K 度,取回其相关节点及边,最后使用这些节点及边生成回答。

Vector type within TiDB>TiDB+Vector Database

为什么在数据服务架构中,选择将向量嵌入到 TiDB 中,而不是"外挂"一个向量数据库。首先,"外挂"向量数据库的方案需要应用程序进行双重操作,即写两次和查两次数据,这会带来数据同步问题。不仅需要确保数据的事务级别同步,即使是最终一致性有时也很难保证。有工程经验的开发者都知道,最终一致性有时很难实现。

将向量嵌入到 TiDB 中,可以简化操作,只需对 TiDB 进行一次读写操作,避免了外挂数据库带来的复杂性。我们选择在 TiDB 中嵌入向量,主要基于以下几个原因。首先,这样的方案可以简化架构,应用程序只需进行一次读写操作,不需要管理两个不同的数据库,从而简化了应用架构。其次,我们希望创建一个兼容 MySQL 生态的向量数据库插件,TiDB Serverless 率先实现了这一功能。尽管 MySQL 9.0 也实现了类似功能,但我们在此之前已经实现了这一点。

通过将向量嵌入 TiDB,我们不仅简化了架构,减少了操作复杂性,还能利用 TiDB 的分布式架构和高可用性,满足大规模数据存储和高并发查询的需求。

All in one 数据库帮助开发者减负

我接下来要讲的是全能型数据库如何帮助开发者减轻负担。在架构方面,我们先回顾一下过去 20 年的技术架构演变。每当关系型数据库(RDB)无法解决问题时,我们总是倾向于创造新的解决方案。最开始,我们有两种数据结构:文档型数据库和关系型数据库。如果需要同时使用两种数据库,就需要将数据从关系型数据库同步到文档型数据库。随后,我们发现 OLAP(联机分析处理)也很有用,因为列存储能加快数据分析速度,所以我们又增加了一份数据同步。然后,我们发现倒排索引适合全文检索,于是再同步一次。现在,我们还想增加一个向量索引。这些变化使得业务开发者感到困扰,因为数据架构的复杂性往往超过了业务本身的复杂性。

许多复杂的数据架构并不是由应用本身引起的,而是由于数据库架构的复杂性。对于一个服务,如果需要集成不同种类的查询,就需要加入不同种类的数据库。例如,一个服务可能需要 MySQL、MongoDB、ClickHouse 和 Redis,开发者必须仔细维护它们之间的关系。这种复杂度不应该由业务开发者承担,而是应该由数据存储来解决。换句话说,现在的数据存储对于业务架构的侵入性越来越强。存储本应用于解耦,但现在反而增加了耦合度,导致本末倒置。即使不增加额外的数据库,有些架构由于数据量的原因,也需要进行分库分表,这同样增加了数据架构的复杂性。

TiDB 作为一个全能型数据库,开发者使用其可以避免上述复杂性,因为 TiDB 能够集成多种数据库功能 ,不需要进行数据同步或维护多个数据库。这不仅简化了数据架构,还提升了开发效率,降低了维护成本,使得开发者可以更加专注于业务本身 。在预算方面,这也能帮助降低成本。

Take away

接下来,我想给大家一些 takeaways。首先,没有任何一种技术是万能的,大家需要根据自身情况选择最适合的技术栈。

对于自部署的 TiDB 方案,它的数据量没有限制,可用性高,加上 TiFlash 后还具备一定的分析能力。然而,自部署版本没有 vector 能力,运维也较为复杂,即使 TiDB 已经是分布式数据库中相对简单的运维方案。

而 TiDB Serverless 的优点在于数据量没有限制,可用性高,因为它是基于云平台的分布式数据库,具备分析和向量计算能力,价格也相对便宜。不过,如果你的服务是持续高负载的,Serverless 的成本可能会比自部署方案稍微贵一些。

最后,我想给大家传递一些愿景。现在,大家的目光都集中在 AI 上,AI 是我们未来可以仰望的天空。然而,我们希望数据库是我们脚下的坚实土壤,只有站得更稳,我们才能看得更远。因此,我想把这句话送给大家:AI is the sky, database is the earth。

这就是我今天的分享内容,感谢大家的聆听,谢谢!

相关推荐
rocksun1 分钟前
MCP利用流式HTTP实现实时AI工具交互
人工智能·mcp
xiaok25 分钟前
docker network create langbot-network这条命令在dify输入还是在langbot中输入
人工智能
It_张27 分钟前
LLM(大语言模型)的工作原理 图文讲解
人工智能·语言模型·自然语言处理
Darach29 分钟前
坐姿检测Python实现
人工智能·python
xiaok29 分钟前
LangBot 和消息平台均运行在 Docker 容器中
人工智能
hui函数30 分钟前
Flask高效数据库操作指南
数据库·python·flask
queeny38 分钟前
Datawhale AI夏令营 科大讯飞AI大赛(大模型技术) Task3 心得
人工智能
ToTensor38 分钟前
Paraformer实时语音识别中的碎碎念
人工智能·语音识别·xcode
陈佬昔没带相机44 分钟前
Mac Mini 玩大模型避坑指南
人工智能·mac
重启的码农1 小时前
llama.cpp 分布式推理介绍(4) RPC 服务器 (rpc_server)
c++·人工智能·神经网络