微软 GraphRAG从构图到检索的核心逻辑与代码实现
01—方法简介GraphRAG的核心贡献是构建了一个基于实体关系的图索引并通过社区划分分层摘要的方式让大模型能从全局视角回答问题。也就是说微软最早提出GraphRAG目的是解决传统RAG在查询聚焦型摘要QFS任务效果差的问题并非简单的信息检索。实现逻辑先把文本拆分成小块从中提取实体、关系和关键声明构建成知识图谱再用社区检测算法把图谱分成一个个紧密关联的实体社区接着为每个社区生成摘要最后针对用户查询汇总多个社区的摘要生成最终的全局答案。02—构图文本分块支持按token数切割TokenChunker和按语义完整的句子切割SentenceChunker依赖 NLTK 的 punkt 模型详细代码见附录实体/关系提取实体关系提取基于LLM实现。提取实体、关系及其描述。在提取时首次调用LLM获取基础提取结果然后还有一个多轮补充提取逻辑询问LLM“是否还有更多实体/关系”如果有则继续提取。代码和提示词见附录实体字段title名称、type类型、description描述、source_id来源关系字段source源、target目标、weight权重、description描述、source_id来源。关于weight的解释在GRAPH_EXTRACTION_PROMPT中relationship_strength对应最终图谱的weight字段是提取关系时必须输出的数值型评分核心要求属于「关系提取步骤」的必填项在提取(source_entity, target_entity)关系对时需同步给出该评分无明确数值范围限制从示例看为整数如 9、5、2但需体现「关系强度差异」评分依据完全基于文本中实体关联的「明确性、紧密性、重要性」例如示例 1 中MARTIN SMITH与CENTRAL INSTITUTION的关系强度为 9核心职位关联极紧密示例 3 中SAMUEL NAMARA与ALHAMIA PRISON的强度为 8直接监禁关系而国家间的斡旋关系强度仅为 2间接关联。weight的核心作用社区聚类的关键依据weight字段是「正确计算 Leiden 社区」的核心 —— GraphRAG 会基于关系的weight对实体进行社区划分层级聚类权重越高的关系越能主导实体的社区归属最终影响社区摘要的生成质量。检索优先级的隐性影响在 Local/DRIFT/Global 检索中高weight的关系会被优先纳入「上下文数据context_data」或「社区报告community_reports」让 LLM 在生成回答时更聚焦核心关联减少无关信息干扰。知识图谱质量评估可通过weight分布判断图谱提取质量若大部分关系权重极低如全为 1-2可能提示提示词未精准引导 LLM 识别核心关联需调优提取提示词如补充「权重评分细则」。实体/关系合并实体合并将从多个文本单元中提取出的实体 DataFrame 列表合并为一个全局实体表核心是按「实体标题实体类型」去重并聚合分散的描述、文本单元关联、出现频次等信息。def _merge_entities(entity_dfs) - pd.DataFrame: # 1. 合并所有文本单元提取出的实体DataFrame忽略行索引 all_entities pd.concat(entity_dfs, ignore_indexTrue) return ( all_entities # 2. 分组依据「title实体名称 type实体类型」—— 这是实体的唯一标识 .groupby([title, type], sortFalse) # 3. 聚合规则对分组内的字段进行合并/统计 .agg( # 将同一实体在不同文本单元中的描述合并为列表 description(description, list), # 将实体关联的所有文本单元ID合并为列表记录实体出现的文本位置 text_unit_ids(source_id, list), # 统计实体出现的文本单元数量即frequency频次 frequency(source_id, count), ) # 4. 重置索引将groupby的分组字段title/type从索引转回普通列 .reset_index() )title type 是实体的核心唯一标识例如“张三Person”和“张三Organization”会被视为两个不同实体聚合字段含义description同一实体在不同文本单元中被提取出的描述会被汇总为列表后续会通过 LLM 总结为单一描述text_unit_ids记录实体出现在哪些文本单元中用于后续溯源和关联frequency实体出现的文本单元数量反映实体的重要性。关系合并将从多个文本单元中提取出的关系 DataFrame 列表合并为一个全局关系表核心是按「源实体目标实体」去重并聚合描述、文本单元关联、关系权重等信息。def _merge_relationships(relationship_dfs) - pd.DataFrame: # 1. 合并所有文本单元提取出的关系DataFrame保留原索引不影响最终聚合 all_relationships pd.concat(relationship_dfs, ignore_indexFalse) return ( all_relationships # 2. 分组依据「source源实体 target目标实体」—— 这是关系的唯一标识 .groupby([source, target], sortFalse) # 3. 聚合规则对分组内的字段进行合并/统计 .agg( # 将同一关系在不同文本单元中的描述合并为列表 description(description, list), # 将关系关联的所有文本单元ID合并为列表 text_unit_ids(source_id, list), # 累加同一关系在不同文本单元中的权重反映关系的强度 weight(weight, sum), ) # 4. 重置索引将groupby的分组字段source/target从索引转回普通列 .reset_index() )source target 是关系的核心唯一标识GraphRAG 中关系为有向边“A→B”和“B→A”会被视为不同关系weight 累加关系的weight由 LLM 在提取阶段给出反映关系的“强度”合并时累加所有文本单元中该关系的权重最终用于社区聚类Leiden 算法声明提取非必须声明提取是从非结构化文本中识别带有事实属性的正向陈述并将其标准化为包含「主体、客体、状态、时间、描述」等字段的结构化数据。核心价值为图谱补充可验证的事实维度如 “某实体对另一实体执行了某行为该行为是否可信”支撑后续推理类查询如欺诈、异常行为识别。整体流程为「文本遍历 → 单文档处理 → 多轮提取 → 结果清洗 → 结构化输出」示例如图03—图社区在 GraphRAG 中“社区Community”是核心概念之一本质是对知识图谱中实体的层次化聚类结果目的是解决传统 RAG 无法高效关联分散信息、难以全局理解数据的问题。社区的定义GraphRAG 中的“社区”是指知识图谱中具有强关联的实体集群这些实体人、地点、组织、事件等因语义/拓扑关联如共享关系、共同出现在文本单元中被归为同一集群社区具有层级结构Hierarchical从顶层的全局社区覆盖整个图谱到底层的局部小社区聚焦特定主题/实体群不同层级对应不同粒度的信息汇总。社区的生成过程社区通过算法自动生成核心步骤如下基础图谱构建先从原始文本TextUnits中提取实体、实体间的关系、关键声明Covariate形成初始知识图谱层级聚类Leiden 算法采用Leiden 层次聚类技术对图谱进行递归聚类直到社区规模达到设定阈值聚类的核心依据是实体间关系的“权重weight”如关系出现的频次、相关性权重是计算社区的关键参数社区层级形成递归聚类后形成“全局社区 → 大社区 → 小社区”的层级结构每个社区对应图谱中一个拓扑紧密的子图。社区的核心作用GraphRAG 围绕“社区”做了两层关键操作最终解决传统 RAG 的核心痛点生成社区报告Community Report对每个社区不同层级进行自下而上的总结提示词见附录报告包含社区内的核心实体、关键关系、核心声明以及该社区的“全局视角摘要”顶层社区报告对应整个数据集的全局总结底层社区报告聚焦局部实体群的细节实现“粗细粒度兼顾”。支撑更智能的检索与推理| 能力维度 | 传统 RAG 问题 | GraphRAG 基于社区的解决方案 || — | — | — || 全局理解 | 无法汇总大规模数据的语义概念 | 顶层社区报告提供数据集全局视角回答“整体主题/趋势”类问题 || 关联分散信息 | 难以跨文档关联实体/关系 | 同社区内的实体被聚类检索时可快速关联“间接相关但拓扑紧密”的信息实现“跨文档连点成线” || 多粒度检索 | 仅能返回文本片段粒度固定 | 不同层级社区对应不同粒度的摘要支持 全局搜索用顶层社区 局部搜索用底层社区 DRIFT 搜索融合社区上下文 |图聚类对提取出的实体 - 关系图进行层级社区聚类Hierarchical Community Detection输入由实体节点和关系边构成的无向图nx.Graph处理通过 Leiden 算法递归聚类生成多层级的社区结构小社区→大社区的层级关系输出各层级的社区列表包含层级、社区 ID、父社区 ID、社区内节点列表。该模块的输出会用于生成各层级社区的摘要GraphRAG 分层理解数据的基础支撑检索时的「分层召回」先找大社区再钻取小社区优化图的拓扑结构提升 RAG 推理的精准性。社区检测算法LeidenLeiden 算法是 2018 年由 Traag 等人提出的层次化社区检测算法核心目标是在图中找到紧密连接的节点集合社区并最大化「模块度Modularity」衡量社区内边密度 vs 社区间边密度的核心指标。Leiden 算法分为 3 个迭代步骤GraphRAG 中hierarchical_leiden函数封装了这一逻辑适配「实体-关系图」的聚类需求步骤 1局部移动Local Moving为每个节点找到「模块度增益最大」的社区包括新建社区。以实体为节点、关系权重weight字段为边权重计算每个实体加入/离开社区的模块度变化优先将实体划入增益最大的社区。步骤 2社区细化Refinement拆分「异质化」社区提升社区内节点的连接紧密性。 针对实体图中「弱关联实体」如低权重关系连接的实体拆分出子社区保证社区内实体的语义/拓扑关联性。步骤 3社区聚合Aggregation将每个社区压缩为单个「超级节点」构建新的聚合图重复步骤 1-2形成层次化社区结构。GraphRAG 中关系的weight字段会参与 Leiden 算法的模块度计算高权重关系强关联实体会提升模块度增益使实体更易划入同一社区低权重关系弱关联则降低增益避免无关实体聚簇。04—图检索GraphRAG 的图检索过程核心是基于预构建的实体-关系图、社区层级结构结合不同检索模式Global/Local/DRIFT匹配 Query 语义并从图结构中提取关联信息补充到 LLM 上下文。以下结合cluster_graph.py生成的社区结构拆解完整的图检索流程检索前的核心依赖来自cluster_graph.py的输出cluster_graph.py输出的Communities层级社区是检索的核心基础每个社区包含level层级、cluster_id社区ID、parent_id父社区、nodes关联实体ID这些社区信息会被持久化到communities.parquet并生成community_reports.parquet社区摘要成为检索的核心数据源。图数据的加载检索阶段会从entities.parquet/relationships.parquet/communities.parquet加载图数据组装为KnowledgeModel类提供图检索的内存数据结构图检索的核心流程GraphRAG 针对不同 Query 类型设计了 3 种核心图检索模式均围绕「图结构社区摘要」展开1. 全局检索Global Search面向宏观/整体类 Query适用于「数据集的核心主题」「主要人物的共同特征」等需要聚合全量信息的 Query核心是基于社区摘要的分层聚合检索Step 1Query 语义匹配无需直接遍历图节点而是基于 Query 语义从community_reports.parquet中筛选不同层级level的社区摘要底层细粒度、上层粗粒度Step 2多批次社区摘要采样将社区摘要随机分批次输入 LLM生成「中间响应」Rated Intermediate ResponseStep 3聚合与排序对多批次中间响应聚合、排序最终生成全局答案图依赖cluster_graph.py生成的层级社区level决定了摘要的粒度层级越低摘要越细响应越精准但耗时越长。2. 局部检索Local Search面向实体/关系类 Query适用于「Scrooge 是谁他的核心关系」「XX 实体的属性」等聚焦具体实体的 Query核心是基于图拓扑的实体扩散检索Step 1实体抽取解析 Query通过「实体描述嵌入Entity Description Embedding」匹配entities.parquet中的实体图节点Step 2图拓扑扩散核心图检索逻辑以目标实体为起点从图中提取关联信息均来自预构建的实体-关系图实体-文本块映射提取实体关联的text_units原始文本片段实体-社区映射提取实体所属的社区摘要community_reports实体-关系扩散提取实体的邻居节点关联实体、边关系、声明CovariatesStep 3筛选与排序对扩散得到的候选实体/关系/文本块/社区摘要按「相关性权重」排序筛选 Top-KStep 4LLM 上下文组装将筛选后的图结构信息实体、关系、社区摘要补充到 LLM 上下文生成答案图依赖cluster_graph.py生成的entity_ids社区关联实体是「实体-社区映射」的核心依据。3. DRIFT 检索Local Global 融合模式适用于需要「实体细节全局上下文」的 Query如「Scrooge 的关系对整个故事的主题有何影响」核心是局部实体扩散 全局社区信息补充Step 1局部实体扩散先执行 Local Search 的「实体抽取图拓扑扩散」获取目标实体的关联信息Step 2全局社区信息补充从目标实体所属的社区cluster_graph.py生成的cluster_id及父社区parent_id中提取摘要补充全局上下文Step 3多轮细化 Query结合社区信息将原始 Query 拆解为更细的子问题遍历图结构获取答案后聚合图依赖cluster_graph.py生成的parent_mapping父子社区映射是「全局社区补充」的核心实现从实体到上层社区的跨层级检索。05—图存储图操作工具networkx是 Python 中用于创建、操作和分析复杂网络图的核心库 MS-GraphRAG 中所有与图结构相关的计算如社区检测都基于它完成。数据载体GraphRAG 提取的实体节点、关系边会被构建成nx.Graph无向图/nx.DiGraph有向图对象networkx提供图的存储、节点/边的增删查改能力社区聚类支撑hierarchical_leiden分层 Leiden 算法、stable_largest_connected_component最大连通子图等核心聚类逻辑依赖networkx提供的图结构基础完成社区检测的计算图分析能力networkx内置了图的拓扑分析如节点度、连通性、子图提取等能力是 GraphRAG 实现「实体关系图聚类」的底层依赖。实体、关系、声明、社区摘要等信息的存储位置GraphRAG 对这些核心数据的存储遵循「索引阶段输出 Parquet 表 可选向量库存储嵌入」的逻辑具体存储位置/形式如下数据类型存储形式/位置关键细节实体Entity1. 核心存储Parquet 表 2. 字段包含title实体名、type类型、description描述、text_unit_ids关联文本块ID、degree节点度等 实体表结构 3. 嵌入存储实体描述的向量嵌入会写入配置的向量库如 Chroma、Azure AI Search。实体表是图的「节点清单」BYOG 场景下需自定义提供该表。关系Relationship1. 核心存储Parquet 表 2. 字段包含source源实体、target目标实体、description关系描述、weight边权重、text_unit_ids关联文本块ID等 3. 是图的「边清单」Leiden 聚类时会基于weight计算社区。关系表是图的「边清单」weight字段直接影响社区检测结果。声明Covariate/Claim1. 核心存储Parquet 表 2. 声明是实体相关的带时间/属性的陈述关联到具体text_unit_ids和实体ID声明Covariate是对实体/关系的补充信息社区摘要生成时会参考该数据。文本块TextUnit1. 核心存储Parquet 表 2. 存储原始文档切分后的文本片段、所属文档ID、token 数等 3. FastGraphRAG 模式下社区报告直接基于该表生成。所有实体/关系/声明都关联text_unit_ids用于溯源和 FastGraphRAG 场景。社区Community1. 核心存储Parquet 表 2. 字段包含community聚类ID、parent父社区ID、level层级、entity_ids关联实体ID、text_unit_ids关联文本块ID等 3. 由cluster_graph.py的聚类结果生成。社区表记录 Leiden 算法的分层聚类结果是社区摘要的基础。社区摘要Community Report1. 核心存储Parquet 表 2. 存储各层级社区的自然语言摘要、关键实体/关系/声明引用 3. 分两种模式 - 标准模式基于实体/关系描述生成 - FastGraphRAG 模式基于 TextUnit 文本生成。社区摘要表是「全局搜索」的核心数据源用于回答宏观问题。06—假如你从2026年开始学大模型按这个步骤走准能稳步进阶。接下来告诉你一条最快的邪修路线3个月即可成为模型大师薪资直接起飞。阶段1:大模型基础阶段2:RAG应用开发工程阶段3:大模型Agent应用架构阶段4:大模型微调与私有化部署配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】68b9e70bf62341ad85.png)配套文档资源全套AI 大模型 学习资料朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2411539.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!