AI Agent 开发(18):GraphRAG 与知识图谱

QuibblerAgentQuibblerAgent 2026-10-25 约 20 分钟 3 次阅读

第 16 篇的混合检索与 Rerank 解决"召回不准",第 17 篇把检索降级成 Agent 的一件工具、让它自己决定查什么。但两篇都在同一个地基上施工——向量相似度:问题变成向量,从库里找"最像它"的几段文本。这个范式对"答案躺在某一段里"的问题近乎完美,对另三类问题却先天乏力。本篇是 RAG 模块的收官,就问这个根本问题:向量检索的天花板在哪,拿什么补。

本文先拆向量检索的失效机理,再讲 GraphRAG 的完整思路与两大代表实现——微软 GraphRAG 与 LightRAG(2026-10 基线),然后手写一个 50 行的微型 GraphRAG 把原理摸到手,最后给一张选型决策表。全文按"天花板 → 原理 → 两大实现 → 手写 → 选型"组织。

1、向量检索的天花板

拿一批公司新闻当例子(第 5 节手写环节还会用它):三条新闻分别讲"华信科技领投智行自动驾驶 B 轮""智行创始人林岚曾任云图智能首席科学家""云图智能与华信科技联合发布方案"。对着这三段建好的向量库,有三类问不动的问题:

问题类型 典型问法 向量检索的困境
全局性 "这批文档的主要主题是什么" 答案不在任何单个 chunk 里,top-k 只是抽样
关系型 "林岚和华信科技隔着什么关系" 链路跨三段文本,中间实体与问题毫不相似
聚合统计 "文中一共出现几家公司" 要全量遍历去重,top-k 采样必然丢数据

逐个看病根。全局性问题里,任何一段文本与"主要主题是什么"都"挺像又都不像",相似度排序彻底失去分辨力——真正需要的是读完全部内容再归纳。关系型问题的答案不在某段文本里,而在两段文本的连接处:问句里有"林岚"和"华信",但把两者连起来的"智行自动驾驶"与"云图智能"所在的段落,和问句在字面上毫不相似,top-k 召回全凭运气。聚合统计更直接:数数需要对全集扫描,而向量检索本质是从全集里抽最像的几条,抽样天然数不准。

三类问题一个病根:embedding 是语义指纹,只会"找相似的",不会"遍历、跳转、计数"。这是原理性短板,第 16 篇的任何调参都补不上。补短板的方向,是让 LLM 先把语料读成一张图。

2、GraphRAG 原理拆解

GraphRAG(Graph + RAG)的核心动作:不直接检索文本,先让 LLM 把语料抽取成一张知识图谱,再在图上做文章。完整方案来自微软 2024 年的论文 From Local to Global,管线五步:

① 实体抽取 ─ LLM 逐 chunk 抽出实体与关系,产出三元组
② 图构建   ─ 三元组合并成图,同名实体归并成一个节点
③ 社区聚类 ─ Leiden 算法把连接密集的节点聚成"社区"
④ 社区摘要 ─ LLM 给每个社区写摘要,再逐层向上归并
⑤ 双路查询 ─ 全局问题查社区摘要,局部问题查图邻域

看关键几步。①② 把"文本集合"变成"实体关系网"——华信、智行、林岚、云图在图上是四个节点、若干条边,第 1 节的关系型问题从"赌运气召回三段原文"变成图上的一次邻域扩展。③ 的 Leiden 算法一句话:图社区发现算法,把连接密集的节点自动分团——相当于按"朋友圈"给节点分组,同行业的公司、同一章的人物会各自抱团。④ 是全局性问题的解药:每个社区配一段 LLM 写的摘要,社区的摘要再逐层向上归并出上级摘要;问"主要主题"时不再扫全部原文,而是读分层摘要,阅读量从"一万段原文"缩到"几十段摘要"。

查询因此分成两路,对应⑤。global search 对社区摘要做 map-reduce:先分批让 LLM 从各社区摘要里提中间结论(map),再把中间结论汇总成最终答案(reduce)。local search 从问题命中的实体出发,把它在图上的邻域——相连实体、关系、相关原文块——拼进上下文生成答案。第 15 篇末尾有个判据:"答案能不能在一段连续原文里划出来";GraphRAG 把划不出来的那半也接住了。

