Skip to content

Latest commit

 

History

History
141 lines (107 loc) · 5.06 KB

File metadata and controls

141 lines (107 loc) · 5.06 KB

graphrag — 知识图谱子图检索 + LLM 生成

概述

graphrag 模块实现基于子图检索增强生成的问答管线:从用户问题中提取医疗实体,围绕实体从 Neo4j 检索多跳子图,将子图转化为结构化文本上下文,最终由 LLM 生成综合回答。

本模块的组件已被 qa_engine/ 工作流复用,不再直接用于问答端点。Bot 类仅保留供 server/ 邻居查询和健康检查使用。


管线架构

用户问题
  │
  ▼
┌──────────────────┐
│ 1. 实体抽取        │  LLM 提取医疗实体(疾病、症状、药品等)
│ EntityExtractor   │  输出: [{"name": "糖尿病", "type": "disease"}, ...]
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ 2. 实体归一化      │  将 LLM 实体映射到 Neo4j 规范名称
│ EntityNormalizer  │  三级匹配:精确 → 子串 → 模糊
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ 3. 多跳子图检索    │  从 Neo4j 检索 1-2 跳邻居子图
│ SubgraphRetriever │  优先扩展 Disease 节点(信息最丰富)
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ 4. 上下文组装      │  将子图转化为结构化文本
│ ContextBuilder    │  按实体分段展示属性 + 关系
└────────┬─────────┘
         │
         ▼
┌──────────────────┐
│ 5. LLM 答案生成   │  问题 + 图谱上下文 → LLM → 综合回答
│ GraphRAGGenerator │  流式 / 非流式两种模式
└──────────────────┘

与纯模板问答的区别

模板 Cypher(KBQA) GraphRAG 子图检索
适用场景 简单单实体查询("感冒有什么症状") 复杂多实体关系("糖尿病和高血压有什么共同并发症")
查询方式 预定义 Cypher 模板 动态多跳邻居检索
上下文来源 精确匹配的单条查询结果 1-2 跳子图的完整上下文
答案生成 模板填充或 LLM 润色 LLM 基于上下文综合生成

目录结构

graphrag/
├── __init__.py            # 模块入口
├── config.py              # 检索/生成参数 + 提示词
├── entity_extractor.py    # LLM 实体抽取器(仅抽取实体,不做意图分类)
├── subgraph_retriever.py  # 多跳子图检索器
├── context_builder.py     # 子图 → 结构化文本上下文
├── generator.py           # 基于图谱上下文的 LLM 答案生成
└── graphrag_bot.py        # [保留] 编排器,串联全部管线

核心参数

子图检索

参数 默认值 说明
MAX_HOPS 2 最大遍历深度
HOP1_LIMIT 50 每个实体的直接邻居上限
HOP2_LIMIT 20 每个 hop-1 节点的邻居上限
HOP2_CANDIDATES 15 第 2 跳扩展候选节点数

上下文组装

参数 默认值 说明
MAX_CONTEXT_CHARS 6000 传给 LLM 的最大字符数
MAX_PROP_VALUE_LEN 200 单个属性值截断长度
MAX_TARGETS_PER_REL 15 每种关系最多列出的目标数

子图检索策略

第 1 跳:从每个抽取实体出发,检索直接邻居
  ┌────────┐
  │ 糖尿病  │──症状──▶ 多饮
  │        │──并发症─▶ 糖尿病肾病
  │        │──药品──▶ 二甲双胍
  │        │──检查──▶ 血糖检测
  └────────┘

第 2 跳:从 hop-1 节点出发,扩展邻居的邻居
  ┌────────┐     ┌──────────┐
  │ 多饮   │────▶│ 糖尿病酮症 │
  └────────┘     └──────────┘

优先级:Disease > 其他类型(Disease 节点携带 desc/病因/预防等属性)

使用方式

独立调用(不推荐,推荐使用 qa_engine)

from graphrag import GraphRAGBot

bot = GraphRAGBot()
result = bot.chat_detail("糖尿病和高血压有什么共同并发症?")
print(result["answer"])
print(result["debug"]["subgraph_stats"])

在 qa_engine 中使用(推荐)

GraphRAG 各组件通过 qa_engine/nodes/graphrag_path.py 编排调用,前端通过统一 stream_qa 入口,无需手动选择模式。


配置说明

共享配置从 settings.py 导入(Neo4j 连接、LLM 参数),模块特有配置定义在 config.py

  • ENTITY_EXTRACT_PROMPT:实体抽取提示词(仅抽取实体,不含意图分类)
  • GENERATION_SYSTEM_PROMPT:答案生成提示词(基于图谱数据 + 免责声明)

LLM 生成时会自动过滤 qwen3 模型的 <think>...</think> 输出。