400 128 6709

行业新闻

知识图谱检索增强的GraphRAG(基于Neo4j代码实现)

发布时间:2024-06-03点击次数:

图检索增强生成(graph rag)正逐渐流行起来,成为传统向量搜索方法的有力补充。这种方法利用图数据库的结构化特性,将数据以节点和关系的形式组织起来,从而增强检索信息的深度和上下文关联性。图在表示和存储多样化且相互关联的信息方面具有天然优势,能够轻松捕捉不同数据类型间的复杂关系和属性。而向量数据库则处理这类结构化信息时则显得力不从心,它们更专注于处理高维向量表示的非结构化数据。在 rag 应用中,结合结构化化的图数据和非结构化的文本向量搜索,可以让我们同时享受两者的优势,这也是本文将要探讨的内容。

构建知识图谱通常是利用图数据表示的强大功能中最困难的一步。它需要收集和整理数据,这需要对领域知识和图建模有深刻的理解。为了简化这一过程,可以参考已有的项目或者利用LLM来创建知识图谱,进而可以把重点放在检索召回上,以提高LLM的生成阶段。下面来进行相关代码的实践。

1.知识图谱构建

为了存储知识图谱数据,首先需要搭建一个 Neo4j 实例。最简单的方法是在 Neo4j Aura 上启动一个免费实例,它提供了 Neo4j 数据库的云版本。当然,也可以通过 Docker 本地启动一个,然后将图谱数据导入到 Neo4j 数据库中。

步骤I:Neo4j环境搭建

下面是本地启动docker的运行示例:

docker run -d \--restart always \--publish=7474:7474 --publish=7687:7687 \--env NEO4J_AUTH=neo4j/000000 \--volume=/yourdockerVolume/neo4j:/data \neo4j:5.19.0

步骤II:图谱数据导入

演示中,我们可以使用伊丽莎白一世的维基百科页面。利用 LangChain 加载器从维基百科获取并分割文档,后存入Neo4j数据库。为了试验中文上的效果,我们导入这个Github上的这个项目(QASystemOnMedicalKG)中的医学知识图谱,包含近35000个节点,30万组三元组,大致得到如下结果:

灵感PPT 灵感PPT

AI灵感PPT - 免费一键PPT生成工具

灵感PPT 308 查看详情 灵感PPT

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

知识图谱检索增强的GraphRAG(基于Neo4j代码实现)图片

或者利用LangChainLangChain 加载器从维基百科获取并分割文档,大致如下面步骤所示:

# 读取维基百科文章raw_documents = WikipediaLoader(query="Elizabeth I").load()# 定义分块策略text_splitter = TokenTextSplitter(chunk_size=512, chunk_overlap=24)documents = text_splitter.split_documents(raw_documents[:3])llm=ChatOpenAI(temperature=0, model_name="gpt-4-0125-preview")llm_transformer = LLMGraphTransformer(llm=llm)# 提取图数据graph_documents = llm_transformer.convert_to_graph_documents(documents)# 存储到 neo4jgraph.add_graph_documents(graph_documents, baseEntityLabel=True, include_source=True)

2.知识图谱检索

在对知识图谱检索之前,需要对实体和相关属性进行向量嵌入并存储到Neo4j数据库中:

  • 实体信息向量嵌入:将实体名称和实体的描述信息拼接后,利用向量表征模型进行向量嵌入(如下述示例代码中的add_embeddings方法所示)。
  • 图谱结构化检索:图谱的结构化检索分为四个步骤:步骤一,从图谱中检索与查询相关的实体;步骤二,从全局索引中检索得到实体的标签;步骤三,根据实体标签在相应的节点中查询邻居节点路径;步骤四,对关系进行筛选,保持多样性(整个检索过程如下述示例代码中的structured_retriever方法所示)。