3、微软 GraphRAG 实操

代表实现是微软开源的 microsoft/graphrag 仓库,当前版本 3.3.0(2026-10 发布),标准 CLI 工具形态。安装与初始化如下:

mkdir graphrag-demo && cd graphrag-demo
python -m venv .venv && source .venv/bin/activate  # Windows: .venv\Scripts\activate
python -m pip install graphrag    # 3.3.0,要求 Python 3.11+
graphrag init                     # 交互式选模型,生成工作区

graphrag init 生成三样东西:input/ 目录放 .txt 语料,.env 里把 GRAPHRAG_API_KEY 换成你的 key,settings.yaml 是管线配置。模型默认走 OpenAI,换模型改它的 models 段(节选,以 init 生成的完整文件为准):

models:
  chat:
    default_chat_model:          # 实体抽取、社区摘要用它
      type: openai_chat
      model: gpt-4o-mini
      api_key: ${GRAPHRAG_API_KEY}
  embedding:
    default_embedding_model:     # 局部检索的向量层
      type: openai_embedding
      model: text-embedding-3-small
      api_key: ${GRAPHRAG_API_KEY}

解读:chat 与 embedding 两套模型各管一摊。压成本的常见玩法是实体抽取用 mini 级模型、只在 global 查询时换强模型。配置搞定,先用官方教程数据集《圣诞颂歌》试水:

curl https://www.gutenberg.org/cache/epub/24022/pg24022.txt \
  -o ./input/book.txt

这本小说规模小、成本可控,是官方指定的入门数据集。语料就位后,一根命令建索引:

graphrag index    # 实体抽取 → 建图 → Leiden 聚类 → 分层社区摘要

跑完在 output/ 落一组 parquet 表(entities、relations、communities……),那就是图谱本体和它的分层摘要。查询两路:

graphrag query "全书的主要主题是什么?"
graphrag query "Scrooge 和 Cratchit 是什么关系?" --method local

不带 --method 默认 global,走社区摘要的 map-reduce;--method local 从实体邻域取上下文。要嵌进自己的代码就走 Python API:from graphrag.api import global_search, local_search,CLI 的 query 命令内部就是这两个函数,另有 DRIFT 混合搜索先全局定位再局部延伸。细节见官方入门文档。

成本警告:索引阶段的实体抽取要过每一个 chunk,社区摘要还要按层级多轮调用——官方文档明确警告消耗大、建议先拿教程数据集试。文档越多 token 花费越线性上涨,务必先小规模试跑再上真实语料。

一个要交代的版本事实:微软 2026 年已将该项目转入维护模式——只修 bug 与依赖,不再加新特性。它仍是参考实现里最完整的"教科书",但选型时值得知道这一点。

4、LightRAG 与双层检索

另一代表 LightRAG 出自港大 HKUDS 团队(GitHub 仓库),论文进了 EMNLP 2025,4 万余星,PyPI 包名 lightrag-hku(1.5.x)。它对微软版最贵的一步动刀:砍掉分层社区摘要。建图同样是 LLM 抽实体关系,但只做单轮抽取;全局问题不靠社区摘要兜底,靠"双层检索"——低层(low-level)拿实体及其直接邻居答细节问题,高层(high-level)拿主题级的相关实体与关系答宏观问题。图谱与向量库配合:实体和关系同样被向量化,查询时先向量召回、再沿图扩展。最小用法(SDK 安装:pip install lightrag-hku):

import os
from lightrag import LightRAG, QueryParam
from lightrag.llm.openai import openai_complete_if_cache, openai_embed

os.environ["OPENAI_API_KEY"] = "sk-..."

rag = LightRAG(
    working_dir="./lightrag_out",              # 图、向量、原文全落这个目录
    llm_model_func=openai_complete_if_cache,   # 默认 gpt-4o-mini
    embedding_func=openai_embed,
)
rag.insert(book_text)    # 单轮抽取建图,无分层摘要

