GraphRAG从Demo到上线,为什么团队接手总是翻车?
这篇不先堆名词。我们把《GraphRAG跑通那天,我才发现前面的学习顺序反了》拆成几级台阶,看完至少知道下一步该学什么、该练什么。
摘要
最近公司引入Claude Code做团队级AI编程,Demo阶段大家觉得挺香,结果联调时才发现:不同人的代码风格、权限边界、日志规范完全对不上,协作效率反而下降了。这件事让我意识到,AI工具从个人试用到团队协作,从来不缺能跑通Demo的人,缺的是能把边界和约束说清楚的人。
回到GraphRAG这个话题,我见过太多项目:一个人能跑通,团队接手就崩。原因往往不是模型不够强,而是知识图谱的建模标准和实体抽取逻辑没有统一。今天聊的,就是我在两个企业知识库项目里踩过的坑和总结的判断标准。
目录
- 传统RAG的瓶颈:为什么纯向量检索不够用
- 知识图谱建模:先别急着抽实体,先把边界想清楚
- 实体关系抽取:规则优先,模型兜底
- 图检索增强:查询时再决定怎么走图
- 评估与优化:别只看准确率,要看场景覆盖率
- 总结
传统RAG的瓶颈:为什么纯向量检索不够用

第一个项目是做一个内部技术文档问答系统。当时用的是标准RAG流程:文档切片、向量化、检索、生成。Demo效果很好,准确率看起来不错。
但上线一个月后,问题开始暴露。
最典型的是一个问题:"我们去年Q3的API限流策略是什么?"
系统能检索到相关文档片段,但答案往往分散在多个切片里,模型需要自己拼凑。更严重的是,当问题涉及跨文档的关联推理时,比如"限流策略和之前的权限变更有什么关系",纯向量检索直接失效。
原因在于,向量检索的本质是语义相似度匹配,它擅长"找相似的内容",但不擅长"梳理内容之间的关系"。当知识库里的信息存在实体关联、层级结构、因果关系时,单纯靠向量相似度会丢失这些结构化信息。
我当时在文档里加了很多注释和标签,试图弥补这个问题,但效果有限。后来才明白,缺的不是更多标注,而是真正的知识图谱。
知识图谱建模:先别急着抽实体,先把边界想清楚

第二个项目是做一个合规知识库系统,涉及制度文档、操作手册、历史案例三类数据。
第一个坑:建模阶段我们急于抽实体,先把文档扔进NER模型里跑了一遍,结果抽出来几千个实体,关系乱七八糟。
后来我们停下来重新想:这个系统的核心查询场景是什么?
经过和合规团队的沟通,我们明确了三类核心问题:
1. 某个操作是否符合规定?
2. 不同制度之间是否存在冲突?
3. 历史案例对当前问题有什么参考?
基于这三类问题,我们重新设计了图谱 schema:
- 核心实体:制度、条款、操作、案例
- 核心关系:引用、约束、冲突、参考
这个schema非常克制,只保留了能回答上述三类问题的实体和关系。很多人做GraphRAG的误区是一上来就追求"全",把文档里所有名词都当成实体,结果图谱膨胀、维护成本爆炸。
我的判断标准是:每个实体和关系,都必须能对应到至少一个真实查询场景。如果抽出来的实体没人会问,那就不要。

实体关系抽取:规则优先,模型兜底
有了schema,接下来是抽取。这里我强烈建议规则优先,模型兜底。
我们当时的做法是:
1. 对制度类文档,用正则表达式提取条款编号、章节结构、生效日期等关键信息,这部分准确率接近100%。
2. 对案例类文档,用规则提取"问题描述-处理依据-处理结果"的三段式结构。
3. 模型只负责处理规则覆盖不到的模糊边界,比如从自然语言描述中提取操作主体和对象。
代码层面,我们写了一个简单的抽取管线:
import re
from typing import List, Dict, Tuple
class RuleBasedExtractor:
"""规则优先的实体关系抽取器"""
def __init__(self):
# 制度条款匹配模式
self.clause_pattern = re.compile(
r'(第[一二三四五六七八九十\d]+章|第[一二三四五六七八九十\d]+条)',
re.UNICODE
)
# 案例结构匹配模式
self.case_pattern = re.compile(
r'(问题描述|处理依据|处理结果)',
re.UNICODE
)
def extract_clauses(self, text: str) -> List[Dict]:
"""从制度文档中提取条款结构"""
clauses = []
current_chapter = None
current_clause = None
for line in text.split('\n'):
line = line.strip()
if not line:
continue
# 匹配章节
chapter_match = re.search(r'第([一二三四五六七八九十\d]+)章', line)
if chapter_match:
current_chapter = chapter_match.group(0)
continue
# 匹配条款
clause_match = re.search(r'第([一二三四五六七八九十\d]+)条', line)
if clause_match:
current_clause = clause_match.group(0)
clauses.append({
'chapter': current_chapter,
'clause': current_clause,
'content': line
})
return clauses
def extract_case_structure(self, text: str) -> Dict:
"""从案例文档中提取三段式结构"""
result = {}
sections = self.case_pattern.split(text)
for i, section in enumerate(sections):
if i == 0:
continue
key = sections[i-1].strip() if i > 0 else ''
if key in ('问题描述', '处理依据', '处理结果'):
result[key] = section.strip()
return result
这个思路的核心是:规则处理结构化程度高的部分,模型处理模糊边界。这样既保证了关键信息的准确率,又控制了模型的调用成本。
实际运行中,我们对制度文档的条款抽取准确率达到了95%以上,案例文档的结构抽取准确率达到88%。剩下的部分才交给LLM处理。
图检索增强:查询时再决定怎么走图
图谱建好了,怎么用?这是第二个大坑。
我们最初的做法是:查询时先把问题转成实体,然后在图里做多跳遍历,把遍历到的子图喂给LLM。
结果发现两个问题:
1. 多跳遍历的候选答案太多,Prompt塞不下。
2. 有些问题其实不需要走图,直接向量检索更快。
后来我们改成了一种"按需走图"的策略:
1. 先用向量检索找到最相关的文档片段。
2. 从片段中提取实体,判断是否需要走图。
3. 如果需要,才在图里做1-2跳的邻居扩展,补充上下文。
4. 把向量检索结果和图扩展结果合并,一起喂给LLM。
这种策略的优势是:简单问题快速响应,复杂问题才有图谱参与。
代码层面,我们实现了一个简单的图扩展逻辑:
class GraphRAGRetriever:
"""按需走图的检索器"""
def __init__(self, vector_store, graph_db):
self.vector_store = vector_store
self.graph_db = graph_db
def retrieve(self, query: str, max_hops: int = 2) -> Dict:
# 第一步:向量检索
vector_results = self.vector_store.search(query, top_k=5)
# 第二步:提取实体
entities = self._extract_entities(query, vector_results)
# 第三步:判断是否需要图扩展
if self._need_graph_expansion(entities, vector_results):
# 第四步:图遍历扩展
graph_context = self._expand_graph(entities, max_hops)
return {
'vector_results': vector_results,
'graph_context': graph_context,
'used_graph': True
}
return {
'vector_results': vector_results,
'graph_context': None,
'used_graph': False
}
def _need_graph_expansion(self, entities, vector_results):
"""判断是否需要图扩展的判断逻辑"""
# 简单启发式:如果实体数量多且向量结果分散,说明可能需要图谱关联
if len(entities) > 2:
scores = [r.score for r in vector_results]
if max(scores) - min(scores) > 0.15:
return True
return False
这里的关键是_need_graph_expansion的判断逻辑。我没有用复杂的模型判断,而是用了一个简单的启发式规则:实体数量多且向量结果分散时,说明问题可能涉及多个概念之间的关联,需要图谱参与。
这个判断逻辑可以根据实际业务场景调整,比如加入实体类型权重、关系类型权重等。
评估与优化:别只看准确率,要看场景覆盖率
很多项目做到这里就停了,因为没有明确的评估标准。
我们当时做了两件事:
第一,建立了场景覆盖矩阵。把合规团队提出的真实查询场景列出来,每个场景标注:需要向量检索、需要图谱、两者都需要。然后统计系统对每个场景的回答质量。
第二,建立了负例收集机制。让合规团队在系统上线后标记错误回答,定期分析错误类型,针对性优化。
经过三个月的迭代,场景覆盖率从65%提升到了92%。提升的关键不是模型换成了更强的,而是实体抽取规则和图扩展策略的优化。
总结
GraphRAG从Demo到上线,最大的差距不在技术,而在对边界和场景的理解。
我做这两个项目的最大体会是:
1. 建模阶段先想清楚查询场景,而不是急于抽实体。schema越克制,后期维护越轻松。
2. 抽取阶段规则优先,模型兜底。结构化信息用规则,模糊边界用模型。
3. 检索阶段按需走图,不是所有问题都需要图谱参与。
4. 评估阶段建立场景覆盖矩阵和负例收集机制,用真实业务数据驱动优化。
这些经验,和Claude Code从个人试用走向团队协作遇到的坑,本质上是同一个问题:能把Demo跑通的人很多,能把边界和约束说清楚的人很少。
GraphRAG的价值不在于用了多复杂的模型,而在于有没有把知识的关系说清楚。
资料展示
下面是我整理的AI大模型学习资料和工具包预览,适合收藏后按主题逐步学习。





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

更多推荐


所有评论(0)