graphrag

微软 GraphRAG:从文本抽取实体关系,构建社区摘要增强 RAG。

补充说明

GraphRAG 先把文档切成 TextUnit,用 LLM 抽取实体、关系和可选 claims,再用 Leiden 算法做社区发现,为每个社区生成摘要。查询时可以走社区摘要的 map-reduce(global)、实体邻域加原文(local)、两者混合(drift),或退化为普通向量检索(basic)。

它适合需要跨文档归纳、关系推理和“全局在讲什么”的问题,例如事故复盘、竞品分析和长篇报告问答。普通向量 RAG 更适合单点事实查找;GraphRAG 的索引成本高、更新复杂,不适合低延迟、高频变更的知识库。它也不是在线向量数据库,生产检索通常还要配合 Milvus/Qdrant。

成本主要来自索引阶段的 LLM 调用:实体抽取、描述摘要、社区报告都会消耗 token,max_gleanings 和社区层级越高越贵。graphrag update 只处理新增文档,已修改或删除的文档通常需要重建;具体行为以当前版本文档为准。

常用示例

安装 CLI,并在空目录初始化配置、提示词和 input 目录:

pip install -U graphrag
graphrag init --root ./ragtest

把 API key 写入 .env,索引和查询都会读取:

echo 'GRAPHRAG_API_KEY=sk-...' > ./ragtest/.env

在 settings.yaml 中配置模型、分块和输出;字段随版本变化,以 init 模板为准:

completion_models:
  default_completion_model:
    model_provider: openai
    model: gpt-4o-mini
    api_key: ${GRAPHRAG_API_KEY}
embedding_models:
  default_embedding_model:
    model_provider: openai
    model: text-embedding-3-small
    api_key: ${GRAPHRAG_API_KEY}
input:
  type: text
  file_pattern: .*\.txt$
chunking:
  size: 1200
  overlap: 100
output:
  type: file
  base_dir: output

把待索引文本放进 input/ 后执行索引;先小规模试跑,确认 token 成本:

graphrag index --root ./ragtest

用 global 模式回答需要跨文档归纳的问题,底层是社区摘要的 map-reduce:

graphrag query --root ./ragtest --method global "这批故障的共同根因是什么?"

local 适合围绕具体实体追问,basic 适合简单事实检索,drift 结合两者:

graphrag query --root ./ragtest --method local "order-service 依赖哪些组件?"
graphrag query --root ./ragtest --method basic "OOMKilled 是什么?"
graphrag query --root ./ragtest --method drift "最近的数据库故障有什么模式?"

新增文档后用 update 做增量索引,结果写入 update_output:

graphrag update --root ./ragtest

检查索引产物,确认实体、关系和社区报告都已生成:

ls -lh ./ragtest/output
python - <<'PY'
import pandas as pd
print(pd.read_parquet("./ragtest/output/entities.parquet").head())
print(pd.read_parquet("./ragtest/output/community_reports.parquet").head())
PY

用词数粗估输入规模,再决定分块和社区层级:

wc -w ./ragtest/input/*.txt | tail -1

易错点与排错

相关命令

读完自测

  1. GraphRAG 索引阶段的核心产物有哪些?
  2. global、local、basic 三种查询分别适合什么场景?
  3. 为什么 GraphRAG 的更新成本高?
答案
  1. TextUnit、实体、关系、可选 claims、Leiden 社区、社区报告及其 embedding,通常以 Parquet 和向量库形式输出。
  2. global 适合跨文档归纳和全局主题;local 适合围绕具体实体追问;basic 是普通向量检索,适合简单事实查找;drift 介于 local 与 global 之间。
  3. 实体和关系由 LLM 抽取,社区摘要也要 LLM 生成;文档修改会影响实体、关系和社区划分,往往需要重建,不能只做增量追加。