print(rag.query("全书的主要主题是什么?",
                param=QueryParam(mode="mix")))

insert 与 query 两个方法就能嵌进现有应用,比 CLI 管线轻得多;带 WebUI 的 API 服务器装 lightrag-hku[api]。查询模式五种:naive(纯向量基线)、local、global、hybrid、mix(默认,三路合并)。两大实现对比:

维度 微软 GraphRAG LightRAG
形态 CLI 管线 + Python API Python SDK + API 服务器
索引成本 高:逐 chunk 抽取 + 分层社区摘要 低:单轮抽取,不做分层摘要
查询模式 global / local(另有 DRIFT) naive / local / global / hybrid / mix
全局问答 社区摘要直接支撑,最强 高层主题检索,够用但无摘要兜底
集成成本 独立管道,偏重 两个方法嵌进现有代码

一句话分工:微软版把"全局问答"做绝,LightRAG 把"图 RAG"做轻。

5、手写微型 GraphRAG

抛开聚类与摘要,GraphRAG 的骨架只有三步:LLM 抽三元组、建图、查邻域。用 50 行代码亲手跑通这个骨架,实体抽取正是第 4 篇结构化输出的主场。先装依赖 networkx(官方文档),三段代码拼成一个文件。第一步,抽三元组:

from typing import List
from pydantic import BaseModel, Field
from langchain.chat_models import init_chat_model

class Triple(BaseModel):
    subject: str = Field(description="头实体:公司名/人名等")
    predicate: str = Field(description="关系:领投/创始人/曾任等")
    object: str = Field(description="尾实体")

class TripleList(BaseModel):
    triples: List[Triple]

llm = init_chat_model("openai:gpt-5")

def extract(text: str) -> List[Triple]:
    prompt = f"抽取文本中的实体关系三元组,宁缺毋滥。\n\n{text}"
    return llm.with_structured_output(TripleList).invoke(prompt).triples

with_structured_output 让 LLM 直接吐 Pydantic 对象——这正是第 4 篇练过的本事,GraphRAG 工业化实现里"实体抽取"一步的内核与它同源。第二步,建图加邻域检索:

import networkx as nx

DOCS = [
    "华信科技领投了智行自动驾驶的 B 轮融资。",
    "智行自动驾驶创始人林岚,曾任云图智能首席科学家。",
    "云图智能与华信科技联合发布了车路协同方案。",
]

G = nx.Graph()
for doc in DOCS:                     # 每段抽一次,LLM 调用随 chunk 数线性涨
    for t in extract(doc):
        G.add_edge(t.subject, t.object, rel=t.predicate)

def graph_context(question: str) -> str:
    seeds = {n for n in G.nodes if n in question}    # 朴素实体链接
    hood = seeds | {n for s in seeds for n in G.neighbors(s)}
    lines = [f"{u} --{G[u][v]['rel']}--> {v}"
             for u, v in G.edges(hood) if u in hood and v in hood]
    return "\n".join(lines) or "图中没有相关信息"

graph_context 就是 local search 的骨架:问题里命中的实体当种子,向外扩一跳得到邻域,把邻域内部的边全部列出来。第三步,塞进 prompt 生成:

from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
    ("system",
     "你是知识图谱问答助手,仅依据三元组回答,资料不足就直说不知道。"
     "\n\n三元组:\n{context}"),
    ("human", "{question}"),
])

chain = prompt | llm | StrOutputParser()
q = "林岚和华信科技隔着什么关系?"
print(chain.invoke({"question": q, "context": graph_context(q)}))

跑起来,邻域里的边大致长这样(谓词由模型抽取,措辞会变):

华信科技 --领投 B 轮--> 智行自动驾驶
智行自动驾驶 --创始人--> 林岚
云图智能 --首席科学家--> 林岚
华信科技 --联合发布--> 云图智能

解读答案从哪来:四条边一拼,两条路径浮出水面——林岚创办智行、华信领投智行;林岚曾任云图首席科学家、云图与华信有合作。这个问题向量 RAG 要赌运气把三段原文同时召回,图检索一次邻域展开就端上完整关系网——答案不在任何一段原文里,而在边的连接处。

