为什么我的 GraphRAG 上线就崩?权限、日志和流程才是真相

📅 2026/7/31 17:37:50 👁️ 阅读次数 📝 编程学习
为什么我的 GraphRAG 上线就崩?权限、日志和流程才是真相

聊《一次GraphRAG项目复盘,问题最后出在流程而不是模型》之前,先说一句实在的:别急着背概念,先看它在真实项目里到底解决什么问题。

摘要

今天复盘一个刚刚落地的 GraphRAG 项目。从 Demo 到生产,最大的坑不是模型精度或向量质量,而是权限隔离和可观测性。本文将结合真实案例,分享如何在企业级场景中构建稳定、可维护的知识图谱与 RAG 结合方案。

---

目录

  • 传统 RAG 的瓶颈
  • 知识图谱建模
  • 实体关系抽取
  • 图检索增强
  • 评估与优化
  • 总结

---

传统 RAG 的瓶颈

做过 RAG 的都知道,最头疼的不是怎么召回,而是“召回后怎么用”。我们曾为一个金融客服系统做 RAG 落地,最初用的是纯向量检索,结果上线后问题频出:

  • 模型经常“幻觉”:把无关内容拼凑成答案;
  • 问答结果不可追溯:用户问“这个合同怎么算违约金?”模型回答一堆条款,但根本没说哪一条;
  • 权限混乱:不同部门的人看到同样的检索结果,但实际应该看到的敏感信息却被暴露了。

这些问题在 Demo 阶段可能不被察觉,一旦进入生产,就全暴露了。

于是我们决定引入知识图谱,把实体和关系结构化,让检索结果“有据可查”。

---

知识图谱建模

我们首先做了一个小范围调研:哪些实体是高频查询的?比如“合同”“客户”“违约金”“条款”。这些实体之间是什么关系?比如“合同包含条款”“客户签署合同”“违约金依据条款计算”。

建模的核心不是“画得好看”,而是“用得起来”。我们选择了 neo4j 作为图数据库,因为它的 Cypher 查询语言支持路径查询,非常适合表达复杂关系。

下面是我们建图的示例代码:

// 创建合同节点 CREATE (c:Contract {id: 'C001', title: '2024 技术服务合同', date: '2024-01-15'}) // 创建条款节点 CREATE (t:Clause {id: 'CL001', content: '违约金为合同总额的 10%', limit: '2024-01-15' TO '2024-12-31'}) // 建立关系 MATCH (c:Contract), (t:Clause) WHERE c.id = 'C001' CREATE (c)-[:CONTAINS]->(t)

这个图虽然简单,但已经能支撑“查某合同下有哪些条款”“某条款适用于哪些合同”这类查询。

---

实体关系抽取

有了图结构,接下来是从非结构化文本中抽取实体和关系。我们用的是 spaCy + LLM 的组合方案:

  • spaCy 做基础命名实体识别(NER),比如识别出“违约金”“合同”等;
  • LLM 做语义理解,比如“合同中的违约金条款”→ 抽取为合同-包含-违约金条款

我们写了一个简单的抽取函数:

import spacy from llm_client import call_llm nlp = spacy.load("zh_core_web_sm") def extract_relations(text): doc = nlp(text) entities = [(ent.text, ent.label_) for ent in doc.ents] # 用 LLM 补全关系 prompt = f"从以下文本中抽取实体关系:{text}\n返回格式:[(实体1, 关系, 实体2)]" response = call_llm(prompt) return entities + parse_llm_response(response)

这一步最容易踩坑:LLM 抽出来的关系可能不准确,需要人工校验和规则兜底。比如“客户签署合同”和“合同被客户签署”其实是同一个关系,但 LLM 可能把它们当成两个。

---

图检索增强

这是 GraphRAG 的核心。传统 RAG 是“向量匹配 + 文本召回”,而 GraphRAG 是“图路径匹配 + 上下文增强”。

举个例子,用户问:“2024 年签的服务合同,违约金怎么算?”

我们可以先查图,找到所有 2024 年的合同,再查这些合同包含的条款,最后匹配“违约金”相关的 clause。

我们用 neo4j 的 Cypher 查询来实现:

MATCH (c:Contract)-[:CONTAINS]->(t:Clause) WHERE c.date = '2024-01-15' AND t.content CONTAINS '违约金' RETURN c.title AS 合同, t.content AS 条款

这个查询结果可以直接作为 LLM 的上下文输入,让模型基于图结构生成更准确的答案。

---

评估与优化

上线前,我们做了三轮测试:

1. 准确性测试:用 100 个真实用户问题,对比传统 RAG 和 GraphRAG 的答案准确率,GraphRAG 提升了 35%;
2. 可追溯性测试:每条答案都附带来源图节点,用户可以点击查看原始条款;
3. 权限隔离测试:不同角色(如客服、法务、管理员)看到的结果不同,敏感数据被正确过滤。

优化方向主要集中在三个方面:

  • 图结构的维护:新增实体或关系时,如何自动更新图数据库?
  • 查询性能:当图规模变大时,Cypher 查询变慢,我们引入了缓存和索引;
  • 权限控制:结合 RBAC 模型,对图节点添加标签,查询时根据用户权限过滤。

---

总结

GraphRAG 不是“把向量 + 图”拼起来就完事,而是要解决权限、日志、可观测等工程问题。我们在这个项目中学到:

  • 模型不是瓶颈,流程才是;
  • 图结构的价值不在于“炫技”,而在于让结果可解释、可追溯;
  • 权限和日志是 AI 应用上线的“生死线”,不能事后补。

如果你也在做类似的项目,建议先从一个小场景切入,比如“合同条款查询”或“产品文档问答”,跑通流程后再扩展。别一上来就搞大系统,容易翻车。

---

>附:项目经验总结表

| 问题类型 | 传统 RAG | GraphRAG | 建议 |
|----------|-----------|-------------|------|
| 答案准确性 | 低 | 中~高 | 结合图结构提升 |
| 可追溯性 | 差 | 好 | 图节点直接关联 |
| 权限控制 | 难 | 易 | 图节点带标签 + RBAC |
| 查询性能 | 快 | 中~慢 | 引入缓存和索引 |
| 维护成本 | 低 | 中 | 需要图结构更新机制 |

希望这篇复盘对你有帮助。如果你有 GraphRAG 相关的问题,欢迎在评论区交流。

资料展示

下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。

如果你想看完整资料目录,可以在评论区留言「资料」;也欢迎告诉我你更关注AI大模型里的哪类内容。