大模型应用实战

企业知识库系列(03):图增强 RAG 实测——GraphRAG vs HippoRAG

同一套 89 道测试题,分别对 GraphRAG 3.1.1 和 HippoRAG 2.0 跑评测。本文记录从部署到出数据的完整过程,包括 GLM-4-flash 结构化输出失败、LanceDB 向量维度不匹配、NV-Embed-v2 离线加载等真实踩坑,以及两个框架在单跳、多跳、边界拒答三个维度上的真实数据。

·约 10 分钟阅读·AI Engineering

这篇的任务

前两篇建好了测试集,并测完了经典向量 RAG(QAnything vs LightRAG)。

这篇测"图增强 RAG"——理论上,知识图谱应该能帮助多跳推理:A 指向 B,B 指向 C,传统向量检索往往只能找到 B,而图结构能顺着边找到 C。

我选了两个代表框架:

  • GraphRAG 3.1.1(微软,2024 年把"图谱 RAG"这个词打出圈的那个)
  • HippoRAG 2.0(2025 年的学术框架,用海马体记忆模型类比图检索)

两个框架,同一套 89 道题(50 单跳 / 20 多跳 / 19 边界),同一个 LLM(GLM-4-flash),数字说话。


两个框架是什么东西

GraphRAG:LLM 驱动的知识图谱提取

GraphRAG 的流程比较重:先用 LLM 从文档里抽取实体和关系,构建一个显式的知识图谱;然后把图谱里的节点按社区(Louvain 算法)分组,每个社区用 LLM 生成摘要报告;查询时,local search 在图谱里做近邻检索,global search 则聚合全局社区报告。

文档 → LLM 抽实体/关系 → 知识图谱 → 社区划分 → 社区摘要报告

查询 ─── local search: 图谱近邻 + 向量检索 ──────────→ LLM 生成答案
      └── global search: 聚合社区报告 ─────────────→ LLM 生成答案

核心特点:建库成本极高(要对每个文本块调 LLM 抽关系),但建好后支持结构化图谱查询。

HippoRAG:海马体启发的图检索

HippoRAG 把检索过程类比成人类记忆的 PPR(Personalized PageRank)机制:用 LLM 从文档里提取三元组(实体、关系、实体),用大维度 embedding(NV-Embed-v2,1024 维)把所有实体存入向量索引,查询时先做向量召回找到种子节点,再沿图谱边做 PPR 扩散找到关联节点。

文档 → LLM 提取三元组 (head, rel, tail) → 知识图谱
     → NV-Embed-v2 把实体向量化 → 向量索引

查询 → 向量召回种子实体 → PPR 图谱扩散 → 召回相关段落 → LLM 生成答案

核心特点:依赖本地大模型 NV-Embed-v2(7B 参数,~14 GB),不依赖 LLM 做 embedding,理论上 embedding 质量更高。


部署过程与踩坑

GraphRAG:pipeline 比想象的脆

GraphRAG 用 YAML 配置文件驱动整个 pipeline,graphrag index 命令会按顺序执行一系列 workflow。文档挺齐,配置也不复杂,但有几个坑。

坑 1:LLM 不支持结构化输出导致 pipeline 崩溃

GraphRAG 的社区报告生成(create_community_reports)期望 LLM 返回 JSON,但 GLM-4-flash 的 structured output 实现不稳定,大量 prompt 会返回空 JSON,导致 DataFrame 里没有 "community" 列,merge 报 KeyError 直接崩溃。

解决方案是在 settings.yamlworkflows: 列表里跳过这个步骤,同时手动创建一个符合 schema 的空 community_reports.parquet——local search 会读这个文件,但允许它是空的。

坑 2:向量维度不匹配

GraphRAG 默认 vector_size: 3072(对应 OpenAI text-embedding-3-large),但我用的 BGE-large-en-v1.5 输出 1024 维。直接跑会报 Vector has dimension 1024, but index configured with 3072,需要在 settings.yaml 里手动加 vector_size: 1024

坑 3:全流程重跑会重新消耗 LLM 配额

第一次跑崩后,再次执行 graphrag index 会从头重跑所有步骤,包括已经完成的 extract_graph(对 4000+ 文本块调 LLM 提取实体关系,费时费钱)。需要单独写一个脚本只跑 generate_text_embeddings 步骤,利用已有的中间产物。

坑 4:SiliconFlow API 对特定内容拒绝

