GraphRAG:知识图谱+大模型 LangChain实现

本文介绍了如何通过构建知识图谱和利用大型语言模型(LLM)增强RAG应用的准确性。重点讲解了使用Neo4j图数据库、LLMGraphTransformer和混合检索方法,包括图数据库中的知识图谱构建、混合搜索策略及其实战示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文整理自Enhancing RAG-based application accuracy by constructing and leveraging knowledge graphs一文。LangChain已经将图构建模块的首个版本集成到了其生态之中,今天本文将展示基于知识图谱的RAG应用实战

图检索增强生成(Graph RAG)正逐渐流行起来,成为传统向量搜索方法的有力补充。这种方法利用图数据库的结构化特性,将数据以节点和关系的形式组织起来,从而增强检索信息的深度和上下文关联性。

img示例知识图谱

图在表示和存储多样化且相互关联的信息方面具有天然优势,能够轻松捕捉不同数据类型间的复杂关系和属性。而向量数据库在处理这类结构化信息时则显得力不从心,它们更擅长通过高维向量处理非结构化数据。在 RAG 应用中,结合结构化的图数据和非结构化的文本向量搜索,可以让我们同时享受两者的优势,这也是本文将要探讨的内容。

知识图谱的确很有用,但如何构建一个呢? 构建知识图谱通常是利用图数据表示的强大功能中最困难的一步。它需要收集和整理数据,这需要对领域知识和图建模有深刻的理解。为了简化这一过程,我们开始尝试使用大型语言模型(LLM)。LLM 凭借其对语言和上下文的深刻理解,可以自动化知识图谱创建过程中的大部分工作。通过分析文本数据,这些模型能够识别实体,理解它们之间的关系,并提出如何在图结构中最佳表示这些实体。基于这些实验,我们已经将图构建模块的首个版本集成到了 LangChain 中,本文将展示其应用。

相关代码已在 GitHub 上发布。

Neo4j 环境搭建

为了跟随本文的示例,您需要搭建一个 Neo4j 实例。最简单的方法是在 Neo4j Aura 上启动一个免费实例,它提供了 Neo4j 数据库的云版本。当然,您也可以通过下载 Neo4j Desktop 应用程序来创建一个本地数据库实例。

os.environ["OPENAI_API_KEY"] = "sk-"
os.environ["NEO4J_URI"] = "bolt://localhost:7687"
os.environ["NEO4J_USERNAME"] = "neo4j"
os.environ["NEO4J_PASSWORD"] = "password"

graph = Neo4jGraph()

此外,您还需要一个 OpenAI 密钥,因为我们将在本文中使用他们的模型。

数据导入

在本次演示中,我们将使用伊丽莎白一世的维基百科页面。我们可以利用 LangChain 加载器 轻松地从维基百科获取并分割文档。

# 读取维基百科文章
raw_documents = WikipediaLoader(query="Elizabeth I").load()

# 定义分块策略
text_splitter = TokenTextSplitter(chunk_size=512, chunk_overlap=24)
documents = text_splitter.
### 回答1: 可以使用Java的Stream API来实现,示例代码如下:List list = Arrays.asList("a", "b", "c", "d", "a", "e");List indices = list.stream() .map(element -> list.indexOf(element)) .collect(Collectors.toList());System.out.println("Indices of elements with same value in the list: " + indices); ### 回答2: 要筛选出List数组中相同值的数据下标,可以使用Java的循环和条件语句来实现。 首先,我们定义一个List数组,并初始化一些数据。 ```java List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(2); list.add(4); ``` 接下来,我们使用一个for循环来遍历数组,依次比较每个元素与其他元素的值是否相同。为了避免重复比较和重复记录下标,我们可以设置一个标志位isDuplicate来判断是否已经找到重复值。 ```java List<Integer> indexList = new ArrayList<>(); boolean isDuplicate = false; for (int i = 0; i < list.size(); i++) { isDuplicate = false; for (int j = i + 1; j < list.size(); j++) { if (list.get(i).equals(list.get(j))) { if (!isDuplicate) { indexList.add(i); isDuplicate = true; } indexList.add(j); } } } ``` 最后,我们可以打印出重复值的下标。 ```java System.out.println("重复值的下标为:" + indexList); ``` 以上代码旨在筛选出List数组中相同值的数据下标,只需运行即可得到结果。 ### 回答3: 要筛选出list数组中相同值的数据下标,可以使用Java中的List和Map来实现。首先,我们可以创建一个空的Map对象来存储数组中的元素和它们的下标。然后,使用for循环遍历数组,将数组元素作为键,将对应的下标作为值存入Map中。如果遇到相同的元素,我们可以使用List来存储它们的下标。 以下是实现该功能的示例代码: ```java import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class Main { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(2); list.add(3); list.add(4); list.add(4); Map<Integer, List<Integer>> indexMap = new HashMap<>(); for (int i = 0; i < list.size(); i++) { int num = list.get(i); if (indexMap.containsKey(num)) { List<Integer> indexes = indexMap.get(num); indexes.add(i); } else { List<Integer> indexes = new ArrayList<>(); indexes.add(i); indexMap.put(num, indexes); } } for (Map.Entry<Integer, List<Integer>> entry : indexMap.entrySet()) { int num = entry.getKey(); List<Integer> indexes = entry.getValue(); if (indexes.size() > 1) { System.out.print(num + "出现的下标为:"); for (int index : indexes) { System.out.print(index + " "); } System.out.println(); } } } } ``` 运行以上代码,输出为: ``` 2出现的下标为:1 2 4出现的下标为:4 5 ``` 以上代码会筛选出list数组中所有相同值的数据下标,并将结果输出。这样,我们就实现了筛选出list数组中相同值数据下标的功能。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值