GraphRAG源码学习

graphrag文件下索引创建

config

input_models

与settings文件相关的类设置。初始的参数设置在这里查看。

graphrag_config_input.py 

GraphRagConfigInput类定义了所有的输入配置模板,用于设置知识图谱增强检索系统的输入参数在create_graphrag_config.py中被调用。

models

模型的一些参数

enums.py 

多个枚举类,用于配置管道(pipeline)的同一参数的可能类型

default.py

一些参数的取值

environment_reader.py

  • EnvironmentReader:
    • 初始化时接收一个environs.Env实例。
    • _read_env: 从环境变量中读取配置值,支持多个备选键。
    • envvar_prefix: 设置环境变量前缀。
    • use: 创建上下文管理器,临时设置配置段。
    • section: 获取当前配置段。
    • strintboolfloatlist: 分别读取字符串、整数、布尔值、浮点数和列表类型的配置值。

create_graphrag_config.py

通过环境变量加载默认配置参数的设置

vector_stores

typing.py

index

首先需要初始化配置文件、output文件等,然后读取文件和相关配置、然后生成图、保存文件

config

workflow.py:
  • Class PipelineWorkflowReference:workflow的name、stepsPipelineWorkflowStep和configPipelineWorkflowConfig
input.py :
  • PipelineInputConfig是一个泛型基类,表示输入配置的基本信息,如文件类型、连接字符串等。
  • PipelineCSVInputConfig继承自PipelineInputConfig,特化为CSV文件输入,增加了CSV特有的字段配置,如列名等。
  • PipelineTextInputConfig同样继承自PipelineInputConfig,特化为文本文件输入,增加了文本文件特有的配置项,如标题长度等。
  • PipelineInputConfigTypes = PipelineCSVInputConfig | PipelineTextInputConfig

storage.py
  • PipelineStorageConfig:泛型基模型类,具有表示存储类型的单个属性。
  • PipelineFileStorageConfig:继承自PipelineStorageConfig,表示管道的文件存储配置。包含类型和基础目录属性。
  • PipelineMemoryStorageConfig:继承自PipelineStorageConfig,表示管道的内存存储配置。包含类型属性。
  • PipelineBlobStorageConfig:继承自PipelineStorageConfig,表示管道的Blob存储配置。包含类型、连接字符串、容器名称、基础目录和存储账户Blob URL属性。
  • PipelineStorageConfigTypes = ( PipelineFileStorageConfig | PipelineMemoryStorageConfig | PipelineBlobStorageConfig)

report.py
  • PipelineReportingConfigTypes =( PipelineFileReportingConfig|PipelineConsoleReportingConfig | PipelineBlobReportingConfig)
pipline.py

PipelineConfig 类用于表示管道配置信息,包含如下属性:

  • extends: 可继承其他管道配置。
  • input: 管道输入配置。
  • reporting: 报告生成配置。
  • storage: 存储配置。
  • cache: 缓存配置。
  • root_dir: 管道的基础目录路径。
  • workflows: 管道中的工作流列表。

emit

CSVTableEmitter、JsonTableEmitter、ParquetTableEmitter

  TableEmitter:将数据表输出到目标位置

  TableEmitterType:数据类型

  create_table_emitter:

  create_table_emitters:

graph

embedding.py class NodeEmbeddings:Node2Vec算法生成图的节点嵌入表示

progress 

types.py 三个关于进度报告的类:ProgressReporterNullProgressReporterPrintProgressReporter

rich.py  RichProgressReporter类 打印进度条

reporting 

file_workflow_callbacks.py:FileWorkflowCallbacks 类,继承自 NoopWorkflowCallbacks。该类的作用是将错误、警告和日志信息写入到指定目录下的 logs.json 文件中,并以 JSON 格式存储每条记录。

storage

typing :PipelineStorage抽象基类

file_pipeline_storage.py

  1. FilePipelineStorage 类

    • 初始化:设置根目录和编码方式,默认为空和'utf-8'。
    • find:根据正则表达式查找文件,可选地使用自定义过滤器和进度报告器。
    • get:获取指定文件的内容,可以选择以字节方式获取。
    • _read_file:异步读取文件内容,支持字节和字符串。
    • set:设置指定文件的内容,支持字节和字符串。
    • has:检查文件是否存在。
    • delete:删除指定文件。
    • clear:清空存储目录中的所有文件和子目录。
    • child:创建一个子存储实例。
  2. 辅助函数

    • join_path:连接文件路径和文件名,与操作系统无关。
    • create_file_storage:创建基于文件的存储实例。
    • _create_progress_status:创建进度状态对象,用于报告操作进度。

该模块主要用于在数据处理和分析中提供灵活的文件存储解决方案。

text_splitting

文档分割

utils

dataframes.py:数据框的相关操作函数

dict_has_keys_with_types:检查字典data是否包含指定键expected_fields及其对应的数据类型

worklfows

default_workflows.py:定义了一个名为 default_workflows 的字典,其中键是各个工作流的名称,值是构建这些工作流步骤的函数统一

typing.py class WorkflowToRun

load.py:对工作流的管理和执行功能

def load_workflows :负责加载指定的工作流,并解析它们之间的依赖关系,确保所有依赖的工作流都被加载。

def create_workflow:根据提供的配置创建一个新的工作流对象。

cli.py

index的核心文件根据提供的参数配置并运行管道流程,并根据命令行界面模式决定是否退出程序。

index_cli()函数首先根据用户输入参数,_initialize_project_at确定是否需要初始化当前文件夹,检查目录下的一些配置、prompt、.env等文件是否存在,没有则创建。

执行index操作时,实际上会执行一个内部函数_run_workflow_async(),主要会涉及到_create_default_config()与run_pipeline_with_config()两个函数。

_create_default_config():

  • 检查配置文件及根目录是否存在;
  • 读取或创建默认配置参数;
  • pipeline_config构建并返回管道配置 _read_config_parameters;
  • 支持详细输出 (verbose) 和预演模式 (dryrun)
  • 最后输出create_pipeline_config对象(PipelineConfig)。
  • _read_config_parameters

  1. 确定配置文件路径:优先使用传入的 config 参数,支持 .yaml.yml.json;否则尝试使用默认文件名 settings.yaml 或 settings.json
  2. 检查文件是否存在,优先使用 .yaml 或 .yml 文件;若不存在,则检查 .json 文件。
  3. 若找到 .yaml 或 .yml 文件,则使用 yaml.safe_load 读取并解析文件内容。
  4. 若找到 .json 文件,则使用 json.loads 读取并解析文件内容。
  5. 若未找到上述文件,则从环境变量读取设置。
  6. 最终调用 create_graphrag_config 函数返回配置对象。

_run_workflow_async#通过异步方式执行管道流程,并根据输出结果更新状态和报告信息

run.py

 run_pipeline_with_config:

用pipeline_config调用load_pipeline_config生成config

     load_pipeline_config该函数用于从文件路径或配置对象pipeline_config中加载管道配置。首先,它检查输入参数的类型,如果是PipelineConfig对象,则直接使用该对象作为配置。如果输入参数是字符串且值为"default",则通过创建默认的管道配置来生成配置对象config ==create_pipeline_config(create_graphrag_config(root_dir="."))。对于其他字符串类型的输入参数,函数会检查是否存在同目录下的.env文件,并根据输入参数的文件扩展名选择不同的加载方式(JSON或YAML)。如果文件类型不合法,将抛出ValueError异常。加载配置后,如果没有指定root_dir,则将其设置为配置文件所在目录的解析路径。如果配置中包含extends字段,函数将递归加载并合并扩展的配置文件。最后,返回加载(或合并)后的配置对象。

        函数create_pipeline_config,根据给定的GraphRagConfig设置创建并返回一个PipelineConfig对象,用于配置管道流程。

设置各种对象传入给run_pipline函数

         run_pipline函数

  • 1.从提供的或默认的工作流中加载实际要运行的工作流及其依赖关系。load_workflows
  • 2.使用给定的存储、缓存和统计信息初始化运行上下文。_create_run_context
  • 3.数据处理流程
    • 遍历所有待运行的工作流:
      • 如果工作流的结果已存在于存储中,则跳过当前工作流。
      • 否则,注入工作流所需的数据依赖。
      • 运行工作流,并记录运行统计信息。
      • 发射工作流的输出数据。
      • 清理资源,释放内存。
    • 4.异常处理
    • 5.结果生成
      • 生成包含工作流名称、输出数据和可能的错误信息的迭代器。
  • 注意:该函数为异步生成器,可以逐个产出结果。

加载workflows:load.py::load_workflows(),除了常规工作流的创建外,还会涉及到拓扑排序问题。

workflows/load.py::create_workflow():利用已有模板,创建不同的工作流。
graphlib::topological_sort():根据workflow之间的依赖关系,计算DAG的拓扑排序、
进一步执行inject_workflow_data_dependencies()、write_workflow_stats()、emit_workflow_output等操作,分别用于依赖注入,数据写入以及保存,真正的workflow.run操作会在write_workflow_stats()之前执行,此处的核心逻辑可参考以下代码。

typing.py

类PipelineRunResult

context.py

PipelineRunStats类用于记录管道运行的统计信息,如总运行时间、文档数量和输入加载时间等。PipelineRunContext类为当前管道运行提供上下文,包括统计信息、存储和缓存。

init_content.py

一个配置文件

INIT_YAML变量

create_pipeline_config.py

函数create_pipeline_config,根据给定的GraphRagConfig设置创建并返回一个PipelineConfig对象,用于配置管道流程。

load_pipeline_config.py

查询

全局查询

graphrag/query/__main__.py中的主函数会依据参数不同,分别路由至cli::run_local_search()以及cli::run_global_search()

全局是与每个社区做检索 

1.获取路径和参数:_configure_paths_and_settings

2.读取parquet文件

3.阅读社区报告:read_indexer_reports

(1)用等级去筛选节点和报告,然后将报告和节点进行内连接至保留有报告的节点

(2)读取社区报告

4.阅读实体:read_indexer_entities