也要清楚这 50 行与微软版的差距:没有实体消歧("华信"与"华信科技"会成为两个节点)、没有社区摘要(全局问题依旧答不了)、实体链接是字符串包含(生产上换 embedding 相似度匹配更稳)。微软版的全部工程量,都在把这三件事做对、做全。

6、选型决策

工具都见过了,回到判断。一张表给出决策:

你的情况 建议
事实细节、单点查询为主 向量 RAG(第 15 篇),别上图
全局综述、主题归纳是刚需 微软 GraphRAG,索引预算给足
多跳关系问题多、成本敏感 LightRAG 起步,不够再升级
语料只有百八十篇 先试大 chunk 向量 RAG,图的收益常盖不住索引成本
语料天天更新 三思:图索引要重建,代价数倍于向量库

别拍脑袋,用数据说话:拿 20 个真实用户问题做分类,全局与关系类占比不到一成就别折腾图;过三成才值得评估——先用 LightRAG 跑一版算 token 账,确认收益后再决定要不要上微软版的社区摘要。

7、总结

回顾全文。向量检索答不好三类问题——全局性、关系型、聚合统计,病根是 embedding 只会"找相似的";GraphRAG 的解法是让 LLM 把语料抽成知识图谱,Leiden 聚出社区、LLM 写分层摘要,global 查摘要、local 查邻域;两大实现里,微软 GraphRAG(3.3.0,维护模式,索引贵但全局问答最强)与 LightRAG(1.5.x,单轮抽取加双层检索,轻)各占一端;50 行手写版揭示了全部骨架——三元组、图、邻域扩展。

练习:给自己的一批文档跑通微软 GraphRAG 全流程——graphrag init、放入语料(或先用《圣诞颂歌》)、graphrag index,然后 graphrag query 问一个全局性问题感受 global search,加 --method local 问一个关系问题;再把同一个问题丢给第 15 篇的向量 RAG 对比答案;有余力换 LightRAG 的 mix 模式跑一遍,对比两边的索引耗时与 token 花费。

对于正在搭知识库问答的同学,建议先用真实问题把向量 RAG 的边界摸清楚,确有全局与关系类刚需再上图——图谱是补短板的,不是标配。RAG 模块到本篇收官,下一篇第 19 篇进入 MCP 模块:模型上下文协议,把工具生态标准化。

相关推荐

Hermes Agent 详解:自进化学习型 AI 代理
Agent

Hermes Agent 详解:自进化学习型 AI 代理

Hermes Agent 详解:自进化学习型 AI 代理Hermes Agent 是由 Nous Research 于 2026 年 2 月开源的自主 AI 代理框架,其核心定位是"与你共同成长的智能体"。与传统的 IDE 编程助手或单一 API 聊天机器人不同,Hermes 运行在你的服务器上,能够记住所学内容,运行时间越长能力越强。它采用 MIT 开源许可,支持 Linux、macOS 和 W

393
Hermes Agent:与你一起成长的开源 AI 代理
Agent

Hermes Agent:与你一起成长的开源 AI 代理

Hermes Agent:与你一起成长的开源 AI 代理大多数 AI 助手是"健忘的租客"——换个窗口就失忆、换个平台就重学、干过的活不留下任何沉淀。Nous Research 出品的 Hermes Agent 反其道而行,口号是"The Agent That Grows With You"(与你一起成长的代理):它是一个开源(MIT)、自托管的 AI 代理,具备持久记忆(学习你的项目、自动生成技

322
speech-to-speech 详解:HuggingFace 的开源语音 Agent 流水线
AI

speech-to-speech 详解:HuggingFace 的开源语音 Agent 流水线

speech-to-speech 详解:HuggingFace 的开源语音 Agent 流水线语音 Agent 的"全开源"路线一直有个尴尬:框架开源了,模型却离不开云端 API。huggingface/speech-to-speech 把这条路走通了:VAD → STT → LLM → TTS 四段低延迟流水线,每个组件都可换成开源模型本地跑——Apple Silicon 一台 Mac 就能撑起

264