RAG 结合了大型语言模型和信息检索模型的力量,允许它们用从大量文本数据中提取的相关事实和细节来补充生成的响应。事实证明,这种方法在提高模型输出的实际准确性和总体质量方面是有效的。
然而,随着 RAG 系统得到更广泛的采用,它们的局限性开始浮出水面,具体而言:
也就是说,对非结构化文本数据的依赖意味着这些模型很难捕捉到处理复杂查询所必需的更深层次的语义关系和上下文细微差别。此外,为每个查询检索和处理大量文本的计算成本构成了重大挑战。
GraphRAG 是检索增强生成领域的一个重要进展。GraphRAG 不使用非结构化的文本,而是利用知识图谱的力量ーー实体的结构化表示、属性以及它们之间的关系。通过以这种结构化的格式表达,GraphRAG 可以克服传统 RAG 方法的局限性。知识图谱可以更精确和全面地检索相关信息,使模型能够产生不仅事实准确而且与上下文相关并涵盖查询所需方面的答复。
让我们来理解 GraphRAG 如何存储信息,例如“2型糖尿病是一种拥有属性高血糖的慢性疾病,可能导致神经损伤、肾脏疾病和心血管疾病等并发症。”
以下是 GraphRAG 如何在知识图谱中表示这些信息:
# 实体
二型糖尿病(病况)
高血糖水平(症状)
神经损伤(并发症)
肾脏疾病(并发症)
心血管疾病(并发症)
# 关系
2型糖尿病-> 有症状-> 高血糖水平
2型糖尿病-> 可导致-> 神经损伤
2型糖尿病-> 可导致-> 肾脏疾病
2型糖尿病-> 可导致-> 心血管疾病
在这个知识图谱中,实体(节点)表示句子中提到的关键概念,如病况、症状和并发症。这些关系(边)捕捉了这些实体之间的联系,例如,2型糖尿病有高血糖水平的症状,并可能导致各种并发症。这种结构化的表示允许 GraphRAG 理解句子中的语义关系和上下文,而不是仅仅将其视为一个单词包。当用户问一个与2型糖尿病相关的问题时,比如“2型糖尿病的并发症是什么?”,
GraphRAG 可以快速遍历知识图,从“2型糖尿病”实体开始,遵循“可以导致”关系来检索相关并发症(神经损伤,肾脏疾病和心血管问题)。
GraphRAG 已被证明可以显著提高生成文本的准确性和相关性,使其成为一个有价值的解决方案,用于准确、合理的实时答案。它还因其通过跟踪图中的关系链来处理复杂查询的能力而受到关注,提供了对回答问题所需信息的更为丰富的理解。
GraphRAG 的主要特性如下:
GraphRAG 的这些关键特性展示了它相对于传统 RAG 模型的优势,以及它在各种应用中革新检索增强生成的潜力。
GraphRAG的应用场景非常广泛。下面简要介绍 GraphRAG 的两个用例,以及它们是如何在每个用例中使用的。
GraphRAG 可以帮助医学专业人员从大量的医学文献中快速找到相关信息,以回答关于患者症状、治疗和结果的复杂问题。通过将医学知识表示为一个结构化的知识图谱,GraphRAG 使得多跳推理能够连接不同的信息并提供全面的答案。这可以导致更快和更准确的诊断,更知情的治疗决定,并改善患者的结果。
GraphRAG 可以通过在知识图谱中表示客户交易、账户信息和行为模式来帮助银行检测和防止欺诈。通过分析图谱中的关系和异常,GraphRAG 可以识别可疑活动,并向银行的欺诈检测系统发出警报。这可以导致更快、更准确的欺诈检测,减少财务损失,提高客户对银行安全措施的信任。
GraphRAG 首先从输入文档中提取实体和关系,生成知识图谱,然后通过图算法检测社区结构。接下来,使用 LLM 为每个社区生成自然语言摘要,保留分层结构。在用户查询时,系统先进行局部检索匹配高级主题,再进行全局检索获取详细信息,最后由 LLM 生成准确相关的响应。GraphRAG 的局部搜索针对特定上下文提供针对性信息,而全局搜索则利用预先计算的社区摘要,回答跨多个文档的综合查询。
其中,GraphRAG 中的局部搜索是指从特定实体或文本块的局部上下文中检索和使用信息。这涉及到使用知识图谱结构来查找直接连接到当前查询或上下文的相关实体、关系和文本单元。局部搜索允许系统检索有针对性的相关信息,以增强语言模型对特定的本地化查询的响应。
GraphRAG 中的全局搜索是指利用知识图的更广泛的层次结构对整个数据集进行推理。这涉及到使用检测到的“社区”或图中相关实体和文本单元的集群来生成完整数据集中关键主题和主题的摘要和概述。全局搜索使系统能够回答需要跨多个文档或实体聚合信息的查询,例如“文档中最重要的5个主题是什么?” 通过利用预先计算的社区摘要,全局搜索可以提供全面的响应,而无需为每个查询从头开始搜索整个数据集。
构建全面而精确的知识图谱不是一个简单的过程,其质量和覆盖率严重依赖于输入数据源,随着知识图谱的增长,计算资源的需求也会增加,对实时应用构成挑战。
有很多种方法可以实现GraphRAG,例如, 采用微软开源的GraphRAG 解决方案。为了简化问题, 这里给出了两种参考实现的示例。
首先需要 pip 安装一些必要的库:
pip install --upgrade --quiet json-repair networkx langchain-core langchain-google-vertexai langchain-experimental langchain-community
#versions used
langchain==0.2.8
langchain-community==0.2.7
langchain-core==0.2.19
langchain-experimental==0.0.62
langchain-google-vertexai==1.0.3
当然,可以自己选择不同的大模型来替换 google 的 verexai。
然后,导入所需的函数,初始化 LLM 对象和引用文本。使用任何 SOTA LLM 获得最佳结果,因为创建知识图谱是一项复杂的任务。
import os
from langchain_experimental.graph_transformers import LLMGraphTransformer
from langchain_google_vertexai import VertexAI
import networkx as nx
from langchain.chains import GraphQAChain
from langchain_core.documents import Document
from langchain_community.graphs.networkx_graph import NetworkxEntityGraph
llm = VertexAI(max_output_tokens=4000,model_name='text-bison-32k')
text = """
your content in details.
"""
接下来,我们需要将该文本作为 GraphDocument 加载,并创建 LLMTransformer 对象。
documents = [Document(page_content=text)]
llm_transformer = LLMGraphTransformer(llm=llm)
graph_documents = llm_transformer.convert_to_graph_documents(documents)
创建知识图谱的时候,最好提供一个要提取的实体和关系列表,否则LLM可能会将所有内容标识为实体或关系。
llm_transformer_filtered = LLMGraphTransformer(
llm=llm,
allowed_nodes=["Person", "Country", "Organization"],
allowed_relationships=["NATIONALITY", "LOCATED_IN", "WORKED_AT", "SPOUSE"],
)
graph_documents_filtered = llm_transformer_filtered.convert_to_graph_documents(
documents
)
我们可以使用 Networkx Graph 工具包将上面标识的节点和边进行可视化,当然生产环境中一般会存入图数据库。
graph = NetworkxEntityGraph()
# 增加节点
for node in graph_documents_filtered[0].nodes:
graph.add_node(node.id)
# 增加边
for edge in graph_documents_filtered[0].relationships:
graph._graph.add_edge(
edge.source.id,
edge.target.id,
relation=edge.type,
)
现在,我们可以创建一个 GraphQAChain,它将帮助我们与知识库进行交互。
chain = GraphQAChain.from_llm(
llm=llm,
graph=graph,
verbose=True
)
最后,就可以使用Query 调用 chain 的对象了。
question = """my question xxxx"""
chain.run(question)
在 LangChain 使用 GraphIndexCreator,它与上述方法非常相似。
from langchain.indexes import GraphIndexCreator
from langchain.chains import GraphQAChain
index_creator = GraphIndexCreator(llm=llm)
with open("/home/abel/sample.txt") as f:
all_text = f.read()
text = "\n".join(all_text.split("\n\n"))
graph = index_creator.from_text(text)
chain = GraphQAChain.from_llm(llm, graph=graph, verbose=True)
chain.run("my question xxxx ?")
两种方法都很容易实现。这些示例使用非常小的数据集。如果您使用大型数据集,知识图谱的创建可能会导致大量token 成本。
特殊地,使用知识图谱作为 RAG 的检索部分有三种方法:
总之,有很多方法可以将矢量数据库和知识图谱结合起来用于搜索、相似性和 RAG。
GraphRAG 代表了检索增强生成领域的一项重要进步。通过利用知识图谱的力量,GraphRAG克服了传统RAG模型的局限性,为复杂查询提供更准确、相关和全面的响应。
在GraphRAG中,结构化的知识表示使系统能够理解不同信息片段之间的语义上下文和关系,从而轻松处理复杂的多主题查询。此外,GraphRAG的高效处理能力使其成为实际应用程序中的实用解决方案,特别是在速度和准确性至关重要的场景中。
GraphRAG已在各个领域被证明是有效的,包括医疗保健和银行业,能够提供有价值的见解并支持决策过程。其不断学习和扩展知识的能力,使其成为一个多功能工具,能够适应新的信息和不断变化的领域。