1. 引言#
youtu-graphrag 是一个面向复杂推理场景的图增强检索增强生成(GraphRAG)框架。与传统的 RAG 系统(主要依赖向量相似度检索)或通用的 GraphRAG(主要依赖全局摘要)不同,该项目采用了一种“垂直统一”的架构设计。其核心特征在于通过 图模式(Graph Schema) 对知识构建进行约束,并通过 智能体(Agent) 机制实现从构建到检索的动态流程。
本文将依据源码,从宏观视角解析其系统架构、数据组织形式以及核心工作流,为后续深入各模块细节奠定基础。
2. 核心设计理念#
通过分析 config/base_config.yaml 和 main.py,可以看出该系统遵循两个核心设计原则:
- Schema 引导 (Schema-Guided): 系统不依赖完全开放的信息抽取,而是基于预定义的种子 Schema(包含节点类型、关系类型、属性)进行知识提取。这在
models/constructor/kt_gen.py中有明确体现,旨在降低噪声并提高知识结构的规范性。 - 代理式范式 (Agentic Paradigm):
- 构建侧: 支持 Schema 的动态演进,允许模型在提取过程中发现新类型并反向更新 Schema。
- 检索侧: 采用 IRCoT (Iterative Retrieval Chain of Thought) 机制,支持多步迭代检索和自我反思。
3. 四层知识树架构 (Four-Level Knowledge Tree)#
youtu-graphrag 在逻辑和物理存储上将知识图谱划分为四个明确的层级。这种分层设计旨在解决不同粒度问题的检索需求。
依据 utils/graph_processor.py 中的节点加载逻辑和 models/constructor/kt_gen.py 的构建逻辑,四层结构如下:
- Level 4: 社区 (Community)
- 定义: 由算法生成的节点聚类,代表宏观的主题或知识簇。
- 载体: 超级节点 (Super Node),包含由 LLM 生成的社区摘要 (
description)。 - 生成方式:
utils/tree_comm.py中的FastTreeComm算法。
- Level 3: 关键词 (Keyword)
- 定义: 连接社区与具体实体的桥梁节点。
- 载体: 关键词节点,用于加速索引和横向关联。
- Level 2: 实体与关系 (Entity & Relation)
- 定义: 知识图谱的主干,包含具体的业务实体及其相互关系。
- 载体: 标准的图节点与边。
- Level 1: 属性 (Attribute)
- 定义: 实体的细粒度特征(如时间、数值、状态)。
- 载体: 属性被升格为独立节点 (
label="attribute"),而非仅作为节点属性存在。这允许系统通过属性值进行跨实体的关联检索。
4. 系统宏观架构#
基于 main.py 的执行流程,系统架构可分为 写入路径 (Write Path) 和 读取路径 (Read Path)。
graph TD
Config[Configuration & Schema] --> Controller["Main Controller (main.py)"]
subgraph "Write Path: Knowledge Construction"
Controller --> KTBuilder[KTBuilder]
KTBuilder --> Extraction[LLM Extraction]
Extraction --> Evolution{Agent Mode?}
Evolution -- Yes --> SchemaUpdate[Update Schema JSON]
Evolution -- No --> GraphMem[NetworkX Graph]
SchemaUpdate --> GraphMem
GraphMem --> TreeComm[FastTreeComm]
TreeComm --> CommDetect[Community Detection]
CommDetect --> Level4[Generate Level 4 Nodes]
Level4 --> Storage[(Output JSON & Indices)]
end
subgraph "Read Path: Retrieval & Reasoning"
Controller --> GraphQ[GraphQ Decomposer]
GraphQ --> SubQ[Sub-Questions]
SubQ --> KTRetriever[Enhanced KT Retriever]
KTRetriever --> DualFAISS[Dual FAISS Retriever]
Storage -.-> DualFAISS
DualFAISS --> Path1[Path 1: Node/Relation/Triple]
DualFAISS --> Path2[Path 2: Community]
Path1 & Path2 --> Rerank[Reranking]
Rerank --> IRCoT[IRCoT Agent Loop]
IRCoT --> FinalAnswer[Final Answer]
end
5. 工作流深度解析#
5.1 写入路径:图谱构建 (Graph Construction)#
构建过程由 main.py 中的 graph_construction 函数触发,核心类为 models.constructor.kt_gen.KTBuilder。
- 初始化与切分: 加载数据集配置与 Schema,对输入文档进行切分 (
chunk_text)。 - 信息抽取 (Extraction):
- 根据
config.construction.mode选择 Prompt 模板。 - 调用 LLM 提取实体、关系和属性。
- Schema 演进: 在
agent模式下,如果 LLM 返回了new_schema_types,系统会调用_update_schema_with_new_types实时更新本地 Schema 文件。
- 根据
- 图结构组装: 将提取的 Level 1 (属性) 和 Level 2 (实体/关系) 写入内存中的
networkx.MultiDiGraph。 - 社区发现 (Community Detection):
- 调用
process_level4方法。 - 使用
FastTreeComm算法(位于utils/tree_comm.py),结合语义 Embedding 和拓扑结构进行聚类。 - 生成 Level 4 的社区节点并建立其与成员节点的连接 (
member_of)。
- 调用
- 持久化: 最终图谱以 JSON 格式保存至
output/graphs/{dataset}_new.json,同时保存 Chunk 映射文件。
5.2 读取路径:检索与推理 (Retrieval)#
检索过程由 main.py 中的 retrieval 函数触发,支持 noagent(单次检索)和 agent(迭代检索)两种模式。
- 索引构建 (Indexing):
KTRetriever初始化时会调用DualFAISSRetriever构建四类 FAISS 索引:Node、Relation、Triple、Community。 - 问题分解 (Decomposition):
models.retriever.agentic_decomposer.GraphQ负责将复杂问题分解为子问题 (sub_questions)。- 同时预测涉及的节点类型 (
involved_types),作为后续检索的过滤器。
- 并行检索: 对于每个子问题,系统并行执行检索。
- IRCoT 迭代 (仅 Agent 模式):
- 进入
agent_retrieval循环。 - LLM 根据当前上下文判断信息是否充足。
- 若不足,生成新查询 (
The new query is: ...) 再次调用检索器。 - 若充足,生成最终答案 (
So the answer is: ...)。
- 进入
6. 代码入口示例#
系统的入口是 main.py,其逻辑结构清晰地反映了上述流程:
# main.py (代码片段逻辑示意)
if __name__ == "__main__":
# 1. 配置加载
config = get_config(args.config)
# 2. 构建阶段 (Write Path)
if config.triggers.constructor_trigger:
# 初始化 Builder,传入 Schema
builder = constructor.KTBuilder(dataset, schema_path, ...)
# 执行构建
builder.build_knowledge_graph(corpus_path)
# 3. 检索阶段 (Read Path)
if config.triggers.retrieve_trigger:
# 初始化分解器
graphq = decomposer.GraphQ(dataset, ...)
# 初始化检索器
kt_retriever = retriever.KTRetriever(dataset, ...)
# 构建 FAISS 索引
kt_retriever.build_indices()
# 根据模式执行推理
if config.triggers.mode == "agent":
agent_retrieval(graphq, kt_retriever, ...)
else:
no_agent_retrieval(graphq, kt_retriever, ...)
7. 总结#
youtu-graphrag 通过四层架构解决了知识粒度问题,通过Schema 引导解决了结构化数据的质量问题,并通过Agent 闭环解决了静态图谱无法适应动态推理的问题。