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 驱动的自主检索

相关推荐
默_笙1 小时前
🌏 MCP 是 AI 界的 USB-C:一个协议让所有模型都能用上所有工具
前端·javascript
以和为贵1 小时前
🔥前端也能搞懂流式输出:从 SSE 到打字机效果
前端·人工智能·架构
阿成学长_Cain2 小时前
Linux telinit 命令详解:运行级别切换|关机重启|系统维护一站式掌握
linux·运维·前端·网络
Patrick_Wilson2 小时前
最佳实践是有保质期的:从一次 CDN external 白屏事故说起
前端·性能优化·前端工程化
YHHLAI3 小时前
[特殊字符] Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·人工智能
nuIl3 小时前
我把 5 个编码 Agent 塞进了一个 npm 包
前端·agent·claude
L-影3 小时前
FastAPI 静态文件:Web 页面的“固定展柜”与“加速引擎”
前端·fastapi
陪我去看海3 小时前
受够了 AI 写完代码留下一堆端口?我做了一个端口管理App!
前端·macos·vibecoding
Xuepoo3 小时前
我抛弃了 DOM,但保留了无障碍访问
前端