class GraphRag(object):def __init__(self):"""Any embedding function implementing `langchain.embeddings.base.Embeddings` interface."""self._database = 'neo4j'self.label = 'Med'self._driver = neo4j.GraphDatabase.driver(uri=os.environ["NEO4J_URI"],auth=(os.environ["NEO4J_USERNAME"],os.environ["NEO4J_PASSWORD"]))self.embeddings_zh = HuggingFaceEmbeddings(model_name=os.environ["EMBEDDING_MODEL"])self.vectstore = Neo4jVector(embedding=self.embeddings_zh, username=os.environ["NEO4J_USERNAME"], password=os.environ["NEO4J_PASSWORD"], url=os.environ["NEO4J_URI"], node_label=self.label, index_name="vector" )def query(self, query: str, params: dict = {}) -> List[Dict[str, Any]]:"""Query Neo4j database."""from neo4j.exceptions import CypherSyntaxErrorwith self._driver.session(database=self._database) as session:try:data = session.run(query, params)return [r.data() for r in data]except CypherSyntaxError as e:raise ValueError(f"Generated Cypher Statement is not valid\n{e}")def add_embeddings(self):"""Add embeddings to Neo4j database."""# 查询图中所有节点,并且根据节点的描述和名字生成embedding,添加到该节点上query = """MATCH (n) WHERE not (n:{}) RETURN ID(n) AS id, labels(n) as labels, n""".format(self.label)print("qurey node...")data = self.query(query)ids, texts, embeddings, metas = [], [], [], []for row in tqdm(data,desc="parsing node"):ids.append(row['id'])text = row['n'].get('name','') + row['n'].get('desc','')texts.append(text)metas.append({"label": row['labels'], "context": text})self.embeddings_zh.multi_process = Falseprint("node embeddings...")embeddings = self.embeddings_zh.embed_documents(texts)print("adding node embeddings...")ids_ret = self.vectstore.add_embeddings(ids=ids,texts=texts,embeddings=embeddings,metadatas=metas)return ids_ret# Fulltext index querydef structured_retriever(self, query, limit=3, simlarity=0.9) -> str:"""Collects the neighborhood of entities mentioned in the question"""# step1 从图谱中检索与查询相关的实体。docs_with_score = self.vectstore.similarity_search_with_score(query, k=topk)entities = [item[0].page_content for item in data if item[1] > simlarity] # scoreself.vectstore.query("CREATE FULLTEXT INDEX entity IF NOT EXISTS FOR (e:Med) ON EACH [e.context]")result = ""for entity in entities:qry = entity# step2 从全局索引中查出entity label,query1 =f"""CALL db.index.fulltext.queryNodes('entity', '{qry}') YIELD node, score return node.label as label,node.context as context, node.id as id, score LIMIT {limit}"""data1 = self.vectstore.query(query1)# step3 根据label在相应的节点中查询邻居节点路径for item in data1:node_type = item['label']node_type = item['label'] if type(node_type) == str else node_type[0]node_id = item['id']query2 = f"""match (node:{node_type})-[r]-(neighbor) where ID(node) = {node_id} RETURN type(r) as rel, node.name+' - '+type(r)+' - '+neighbor.name as output limit 50"""data2 = self.vectstore.query(query2)# step4 为了保持多样性,对关系进行筛选rel_dict = defaultdict(list)if len(data2) > 3*limit:for item1 in data2:rel_dict[item1['rel']].append(item1['output'])if rel_dict:rel_dict = {k:random.sample(v, 3) if len(v)>3 else v for k,v in rel_dict.items()}result += "\n".join(['\n'.join(el) for el in rel_dict.values()]) +'\n'else:result += "\n".join([el['output'] for el in data2]) +'\n'return result

3.结合LLM生成

最后利用大语言模型(LLM)根据从知识图谱中检索出来的结构化信息,生成最终的回复。下面的代码中我们以通义千问开源的大语言模型为例:

步骤I:加载LLM模型

from langchain import HuggingFacePipelinefrom transformers import pipeline, AutoTokenizer, AutoModelForCausalLMdef custom_model(model_name, branch_name=None, cache_dir=None, temperature=0, top_p=1, max_new_tokens=512, stream=False):tokenizer = AutoTokenizer.from_pretrained(model_name, revision=branch_name, cache_dir=cache_dir)model = AutoModelForCausalLM.from_pretrained(model_name,device_map='auto',torch_dtype=torch.float16,revision=branch_name,cache_dir=cache_dir)pipe = pipeline("text-generation",model = model,tokenizer = tokenizer,torch_dtype = torch.bfloat16,device_map = 'auto',max_new_tokens = max_new_tokens,do_sample = True)llm = HuggingFacePipeline(pipeline = pipe,model_kwargs = {"temperature":temperature, "top_p":top_p,"tokenizer":tokenizer, "model":model})return llmtongyi_model = "Qwen1.5-7B-Chat"llm_model = custom_model(model_name=tongyi_model)tokenizer = llm_model.model_kwargs['tokenizer']model = llm_model.model_kwargs['model']

步骤II:输入检索数据生成回复

final_data = self.get_retrieval_data(query)prompt = ("请结合以下信息,简洁和专业的来回答用户的问题,若信息与问题关联紧密,请尽量参考已知信息。\n""已知相关信息:\n{context} 请回答以下问题:{question}".format(cnotallow=final_data, questinotallow=query))messages = [{"role": "system", "content": "你是**开发的智能助手。"},{"role": "user", "content": prompt}]text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)model_inputs = tokenizer([text], return_tensors="pt").to(self.device)generated_ids = model.generate(model_inputs.input_ids,max_new_tokens=512)generated_ids = [output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)]response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]print(response)

4 结语

对一个查询问题分别进行了测试, 与没有RAG仅利用LLM生成回复的的情况进行对比,在有GraphRAG 的情况下,LLM模型回答的信息量更大、准确会更高。

以上就是知识图谱检索增强的GraphRAG(基于Neo4j代码实现)的详细内容,更多请关注其它相关文章!


