跳到主要内容

知识图谱进 RAG

这一章讲三件事: 本体怎么变成 Neo4j 里能查的图;hybrid embeddings 怎么让「用户的大白话」 找得到图里的节点;以及一段会改变你对「KG 数据怎么喂给 LLM」认知的研究。 最后一幕:第 09 章立的五个验收问题,全部答对。

1. 先辨名:本章不是讲 GraphRAG

原书特意不给这一章起名「GraphRAG」——GraphRAG 是微软研究院一个具体项目的名字: 用 LLM 自动从非结构化文本抽实体建图、聚类(即把相近的东西自动归成一堆一堆)、生成社区摘要的完整管线,查询还分两种模式 (global search 看全局聚类概览,local search 缩放到具体节点)。它的实验显示多跳问题准确率 超过标准 RAG 管线。论文 arXiv:2404.161301

本书讲的是更朴素的 graph-based RAG:本体是人写的(第 09 章),图是确定性(即同问同答、不带随机)的, 检索走「语义找入口 + 图上扩展」。两者共同点是:把结构化、天然带关系的图数据喂给 LLM。 (补充(不在书里,依据我们的 frontier 书架):微软 GraphRAG 的索引管线、Leiden 聚类与四种查询模式, 在我们对 microsoft/graphrag 源码的拆解里有逐文件分析。 依据: shelf=ai-frontier-reference/graphrag#04-query-search.md 事实=GraphRAG 查询层提供 global(map-reduce 全局)/local(实体邻域)/drift/basic 四种搜索,与原书对 GraphRAG 搜索方式的描述一致。)

2. 图能给 RAG 什么

原书列了七条 KG+RAG 的优势,归成三组2:

  • 准: 沿显式的边遍历,而不是赌向量距离——噪声被过滤,返回的是精准匹配意图的子图;
  • 深: 多跳推理(A→B→C 的关系链)把分散的事实接起来;同义词与消歧路径写进图里, 多义词不再被张冠李戴;
  • 可信与常新: 每个节点、每条边带出处元数据,审计可追溯(医疗、金融刚需); 图可以增量更新,总在查最新事实,还能顺带压幻觉、免掉昂贵的模型重训

3. 两种图,别搞混

第 08 章 LangGraph 的循环图(cyclical graph)和本章的本体 KG 是两种不同的图3:

循环图(LangGraph)本体 KG(本章)
形状有环,允许回到起点DAG(有向无环图),沿着边走不回起点
类型层级无强制is-a / part-of 的分类树,类不能是自己的祖先
用法agent 的控制流:提出假设、探索、迭代查询库:按 schema 精确取事实,过滤出合规数据给 LLM
风险死循环,要做环检测表达力受 schema 限制

本章的金融本体正是后者:Stock、Bond、Organization 的清晰层级,加上 issuedBy、 isRegulatedBy 的显式关系——一块给 LLM 的回答托底的稳定骨架4

4. 主走查(上):本体进 Neo4j

原书的代码实验室把第 09 章的 FinancialOntology.ttl 变成 Neo4j 里活的数据,关键步骤:

  1. 解析与转换: rdflib 解析 Turtle 文件的三元组,转成节点表、边表、数据表三份 CSV,经 Python 驱动导入 Neo4j Desktop(本地 bolt://127.0.0.1:7687)5;
  2. 补类型边: 导入用的都是通用 :Resource 标签(而不是 :Stock、:Bond),所以要回填 rdf:type 的成员关系——从 TTL 里抽出(个体, 类)对,共 12 对,建成 (:AAPL)-[:IS_A]->(:Stock) 这样的边6;
  3. 建锚点节点: 为每类造一个「枢纽」概念节点(All Stocks、All Bonds、All Orgs、All Regulators),用 :INCLUDES 边连到全部成员——查询入口从此有个「目录页」。验证输出:All Bonds 包含 1 个成员,All Stocks 包含 2 个7

到这里,「AAPL 是股票、由 Apple_Inc 发行、受 SEC 监管」这些事实在图里是可以精确查询的 ——但用户的输入是自然语言,不知道你的 schema、不知道边叫什么名字。缺口怎么补?

5. 主走查(中):hybrid embeddings,本书的独门机制

问题: 用户问「equities regulated by the SEC」。图里类的标签是 Stock,没有「equity」这个词; 边名 IS_REGULATED_BY 用户也不知道。纯图查询接不住,纯向量搜索又够不着图的结构。8

解法(hybrid embeddings): 给每个实体生成一段「图文并茂」的文本—— 它自己的属性 加上沿边能走到的上下文——把这段文字变成向量(嵌入,即把文字转成向量)。AAPL 的完整版长这样9:

Stock AAPL [AAPL] issued by Apple Inc. regulated by SEC —
A security representing equity ownership in a corporation.
Issuer regulated by SEC.

注意最后一句「Issuer regulated by SEC」——发行人的监管者是二阶邻居(多跳)信息, 被预先埋进了向量。生成它的是一条 Cypher 查询:匹配实体,可选匹配 ISSUED_BY、 IS_REGULATED_BY、发行人的 IS_REGULATED_BY,拼成一段描述文本10

这个设计买到了三样东西11:

  • 召回: 「equity」在图里不存在,但这段文本里有——语义搜索照样命中 AAPL;
  • 分工: 语义搜索负责「找到对的实体」,Cypher 负责「取回精确事实」——两套机制各干各的强项;
  • 预埋的多跳: 问「发行人的监管者是谁」,不用真的扩展图,向量的相似度已经把答案顶上来了。

作者给这个机制的最高评价是:它是 KG-based RAG 常常胜过纯向量 RAG 的最大单项原因12

6. 主走查(下):检索、扩展、按「字典格式」喂给 LLM

查询时的流水线13:

用户问题 → 向量化 → 在 hybridText 向量里搜 top-5 → 拿实体 ID 回 Neo4j
→ 沿边扩展(深度 2)取邻居事实 → 组装上下文 → LLM 生成

图说:语义搜索定入口,图扩展取事实;引用键 [E1][E2] 标注每个命中实体。

一个反直觉的研究:喂图数据,JSON 是差生

KG 查出来的结构化数据,给 LLM 时用什么格式?直觉会说自然语言或 JSON。 原书引了 Wu & Tsioutsiouliklis(2024)的实验,结论反直觉14:

KG 表示格式多跳推理准确率
自然语言44.6%
JSON26.1%(比基线还低!)
Python 静态字典67.9%(比基线高 78%)
Python 格式 + 微调91.5%

解释:LLM 的预训练语料里有海量代码,它能把 relationships['type']['AAPL'] 这样的字典查找 当作显式的推理步骤来「执行」,而不是含糊的模式匹配。所以组装上下文时,输出长这样:

relationships = {
'type': {'AAPL': 'Stock', 'USTB': 'Bond'},
'issuedBy': {'AAPL': 'Apple Inc', 'USTB': 'US Treasury'},
'isRegulatedBy': {'AAPL': 'SEC', 'MSFT': 'SEC'},
}
# Example: relationships['type']['AAPL'] returns 'Stock'

验收:五个问题全过

LangChain 链(make_context → 提示词 → LLM)跑第 09 章立的五个能力问题15:

能力问题agent 的回答
AAPL 是股票还是债券?AAPL is a stock.
USTB 是什么工具?USTB is a bond.
谁监管 MSFT?MSFT is regulated by the SEC.
SEC 监管哪些股票?发行人是谁?AAPL(Apple Inc)和 MSFT(Microsoft Corp)
你知道哪些股票/债券?两只股票:AAPL、MSFT;一只债券:USTB

第 4 问是真多跳:股票→监管者是一跳,监管者→受监管的全部股票→各自的发行人,又两跳。 Python 字典格式把答案钉在结构化事实上,LLM 没有机会动用训练数据里的旧知识或幻觉16

7. 边界与局限

  • 本体要人工维护:本体演化后要「定期导出、重新导入」;原书的最佳实践清单把它列为第一条17;
  • hybridText 是「快照式」的——图变了必须重生成、重嵌入,这是它相对于「查询时实时扩展」的额外成本(书里未展开讨论这一权衡);
  • Wu & Tsioutsiouliklis 的实验基于特定数据集与模型,数字不宜外推——即推广到自己的场景——为普适定律;但「给 LLM 代码格式优于 JSON」这个方向,与我们在 LangChain 拆解里见到的「结构化输出优先」倾向一致。

8. 可带走的

  1. GraphRAG 是微软的项目名;graph-based RAG 是本书的朴素路线,别混用。
  2. 循环图(agent 控制流)与本体的 DAG 是两种图——一个管「怎么推理」,一个管「事实长什么样」。
  3. hybrid embeddings = 把图上下文拍平进文本再嵌入;它是「自然语言找得到结构化图」的桥。
  4. 多跳信息可以预埋进向量,减少运行时的图扩展。
  5. 给 LLM 喂 KG 数据,Python 字典格式大幅优于 JSON(26.1% vs 67.9%)——JSON 反而比基线差。
  6. 语义搜索定入口、Cypher 取事实——两套检索各干各的强项。
  7. 验收靠 competency questions——上一章立的问题,这一章全过,闭环完成。

9. 原文地图

主题原书章原文位置
GraphRAG 是微软项目名与两种搜索Graph-Based RAGtext/77-fm-graph-based-rag.txt:32(搜「GraphRAG」) · text/77-fm-graph-based-rag.txt:35(搜「Microsoft Research」)
GraphRAG 论文与仓库Graph-Based RAGtext/77-fm-graph-based-rag.txt:35(搜「2404.16130」)
KG+RAG 七优势Graph-Based RAGtext/77-fm-graph-based-rag.txt:53(搜「Enhanced retrieval precision」) · text/77-fm-graph-based-rag.txt:71(搜「incrementally updatable」)
循环图 vs 本体 DAGGraph-Based RAGtext/77-fm-graph-based-rag.txt:81(搜「directed acyclic graphs」) · text/77-fm-graph-based-rag.txt:95(搜「cyclical graphs」)
本体 KG 给 LLM 过滤合规事实Graph-Based RAGtext/77-fm-graph-based-rag.txt:101(搜「schema-compliant」)
导入流程(ttl→CSV→Neo4j)Step 4 – importing nodes, edges, and data properties into Neo4jtext/81-fm-step-4-importing-nodes-edges-and-data-properties.txt:1(搜「importing」)
环境与库(nutneo4j/rdflib/faiss)Step 2 – preparing your notebook environmenttext/79-fm-step-2-preparing-your-notebook-environment.txt:59(搜「neo4j ==6.0.3」) · text/79-fm-step-2-preparing-your-notebook-environment.txt:60(搜「rdflib」)
12 对类型边Step 5 – add navigational anchor nodes (stocks, bonds, and so on)text/82-fm-step-5-add-navigational-anchor-nodes-stocks-bond.txt:61(搜「The output is 12」)
锚点节点与验证Step 5.2 – create All X concept nodes and wire memberstext/83-fm-step-5-2-create-all-x-concept-nodes-and-wire-mem.txt:9(搜「All Stocks」) · text/83-fm-step-5-2-create-all-x-concept-nodes-and-wire-mem.txt:88(搜「members」)
用户不知道 schema 的问题Step 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:7(搜「without knowing the schema」)
hybrid embeddings 定义Step 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:1(搜「hybrid embeddings」)
AAPL 的 hybridTextStep 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:30(搜「Stock AAPL」)
多跳信息预埋Step 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:36(搜「multi-hop information」)
equity 命中与两套检索分工Step 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:50(搜「equities regulated by SEC」)
「最大单项原因」断言Step 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:46(搜「secret sauce」)
Cypher 拼 hybridTextStep 6 – enable hybrid embeddings (text + structure) and multi-hop supporttext/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:4(搜「ISSUED_BY」)
检索+扩展流水线Step 7 – vector search and graph expansion (ready-to-prompt context)text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:8(搜「Gets embedded and matched」)
三种上下文格式与 JSON 反而差Step 7 – vector search and graph expansion (ready-to-prompt context)text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:140(搜「Natural language」)
Wu & Tsioutsiouliklis 实验数字Step 7 – vector search and graph expansion (ready-to-prompt context)text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:157(搜「67.9%」) · text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:157(搜「91.5%」)
LLM 把字典查找当推理步骤Step 7 – vector search and graph expansion (ready-to-prompt context)text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:160(搜「mentally」所在段,搜「execute」)
引用键与上下文组装Step 7 – vector search and graph expansion (ready-to-prompt context)text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:17(搜「citations」)
生成链与五问全答Step 8 – generate with LangChain and OpenAItext/86-fm-step-8-generate-with-langchain-and-openai.txt:14(搜「make_context」) · text/86-fm-step-8-generate-with-langchain-and-openai.txt:54(搜「Is AAPL a stock or bond?」)
多跳验证(SEC 监管的股票)Step 8 – generate with LangChain and OpenAItext/86-fm-step-8-generate-with-langchain-and-openai.txt:61(搜「issued by Apple Inc」)
字典格式防幻觉Step 8 – generate with LangChain and OpenAItext/86-fm-step-8-generate-with-langchain-and-openai.txt:102(搜「hallucinated information」)
最佳实践清单Best practices and next stepstext/87-fm-best-practices-and-next-steps.txt:1(搜「best practices」) · text/87-fm-best-practices-and-next-steps.txt:36(搜「larger ontologies」)
别局限于本体Best practices and next stepstext/87-fm-best-practices-and-next-steps.txt:48(搜「limit yourself to ontologies」)

Footnotes

  1. 出处:「Graph-Based RAG」第 35 段(text/77-fm-graph-based-rag.txt:35,搜「Microsoft Research」)与第 35 段(text/77-fm-graph-based-rag.txt:35,搜「2404.16130」)。

  2. 出处:「Graph-Based RAG」第 53-71 段(text/77-fm-graph-based-rag.txt:53,搜「Enhanced retrieval precision」;text/77-fm-graph-based-rag.txt:71,搜「incrementally updatable」)。

  3. 出处:「Graph-Based RAG」第 81 段(text/77-fm-graph-based-rag.txt:81,搜「directed acyclic graphs」)与第 95 段(text/77-fm-graph-based-rag.txt:95,搜「cyclical graphs」)。

  4. 出处:「Graph-Based RAG」第 101 段(text/77-fm-graph-based-rag.txt:101,搜「schema-compliant」)。

  5. 出处:「Step 2 – preparing your notebook environment」第 59-94 段(text/79-fm-step-2-preparing-your-notebook-environment.txt:59,搜「neo4j ==6.0.3」;text/79-fm-step-2-preparing-your-notebook-environment.txt:60,搜「rdflib」)与「Step 4 – importing nodes, edges, and data properties into Neo4j」第 1 段(text/81-fm-step-4-importing-nodes-edges-and-data-properties.txt:1,搜「importing」)。

  6. 出处:「Step 5 – add navigational anchor nodes (stocks, bonds, and so on)」第 61 段(text/82-fm-step-5-add-navigational-anchor-nodes-stocks-bond.txt:61,搜「The output is 12」);通用 :Resource 标签的原因在第 15 段(同文件,搜「generic」)。

  7. 出处:「Step 5.2 – create All X concept nodes and wire members」第 9 段(text/83-fm-step-5-2-create-all-x-concept-nodes-and-wire-mem.txt:9,搜「All Stocks」)与第 88 段(text/83-fm-step-5-2-create-all-x-concept-nodes-and-wire-mem.txt:88,搜「members」)。

  8. 出处:「Step 6 – enable hybrid embeddings (text + structure) and multi-hop support」第 7 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:7,搜「without knowing the schema」)。

  9. 出处:「Step 6 – enable hybrid embeddings (text + structure) and multi-hop support」第 30 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:30,搜「Stock AAPL」)。

  10. 出处:「Step 6 – enable hybrid embeddings (text + structure) and multi-hop support」第 75-90 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:4,搜「ISSUED_BY」)。

  11. 出处:「Step 6 – enable hybrid embeddings (text + structure) and multi-hop support」第 50-56 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:50,搜「equities regulated by SEC」)与第 36 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:36,搜「multi-hop information」)。

  12. 出处:「Step 6 – enable hybrid embeddings (text + structure) and multi-hop support」第 46 段(text/84-fm-step-6-enable-hybrid-embeddings-text-structure-a.txt:46,搜「secret sauce」)。原文:「This is one of the biggest reasons why KG-based RAG often outperforms traditional vector-only RAG.」

  13. 出处:「Step 7 – vector search and graph expansion (ready-to-prompt context)」第 8-17 段(text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:8,搜「Gets embedded and matched」)。

  14. 出处:「Step 7 – vector search and graph expansion (ready-to-prompt context)」第 140-160 段(text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:157,搜「67.9%」;text/85-fm-step-7-vector-search-and-graph-expansion-ready-t.txt:157,搜「91.5%」)。JSON 26.1% 与自然语言 44.6% 在同段。

  15. 出处:「Step 8 – generate with LangChain and OpenAI」第 54-63 段(text/86-fm-step-8-generate-with-langchain-and-openai.txt:54,搜「Is AAPL a stock or bond?」)。

  16. 出处:「Step 8 – generate with LangChain and OpenAI」第 102 段(text/86-fm-step-8-generate-with-langchain-and-openai.txt:102,搜「hallucinated information」)。

  17. 出处:「Best practices and next steps」第 4-10 段(text/87-fm-best-practices-and-next-steps.txt:1,搜「best practices」)。