跳至主要內容

如何选择在RAG系统中使用知识图谱还是向量数据库?

程序员小富大约 12 分钟

如何选择在RAG系统中使用知识图谱还是向量数据库?

先说结论:不是二选一的问题,而是看你的数据长什么样、用户怎么问。

我做过三个RAG项目,分别用过纯向量检索、纯知识图谱、以及两者混合的方案。最后得出的经验是——选错了技术路线,后面怎么调优都很难救回来,但选对了,很多问题根本不用调就自然解决了。


先搞清楚你的数据和查询模式

在讨论技术选型之前,先回答两个问题:

第一,你的知识库里,实体之间的关系重要吗?

如果你做的是企业内部的制度问答,用户问"出差报销的流程是什么",这类问题的答案基本就是一段文本,实体之间的关系不复杂。这种场景,向量数据库就够用了——把文档切块、做embedding、检索最相似的几个chunk、扔给LLM生成答案,流程清晰,工程量也不大。

但如果你做的是医疗领域的问答,用户问"某个药物和某个药物能不能一起吃",这个问题的答案不在某一段文本里,而是分散在药物说明书、临床指南、不良反应数据库等多个来源中,需要你把"药物A→作用于→靶点X""药物B→抑制→酶Y""酶Y→代谢→药物A"这些关系串起来才能回答。这种场景,知识图谱的优势就很明显了。

第二,你的用户是怎么提问的?

如果用户的问法比较模糊、口语化,比如"那个之前开会提到的关于降本的方案,具体内容是什么来着",这种查询靠关键词匹配几乎不可能命中,但向量检索的语义理解能力可以很好地处理。

如果用户的问法是结构化的、精确的,比如"张三在2024年Q3负责了哪些项目",这种查询需要精确匹配实体(张三)和关系(负责),知识图谱的图查询会比向量检索更准。


向量数据库:适合"大海捞针"型检索

向量数据库的核心能力是语义相似度匹配。你把一段文本转成一个高维向量,查询的时候把用户的问题也转成向量,然后在向量空间里找最近的几个邻居。

它的强项在于:

  • 对非结构化文本友好。文档、邮件、聊天记录、会议纪要,这些东西很难提取出干净的实体关系,但做embedding很方便。
  • 语义理解能力强。用户说"降本增效"和文档里写的"成本优化措施",虽然字面不一样,但embedding之后的向量距离是很近的。
  • 工程链路简单。现在主流的向量数据库(Milvus、Pinecone、Weaviate、Qdrant)都比较成熟,配合LangChain或LlamaIndex,一两天就能搭出一个可用的RAG pipeline。

但它有几个明显的短板:

我在项目里踩过一个大坑——向量检索对"关系型问题"几乎无能为力。

举个真实例子。我们做了一个企业知识库,里面有很多项目文档。用户问:"A项目的负责人同时还负责了哪些其他项目?"这个问题的回答需要两步推理:第一步,找到A项目的负责人是谁;第二步,找到这个人还负责了哪些项目。

向量检索能做的是,把这个问题的embedding和所有文档chunk的embedding做比较,召回和"A项目"语义最相近的几段文本。但这些文本里大概率只提到了A项目本身的信息,并不会包含"这个负责人同时还管着B项目和C项目"这种跨文档的关联信息。

我们当时试了几种补救措施:增大召回数量(top-k从5调到20)、用HyDE先让LLM生成假设性回答再检索、用multi-query把原始问题拆成多个子查询分别检索。有一定改善,但终究是在语义匹配的框架里打补丁,治标不治本。

另一个坑是"数值和时间的精确匹配"。向量检索本质上是模糊匹配,用户问"2024年第三季度的销售额",它可能召回2023年或者第二季度的内容,因为这些文本在语义上确实很相近。我们后来的做法是在向量检索之外加了一层metadata filter,把年份、季度这些结构化字段单独提取出来做精确过滤,再在过滤后的结果集里做向量排序。这个方案管用,但等于你自己又手工补了一部分结构化检索的能力。


知识图谱:适合"精确推理"型检索

知识图谱的核心是把知识表示成三元组(实体-关系-实体),然后通过图查询语言(比如Cypher、SPARQL)做多跳推理。

它的强项在于:

  • 多跳推理。"A项目的负责人还负责了哪些项目"这种问题,在图上就是两跳查询,结果精确且完整。
  • 关系的可解释性。向量检索返回的是"最相似的文本片段",用户看不到推理过程。知识图谱返回的是一条推理路径(张三→负责→A项目,张三→负责→B项目),可解释性强很多,在金融、医疗、法律这些合规要求高的领域,这个特性有时候是硬需求。
  • 数据更新的精确性。如果某个项目换了负责人,在知识图谱里改一条边就行了。在向量数据库里,你得找到所有提到这个关系的chunk,重新做embedding,还得确保旧的chunk被正确删除或更新,操作上容易出错。

但知识图谱的门槛也是实打实的高:

最大的成本在知识抽取。你的原始数据大概率是非结构化的文档,要把它们变成三元组,需要做实体识别(NER)、关系抽取(RE)、实体消歧(Entity Resolution)。这三步里每一步都可能引入误差。

我们做过一个尝试,用GPT-4从技术文档里自动抽取三元组。效果怎么说呢——简单的关系(比如"某人属于某部门")抽得还行,准确率大概在85%左右。但复杂一点的关系(比如"某系统在某条件下依赖某服务的某个接口"),准确率直接掉到60%以下。抽取质量不行,后面的图查询结果自然也不可靠。

