【项目】GraphRAG基于知识图谱的检索增强技术-实战入门
GraphRAG—基于知识图谱的检索增强技术
- (一)GraphRAG入门介绍
- (二)GraphRAG基本原理回顾
- (三)GraphRAG运行流程
- 3.1 索引(Indexing)过程
- 3.2 查询(Query)过程
- 3.3 Prompt 调优
- 3.4 GraphRAG计算流程极简示例
- (四)GraphRAG安装与Indexing&Query流程实现
- (五)GraphRAG API使用方法
(一)GraphRAG入门介绍
发展历程
• 2024年2月,由微软研究院提出GraphRAG基本思路;
• 2024年4月,同样由微软研究院发表相关论文《From Local to Global: A Graph RAG Approach to Query-Focused Summarization》,学术角度论证GraphRAG有效性;
• 2024年6月,正式发布GraphRAG项目…
GraphRAG 项目地址:https://github.com/microsoft/graphrag/
检索增强生成(RAG) 是一种通过结合真实世界的信息来提升大型语言模型(LLM)输出质量的技术。RAG 技术是大多数基于 LLM 的工具中的一个重要组成部分。大多数 RAG 方法使用 向量相似性 作为检索技术,我们将其称为 基线 RAG(Baseline RAG)。
RAG 技术在帮助 LLM 推理私有数据集方面显示了很大的潜力——例如,LLM 没有在训练时接触过的、企业的专有研究、业务文档或通信数据。基线 RAG 技术最初是为了解决这个问题而提出的,但我们观察到,在某些情况下,基线 RAG 的表现并不理想。以下是几个典型的场景:
- 基线 RAG 很难将信息串联起来:当一个问题的答案需要通过多个不同的信息片段,并通过它们共享的属性来连接,进而提供新的综合见解时,基线 RAG 表现得很差。
- 例如,在回答类似“如何通过现有的数据推断出新结论”这种问题时,基线 RAG 无法很好地处理这些散布在不同文档中的相关信息,它可能会遗漏一些关键联系点。
- 基线 RAG 无法有效理解大型数据集或单一大文档的整体语义概念:当被要求在大量数据或复杂文档中进行总结、提炼和理解时,基线 RAG 往往表现不佳。
- 例如,如果问题要求对整个文档或多篇文档的主题进行总结和理解,基线 RAG 的简单向量检索方法可能无法处理文档间的复杂关系,导致对全局语义的理解不完整。
为了应对这些挑战,技术社区正在努力开发扩展和增强 RAG 的方法。微软研究院(Microsoft Research)提出的 GraphRAG 方法,使用 LLM 基于输入语料库构建 知识图谱。这个图谱与社区总结和图谱机器学习输出结合,能够在查询时增强提示(prompt)。GraphRAG 在回答以上两类问题时,展示了 显著的改进,尤其是在 复杂信息的推理能力 和 智能性 上,超越了基线 RAG 之前应用于私有数据集的其他方法。
(二)GraphRAG基本原理回顾
GraphRAG 是微软研究院开发的一种先进的增强检索生成(RAG)框架,旨在提升语言模型(LLM)在处理复杂数据时的性能。与传统的 RAG 方法依赖向量相似性检索不同,GraphRAG 利用 知识图谱 来显著增强语言模型的问答能力,特别是在处理私有数据集或大型、复杂数据集时表现尤为出色。
传统的 Baseline RAG 方法在某些情况下表现不佳,尤其是当查询需要在不同信息片段之间建立联系时,或是当需要对大规模数据集进行整体理解时。GraphRAG 通过以下方式克服了这些问题:
- 更好的连接信息点:GraphRAG 能够处理那些需要从多个数据点合成新见解的任务。
- 更全面的理解能力:GraphRAG 更擅长对大型数据集进行全面理解,能够更好地处理复杂的抽象问题。
而借助微软开源的GeaphRAG项目,我们可以快速做到以下事项:
- 基于图的检索:传统的 RAG 方法使用向量相似性进行检索,而 GraphRAG 引入了知识图谱来捕捉实体、关系及其他重要元数据,从而更有效地进行推理。
- 层次聚类:GraphRAG 使用 Leiden 技术进行层次聚类,将实体及其关系进行组织,提供更丰富的上下文信息来处理复杂的查询。
- 多模式查询:支持多种查询模式:
- 全局搜索:通过利用社区总结来进行全局性推理。
- 局部搜索:通过扩展相关实体的邻居和关联概念来进行具体实体的推理。
- DRIFT 搜索:结合局部搜索和社区信息,提供更准确和相关的答案。
- 图机器学习:集成了图机器学习技术,提升查询响应质量,并提供来自结构化和非结构化数据的深度洞察。
- Prompt 调优:提供调优工具,帮助根据特定数据和需求调整查询提示,从而提高结果质量。
(三)GraphRAG运行流程
3.1 索引(Indexing)过程
- 文本单元切分:将输入文本分割成 TextUnits,每个 TextUnit 是一个可分析的单元,用于提取关键信息。
- 实体和关系提取:使用 LLM 从 TextUnits 中提取实体、关系和关键声明。
- 图构建:构建知识图谱,使用 Leiden 算法进行实体的层次聚类。每个实体用节点表示,节点的大小和颜色分别代表实体的度数和所属社区。
- 社区总结:从下到上生成每个社区及其成员的总结,帮助全局理解数据集。
3.2 查询(Query)过程
索引完成后,用户可以通过不同的搜索模式进行查询:
- 全局搜索:当我们想了解整个语料库或数据集的整体概况时,GraphRAG 可以利用 社区总结 来快速推理和获取信息。这种方式适用于大范围问题,如某个主题的总体理解。
- 局部搜索:如果问题关注于某个特定的实体,GraphRAG 会向该实体的 邻居(即相关实体)扩展搜索,以获得更详细和精准的答案。
- DRIFT 搜索:这是对局部搜索的增强,除了获取邻居和相关概念,还引入了 社区信息 的上下文,从而提供更深入的推理和连接。
3.3 Prompt 调优
为了获得最佳性能,GraphRAG 强烈建议进行 Prompt 调优,确保模型可以根据你的特定数据和查询需求进行优化,从而提供更准确和相关的答案。
3.4 GraphRAG计算流程极简示例
(四)GraphRAG安装与Indexing&Query流程实现
最新版GraphRAG特性如下:
(1)架构升级与知识图谱构建优化
- 智能化的知识图谱构建
GraphRAG 2.0 在数据预处理阶段,通过大模型自动抽取文本中的实体及关系,构建出层次化的知识图谱。相比传统的简单文本片段检索,构建后的图谱能够以“社区”(topic-based clusters)的方式对数据进行组织,这样不仅可以覆盖全局信息,也能针对局部查询给出更精准的答案。 - 动态社区选择机制
新版本引入了动态社区选择流程。系统会在生成响应之前,对知识图谱中不同“社区”的相关性进行评估,从而仅保留与当前查询最匹配的部分。这种机制能有效“丢弃”噪声数据,提高检索效率和答案的准确性。
(2)查询流程与成本优化
- **两阶段查询流程:**GraphRAG 2.0 将整个流程拆分为“索引阶段”和“查询阶段”:
- 在索引阶段,系统利用大模型对原始数据进行结构化处理,提取实体及其关系,构建分层知识图谱;
- 在查询阶段,则先进行初步的相关性测试,再利用经过动态社区筛选的信息来生成上下文丰富、精准的回答。
这种分步处理不仅提高了检索的广度和深度,还能根据查询需求灵活调用大模型。
- Token消耗大幅降低
为了应对大规模数据调用时高昂的成本,GraphRAG 2.0 对 LLM 的调用做了优化。据报道,在某些场景下整体 Token 消耗降低高达 77%,这使得系统在保证高质量回答的同时,也大幅提升了成本效率。 - LazyGraphRAG 模式
新版本还推出了“LazyGraphRAG”模式——一种结合了向量检索和图结构检索优势的方案。该模式采用迭代深化的方式,只有在必要时才调用资源密集型的大模型进行深度分析,从而实现了与传统 GraphRAG 相比成本更低但效果相当的目标。
(3)搜索结果质量与应用扩展
- 精准且上下文丰富的答案
利用层次化的知识图谱和动态社区筛选,GraphRAG 2.0 能够生成更具有可解释性和上下文关联的答案。无论是全局性问题(例如“核心主题是什么?”)还是局部性查询(如“谁、何时、何地”等),系统都能根据不同场景调整检索策略,返回最相关的信息。 - 多系统和多场景集成
此外,新版本在设计上也更注重与其它系统的集成能力,例如在数字营销场景中,通过与 URL 缩短服务、链接分析等工具相结合,为用户提供定制化且综合的查询反馈。
# Step 1.使用pip安装graphrag
pip install graphrag
pip show graphrag# Step 2.创建检索项目文件夹
mkdir -p ./ragtest/input# Step 3.上传数据集
目前GraphRAG只支持txt和csv两种文本格式 https://whakv.xetslk.com/s/pxKHG 中会详细介绍如何修改源码,拓展支持文件类型。# Step 4.初始化项目文件
graphrag init --root ./ragtest# Step 5.修改项目配置
打开.env文件,填写DeepSeek API-KEY或OpenAI API-Key
打开setting.yaml文件,填写模型名称和反向代理地址:# 【可选】Step 6.验证API-KEY和反向代理地址是否可以正常运行
from openai import OpenAI
api_key = 'your-openai-api-key'
# 实例化客户端
client = OpenAI(api_key=api_key, base_url="反向代理地址")
# 调用 GPT-4o-mini 模型
response = client.chat.completions.create(model="gpt-4o-mini",messages=[{"role": "user", "content": "你好,好久不见!"}]
)
# 输出生成的响应内容
print(response.choices[0].message.content)
你好!好久不见!你最近怎么样?有什么新鲜事分享吗?
然后查看当前API-KEY可以调用的模型:models_list = client.models.list()
models_list.data# Step 7.借助GraphRAG脚本自动执行indexing
graphrag index --root ./ragtest
graphrag query --root ./ragtest --method local --query "请帮我介绍下ID3算法"
(五)GraphRAG API使用方法
## 1.初始化项目
from pathlib import Path
from pprint import pprint
import pandas as pd
import graphrag.api as api
from graphrag.config.load_config import load_config
from graphrag.index.typing.pipeline_run_result import PipelineRunResultmkdir -p ./graphrag/inputgraphrag init --root ./graphrag## 2.借助API进行Indexing过程
PROJECT_DIRECTORY = "./graphrag"
# 生成 GraphRagConfig 对象graphrag_config = load_config(Path(PROJECT_DIRECTORY))"""
索引 API
索引是指摄取原始文本数据并构建知识图谱的过程。GraphRAG 目前支持纯文本(.txt)和 .csv 文件格式。
构建索引
index_result: list[PipelineRunResult] = await api.build_index(config=graphrag_config)
[2025-03-19T13:17:26Z WARN lance::dataset::write::insert] No existing dataset at /root/autodl-
tmp/MCP/graphrag/output/lancedb/default-entity-description.lance, it will be created
[2025-03-19T13:17:28Z WARN lance::dataset::write::insert] No existing dataset at /root/autodl-
tmp/MCP/graphrag/output/lancedb/default-community-full_content.lance, it will be created
[2025-03-19T13:17:30Z WARN lance::dataset::write::insert] No existing dataset at /root/autodl-
tmp/MCP/graphrag/output/lancedb/default-text_unit-text.lance, it will be created
"""
# index_result 是一个包含索引流水线各个工作流的列表,每个工作流代表一次索引构建过程。for workflow_result in index_result:status = f"error\n{workflow_result.errors}" if workflow_result.errors else "success"print(f"Workflow Name: {workflow_result.workflow}\tStatus: {status}")
"""
Workflow Name: create_base_text_units Status: success
Workflow Name: create_final_documents Status: success
Workflow Name: extract_graph Status: success
Workflow Name: finalize_graph Status: success
Workflow Name: create_communities Status: success
Workflow Name: create_final_text_units Status: success
Workflow Name: create_community_reports Status: success
Workflow Name: generate_text_embeddings Status: success
在此循环中,遍历 index_result 列表,并打印每个工作流的名称及其执行状态。如果工作流中存在错误,则输出错误信息,否则输出 "success"。
"""## 2.借助API进行Query过程
# 查询索引, 在查询索引之前,必须先将多个索引文件加载到内存中,并传递给查询 API。
entities = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/entities.parquet")
communities = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/communities.parquet")
community_reports = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/community_reports.parquet"
)
# 上述代码读取 .parquet 格式的索引数据,包括 实体(entities)、社群(communities) 以及 社群报告(community_reports)。
# 执行全局搜索
query = "请帮我对比下ID3和C4.5决策树算法优劣势。并用中文进行回答。"
response, context = await api.global_search(config=graphrag_config,entities=entities,communities=communities,community_reports=community_reports,community_level=2,dynamic_community_selection=False,response_type="Multiple Paragraphs",query=query,
)
# 在这里,我们调用 global_search 方法,使用已加载的索引数据进行查询。
community_level=2:设定社群层级为 2 级。
dynamic_community_selection=False:禁用动态社群选择。
response_type="Multiple Paragraphs":设置返回的查询结果为多段落格式。
query=query:查询问题为 **"请帮我对比下ID3和C4.5决策树算法优劣势。并用中文进行回答。"**。
# 解析查询结果
print(response)"""
在决策树算法的发展历程中,ID3算法和C4.5算法是两个非常重要的里程碑。它们各自具有独特的特点和应用场景,以下是对这两种算法优劣势的对比分析。### ID3算法ID3算法是决策树算法的先驱,它使用信息熵作为选择分裂规则的标准。这种方法的优点在于其简单性,使得算法在处理较小或者较简单的数据集时计算效率较高。然而,ID3算法也存在一些明显的局限性。首先,它无法直接处理连续特征,这在实际应用中是一个较大的限制。其次,ID3没有机制来防止过拟合,这意味着在处理更复杂的数据集时,其性能可能不如预期 [Data: Reports (10)]。### C4.5算法C4.5算法在ID3的基础上进行了显著的改进。首先,它引入了增益率(Gain Ratio)和信息价值(Information Value)来优化数据分割过程,这不仅解决了ID3处理连续变量不足的问题,还通过引入增益率来减少对具有更多类别的属性的偏见。其次,C4.5通过剪枝过程改善了决策树的泛化能力,有效减少了过拟合的风险。然而,这些改进也使得C4.5算法的计算复杂度增加,尤其是在处理大规模数据集时 [Data: Reports (2, 11, +more)]。### 总结总的来说,ID3算法以其简单高效著称,适合于处理较小或简单的数据集。而C4.5算法则在ID3的基础上做了重要改进,不仅能够处理连续变量,还通过剪枝过程减少了过拟合的风险,使其更适合处理复杂的数据集。然而,这些改进也带来了更高的计算复杂度。因此,在选择使用哪种算法时,需要根据实际的数据特性和应用场景做出合理的决策。
response 变量是 GraphRAG 返回的正式查询结果。
"""print(context)
"""
{'reports': id title occurrence weight \
0 2 Evolution of Decision Tree Algorithms: From ID... 1.000000
1 3 Scikit-Learn Ecosystem: A Comprehensive Machin... 0.916667
2 11 Evolution of Decision Tree Algorithms: From C4... 0.833333
3 0 CART and Its Foundational Impact on Machine Le... 0.833333
4 13 Scikit-Learn Ecosystem 0.750000
5 5 Machine Learning Ecosystem: Scikit-Learn, CART... 0.666667
6 10 Decision Tree Models and Metrics Community 0.666667
7 21 Python Data Science Ecosystem 0.416667
8 9 Friedman and the Evolution of Boosting Algorithms 0.416667
9 15 Scikit-Learn Decision Tree Analysis 0.416667
10 22 Decision Tree Algorithms: CART and CHAID 0.333333
11 8 Statistical Measures and Predictive Modeling C... 0.333333
12 14 Scikit-learn's DecisionTreeClassifier Ecosystem 0.250000
13 4 Decision Tree Parameters and Strategies in skl... 0.250000
14 18 Decision Tree Parameters Community 0.250000
15 19 Decision Tree Model Parameters Community 0.166667
16 16 Decision Tree Model Strategies and Randomness ... 0.166667
17 20 Aurélien Géron and Machine Learning Technologies 0.083333
18 12 GR, IG, and IV in Decision Tree Algorithms 0.083333
19 7 CART and Its Foundational Impact on Machine Le... 0.500000
20 6 Decision Tree Analysis and Income-Credit Ratin... 0.333333
21 1 Logistic Regression and Its Ecosystem in Machi... 0.333333
22 17 ExtraTreeClassifier and Its Parameters in Sklearn 0.083333 content rank
0 # Evolution of Decision Tree Algorithms: From ... 8.5
1 # Scikit-Learn Ecosystem: A Comprehensive Mach... 8.5
2 # Evolution of Decision Tree Algorithms: From ... 8.5
3 # CART and Its Foundational Impact on Machine ... 8.5
4 # Scikit-Learn Ecosystem\n\nThe Scikit-Learn (... 8.5
5 # Machine Learning Ecosystem: Scikit-Learn, CA... 8.5
6 # Decision Tree Models and Metrics Community\n... 7.5
7 # Python Data Science Ecosystem\n\nThe communi... 8.5
8 # Friedman and the Evolution of Boosting Algor... 8.5
9 # Scikit-Learn Decision Tree Analysis\n\nThis ... 7.5
10 # Decision Tree Algorithms: CART and CHAID\n\n... 7.5
11 # Statistical Measures and Predictive Modeling... 7.5
12 # Scikit-learn's DecisionTreeClassifier Ecosys... 8.0
13 # Decision Tree Parameters and Strategies in s... 7.5
14 # Decision Tree Parameters Community\n\nThis c... 7.5
15 # Decision Tree Model Parameters Community\n\n... 7.5
16 # Decision Tree Model Strategies and Randomnes... 7.5
17 # Aurélien Géron and Machine Learning Technolo... 8.5
18 # GR, IG, and IV in Decision Tree Algorithms\n... 7.5
19 # CART and Its Foundational Impact on Machine ... 8.5
20 # Decision Tree Analysis and Income-Credit Rat... 7.5
21 # Logistic Regression and Its Ecosystem in Mac... 7.5
22 # ExtraTreeClassifier and Its Parameters in Sk... 7.5 }
context 变量包含关于查询过程的详细元数据,包括:查询过程中检索到的数据信息
被用于构建上下文的文本片段
其他元数据
深入分析 context 对象可以获取更精细的信息,比如LLM 模型最终使用的文本数据来源。
"""
# 3.封装函数完成GraphRAG Query
async def rag_ML(query: str) -> str:"""输入机器学习领域相关问题,获得问题答案。:param query: 机器学习领域的相关问题:return: query问题对应的答案"""PROJECT_DIRECTORY = "/root/autodl-tmp/MCP/mcp-graphrag/graphrag"graphrag_config = load_config(Path(PROJECT_DIRECTORY))# 加载实体entities = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/entities.parquet")# 加载社区communities = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/communities.parquet")# 加载社区报告community_reports = pd.read_parquet(f"{PROJECT_DIRECTORY}/output/community_reports.parquet")# 进行全局搜索response, context = await api.global_search(config=graphrag_config,entities=entities,communities=communities,community_reports=community_reports,community_level=2,dynamic_community_selection=False,response_type="Multiple Paragraphs",query=query,)return response
query = '请帮我对比下ID3和C4.5决策树算法优劣势。并用中文进行回答。'
await rag_ML(query)
"""
'### ID3算法与C4.5算法的对比\n\n#### ID3算法概述\n\nID3算法是由Ross Quinlan开发的决策树算法的早期版本,它主要通过信息增益(Information Gain)作为选择属性的标准,专注于处理分类问题。ID3算法的主要优点在于其简单直观,易于理解和实现,使其成为决策树算法中的一个重要基石 [Data: Reports (1, 13)]。然而,ID3算法存在几个显著的限制,包括无法直接处理连续属性和缺失值,以及缺乏有效的过拟合预防措施,这些限制可能会影响算法的泛化能力和应用范围 [Data: Reports (1, 13)]。\n\n#### C4.5算法改进\n\nC4.5算法是在ID3的基础上进行改进的,同样由Ross Quinlan开发。C4.5算法的主要改进包括引入信息增益率(Gain Ratio)来选择属性,这一改进解决了ID3算法在属性选择时偏向于选择取值多的属性的问题。此外,C4.5算法能够处理连续属性和缺失值,并引入了剪枝技术来减少过拟合的风险,从而提高了模型的泛化能力 [Data: Reports (1, 13)]。C4.5算法的这些改进使得它更加健壮,适用于更广泛的数据集。然而,需要注意的是,C4.5算法的计算复杂度较高,尤其是在处理大型数据集时,这可能会成为其应用的一个限制 [Data: Reports (1, 13)]。\n\n#### 总结\n\n总的来说,C4.5算法在功能上对ID3算法进行了显著的改进,包括处理连续属性和缺失值的能力,以及引入剪枝策略来避免过拟合问题,这些改进显著提高了决策树模型的泛化能力。然而,这些改进也带来了更高的计算复杂度,特别是在处理大规模数据集时 [Data: Reports (1, 13)]。因此,在选择使用ID3算法还是C4.5算法时,需要根据具体的应用场景和数据集的特点来权衡算法的优势和潜在的限制。'
"""