Skip to content

课 3 · Graph RAG 融合与适用场景

本课目标

把图检索和向量检索融合到完整 RAG 流程里,理解 Graph RAG 解决什么问题、不解决什么问题。

关键理解:Graph RAG 不是向量 RAG 的升级替代,而是专门针对关系推理场景的补充。

Graph RAG 的定位

融合检索流程

typescript
// packages/rag-core/src/retrieval/full-pipeline.ts
import { hybridSearch } from './hybrid-search'
import { graphSearch } from '../graph/graph-search'
import { rerankWithLLM } from './rerank'

interface RetrievalContext {
  chunks: Array<{ id: string; content: string; fileName: string }>
  graphFacts: string[]  // 图谱检索到的结构化事实
}

export async function retrieveWithGraph(query: string): Promise<RetrievalContext> {
  // 1. 混合检索(向量 + 关键词)
  const chunks = await hybridSearch(query, 10)

  // 2. 图检索(实体关系)
  const graphRelations = await graphSearch(query)

  // 把图检索结果转成自然语言片段
  const graphFacts = graphRelations.map(
    (r) => `${r.entity.name} -[${r.relType}]-> ${r.related.name}: ${r.related.description ?? ''}`
  )

  // 3. 对 chunks 做 Rerank(图检索结果不参与 Rerank,直接放入上下文)
  const rerankedChunks = await rerankWithLLM(query, chunks, 5)

  return {
    chunks: rerankedChunks,
    graphFacts,
  }
}

在 Agent 生成答案时,把图谱事实和文档片段一起放入上下文:

typescript
// apps/api/src/services/agent.ts
const { chunks, graphFacts } = await retrieveWithGraph(message)

const context = [
  graphFacts.length > 0
    ? `【知识图谱关系】\n${graphFacts.join('\n')}`
    : '',
  chunks.map((c, i) => `[${i + 1}] ${c.fileName}\n${c.content}`).join('\n\n'),
].filter(Boolean).join('\n\n---\n\n')

Graph RAG 适用场景

适合

场景例子
多跳关系查询"A 的合作伙伴是哪些?他们各自的产品是什么?"
关系推理"谁参与开发了同时用到 X 和 Y 技术的项目?"
实体聚合"列出所有和 OpenAI 有合作关系的机构"
路径解释"解释 A 和 B 之间的关联路径"

不适合

场景原因
语义相似查询"哪些文档讲到类似的做法?"→ 向量检索更好
长文档理解图谱只记录实体关系,不记录上下文细节
动态数据图谱需要维护,频繁变化的数据维护成本高
小知识库(< 100 文档)引入 Neo4j 的成本超过收益,向量检索已足够

路由决策

不是所有问题都需要图检索,加一个路由判断:

typescript
// packages/rag-core/src/retrieval/router.ts
async function shouldUseGraphSearch(query: string): Promise<boolean> {
  // 简单规则:包含关系词就用图检索
  const relationKeywords = [
    '关系', '相关', '合作', '开发者', '属于', '哪些', '列出', '谁参与',
    '和.*有.*关', '如何关联',
  ]
  return relationKeywords.some((kw) => new RegExp(kw).test(query))
}

export async function smartRetrieve(query: string) {
  const useGraph = await shouldUseGraphSearch(query)

  if (useGraph) {
    return retrieveWithGraph(query)
  } else {
    const chunks = await hybridSearch(query, 5)
    return { chunks, graphFacts: [] }
  }
}

Graph RAG 的实际限制

面试时能说出限制比只夸优点更有价值:

  1. 抽取质量依赖 LLM:LLM 抽取的实体和关系会有误差,影响图谱质量
  2. 维护成本:文档更新时,图谱也要同步更新,有额外的维护负担
  3. 冷启动:知识库较小时图谱稀疏,关系推理效果不明显
  4. Embedding 已覆盖大多数场景:大多数知识库问答用混合检索就够了,Graph RAG 是锦上添花

Agentic RAG 和 Graph RAG 的关系

面试常问这两者的区别:

Agentic RAGGraph RAG
核心思路Agent 主动决定检索策略(Query Rewrite、多轮检索、Self-check)用图结构表示知识,支持关系推理
解决问题复杂问题的多步检索实体关系的路径推理
可以组合✅ Agentic RAG + Graph RAG 是完整方案

两者不互斥,生产环境往往同时用:Agent 决定"用什么检索策略",Graph RAG 是其中一种检索选项。

本节产物

packages/rag-core/src/retrieval/
  full-pipeline.ts        # 融合检索:混合检索 + 图检索 + Rerank
  router.ts               # 是否使用图检索的路由判断

面试追问

Graph RAG 适合什么场景?

适合需要多跳关系推理的场景:实体之间的关联路径、聚合查询("和 X 相关的所有 Y")、复杂的因果链推导。不适合的场景:纯语义相似查询、小知识库、动态频繁更新的数据。判断标准:如果用户问题的答案需要"跨文档追踪关系链",就适合 Graph RAG;如果只需要"找相关文档段落",混合检索就够了。

Agentic RAG 和 Graph RAG 是什么关系?

Agentic RAG 解决"如何检索"的问题(多步检索、查询改写、自我验证),Graph RAG 解决"存储什么"的问题(用图结构表示实体关系)。两者关注的层次不同,可以叠加:用 Agentic RAG 的 Router 决定何时触发 Graph RAG 检索,形成完整的知识检索体系。

面向前端工程师和独立开发者的 AI 应用工程课程