【RAG系列】KG-RAG 用最简单的方式将知识图谱引入RAG

目录

前言

一、引入知识图谱的作用

二、引入知识图谱的挑战

三、KG-RAG的理论

query多跳有限性

知识局部密集性

四、KG-RAG的方法

向量入库

向量相似搜索

扩展子图

LLM Rerank

LLM response

五、效果比对

六、源码

总结


前言

本文介绍一种比较新颖的RAG范式,KG-RAG,将知识图谱融入到RAG范式中,提高知识召回率。KG-RAG基于query多跳有限性 和 知识局部密集性 两点思想,提出了一套在知识图谱上检索相关实体知识的流程,在回答上准确性上有着很不错的表现。


一、引入知识图谱的作用

RAG通过给LLM提供回答query所需的知识,改善LLM的幻觉、领域知识不足等问题,但仅仅靠RAG范式存在一定局限性,尤其在处理复杂的实体关系和多跳问题的时候,模型往往难以提供准确的回答。

将知识图谱引入RAG系统为解决上述问题提供了新的思路,通过引入KG,RAG在回答实体关系和多跳问题的时候能够更精确地定位相关知识。Direct LLM、RAG 和 GraphRAG对比:

问题:19世纪的艺术运动是如何影响20世纪现代艺术的发展的?

Direct LLM:19世纪的艺术运动通过鼓励对色彩、形式和题材的实验影响了20世纪的现代艺术。这些运动为抽象主义、表现主义和其他创新艺术开辟了道路。

RAG:

检索文本:

1.  像克劳德·莫奈这样的印象派艺术家引入了新技术,彻底改变了对光和颜色的描绘

2.  印象派的技法影响了后来的艺术运动。

3.  毕加索开创了立体主义,从根本上改变了视觉表现的方式

4.  立体主义出现在20世纪初,挑战了传统的艺术观点。

回答:

19世纪,像克劳德·莫宁这样的印象派艺术家引入了影响后来艺术运动的新技术。帕布洛·毕加索在20世纪初提出了立体派相对论。

GraphRAG:

检索三元组:

莫奈-引进-新技术

新技术-革命性的-光与色的描绘

印象派技法-影响-后期艺术运动

毕加索-先驱-立体主义

立体主义-出现于-20世纪初

回答:

莫奈引进的新技术彻底改变了对光和色彩的描绘。他的印象派技术影响了后来的艺术运动,包括毕加索的立体派,这一影响在20世纪初形成。这种影响帮助塑造了毕加索对碎片化视角的创新方法。

显然,在引入KG的实体知识后,LLM的回答更具体更具有逻辑性。Direct LLM和RAG的回答也算沾边,但是缺少详细的实体信息导致不够连贯,有点一知半解。

二、引入知识图谱的挑战

KG-RAG 还处于早期的探索阶段,最关键的问题是如何根据 query 有效检索到 KG 中的相关 entities 和 relationships。

比如,微软的 From Local to Global 使用大量的 LLM 访问将子图结构以汇总成社区摘要,但这一过程消耗大量的 LLM tokens,使这一方法昂贵且不切实际。HippoRAG 使用 Personalized PageRank 重新更新图节点的权重,以找到重要的 entities,但这种以 entity 为中心的方法很容易受到 NER 遗漏的影响,而忽略了上下文中的其它信息。IRCoT 使用多步LLM 请求来逐步推理得到最终的回答,但这种方法将 LLM 引入多跳查找过程,导致回答问题的时间过长,很难实际应用。

但实际上使用一个简单的 多路召回 然后 rerank 的 RAG 范式,就能够很好的处理复杂的多跳 KG-RAG 场景,这一过程仅仅用到向量存储和少量的 LLM 开销。

三、KG-RAG的理论

KG-RAG 因为以下两点而有效:query多跳有限性 和 知识局部密集性。

query多跳有限性

直觉上,用户的提问query不太可能涉及非常多的 entities 和 relationships,否则这个问题会很奇怪,例如:

正常的query:爱因斯坦获得诺贝尔奖的时间是哪一年?(2跳)

查询路径:

  • 找到节点“爱因斯坦”。

  • 跳转到与“爱因斯坦”相关的“诺贝尔奖”节点。

  • 返回奖项颁发的年份信息。

奇怪的query:相对论发现者获得诺贝尔奖年份与他们在一个以银行保密法和阿尔卑斯山壮丽风景而闻名的国家发明的专利数量之间有什么关系?(7跳)