我们最后的做法是半自动化:LLM先做初步抽取,然后由领域专家review和修正。这个人工成本是不低的,一万篇文档大概需要两个人花三周时间做质量审核。所以如果你的知识库规模大、更新频繁,纯知识图谱的方案在维护成本上可能会让你吃不消。

另一个问题是schema设计。知识图谱需要预先定义实体类型和关系类型,这个schema设计得不好,后面很难改。我们在一个项目里,一开始没把"临时负责"和"正式负责"区分成两种关系类型,结果后面业务方要查"正式负责人是谁"的时候,发现数据里混着一堆临时代理的关系,只能回去改schema重新导数据。


混合方案:大多数实际项目的落脚点

说实话,我做的三个项目最终都走向了某种程度的混合方案,区别只在于混合的方式不同。

方案一:向量检索为主,知识图谱做补充

适合知识库以非结构化文档为主、但有一部分核心实体关系需要精确查询的场景。

具体做法是:先用向量检索召回相关文档片段,同时从用户query中提取实体,去知识图谱里查相关的结构化信息(比如实体的属性、关联实体),然后把两部分结果一起塞给LLM做生成。

我们在一个内部知识库项目里用的就是这个方案。向量检索负责回答"这个东西是什么""怎么用"这类问题,知识图谱负责回答"谁负责的""依赖了哪些组件""上下游是什么"这类关系型问题。路由层根据query的类型决定走哪条路径,或者两条都走然后合并结果。

实际效果是,相比纯向量检索,整体的答案准确率提升了大约15个百分点(从71%到86%),主要提升来自于那些关系型问题——之前纯向量方案基本答不对的,加了知识图谱之后大部分能答对了。

方案二:知识图谱为主,向量检索做兜底

适合领域知识已经有比较完善的本体结构(ontology)、但又不可能把所有知识都塞进图谱的场景,比如医疗、金融。

做法是:用户query先尝试转成图查询(Text-to-Cypher),如果图谱里能查到结果,直接返回;如果查不到(可能是图谱覆盖不全,或者query太模糊没法转成图查询),再fallback到向量检索。

这个方案的核心难点在Text-to-Cypher这一步。让LLM把自然语言问题翻译成Cypher查询,对schema的理解能力要求很高,而且很容易生成语法正确但语义错误的查询。我们的做法是给LLM提供完整的schema定义和几个few-shot example,同时对生成的Cypher做语法校验和结果合理性检查(比如返回结果为空的时候自动fallback)。

方案三:Graph RAG

这是最近比较热的一种思路,微软去年开源的GraphRAG项目把这个概念带火了。核心思想是用LLM从文档中自动构建社区级别的知识图谱,然后在检索时利用图的社区结构做多层次的摘要和检索。

我试过这个方案,说说真实感受:对于"全局性问题"(比如"这个代码库整体的架构是怎样的")效果确实比纯向量检索好,因为它能把分散在多个文档里的信息通过图的社区结构汇总起来。但缺点也很明显——构建索引的成本极高(token消耗是纯向量方案的几十倍),而且对于细节性的点查询("某个函数的参数是什么"),效果反而不如简单的向量检索。

所以GraphRAG更适合那种需要跨文档总结和全局视角的场景,不太适合做精确的事实查询。


选型的决策框架

如果让我把经验总结成一个决策流程,大概是这样的:

先看数据:

  • 数据主要是非结构化文本(文档、邮件、记录)→ 向量数据库为主
  • 数据有清晰的实体关系结构(组织架构、产品依赖、知识本体)→ 知识图谱为主
  • 两种都有 → 混合方案

再看查询:

  • 用户问的主要是"是什么""怎么做"→ 向量检索擅长
  • 用户问的主要是"谁和谁有什么关系""A通过什么路径影响B"→ 知识图谱擅长
  • 都有 → 做路由,不同类型的问题走不同的检索路径

最后看团队和资源:

  • 团队没有图数据库经验、项目周期紧 → 先用向量数据库快速上线,后面再考虑引入知识图谱
  • 有领域专家能参与schema设计和数据质量审核 → 可以上知识图谱
  • 知识库更新频繁 → 向量数据库的维护成本明显更低

一些容易踩的坑

最后说几个我自己踩过的具体的坑:

1. 别在向量检索上死磕多跳推理。 我见过有团队用很复杂的prompt chain试图在纯向量检索的基础上实现多跳推理——先检索一次拿到中间结果,把中间结果再作为query检索第二次,如此反复。能跑通,但召回的噪音会随着跳数指数级放大,三跳以上基本不可用。这种场景就老老实实用知识图谱。

2. 知识图谱的"冷启动"比你想象的慢。 如果你的领域没有现成的本体结构可以复用,从零开始设计schema、抽取三元组、做实体消歧,光前期准备工作就可能要一两个月。别低估这个时间。

3. 向量数据库的embedding模型选型很关键。 我们早期用的是通用的sentence-transformers模型,后来换成了在领域数据上fine-tune过的embedding模型,召回率提升了12个百分点。如果你的领域有大量专业术语,通用模型的效果可能会打折扣。

4. 混合方案里的路由层不要过度设计。 一开始我们试过用分类模型来判断query该走哪条路径,后来发现用几条简单的规则(比如query里有明确的人名/组织名就走知识图谱,否则走向量检索)效果反而更稳定。工程上的简单往往比算法上的精巧更可靠。

以上是我的实际经验,希望对正在做RAG系统技术选型的人有点参考价值。

上次编辑于: