Graph RAG:知识图谱增强检索

进阶 B · Graph RAG:知识图谱增强检索

当知识之间存在关联("A 依赖 B"、"X 是 Y 的子模块"),传统 RAG 无法捕捉这些关系。Graph RAG 用知识图谱把知识织成网。


1. 传统 RAG 的盲区

arduino 复制代码
问题:"项目中哪些模块依赖了 userService?"

传统 RAG:检索到 3 个提到 userService 的文档 Chunk
实际需要:遍历 import 图,找出所有直接/间接引用 userService 的文件 → 可能有 15 个

传统 RAG 只能检索"文本相似"的内容,无法理解"关系"。Graph RAG 弥补了这个缺陷。


2. Graph RAG 架构

markdown 复制代码
文档摄入
    │
    ├──→ 文本分块 → 向量存储(传统 RAG)
    │
    └──→ 实体关系抽取 → 知识图谱(Neo4j / NebulaGraph)
              │
              ▼
        图谱检索
              │
              ▼
    检索结果融合 → LLM 生成

2.1 实体关系抽取(Node.js)

csharp 复制代码
// graph/extract.ts
import { ChatOpenAI } from "@langchain/openai";

interface EntityRelation {
  entities: { name: string; type: string }[];
  relations: { from: string; to: string; type: string }[];
}

class GraphExtractor {
  private llm = new ChatOpenAI({ model: "gpt-4o", temperature: 0 });

  async extractFromDocument(doc: string): Promise<EntityRelation> {
    const response = await this.llm.invoke(`
      从以下文档中提取实体和关系,以 JSON 返回。
      实体类型:模块、组件、函数、API、配置项
      关系类型:depends_on, contains, calls, configures

      文档:
      ${doc}

      返回格式:
      {
        "entities": [{"name": "名称", "type": "类型"}],
        "relations": [{"from": "实体A", "to": "实体B", "type": "关系类型"}]
      }
    `);

    return JSON.parse(response.content as string);
  }
}

2.2 存入 Neo4j

php 复制代码
// graph/store.ts
import neo4j from "neo4j-driver";

const driver = neo4j.driver(
  "bolt://localhost:7687",
  neo4j.auth.basic("neo4j", "password")
);

class GraphStore {
  async insert(entityRelation: EntityRelation): Promise<void> {
    const session = driver.session();

    try {
      // 创建节点
      for (const entity of entityRelation.entities) {
        await session.run(
          `MERGE (n:Entity {name: $name}) SET n.type = $type`,
          entity
        );
      }

      // 创建关系
      for (const rel of entityRelation.relations) {
        await session.run(
          `MATCH (a:Entity {name: $from}), (b:Entity {name: $to})
           MERGE (a)-[r:${rel.type}]->(b)`,
          rel
        );
      }
    } finally {
      await session.close();
    }
  }
}

2.3 图谱检索

vbnet 复制代码
// graph/search.ts
class GraphRetriever {
  async search(query: string): Promise<GraphResult> {
    const session = driver.session();

    try {
      // 1. 找出与查询相关的实体
      const entities = await session.run(`
        MATCH (n:Entity)
        WHERE n.name CONTAINS $query
        RETURN n.name, n.type
        LIMIT 10
      `, { query });

      const entityNames = entities.records.map(r => r.get("n.name"));

      // 2. 查找 1 跳邻居关系(直接依赖/引用)
      const neighbors = await session.run(`
        MATCH (n:Entity)-[r]->(m:Entity)
        WHERE n.name IN $names
        RETURN n.name AS source, type(r) AS relation, m.name AS target
        LIMIT 50
      `, { names: entityNames });

      return {
        entities: entityNames,
        relations: neighbors.records.map(r => ({
          from: r.get("source"),
          relation: r.get("relation"),
          to: r.get("target"),
        })),
      };
    } finally {
      await session.close();
    }
  }
}

3. 与文本 RAG 融合

javascript 复制代码
// graph/fusion.ts
async function graphEnhancedRAG(query: string) {
  // 1. 文本 RAG 检索
  const textResults = await textVectorStore.similaritySearch(query, 5);

  // 2. 图谱检索
  const graphResults = await graphRetriever.search(query);

  // 3. 融合生成
  const prompt = `
## 相关文档
${textResults.map(d => d.pageContent).join("\n\n")}

## 知识关联
${graphResults.relations.map(r => `"${r.from}" --[${r.relation}]--> "${r.to}"`).join("\n")}

## 问题
${query}

请结合文档内容和知识关联来回答。如果知识关联揭示了文档中不明显的依赖/module关系,请特别指出。
`;

  return llm.invoke(prompt);
}

4. 适用场景与局限

场景 传统 RAG +Graph RAG
"React.memo 怎么用?" 没帮助
"哪些模块依赖了 AuthService?" ⚠️ 可能漏 ✅ 精确遍历
"支付流程涉及哪些服务和中间件?" 能搜到部分 ✅ 完整链路
"这个 Bug 可能影响哪些模块?" 粗糙 ✅ 追踪调用链

建议

  • Graph RAG 是传统 RAG 的增强,不是替代
  • 知识关系密集的场景(代码库、微服务文档、API 文档)收益最大
  • 需要额外维护 Neo4j 实例和抽取流水线,投入产出需评估

上一篇:A · 多模态 RAG:图片与表格检索 下一篇:C · Agentic RAG:Agent 驱动的自主检索

相关推荐
紫幽10 小时前
从 0 用 Vue 做屏并生成 LVGL 单片机代码(完整源码备忘)
前端·单片机
郭邯10 小时前
用 AI 辅助开发一个文件大小转换工具:从需求到上线的完整过程
前端
勾勾圈圈蛋蛋10 小时前
前中台项目
前端
触底反弹10 小时前
🔐 前端鉴权不再难!手把手带你搞懂 JWT + Zustand + Axios 的完整登录方案
前端·axios
打呵欠的猫11 小时前
我用 AI 写了一个"需求翻译器",产品的 PRD 直接变成开发任务清单
前端·ai编程
fatcoder11 小时前
玩转Nginx 09 — 运维排障:三场"火灾"实战演练
前端·后端·nginx
前端玩坑坑11 小时前
View Transitions API 入门教程,优雅过度
前端
李高钢11 小时前
WPF MVVM Light(三):RelayCommand 命令与 Messenger 消息
前端·c#·wpf
lichenyang45311 小时前
Socket.IO 原理与技术选型
前端
qq210846295311 小时前
在python中什么是 self 和 cls?
开发语言·前端·python