显然,正常的query更符合用户的提问习惯,即用户想要知道的是与某个具体实体直接相关的单一事实。知识图谱在这种情况下只需要进行少量跳数的查询即可完成任务,因为所有相关信息都直接与爱因斯坦这个中心节点关联。这种查询在实际应用中非常普遍,例如查询名人背景信息、奖项历史、事件时间等。

知识局部密集性

知识图谱中存在着一些局部 dense 结构,对于有些 query,有一些“捷径”,可以从一个 entity 通过捷径快速连接到多跳之外的 entity:

Daniel 是 Alex 的舅舅 (Daniel-uncle_of-Alex) 这条路径就可以通过另外三条路径推导出来。

结合 query多跳有限性 和 知识局部密集性 可以得到如下结论:有限次的在知识图谱中的路由查找过程,往往只涉及到局部的知识图谱信息。因此 KG-RAG 的检索过程可以通过以下两步实现:

1. 找到路由起点,可以通过向量相似度查找来完成。涉及 query与entities 和 query与relationships 的相似度查找。

2. 从起点找到其他信息,这一步可以交给LLM完成,将以起点为中心的局部子图交给LLM,由LLM自己来挑选和推导实体的信息。输入局部子图是由于多跳有限性。

整个过程不需要复杂的 KG存储和 KG查询语句,只需要使用 vector database 和一次 LLM 的调用。vector retrieval + LLM rerank 是这个 pipeline 中最关键的部分,这也就解释了只用一个简单的两路召回,就可以达到远超基于图理论的方法(如 HippoRAG) 的表现。这也说明不需要复杂的图算法,只需要将图结构的逻辑关系存储在向量数据库里,用一个传统的架构就可以进行逻辑上的子图路由,而 LLM 强大的能力帮助做到了这一点。

四、KG-RAG的方法

假设已经得到了一组 corpus 的三元组信息,它包含一系列的 entities 和 relationships 信息。这些信息可以表示一个知识图谱的信息。

总的来说,将 entities, relationships 信息分别进行向量化,并存储在向量存储里。当进行 query 查询时,会先把相关的 entities 和 relationships 检索出来。通过这些 entities 和 relationships,在图结构上进行有限的拓展。将这些 relationships 与 query 组装进 prompt 内,使用 LLM 的能力对这些 relationships 进行 reranking。最后得到 topK 个重要的 relationships,在他们的 metadata 信息内获得与他们相关的 passages,作为最终的 retrieved passages。

向量入库

准备两个向量存储 collections,一个是 entity collection,另一个是 relationship collection。将一系列的 unique entities 信息和 relationships 信息,使用 embedding 模型转换成向量存储在向量存储中。对于 entities 信息,直接将他们的字符描述转换成 embedding。对于 relationships 的原始数据形式,它的结构是一个三元组:

(Subject, Predicate, Object)

我们启发性地直接将它们合并成一个句子

"Subject Predicate Object"

比如:

(Alex, child of, Brian) -> "Alex child of Brian"

(Cole, married to, Brian) -> "Cole married to Bria"

然后直接将这个句子转换成 embedding,存储在向量数据库里。虽然这样做可能存在少量的语法问题,但这不影响句子含义的表达,也不影响它在向量空间中的分布。当然,同样鼓励在前期抽取三元组的时候,直接使用 LLM 生成简短的句子描述。

向量相似搜索

  • 对于输入的 Query,遵循常见的 GraphRAG 中的范式(如HippoRAG,MS GraphRAG),提取 query 中的 entities,对于每个 query entity,转换成 embedding,分别对 entity collection 进行 vector similarity search。然后将所有 query entities搜索得到的结果进行合并。

  • 对于 relationship 的向量搜索,直接将 query string,转换成 embedding,对 relationship collection 进行 vector similarity search。

扩展子图

分别以搜索到的 entities 和 relationships 为知识图谱里的起始点,往外扩大一定范围,然后将两个扩展子集的 relationships 进行合并。具体来说:

entities扩充:对于起始entities,往外扩大一定的跳数后取它们邻接的relationships。

relationship扩充:往外扩大一定的跳数得到扩展的relationships。

将两者的relationships合并,得到最终的relationships集合。

