ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

RAG知识库和知识图谱到底啥关系?搞大模型应用前得先弄明白

RAG知识库和知识图谱到底啥关系?搞大模型应用前得先弄明白 前言如果你正在给公司做基于大模型的知识问答系统大概率绕不开两个词RAG知识库和知识图谱。这篇文章就是帮你把这两个概念彻底掰扯清楚顺便讲明白它们在实际项目里怎么配合。适合谁看正在做AI应用落地、被老板催着出方案的后端和算法同学以及想搞清楚技术选型的产品经理。看完你能收获一套可落地的RAG图谱混合架构思路以及我们团队踩过的真实坑。问题背景去年下半年我陪一个做工业设备维保的客户聊需求。他们攒了十几年的维修工单、设备手册、专家经验全塞在共享盘里。老板想做个“能问能答”的系统让新来的维修工对着手机就能查故障。一开始我们想得很简单上RAG把文档切片、向量化接个大模型就完事。结果第一版demo跑出来问“A型号泵在高温环境下轴承异响怎么处理”模型答得头头是道但把B型号的处置方案混进去了。维修工真按这个去拆机器是要出事的。问题出在哪文档切片把“A型号”和“B型号”的上下文切散了向量检索只认语义相似不认实体之间的硬关系。这时候知识图谱才被我们重新捡起来。原理先把两个东西说透RAG知识库是什么RAGRetrieval-Augmented Generation检索增强生成。说白了就是用户问问题系统先去知识库里捞相关片段再把片段塞进提示词让大模型基于这些片段回答。它的核心是“向量检索”。文档切成chunk用embedding模型转成向量存进向量数据库Milvus、Qdrant、pgvector都行。查询时算余弦相似度取Top-K。优点很直接搭建快两周能出东西对非结构化文本友好手册、FAQ、聊天记录都能塞。缺点也明显它不理解实体关系。你问“张三的上级是谁”如果文档里没直接写这句话只是分散在几处提到RAG大概率拼不出来。知识图谱是什么知识图谱是另一套东西。它把信息拆成“实体-关系-实体”的三元组比如A型号泵适用场景高温环境、A型号泵故障表现轴承异响。存进Neo4j、NebulaGraph这类图数据库。查询靠的是图遍历不是相似度。你问“A型号泵高温异响怎么处理”系统能沿着“泵→故障→处置方案”这条路径精确走不会串到B型号。但图谱的毛病是构建成本高。要么靠人工抽要么靠模型抽还得做实体对齐、消歧。一个中型项目光schema设计就能吵两周。二者关系一句话RAG管“广度”图谱管“精度”。RAG像图书馆的检索员你报个关键词他抱一堆书过来里面可能有你需要的也可能夹着无关的。图谱像老技师脑子里的关系网你提个设备他直接告诉你哪个零件跟哪个故障连着。实际项目里它们不是二选一而是互补。我们后来的方案是图谱负责实体链接和关系约束RAG负责把相关文本片段捞出来给模型做上下文。实操一个混合检索的简化实现下面是我们团队验证过的最小可行代码用Python串起图谱查询和向量检索。fromneo4jimportGraphDatabasefromsentence_transformersimportSentenceTransformerimportnumpyasnp# 1. 图谱查询先锁定实体classGraphRetriever:def__init__(self,uri,user,password):self.driverGraphDatabase.driver(uri,auth(user,password))defget_related_entities(self,entity_name):query MATCH (e:Entity {name: $name})-[r]-(related) RETURN e.name AS source, type(r) AS relation, related.name AS target LIMIT 20 withself.driver.session()assession:resultsession.run(query,nameentity_name)return[dict(record)forrecordinresult]# 2. 向量检索捞文本片段classVectorRetriever:def__init__(self,model_nameparaphrase-multilingual-MiniLM-L12-v2):self.modelSentenceTransformer(model_name)self.doc_embeddings[]self.doc_texts[]defadd_documents(self,texts):self.doc_textstexts self.doc_embeddingsself.model.encode(texts)defsearch(self,query,top_k5):q_embself.model.encode([query])[0]scoresnp.dot(self.doc_embeddings,q_emb)top_idxnp.argsort(scores)[-top_k:][::-1]return[(self.doc_texts[i],scores[i])foriintop_idx]# 3. 混合调度defhybrid_retrieve(query,graph_retriever,vector_retriever):# 简单实体抽取实际项目用NER模型entityquery.split(的)[0]if的inqueryelsequery[:4]graph_contextgraph_retriever.get_related_entities(entity)vector_contextvector_retriever.search(query,top_k3)# 图谱结果转成文本拼进提示词graph_text\n.join([f{r[source]}--{r[relation]}--{r[target]}forringraph_context])vector_text\n.join([tfort,_invector_context])returnf【图谱关系】\n{graph_text}\n\n【文档片段】\n{vector_text}这段代码跑通后那个工业客户的问答准确率从第一版的六成出头提到了八成五左右。关键改动就是图谱先把实体关系框死向量检索只在相关子集里捞文本。踩坑坑一以为图谱能自动建。我们一开始想用大模型直接抽三元组结果抽出来的关系五花八门“属于”“是”“包含”混着用schema根本收敛不了。后来老老实实人工定义了二十来个关系类型模型只负责填槽。坑二向量维度选太大。有同事非要用1024维的模型说效果好。结果检索延迟从80毫秒涨到400多毫秒用户等不及。换成384维的轻量模型效果掉了一点点但响应快了一倍。坑三图谱和向量库的数据不同步。设备手册更新了向量库重新索引了图谱忘了改。结果模型拿着旧关系去解释新文档答非所问。后来加了个定时任务两边一起刷。还有个不算坑的坑别指望一套方案打天下。我们给另一个做餐饮的客户做菜品知识库图谱基本没用上纯RAG加关键词过滤就够了。技术选型得看数据形态。总结RAG知识库和知识图谱不是谁替代谁的问题。RAG解决“找得到”图谱解决“找得准”。数据关系简单、文档量不大RAG单干就行实体关系复杂、容错率低图谱得进来兜底。真要上混合架构先想清楚schema再考虑模型。别一上来就堆技术栈最后维护成本能把人拖垮。有在做的同学欢迎评论区聊聊你们踩过的坑。
返回列表