Vector | Graph:蚂蚁首个开源Graph RAG框架设计解读
在RAG领域深耕了一段时间的朋友应该都有体会——检索增强生成技术确实是个好东西,但真正落地时,那叫一个“坑多路滑”。大模型推理时信口开河的“幻觉”问题,靠它缓解了不少,可架不住现有框架和工具链各成一派,换一个场景就得重新搭积木。

那么问题来了:有没有一个足够通用的RAG框架,既能兼容现在主流的向量数据库,又能把知识图谱那套图数据库也请进门,还能给未来可能冒出来的新索引格式留个扩展口?答案是肯定的。本文就聊聊我们怎么设计这样一个框架,以及它在蚂蚁的开源生态里是如何落地的。
一、概述
RAG的核心逻辑很直白:把知识库里的文档检索出来,当作提示词的上下文喂给大模型,让它产出更靠谱的答案。再往前走一步,整个RAG链路还能跟提示词工程、模型微调、知识图谱这些技术玩“合体”,构成一个更广义的RAG问答链路。
(图:广义的RAG问答链路)
其实RAG的理念不仅能用来增强生成,还可以渗透到链路的不同阶段:
- REALM在预训练阶段就塞进一个知识检索器,让大模型从一开始就学会“翻书”回答问题,效果和可解释性都有提升。
增强训练:
- RA-DIT对大模型和检索器做双指令微调,RAFT则通过微调让大模型学会识别哪些是干扰文档——相当于训练了一个“文档质检员”。
增强微调:
- MuRAG支持多模态数据检索,图像和文本混着查,推理质量自然更扎实。
增强语料:
- GraphRAG用图社区摘要来搞定总结性查询,等于把知识图谱技术直接请进了RAG。
增强知识:
- CRAG给检索到的文档做置信度评估,动态决定要不要用、用多少,上下文质量一下就上去了。
增强检索:
- RAT干脆把RAG和思维链CoT结合起来,一边推理一边检索,长程推理和生成任务的表现明显改善。
增强推理:
好了,铺垫这么多,重点来了:引入知识图谱之后,传统的RAG链路会变成什么样?向量数据库和图数据库怎么兼容?蚂蚁开源的Graph RAG方案到底怎么用、往哪优化?下面逐一展开。
二、传统RAG
先快速回顾一下传统RAG的核心链路。
(图:基于Vector的RAG链路)
传统RAG的流程分三段:
- 用Embedding模型把文档编码成向量,塞进向量数据库。
索引(向量嵌入):
- 把用户查询也编码成向量,然后用近似最近邻搜索(ANN)捞回TopK结果。
检索(相似查询):
- 把检索到的文档拼成上下文,跟问题一起喂给大模型。
生成(文档上下文):
理想很丰满,现实却很骨感。传统RAG看起来天衣无缝,真用起来问题一堆。有篇论文专门总结了7个典型痛点:
(图:传统RAG的不足)
- 文档库里压根没有能回答问题的内容,系统只能瞎编。理想情况应该大大方方说“抱歉,不知道”。
知识库内容缺失:
- 那些跟查询相关的文档,因为相似度排名不够靠前,被无情地截掉了——相似度分数不等于相关性,这事儿谁都头疼。
TopK截断有用文档:
- 明明数据库里捞到了正确答案,结果重排序或过滤规则一折腾,有用的东西被丢掉了。
上下文整合丢失:
- 大模型能力有限,价值连城的内容摆在面前,它愣是没看出来。尤其是上下文里噪音太多或者信息互相矛盾的时候。
有用信息未识别:
- 指令写得太别扭,大模型根本理解不了用户到底想问什么。
提示词格式问题:
- 大模型要么没用好上下文,要么用得太过了。比如给学生找老师,首要看教育资源,结果它跑去纠结具体是谁。另外用户问题太笼统也会翻车。
准确性不足:
- 只基于上下文给答案,不像人类会分而治之。比如问“文档A、B和C的主流观点是什么”,更好的做法是逐个提问再总结。
答案不完整:
如果把这些问题归归类:
- 属于知识库工程层面——完善知识库、增强知识确定性、优化上下文整合策略都能帮上忙。
问题1~3
- 是大模型自身能力问题,只能靠训练和迭代来解决。
问题4~6
- 是RAG架构层面的硬伤,更有前景的方案是用Agent引入规划能力。
问题7
传统RAG的短板看得清清楚楚,Graph RAG就是从“增强知识确定性”这个角度切入的改进方案。它把原来基于向量的知识库,换成了用知识图谱(Graph)来存储和检索。
(图:基于Graph的RAG链路)
Graph RAG的核心链路也分三个阶段:
- 靠LLM从文档里抽取出(主体,关系,客体)这样的三元组,写入图数据库。
索引(三元组抽取):
- 同样靠LLM从用户查询里提取关键词(同时考虑大小写、别称、同义词这些花样),然后基于关键词在图里做DFS/BFS遍历,召回N跳以内的局部子图。
检索(子图召回):
- 把局部子图数据格式化成文本,作为上下文和问题一起交给大模型处理。
生成(子图上下文):
需要特别说明的是,三元组抽取和关键词提取现在都靠文本大模型完成,传统的NLP技术(分词、句法分析、实体识别)已经不是最优选。而且借助模型微调,可以针对性地打造知识抽取、实体识别甚至图查询语言翻译的专用模型。比如蚂蚁和浙大联合研发的OneKE,在零样本泛化性能上全面超越了现有模型。还有一个方向是Text2GQL、Text2Cypher这类微调模型,可以直接把自然语言翻译成图查询语言,比单纯基于关键词的子图搜索精确得多。
(图:OneKE知识抽取模型能力透视)
四、通用RAG设计
对比传统RAG和Graph RAG会发现,两者核心差异其实就一点:知识存储格式从Vector变成了Graph,随之带来索引、检索、生成阶段数据格式的变化。但RAG的关键流程骨架根本没变。这么一看,完全可以把它们抽象成一个更通用的RAG结构——既能兼容向量索引,也能兼容图索引,甚至全文索引等其他格式。
4.1 架构设计
一个兼容多种知识索引格式的通用RAG架构,可以这样设计:
- 所有索引存储统一抽象成
IndexStore,LLM服务作为构建索引的能力依赖(文本模型、嵌入模型等)。 - 当下支持向量存储(
VectorStore)和知识图谱(KnowledgeGraph)两种,其他索引格式保留扩展能力。 - 知识图谱层负责知识表示和语义抽象,数据底座是图存储(
GraphStore),也可以直接对接外部知识图谱系统。 - 最底层接入多样化的向量数据库、图数据库、大模型服务等外部组件。
- 最上层借助
IndexStore核心抽象,搭配外围的Loader/Splitter实现文本读取切分、Transformer实现索引构建、Retriver/Synthesizer实现知识检索与合成——完整的RAG能力就这样搭起来了。
(图:通用RAG架构)
4.2 领域建模
建模是架构落地的第一步。这里对通用RAG的核心设计做几点说明:
- 为了让框架足够灵活,把索引的加工和存储分离,使用“桥接模式”构建抽象依赖关系。
- 索引的加工接口(
Transformer)提供三类实现:嵌入、抽取、翻译。向量索引走嵌入(如Text2Vector、OpenAI Embedding),图索引走抽取(如三元组抽取、关键词抽取)。翻译作为通用能力单独对待,承载DSL的模型微调能力(如Text2SQL、Text2GQL、Text2Cypher)。索引加工的输入是Splliter切分好的文本块(未来也可以是多模态数据),输出是索引存储系统,成为连接内容和存储的桥梁。 - 索引的存储接口(
IndexStore)提供向量存储和知识图谱两类实现。知识图谱接口依赖于图存储接口,也可单独实现。注意:图存储系统定位是数据基座而非搜索语义,它和向量存储不在同一个架构层次。 - 大模型服务的接口设计未在图中展开,可以将其看做索引加工过程依赖的内部能力。
(图:通用RAG建模)
4.3 技术选型
要构建一个完整的开源Graph RAG链路,离不开三个子系统:可支持RAG的AI工程框架、知识图谱系统、图存储系统。开源的AI工程框架有LangChain、LlamaIndex、RAGFlow、DB-GPT等;知识图谱系统有Jena、RDF4J、Oxigraph、OpenSPG等;图存储系统有Neo4j、JanusGraph、NebulaGraph、TuGraph等。蚂蚁首个对外开源的Graph RAG框架,选用了全自主的开源产品:DB-GPT + OpenSPG + TuGraph。
(图:蚂蚁Graph RAG开源方案)
4.3.1 AI工程框架(@DB-GPT)
DB-GPT是一个开源的AI原生数据应用开发框架,目标是构筑大模型领域的基础设施。它集成了多模型管理、Text2SQL效果优化、RAG框架与优化、Multi-Agents框架协作、AWEL(智能体工作流编排)等多种能力,让围绕数据库构建大模型应用这件事更简单、更方便。
(图:DB-GPT技术架构)
4.3.2 知识图谱(@OpenSPG)
OpenSPG是蚂蚁集团结合多年金融领域多元场景知识图谱构建与应用经验,与OpenKG联合推出的基于SPG(Semantic-enhanced Programmable Graph)框架研发的知识图谱引擎。
(图:OpenSPG技术架构)
4.3.3 图数据库(@TuGraph)
TuGraph是蚂蚁集团与清华大学联合研发的大规模图处理系统,构建了包括图数据库、图计算引擎、图机器学习、图研发平台的完整图技术体系。它支持海量多源关联数据的实时处理,显著提升数据分析效率,支撑蚂蚁支付、安全、社交、公益、数据治理等300多个场景应用,多次打破图数据库性能基准测试LDBC-SNB世界纪录,跻身IDC中国图数据库市场领导者象限。
(图:TuGraph技术架构)
五、开源技术方案
在DB-GPT的v0.5.6版本中,完整的Graph RAG框架实现已经上线(PR 1506)。下面结合这个PR细说关键实现细节。
5.1 索引
索引加工的统一抽象是TransformerBase接口。目前提供嵌入、抽取、翻译三类转换器。图索引的构建,则通过三元组提取器TripletExtractor来实现。
(图:TransformerBase接口的继承树)
ExtractorBase接口负责信息提取。目前已有的三元组提取器和关键词提取器都依赖大模型能力,所以抽象类LLExtractor负责与LLM交互的公共逻辑,具体实现类只需要提供提示词模板和结果解析即可。TripletExtractor的提示词模板(受LlamaIndex启发),核心理念是用few-shot样本引导大模型生成三元组结构。
TRIPLET_EXTRACT_PT = (
"Some text is provided below. Given the text, "
"extract up to knowledge triplets as more as possible "
"in the form of (subject, predicate, object).n"
"A void stopwords.n"
"---------------------n"
"Example:n"
"Text: Alice is Bob's mother.n"
"Triplets:n(Alice, is mother of, Bob)n"
"...TL;DR..."
"Text: Philz is a coffee shop founded in Berkeley in 1982.n"
"Triplets:(Philz, is, coffee shop)n(Philz, founded in, Berkeley)n(Philz, founded in, 1982)n"
"---------------------n"
"Text: {text}n"
"Triplets:n"
)
大模型让三元组抽取变得极其简单,但抽得好不好又是另一回事。最简单的办法是通过提示词工程不断优化模板,让通用大模型给出更理想的答案。使用专有的知识抽取大模型(如OneKE)效果更好,这部分工作还在进行中,期待OnekeExtractor的社区贡献早日发布。
5.2 存储
索引存储的统一抽象是IndexStoreBase接口。目前提供向量、图、全文三类索引实现。知识图谱接口KnowledgeGraphBase是Graph RAG的存储底座,目前DB-GPT内置的BuiltinKnowledgeGraph基于文本大模型能力构建,OpenSPG的接入工作已经在推进中。
(图:IndexStoreBase接口的继承树)
知识图谱提供了和向量数据库一样的接口,让知识的存取过程透明化。文档内容经过三元组解析器解析后,直接写入图存储。
async def aload_document(self, chunks: List[Chunk]) -> List[str]:
"""Extract and persist triplets to graph store."""
for chunk in chunks:
triplets = await self._triplet_extractor.extract(chunk.content)
for triplet in triplets:
self._graph_store.insert_triplet(*triplet)
return [chunk.chunk_id for chunk in chunks]
图存储接口GraphStoreBase提供统一抽象。目前内置MemoryGraphStore和TuGraphStore的实现,分别用于本地测试和生产部署,并预留了Neo4jStore扩展点。
(图:GraphStoreBase接口的继承树)
具体图存储提供三元组写入的实现,一般调用图数据库的查询语言完成。例如TuGraphStore根据三元组生成Cypher语句并执行。
def insert_triplet(self, subj: str, rel: str, obj: str) -> None:
subj_query = f"MERGE (n1:{self._node_label} {{id:'{subj}'}})"
obj_query = f"MERGE (n1:{self._node_label} {{id:'{obj}'}})"
rel_query = (f"MERGE (n1:{self._node_label} {{id:'{subj}'}})"
f"-[r:{self._edge_label} {{id:'{rel}'}}]->"
f"(n2:{self._node_label} {{id:'{obj}'}})")
self.conn.run(query=subj_query)
self.conn.run(query=obj_query)
self.conn.run(query=rel_query)
5.3 检索
ExtractorBase的另一个实现是关键词抽取器KeywordExtractor,它从用户问题中提取实体关键词,同样借助大模型,也继承自LLExtractor。提示词模板如下:
KEYWORD_EXTRACT_PT = (
"A question is provided below. Given the question, extract up to "
"keywords from the text. Focus on extracting the keywords that we can use "
"to best lookup answers to the question.n"
"Generate as more as possible synonyms or alias of the keywords "
"considering possible cases of capitalization, pluralization, "
"common expressions, etc.n"
"A void stopwords.n"
"Provide the keywords and synonyms in comma-separated format."
"Formatted keywords and synonyms text should be separated by a semicolon.n"
"---------------------n"
"Example:n"
"Text: Alice is Bob's mother.n"
"Keywords:nAlice,mother,Bob;mummyn"
"Text: Philz is a coffee shop founded in Berkeley in 1982.n"
"Keywords:nPhilz,coffee shop,Berkeley,1982;coffee bar,coffee housen"
"---------------------n"
"Text: {text}n"
"Keywords:n"
)
关键词抽取涉及文本中的实体识别,构造提示词时要考虑大小写、别称、同义词,这部分优化空间还很大。另外用模型微调把自然语言直接翻译成图查询语句,也是个值得探索的方向。图存储接口GraphStoreBase提供了基于关键词的探索接口explore,会根据抽取的关键词召回局部子图。
@abstractmethod
def explore(
self,
subs: List[str],
direct: Direction = Direction.BOTH,
depth: Optional[int] = None,
fan: Optional[int] = None,
limit: Optional[int] = None,
) -> Graph:
"""Explore on graph."""
接口参数说明:
subs:子图搜索的起点列表。direct:搜索方向,默认双向,即同时探索引用和被引用关系。depth:搜索深度,控制最大跳数,默认不限。fan:扇出限制,控制每跳最大邻居数,避免数据热点,默认不限。limit:结果边数限制,默认不限。
返回值是Graph接口类型,表示搜索结果子图,提供了便捷的点边更新API。TuGraph的explore核心逻辑是把上述参数转成Cypher查询语句:
query = (f"MATCH p=(n:{self._node_label})"
f"-[r:{self._edge_label}*1..{depth}]-(m:{self._node_label}) "
f"WHERE n.id IN {subs} RETURN p LIMIT {limit}")
5.4 生成
和其他向量数据库类似,BuiltinKnowledgeGraph同样实现了IndexStoreBase的相似性查询接口。
async def asimilar_search_with_scores(
self,
text,
topk,
score_threshold: float,
filters: Optional[MetadataFilters] = None,
) -> List[Chunk]:
"""Search neighbours on knowledge graph."""
keywords = await self._keyword_extractor.extract(text)
subgraph = self._graph_store.explore(keywords, limit=topk)
content = (
"The following vertices and edges data after [Subgraph Data] "
"are retrieved from the knowledge graph based on the keywords:n"
f"Keywords:n{','.join(keywords)}n"
"---------------------n"
"You can refer to the sample vertices and edges to understand "
"the real knowledge graph data provided by [Subgraph Data].n"
"Sample vertices:n(alice)n"
"Sample edges:n(alice)-[reward]->(alice)n"
"---------------------n"
f"Subgraph Data:n{subgraph.format()}n"
)
return [Chunk(content=content, metadata=subgraph.schema())]
关键词通过_keyword_extractor完成抽取,然后传给_graph_store做子图探索,结果直接格式化成提示词上下文字符串content。
这里有个巧思:子图探索结果封装为Graph接口类型,还提供了一个MemoryGraph工具类。这样实现图探索接口时,无需把查询结果转成Path/Table等内存不友好的格式,同时降低了提示词中编码子图数据的token开销。当然,这建立在大模型对Graph数据结构有原生理解能力的基础上——相信当下主流大模型都具备这个能力。
(图:Graph接口的核心API)
5.5 测试
用《变形金刚》的故事情节作为测试文本,验证DB-GPT上Graph RAG的效果。具体操作手册见DB-GPT的文档《Graph RAG User Manual》。
启动DB-GPT后,新建Knowledge Space,选择Knowledge Graph存储类型。上传文本文件后切片自动构建图索引。
(图:创建知识图谱)
构建好的知识图谱支持快速预览。
(图:知识图谱预览)
基于知识图谱的对话测试。
(图:知识图谱对话)
六、优化方向
如果对DB-GPT上Graph RAG实现做初步测试,会发现当下仍有不少体验问题。除了功能完善度原因,也包含Graph RAG自身设计上的不足。有文章总结了Graph RAG的三大类局限:
- 如何构建高质量的知识图谱?
信息抽取:
- 如何在知识图谱上生成查询?
查询生成:
- 如何限制查询结果的规模?
推理边界:
前边提到的知识抽取/关键词/查询语言微调模型,主要专注于信息抽取和查询生成。另外,论文实现的基于图的推理增强框架(RoG)则是在推理边界方向上尝试创新。
(图:RoG:基于图的推理增强)
这三个阶段也可以简化合并为两个:内容索引阶段和检索生成阶段。下面分别讨论可能的优化方向。
6.1 内容索引阶段
这个阶段的核心目标是构建高质量的知识图谱。值得探索的方向包括:
- 从文本到知识图谱是非结构化信息到结构化信息的转换。有结构的LPG(Labeled Property Graph)除了有利于图存储性能优化,还能协助大模型更好地理解图谱语义,生成更准确的查询。
图谱元数据:
- 通用大模型在三元组识别上实际效果并不理想,针对知识抽取的微调模型表现更好,比如OneKE。
知识抽取微调:
- 微软的Graph RAG研究工作表明,构建知识图谱的同时生成图社区摘要,可以解决知识图谱面对总结性查询时“束手无策”的问题。结合图社区摘要与子图明细,能生成更高质量的上下文。
图社区总结:
- 多模态知识图谱能大幅扩展内容丰富度,对客观世界数据更友好。浙大的MyGO框架提升了MMKGC的准确性和可靠性。Graph RAG可借助MMKG和MLLM实现更全面的多模态RAG能力。
多模态知识图谱:
- 同时使用向量/图等多种存储系统,结合传统RAG和Graph各自的优点。有文章提出了多种混合架构,如语义聚类、图谱向量双上下文增强、向量增强图谱搜索、混合检索等,能充分利用不同存储的优势提升检索质量。
混合存储:
(图:混合检索的Graph RAG)
6.2 检索生成阶段
这个阶段的核心目标是从知识图谱上召回高质量上下文。值得探索的方向:
- 除了基本的关键词搜索,还可以尝试使用图查询语言微调模型,直接把自然语言翻译成图查询语句。这需要结合图谱元数据才能获得更准确的翻译结果。Text2GQL方向的初步工作已经在做了。
图语言微调:
- 与混合存储一体两面。借助底层向量/图/全文索引,结合关键词/自然语言/图语言多种检索形式,针对不同业务场景探索高质量上下文的构建。
混合RAG:
- Graph RAG的测试可参考传统RAG的Benchmark方案,如RAGAS、ARES、RECALL、RGB、CRUD-RAG等。
测试验证:
- 某种意义上,RAG本身就是Agent的简化形式(知识库可看作检索工具)。当下RAG对记忆和规划能力的集成诉求(如RAT/RoG)越来越明显,未来RAG向带有记忆和规划能力的智能体架构演进几乎是必然趋势。而Agent自身需要的长期记忆存储也会反向依赖RAG的知识库——两者相辅相成、互相促进。
RAG智能体:
七、尾记
通过以上介绍,相信大家对RAG到Graph RAG的技术演进有了更清晰的了解。基于RAG的索引、检索、生成三个基本阶段,我们抽象出了通用的RAG框架,兼容了Vector、Graph、FullText等多种索引形式,并在开源技术中完整落地。最后探讨了Graph RAG未来的优化与演进方向,总结了内容索引和检索生成阶段的改进思路,以及RAG向Agent架构演化的趋势。Graph RAG是一个相对新颖的AI工程领域,需要探索和改进的工作还有很多。Jerry Liu(LlamaIndex CEO)在技术报告《Beyond RAG: Building Advanced Context-Augmented LLM Applications》中也提出了“RAG的未来是Agent”的观点。不管是“RAG for Agents”还是“Agents for RAG”,亦或是“从RAG到Graph RAG再到Agents”,可以确定的是,智能体将是未来AI应用的主旋律。
-
- 关于宇宙的好的网名有哪些
- 角色扮演 | 1
- 网名