节点(基本属性(如名称、排名和社区信息)、实体嵌入、社区等级

(1)过滤节点,对接点列进行重命名、值处理

(2)使用groupbyagg方法按"name""rank"分组,并取每组中"community"的最大值。

(3)然后将实体和实体嵌入用名字进行内连接至保留有嵌入的节点,以将嵌入信息附加到每个实体上。

(4)读取实体

5.构建查询对象

6.用问题查询

# Step 1: Generate answers for each batch of community short summaries

 #并行地对社区简短摘要进行大型语言模型(LLM)调用以生成每个批次的答案

 # Step 2: Combine the intermediate answers from step 2 to generate the final answer

 #将步骤1中生成的答案合并以生成最终答案

具体来说,这个过程分为两个主要步骤:

  1. 构建上下文 (build_context 方法):
    • 这个步骤通过 self.context_builder.build_context 方法,根据传入的 conversation_history(如果有的话)和其他可能的参数(**self.context_builder_params),来构建出用于后续检索的上下文数据。这些数据被分为两部分:context_chunks 和 context_recordscontext_chunks 可能包含了一系列简短的文本块,这些文本块可能代表了不同社区或不同主题的简短摘要,而 context_records 则可能包含了这些文本块的额外信息或元数据。
  2. 并行检索 (asyncio.gather 和 _map_response_single_batch 方法):
    • 在这一步中,使用 asyncio.gather 来并行地对每个 context_chunk 进行检索。这是通过调用 _map_response_single_batch 方法实现的,该方法接受一个 context_data(即一个 context_chunk)和查询 query,以及其他可能的参数(**self.map_llm_params),然后对每个批次的数据进行大型语言模型(LLM)的调用,以生成针对该批次数据的答案。
  3. 合并答案 (_reduce_response 方法):
    • 在所有批次的答案生成后,使用 _reduce_response 方法来合并这些中间答案,以生成最终的答案。这个过程可能涉及对多个答案的评估、选择、汇总或其他逻辑处理,以产生最符合查询意图的响应。

build_context 方法的主要作用是为全局搜索准备社区报告数据的批次作为上下文数据。这个方法首先处理可能存在的对话历史(conversation_history),然后根据配置参数构建社区上下文(community_context)。最终,它返回两个主要部分:一个是包含所有上下文文本的字符串或字符串列表(final_context),另一个是包含与上下文文本关联的额外信息的字典(final_context_data)。

以下是该方法的详细步骤解析:

  1. 初始化变量:方法开始时,初始化了两个变量conversation_history_context(用于存储对话历史生成的上下文文本)和final_context_data(用于存储与上下文文本相关的数据)。

  2. 处理对话历史

    • 如果传入了conversation_history,则调用其build_context方法来生成对话历史的上下文文本(conversation_history_context)和相关的数据(conversation_history_context_data)。
    • 如果对话历史生成的上下文文本不为空,则将其相关的数据添加到final_context_data中。
  3. 构建社区上下文

    • 调用build_community_context函数(这个函数可能是一个外部定义或内部实现的辅助函数),根据社区报告(self.community_reports)、实体(self.entities)、令牌编码器(self.token_encoder)以及其他配置参数来构建社区上下文。
    • 函数返回两个值:community_context(包含社区上下文文本的字符串或字符串列表)和community_context_data(包含与社区上下文文本相关的数据的字典)。
  4. 合并上下文

    • 如果community_context是列表,则遍历该列表,将每个社区上下文文本与对话历史上下文文本(如果存在)合并,生成最终的上下文文本列表final_context
    • 如果community_context不是列表(即只有一个上下文文本),则直接将其与对话历史上下文文本合并。
  5. 更新最终上下文数据

    • community_context_data中的数据添加到final_context_data中,以包含所有相关的上下文数据。
  6. 返回结果

    • 返回最终的上下文文本(final_context)和相关的上下文数据(final_context_data)。

map-reduce机制:用户只需要定义一个map函数来处理一个key/value对以生成一批中间的key/value对,再定义一个reduce函数将所有这些中间的有着相同key的values合并起来。

用使用节点处理后的社区报告和实体生成context_builder

local searsh

直接根据上下文给出回复,更接近于常规的RAG语义检索策略,所消耗的Token也比较少。
与全局搜索不同的地方在于,Local 模式综合了nodes,community_reports,text_units,relationships,entities,covariates等多种源数据。

1.获取路径和参数:_configure_paths_and_settings

2.读取parquet文件:节点、社区报告、文本、实体、协变量

3.根据配置参数动态地确定向量存储的类型和配置,并基于这些配置创建一个适合存储实体语义嵌入的存储对象。 

4.阅读实体:read_indexer_entities

节点(基本属性(如名称、排名和社区信息)、实体嵌入、社区等级

(1)过滤节点,对接点列进行重命名、值处理

(2)使用groupbyagg方法按"name""rank"分组,并取每组中"community"的最大值。

(3)然后将实体和实体嵌入用名字进行内连接至保留有嵌入的节点,以将嵌入信息附加到每个实体上。

(4)读取实体

5.将实体的语义嵌入信息存储在给定的向量存储 store_entity_semantic_embeddings

6.5.构建查询对象

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值