测试文档里包含 .env 配置文件的内容,里面有类 API key 格式的字符串。SiliconFlow 的内容过滤会对这类输入返回 400 错误(code 20015),导致 embedding 步骤批量失败。把 embed_text.names 限定为只嵌入 entity_description(而不是整个 text_unit),可以绕过这个问题,同时 local search 也不需要 text_unit 的 embedding。

HippoRAG:本地大模型的环境依赖地狱

HippoRAG 最大的依赖是 NV-Embed-v2,一个基于 Mistral-7B 的 7B embedding 模型。

坑 1:离线加载失败

NV-Embed-v2 的 modeling_nvembed.py__init__ 里调用 AutoTokenizer.from_pretrained("nvidia/NV-Embed-v2")(字符串 ID,非本地路径),导致 transformers 每次都去 HuggingFace hub 下载,断网环境直接报错。

解决方案是在脚本最顶部 monkey-patch AutoTokenizer.from_pretrained,把 "nvidia/NV-Embed-v2" 这个字符串重定向到本地模型路径。

坑 2:显存不足

RTX 3060(12 GB)在跑 NV-Embed-v2(Mistral-7B bf16,~14 GB 权重)时,device_map="auto" 会把部分层卸载到 CPU,但前向推理的激活值仍需要 GPU 临时空间。默认的 batch_size=16 加上 max_seq_len=2048 会导致 OOM。

调小参数即可:embedding_max_seq_len=512embedding_batch_size=1,同时显式指定 embedding_model_dtype="bfloat16" 防止 auto 选到 fp32。


评测数据

数值汇总

指标GraphRAG 3.1.1HippoRAG 2.0
建库时间31.1 min36.5 min
边界拒答率15.8%5.3%
P90 延迟32.4 s84.0 s
平均延迟26.6 s30.1 s
单跳匹配率0.1070.122
多跳匹配率0.2110.163
边界题匹配率0.0300.021

答案匹配用 Jaccard 关键词重叠,非 LLM judge;LLM 均为 GLM-4-flash

多跳推理:GraphRAG 赢了,但没赢太多

GraphRAG 的 multi_hop 匹配率 0.211,高于 HippoRAG 的 0.163。这符合预期——微软的论文里也是拿多跳推理作为卖点。

但差距没有大到"质变"的程度:0.211 vs 0.163,只高了约 30%。考虑到 GraphRAG 的建库成本(31 分钟,期间调用 LLM 提取了数千次实体关系),这个收益并不那么令人振奋。

和上一篇的向量 RAG 对比一下:LightRAG 的 multi_hop 匹配率是 0.152,QAnything 是 0.125。GraphRAG 的 0.211 确实比向量 RAG 高出不少,但 HippoRAG 的 0.163 仅比 LightRAG 高了一点点。

单跳检索:图增强没有优势

单跳事实查询("X 的默认值是什么")上,HippoRAG(0.122)比 GraphRAG(0.107)还略高,两者都不如上一篇的 LightRAG(0.156)。

这说明:知识图谱结构对直接的事实查询没有帮助,甚至有干扰。图谱检索路径更长,引入了更多的"图谱噪声"(社区摘要、关系路径),反而稀释了直接的答案。

边界拒答:GraphRAG 意外有优势

GraphRAG 的边界拒答率 15.8%,HippoRAG 只有 5.3%。这个差异出乎意料。

GraphRAG 的 local search 会说"根据知识库内容,我无法回答……",而 HippoRAG 因为 PPR 扩散几乎总能找到"相关"节点,LLM 便倾向于硬答。

不过,15.8% 对比上一篇 QAnything 的 52.6% 仍差距悬殊。图增强 RAG 在拒答上的表现整体不如有明确 confidence threshold 的向量 RAG 系统。

延迟:HippoRAG 慢得超出预期

HippoRAG 的 P90 延迟高达 84 秒,平均 30 秒。这和我最初的预期相反——本地模型推理应该更快才对。

原因是双重的:

  1. embedding_batch_size=1 降低了显存压力,但批量推理效率也大幅下降。在正常显存配置(A100 或 3090 Ti)下,batch_size 调回 16,嵌入速度会快 10-20 倍。
  2. HippoRAG 的查询路径比较长:向量召回 → PPR 扩散 → 段落组装 → LLM 生成,每步都有开销。

