赞
踩
在当今信息爆炸的时代,人工智能(AI)正迅速成为处理和理解海量数据的中坚力量。作为AI领域的关键技术之一,大型语言模型(LLM)在自然语言处理(NLP)方面取得了显著成就。然而,面对复杂和多样化的私有数据集,如何提升LLM的理解和推理能力,成为了技术发展的一个重要课题。
2024年7月2日,微软开源了GraphRAG技术,这一举措不仅为AI领域带来了创新的解决方案,也为开发者社区注入了新的活力。GraphRAG,即基于图的检索增强生成(Graph-based Retrieval-Augmented Generation),是一种革命性的技术,它通过结合知识图谱和图机器学习,显著提升了LLM在处理私有数据时的性能。
GraphRAG的开源,是微软对AI技术共享精神的又一次体现。它不仅推动了技术的创新和普及,也为全球的开发者和研究者提供了一个探索和实验的新平台。随着GraphRAG技术的不断发展和完善,我们有理由相信它将在智能问答、数据摘要、知识推理等多个领域发挥重要作用。
GraphRAG代表了一种技术革新,它通过结合检索增强生成(RAG)技术和知识图谱,为大模型提供了一种全新的数据理解和生成能力。与传统的RAG技术相比,GraphRAG通过构建基于图的数据结构,使得模型能够更深入地挖掘数据间的复杂关系和交互,从而在问答、摘要和推理任务中表现出更优的性能。
GraphRAG技术的核心在于其能够将非结构化的文本数据转换为结构化的图谱形式。在这个过程中,文本中的每个实体和概念都被视为图中的节点,而它们之间的关系则构成了节点之间的边。这种方法不仅增强了模型对数据的理解能力,也为模型提供了更丰富的信息检索和推理路径。
微软开源GraphRAG的决定对整个AI社区产生了深远的影响。开源意味着技术的透明度和可访问性的提升,它鼓励全球的开发者和研究者共同参与到技术的发展和完善中来。此外,开源还促进了技术的快速迭代和创新,为AI领域带来了更多的合作机会和应用场景。
自GraphRAG开源以来,它已经迅速获得了技术社区的广泛关注和积极响应。开发者们对这项技术表现出了浓厚的兴趣,他们在GitHub上积极地star和fork项目,参与到讨论和贡献中。GraphRAG的开源地址已成为了一个充满活力的交流平台,汇聚了来自世界各地的开发者的智慧和创意。
GraphRAG的架构是一个多层次、模块化的设计,主要包括以下几个关键部分:
知识图谱的构建是GraphRAG技术的核心。这一过程涉及以下几个步骤:
在知识图谱构建完成后,GraphRAG进一步执行以下操作:
GraphRAG的功能特性是其技术创新的具体体现,主要包括以下几个方面:
GraphRAG的技术优势是其在多个方面超越传统技术的体现:
GraphRAG的应用潜力巨大,它不仅可以作为独立的问答系统,还可以集成到现有的AI平台中,提升其数据处理和分析能力。以下是GraphRAG应用潜力的几个方面:
GraphRAG技术在私有数据分析方面展现出了巨大潜力。企业可以利用GraphRAG从内部数据中提取深层洞见,这些数据可能包括客户互动记录、市场研究报告、产品使用数据等。GraphRAG能够帮助企业快速识别关键信息,构建知识图谱,并提供决策支持。
在新闻媒体行业,GraphRAG的应用可以极大地提高新闻报道的深度和广度。它能够快速从大量文本中提取关键信息,生成新闻摘要,甚至对事件进行深入分析和报道。
GraphRAG在学术研究中的应用可以加速知识的发现和传播。研究人员可以利用GraphRAG来分析文献,识别研究趋势,甚至发现新的研究方向。
在医疗健康领域,GraphRAG可以帮助整合和分析病历记录、医学研究和治疗指南,为医生提供诊断支持和个性化治疗建议。
GraphRAG在教育领域的应用可以提供个性化的学习体验。通过分析学生的学习历史和偏好,GraphRAG能够推荐适合的学习材料和课程。
微软官方提供了详尽的GraphRAG文档和GitHub仓库,这是学习GraphRAG的首要资源。在这里,你可以找到安装指南、快速入门教程、API文档以及贡献指南。
# 受 MIT 许可证许可。
import os
import pandas as pd
import tiktoken
# 从 graphrag 包中导入所需的模块和类
from graphrag.query.context_builder.entity_extraction import EntityVectorStoreKey
from graphrag.query.indexer_adapters import (
read_indexer_covariates,
read_indexer_entities,
read_indexer_relationships,
read_indexer_reports,
read_indexer_text_units,
)
from graphrag.query.input.loaders.dfs import (
store_entity_semantic_embeddings,
)
from graphrag.query.llm.oai.chat_openai import ChatOpenAI
from graphrag.query.llm.oai.embedding import OpenAIEmbedding
from graphrag.query.llm.oai.typing import OpenaiApiType
from graphrag.query.question_gen.local_gen import LocalQuestionGen
from graphrag.query.structured_search.local_search.mixed_context import (
LocalSearchMixedContext,
)
from graphrag.query.structured_search.local_search.search import LocalSearch
from graphrag.vector_stores.lancedb import LanceDBVectorStore
# 本地搜索示例
# 本地搜索方法通过结合AI提取的知识图谱中的相关数据与原始文档的文本块来生成答案。
# 这种方法适用于需要理解文档中提到的特定实体的问题(例如,甘菊的治愈属性是什么?)。
# 加载文本单元和图数据表作为本地搜索的上下文
# 在此测试中,我们首先将parquet文件中的索引输出加载到数据框中,然后将这些数据框转换为与知识模型对齐的数据对象集合。
# 输入目录和Lancedb的URI
INPUT_DIR = "./inputs/operation dulce"
LANCEDB_URI = f"{INPUT_DIR}/lancedb"
# 定义数据表名称
COMMUNITY_REPORT_TABLE = "create_final_community_reports"
ENTITY_TABLE = "create_final_nodes"
ENTITY_EMBEDDING_TABLE = "create_final_entities"
RELATIONSHIP_TABLE = "create_final_relationships"
COVARIATE_TABLE = "create_final_covariates"
TEXT_UNIT_TABLE = "create_final_text_units"
COMMUNITY_LEVEL = 2
# 读取实体
# 读取节点表以获取社区和度数数据
entity_df = pd.read_parquet(f"{INPUT_DIR}/{ENTITY_TABLE}.parquet")
entity_embedding_df = pd.read_parquet(f"{INPUT_DIR}/{ENTITY_EMBEDDING_TABLE}.parquet")
entities = read_indexer_entities(entity_df, entity_embedding_df, COMMUNITY_LEVEL)
# 加载描述嵌入到内存中的lancedb向量存储中
# 要连接到远程数据库,请指定url和端口值。
description_embedding_store = LanceDBVectorStore(
collection_name="entity_description_embeddings",
)
description_embedding_store.connect(db_uri=LANCEDB_URI)
entity_description_embeddings = store_entity_semantic_embeddings(
entities=entities, vectorstore=description_embedding_store
)
print(f"实体数量: {len(entity_df)}")
entity_df.head()
# 读取关系
relationship_df = pd.read_parquet(f"{INPUT_DIR}/{RELATIONSHIP_TABLE}.parquet")
relationships = read_indexer_relationships(relationship_df)
print(f"关系数量: {len(relationship_df)}")
relationship_df.head()
covariate_df = pd.read_parquet(f"{INPUT_DIR}/{COVARIATE_TABLE}.parquet")
claims = read_indexer_covariates(covariate_df)
print(f"声明记录数: {len(claims)}")
covariates = {"claims": claims}
# 读取社区报告
report_df = pd.read_parquet(f"{INPUT_DIR}/{COMMUNITY_REPORT_TABLE}.parquet")
reports = read_indexer_reports(report_df, entity_df, COMMUNITY_LEVEL)
print(f"报告记录数: {len(report_df)}")
report_df.head()
# 读取文本单元
text_unit_df = pd.read_parquet(f"{INPUT_DIR}/{TEXT_UNIT_TABLE}.parquet")
text_units = read_indexer_text_units(text_unit_df)
print(f"文本单元记录数: {len(text_unit_df)}")
text_unit_df.head()
# 从环境变量中获取API密钥、LLM模型和嵌入模型
api_key = os.environ["GRAPHRAG_API_KEY"]
llm_model = os.environ["GRAPHRAG_LLM_MODEL"]
embedding_model = os.environ["GRAPHRAG_EMBEDDING_MODEL"]
# 初始化ChatOpenAI实例
llm = ChatOpenAI(
api_key=api_key,
model=llm_model,
api_type=OpenaiApiType.OpenAI, # OpenaiApiType.OpenAI 或 OpenaiApiType.AzureOpenAI
max_retries=20,
)
# 初始化文本编码器
token_encoder = tiktoken.get_encoding("cl100k_base")
# 初始化OpenAIEmbedding实例
text_embedder = OpenAIEmbedding(
api_key=api_key,
api_base=None,
api_type=OpenaiApiType.OpenAI,
model=embedding_model,
deployment_name=embedding_model,
max_retries=20,
)
# 创建本地搜索上下文构建器
context_builder = LocalSearchMixedContext(
community_reports=reports,
text_units=text_units,
entities=entities,
relationships=relationships,
covariates=covariates,
entity_text_embeddings=description_embedding_store,
embedding_vectorstore_key=EntityVectorStoreKey.ID, # 如果向量存储使用实体标题作为ID,则将其设置为EntityVectorStoreKey.TITLE
text_embedder=text_embedder,
token_encoder=token_encoder,
)
# 创建本地搜索引擎
# text_unit_prop: 专用于相关文本单元的上下文窗口比例
# community_prop: 专用于社区报告的上下文窗口比例。
# 其余比例专用于实体和关系。text_unit_prop 和 community_prop 的总和应 <= 1
# conversation_history_max_turns: 要包含在对话历史中的最多轮次数。
# conversation_history_user_turns_only: 如果为True,则只包含用户查询在对话历史中。
# top_k_mapped_entities: 从实体描述嵌入存储中检索的相关实体数量。
# top_k_relationships: 控制要拉入上下文窗口的网络外关系的数量。
# include_entity_rank: 如果为True,则在上下文窗口中包含实体表中的实体排名。默认实体排名 = 节点度数。
# include_relationship_weight: 如果为True,则在上下文窗口中包含关系权重。
# include_community_rank: 如果为True,则在上下文窗口中包含社区排名。
# return_candidate_context: 如果为True,则返回一组包含所有候选实体/关系/协变量记录的数据框,
# 这些记录可能相关。注意,并非所有这些记录都会被包含在上下文窗口中。这些数据框中的"in_context"列指示记录是否包含在上下文窗口中。
# max_tokens: 上下文窗口使用的最大令牌数。
local_context_params = {
"text_unit_prop": 0.5,
"community_prop": 0.1,
"conversation_history_max_turns": 5,
"conversation_history_user_turns_only": True,
"top_k_mapped_entities": 10,
"top_k_relationships": 10,
"include_entity_rank": True,
"include_relationship_weight": True,
"include_community_rank": False,
"return_candidate_context": False,
"embedding_vectorstore_key": EntityVectorStoreKey.ID, # 如果向量存储使用实体标题作为ID,则将其设置为EntityVectorStoreKey.TITLE
"max_tokens": 12_000, # 根据您在模型上的令牌限制更改此值(如果您使用的是8k限制的模型,一个良好的设置可能是5000)
}
llm_params = {
"max_tokens": 2_000, # 根据您在模型上的令牌限制更改此值(如果您使用的是8k限制的模型,一个良好的设置可能是1000-1500)
"temperature": 0.0,
}
search_engine = LocalSearch(
llm=llm,
context_builder=context_builder,
token_encoder=token_encoder,
llm_params=llm_params,
context_builder_params=local_context_params,
response_type="多段文本", # 描述响应类型和格式的自由形式文本,可以是任何内容,例如优先级列表、单段文本、多段文本、多页报告
)
# 在示例查询上运行本地搜索
result = await search_engine.asearch("告诉我关于Agent Mercer的信息")
print(result.response)
question = "告诉我关于Dr. Jordan Hayes的信息"
result = await search_engine.asearch(question)
print(result.response)
# 检查用于生成响应的上下文数据
result.context_data["entities"].head()
result.context_data["relationships"].head()
result.context_data["reports"].head()
result.context_data["sources"].head()
if "claims" in result.context_data:
print(result.context_data["claims"].head())
# 问题生成
# 下面的部分是问题生成功能的实现,它接收用户查询列表并生成下一个候选问题。
# LocalQuestionGen 类负责生成问题,它使用与搜索相同的底层模型和上下文构建器。
question_generator = LocalQuestionGen(
llm=llm,
context_builder=context_builder,
token_encoder=token_encoder,
llm_params=llm_params,
context_builder_params=local_context_params, # 这里缺少了参数的定义,应从前面代码中获取
)
# 定义一个用户查询的历史列表
question_history = [
"告诉我关于Agent Mercer的信息",
"Dulce军事基地发生了什么?",
]
# 使用问题生成器来生成候选问题
# agenerate 方法接收问题历史、上下文数据和所需生成的问题数量
candidate_questions = await question_generator.agenerate(
question_history=question_history,
context_data=None, # 这里传入None,实际使用时可以传入相关上下文数据
question_count=5
)
# 打印生成的候选问题
print(candidate_questions.response)
随着人工智能技术的不断进步,GraphRAG的未来充满了无限可能。以下是一些可能的发展方向:
未来GraphRAG可能会集成多模态数据处理能力,结合文本、图像、声音等多种数据类型,提供更丰富的信息分析和生成能力。
GraphRAG在个性化服务方面具有巨大潜力,未来可能会根据用户的行为和偏好提供更加定制化的信息和服务。
GraphRAG可能会进一步发展其跨领域知识融合的能力,连接不同领域的知识图谱,促进跨学科的创新和发现。
随着对模型可解释性需求的增加,GraphRAG的未来发展可能会更加注重其决策过程的透明度和可解释性。
GraphRAG作为微软开源的一项重要技术成果,已经在AI领域引起了广泛关注。它不仅为开发者和企业提供了新的工具和思路,也为AI技术的发展开辟了新的道路。本文通过介绍GraphRAG的技术原理、应用场景以及学习资源,希望能够激发读者对这项技术的兴趣,并鼓励大家参与到GraphRAG的学习和实践中来。
随着技术的不断发展,我们期待GraphRAG能够在未来发挥更大的作用,推动人工智能技术的进一步发展。让我们一起期待并见证GraphRAG在未来AI领域的无限可能。
为了帮助大家进一步探索GraphRAG技术,以下是一些有用的参考资料和链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。