基于多跳有限性,仅需要扩大较小的度数(如1,2等)就能涵盖大部分可能有助回答的 relationships。这一步扩展的度数的概念和回答问题总共需要的跳度的概念不同。比如,如果回答一个 query 问题涉及两个相差 n 跳的 entities,那么实际上往往只需要扩展 ⌈n / 2⌉ 度就可以,因为这两个 entities 是被向量相似召回后的两个起始端点。如图,向量召回到了两个红色的 entities,只需要从它们开始相向扩展 2 度就能覆盖到 4 度的跳数,这足以回答涉及到这两个 entities 的 4 跳问题。

LLM Rerank

这一步中,使用 LLM 强大的语义理解能力对 relationships 候选集的进行筛选和排序。具体来说,使用 one-shot Chain-of-Thought prompt,将 query 和 relationships 候选集放入 prompt 里,要求 LLM 从中选择出可能对回答这个 query 有帮助的 relationships,并写下思考过程。规定 LLM 的返回为 json 格式,以便于解析。具体的 prompt 参考如下:

输入:

I will provide you with a list of relationship descriptions. Your task is to select 3 relationships 

that may be useful to answer the given question. Please return a JSON object containing 

your thought process and a list of the selected relationships in order of their relevance.

**Question:**
When was the mother of the leader of the Third Crusade born?

**Relationship descriptions:**
[1] Eleanor was born in 1122.
[2] Eleanor married King Louis VII of France.
[3] Eleanor was the Duchess of Aquitaine.
[4] Eleanor participated in the Second Crusade.
[5] Eleanor had eight children.
[6] Eleanor was married to Henry II of England.
[7] Eleanor was the mother of Richard the Lionheart.
[8] Richard the Lionheart was the King of England.
[9] Henry II was the father of Richard the Lionheart.
[10] Henry II was the King of England.
[11] Richard the Lionheart led the Third Crusade.

LLM response:

{

         "thought_process": "To answer the question about the birth of the mother of the leader of the Third Crusade, I first need to identify who led the Third Crusade and then determine who his mother was. After identifying his mother, I can look for the relationship that mentions her birth.",
         "useful_relationships": [
                      "[11] Richard the Lionheart led the Third Crusade",
                      "[7] Eleanor was the mother of Richard the Lionheart",
                      "[1] Eleanor was born in 1122"
          ]
}

这个 prompt 是一个展示的参考,实际上把 relationships 中的三元组转成一个通顺的短句是一个棘手的问题。但是完全可以用上文提到的启发性的方法把三元组直接拼在一起。如:

(Eleanor, born in, 1122) 可以直接转成 Eleanor born in 1122

这种方式有时会带来一定的语法问题,但它是最快最直接的方式,也不会对 LLM 带来误解。

LLM response

在上面的例子中,实际上可以在 LLM rerank 这个阶段直接返回最终的回答,比如在 One shot output prompt 的 json 字段里加上比如 “final answer”的字段。但是这一步的 prompt 里只有 relationships 的信息,不一定所有问题都可以在这个阶段返回最终答案,所以其它具体的信息需要从原始的 passsage 里获得。

LLM 返回精确排序的 relationships后,只需要取出之前存储的 relationship 信息,从中获取相应的 metadata中对应的 passage ids。这些 passages 信息就是最终被 retrieved 到的 passages。后续生成回答的过程和 naive RAG 一样,将它们放入 prompt 的 context 中让 LLM 给出最后的回答。

五、效果比对

使用与 HippoRAG 中一致的 dense embedding,facebook/contriever,作为 embedding 模型,可以看到在三个 multi-hop 的数据集上结果比较上,KG-RAG大幅超过 naive RAG 和 HippoRAG 的结果。所有的方法使用相同的 embedding 模型设置。使用 Recall@2 作为衡量指标,

Recall(召回率) = 检索到的相关文档总数/数据存储中相关文档总数

六、源码

https://milvus.io/docs/graph_rag_with_milvus.md


总结

回顾KG-RAG的方法,把 entities 和 relationships 转成向量并进行搜索就是在寻找子图的起点,它像是破解刑侦案件中的现场发现的“线索”。而后面扩展子图和 LLM rerank 的过程像是具体通过这些“线索”进行分析的过程,LLM 拥有“上帝视角”,可以在一众的候选 relationships 中,聪明地选择对破案有用的 relationships。这两个阶段回归本质也就是对应朴素的 vector retrieval + LLM reranking 范式。

上一篇:vue2面试题5|[2024-11-08]


下一篇:《Python编程实训快速上手》第三天--字典和结构化数据