GraphRAG 的平均 26.6 秒也不快,主要是 GLM-4-flash 的 rate limit 压制了并发(concurrent_requests: 1)。


横向对比:四个框架的完整数据

把这两篇的数字放一起:

框架类型建库时间拒答率P90 延迟单跳多跳
QAnything v2向量 RAG~5 min52.6%49.2 s0.1320.125
LightRAG 1.5.6图+向量~8 min21.1%17.9 s0.1560.152
GraphRAG 3.1.1图 RAG31.1 min15.8%32.4 s0.1070.211
HippoRAG 2.0图 RAG36.5 min5.3%84.0 s0.1220.163

几个明显的规律:

  1. 建库时间跟"图谱有多重"正相关:LightRAG 靠 LLM 异步抽图,8 分钟;GraphRAG 和 HippoRAG 要对每个块调 LLM 提取结构化三元组,30 分钟级别。
  2. 多跳推理图 RAG 确实比向量 RAG 强:GraphRAG 0.211 vs LightRAG 0.152,图结构对多跳推理有统计上可见的优势。
  3. 单跳检索向量 RAG 更胜任:LightRAG 的 0.156 优于所有图 RAG 方案。
  4. 拒答能力与检索机制无关,与系统设计有关:QAnything 有置信度过滤,所以拒答率高;图 RAG 框架没做这层,几乎不拒答。

选哪个?

基于这次评测:

优先选 GraphRAG,如果:

  • 核心场景是复杂多跳推理(政策关联、因果链分析)
  • 有足够的 LLM 配额承担建库成本
  • 使用支持结构化输出的 LLM(GPT-4o、Claude 等),可以启用社区报告
  • 不在乎建库时间(30 分钟级别)

优先选 HippoRAG,如果:

  • 有本地 GPU(>12 GB,最好 24 GB),不想依赖外部 embedding API
  • 知识库需要频繁更新(HippoRAG 的增量更新比 GraphRAG 快)
  • 愿意接受更高延迟换取更强的本地私有化部署

这两个框架都不适合,如果:

  • 主要场景是快速事实查询(选 LightRAG)
  • 需要强拒答能力(选 QAnything,或在图 RAG 上加置信度后处理)
  • 对部署成本敏感(图 RAG 的建库 LLM 开销是向量 RAG 的 5-10 倍)

本次评测的限制

  • LLM 使用 GLM-4-flash(免费额度),对结构化输出支持有限,GraphRAG 无法启用社区报告——社区报告是 global search 的核心,本次只测了 local search
  • HippoRAG 受显存限制强制降低了 batch_size 和 max_seq_len,延迟数据有失真,在正常硬件上会好很多
  • 答案匹配用 Jaccard 关键词重叠,不是 LLM judge,偏保守

评测代码

完整代码在 llm-in-action/kb-03-graphrag-eval/llm-in-action/kb-03-hipporag-eval/

GraphRAG 评测关键配置:

# settings.yaml 关键调整
workflows:                          # 跳过社区报告生成(LLM 结构化输出不稳定时)
  - create_base_text_units
  - create_final_documents
  - extract_graph
  - finalize_graph
  - extract_covariates
  - create_communities
  - create_final_text_units
  - generate_text_embeddings
 
vector_store:
  type: lancedb
  vector_size: 1024                 # 必须与 embedding 维度一致
 
embed_text:
  names:
    - entity_description            # 只嵌入实体描述,跳过 text_unit
  batch_max_tokens: 300
  batch_size: 4
 
concurrent_requests: 1              # GLM-4-flash rate limit 限制

HippoRAG 评测关键初始化:

from hipporag.utils.config_utils import BaseConfig
 
global_config = BaseConfig(
    embedding_max_seq_len=512,       # 降低显存需求
    embedding_batch_size=1,
    embedding_model_dtype="bfloat16",
)
 
hipporag = HippoRAG(
    global_config=global_config,
    save_dir=SAVE_DIR,
    llm_model_name=LLM_MODEL,
    llm_base_url=LLM_BASE_URL,
    embedding_model_name=EMBEDDING_MODEL_PATH,  # 本地路径
)

下一篇:HyperGraphRAG 实测——超图结构的多跳推理。同样 89 道题,看看把二元关系升级为超图之后,多跳推理能提升多少。


欢迎访问 PrimeSkills —— 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。

更多实用知识和有趣产品,欢迎访问我的个人主页