# llm  # 才华横溢  # 土默特右旗建设网站  # 闵行交大附近网站建设  # 营销推广策略包括哪些内容  # 南宁关键词推广优化排名  # 抚顺市SEO排名  # seo学习视频资源贴吧  # qq营销推广怎么赚钱  # 雪儿漫画网站建设游戏  # 如何优化不正规网站  # 安徽网站建设方案开发  # 小红  # 伊丽莎白  # 数据库中  # 胡言乱语  # 加载  # 维基百科  # 所示  # 开源  # 结构化  # type  # langchain  # qwen  # 通义千问  # docker  # git  # graphrag  # rag 


相关栏目: 【 行业新闻62819 】 【 科技资讯67470


相关推荐: 国产医疗企业的人工智能  13万个注释神经元,5300万个突触,普林斯顿大学等发布首个完整「成年果蝇」大脑连接组  机智云AI离线语音识别模组,让家电变得更加智能便捷  智能客服进入AI 2.0时代 容联云发布语言大模型“赤兔”  小米发布CyberDog2 - 他们的第二代仿生四足机器人展示  首届亚太网络法实务大会召开 九位大咖探讨元宇宙与人工智能发展  Databricks推出人工智能模型共享机制,可令开发者与公司“双赢”  能走、能飞、能游泳,科学家打造全能 M4 机器人  微软 Azure AI 文本转语音服务升级:新增男性声音和扩展语言支持  百亿量化私募:量化投资进入“精耕细作”时代 AI带来行业新变革  软通动力多项AI创新产品及应用亮相2025世界人工智能大会  重磅! 捷通华声灵云AICC荣获第二届光合组织AI解决方案大赛二等奖  微幼科技晨检机器人与人工晨检相比,有何优势  出门问问亮相2025世界人工智能大会,展示AI CoPilot解决方案  AI连线 | 专访风平智能CEO林洪祥:让AI数字人拥有漂亮的外表和有趣的灵魂,安全问题是重要考量  无人机巡检方案是什么,该如何选择适合的巡检方案  谷歌推出 AI 反洗钱工具,可将金融机构内部风险预警准确率提高2至4倍  争鸣:OpenAI奥特曼、Hinton、杨立昆的AI观点到底有何不同?  国内通用人形机器人将发布、产业加速突破  马斯克嘲讽人工智能:机器学习本质就是统计学  Goodnotes 6推出,带来多项全新AI功能,让电子笔记更智能  中国电信AI能力通过国家级金融领域权威认证并荣膺AI国际头部竞赛冠军  网友自制 AI 版《流浪地球 3》预告片,登上 CCTV6  陈丹琦ACL学术报告来了!详解大模型「*」数据库7大方向3大挑战,3小时干货满满  网易易盾 AI Lab 论文入选 ICASSP 2025!黑科技让语音识别越“听”越准  智能机器人与话剧的完美结合:宇树四足机器人B1助力《骆驼祥子》重现经典  沐曦首款AI推理GPU亮相:INT8算力达160TOPS!  OpenAI CEO 山姆・阿尔特曼呼吁 AI 领域中美应当合作  李开复官宣新公司「零一万物」,进军 AI 2.0  1.6亿美元收购Singularity AI,昆仑万维布局通用人工智能  吴恩达、Hinton最新对话!AI不是随机鹦鹉,共识胜过一切,LeCun双手赞成  AI大模型,将为智慧城市带来哪些新变化?  IBM与NASA联手开源地理空间AI基础模型,促进气候科学领域进步  多家欧洲企业签署公开信,批评欧盟 AI 法案草案限制产业发展  人工智能在交通领域的革新:智能解决方案彻底改变交通方式  业内领先 四川大学华西第四医院甲状腺乳腺外科成功进入手术机器人时代  埃森哲俞毅:AI时代我们需要新的“摩尔定律”  五项人工智能尚未能够实现的任务  美图影像节演讲实录:191次提及AI,发布7款影像生产力工具  马斯克反讽人工智能AI炒作:“机器学习”本质就是统计  美图秀秀发布七款 AI 工具:修图一样修视频、打造电影级上镜脸  生成式人工智能来了,如何保护未成年人? | 社会科学报  精准度可提高 20%:英国九家银行签约使用基于 AI 的“消费者欺诈风险系统”应对*  1分钟做出苹果Vision Pro「官网」?上班8小时搞出480个网页,同事被卷疯了  宇宙探索下一阶段,机器代替人类,AI会在太空探索中取代人类吗?  掌阅科技对话式AI应用“阅爱聊”开启内测  联想举办2025创新开放日,展出260余项算力及AI产品技术  Unity 内测 Safe Voice 服务,利用 AI 自动识别玩家不当聊天内容  美图秀秀发布7款AI产品:支持用户创作、商业创作  【澎湃原动力】人工智能产业协同创新中心:全产业链资源在这里汇聚 

400 128 6709
E-mail

contact@tlftec.cn

扫一扫,添加微信

©  云南淘乐房科技有限公司 版权所有  滇ICP备2025071560号  

云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司 云南淘乐房科技有限公司