跳到主要内容

社区检测与社区报告 — 全局问题的预计算资产

这一章讲三件事: 「社区」的严格定义和检测算法(Louvain/Leiden)怎么回事; 社区报告长什么样(五个字段,含一个 0-10 的影响分); 为什么这一步是全书「全局检索」能力的地基——以及算法不确定性带来的工程后果。

1. 这一章在链条里的位置

第 08 章结束时,手里是一张每个节点、每条边都带摘要的厚图。 但「这批材料整体在讲什么」这类全局问题,还是没法答—— 答案不在任何一个节点上,散在全图。微软 GraphRAG 的解法分两步走完:

厚图 ──→ ① 社区检测:把「抱团」的实体切成一群一群 ←本章前半
──→ ② 社区摘要:每群预先写一份结构化报告 ←本章后半


第 10 章:global search 直接吃这些报告

一句话:这一章把「归纳」从查询时挪到了索引时。查询时你只会 「读几份现成的报告」,而不是「现读全图」。

2. 社区检测:算法自己找「抱团」

定义

社区 = 内部连接明显比对外连接密的实体群1。 《奥德赛》的图里,围绕「伊萨卡家务事」的一群人(忒勒马科斯、密涅瓦、求婚者们) 互相之间的关系远多于他们与「特洛伊旧人」群的联系——这就是两个社区。

算法:让机器找团,不用你定义团

书里用 GDS 库(Neo4j 的图算法插件,第 12 章介绍)跑 Louvain 方法; 原论文实现用的是 Leiden——两者都是社区检测算法,Leiden 也在 GDS 里2

这类算法的工作方式值得知道一个大概,因为它带来一个工程后果。 它们不是「按规则划分」,而是靠优化(反复微调、找更好解)的:反复把节点挪来挪去, 寻找让「社区内部连边占比尽量高」的划分——这个占比的度量叫模块度 (补充(不在书里,来自通用知识):模块度是社区检测的标准目标函数, Louvain 与 Leiden 都在优化它,Leiden 是 Louvain 的改进版,保证了划分的连通性)。

三个必须知道的工程性质

书里在实跑中把三个坑都点到了:

  1. 结果不确定:同一张图跑两次 Louvain,社区划分可能略有不同—— 优化过程有随机性3;
  2. 结果依赖图本身:实体和关系抽多抽少(还记得 66/182「每次会变」吗?), 社区划分跟着变3;
  3. 有层级:社区里还有子社区(伊萨卡家务事群内部还能分「求婚者」和「忠仆」); 论文用分层版本抓多粒度,本书图小只做单层4

判断(我们的,不是书里的): 「社区划分每次跑都不一样」听像缺陷, 对检索场景其实影响有限——因为社区只是报告的组织单位, 不是答案本身;两次划分下生成的报告集在内容上高度重叠。 真正要小心的场景是「把社区 ID 当稳定主键用」(比如人工运营某几个社区), 那时不确定性会咬人。生产上可固化随机种子让结果可复现, 我们的微软 GraphRAG 源码拆解确认了开源实现正是这么做的(透传 seed)。 如果错,会错在: 如果下游有「按社区计数」的统计需求, 两次跑的数字对不上,问题不在统计而在拿不稳定的东西当单位。

3. 主走查:66 个实体的图,切出 9 份报告

书里对第一卷的图(66 实体、182 关系)跑 Louvain,全程5:

输入:66 个实体、182 条带摘要的关系(第 08 章的产出)

第 1 步 Louvain 优化划分 → 检出 9 个社区,大小从 2 到 13 个节点
(2 人的小团到 13 人的大群都有)

第 2 步 每个社区,把「成员实体 + 成员间的关系(带摘要)」
打包喂给 LLM

第 3 步 LLM 按固定结构写报告,五个字段:
TITLE 短而具体的社区名,尽量带上代表实体
SUMMARY 执行摘要:这群人怎么互相勾连、有何要事
IMPACT 0-10 的影响严重度评分
EXPLANATION 评分的一句话理由
FINDINGS 5-10 条关键发现,每条短评+展开段[^6]

第 4 步 报告写回图里,社区成为可检索的节点(带 rating 属性)

产出:取成员最多的社区(第 2 步按成员数挑最大者),
报告标题是:"Minerva, Telemachus, and the Ithacan Household"
——密涅瓦引导忒勒马科斯寻父、求婚者盘踞家宅、
智慧/勇气/坚韧是主题,这就是第一卷最大「抱团」的缩影[^7]

走查里每步都有具体的数:9 个社区、2–13 个节点、0-10 分、5-10 条发现。

为什么说这份报告是「资产」:第 03 章的向量检索回答全局问题时, 要把全部 89 个块塞进上下文现归纳(塞不下就答不了); 现在,同样的全局问题变成「读 9 份各几百字的现成报告」—— 归纳的成本在索引期付过了,查询期只是汇总。

4. 影响分:一个容易被当成装饰的字段

社区报告里的 IMPACT SEVERITY RATING(影响严重度评分)值得单独看一眼, 因为它是给机器用的,不是给人读的:第 10 章的 global search 检索时, 会先按这个分过滤——低于阈值的社区报告根本不进查询流程6。 原论文是新闻情报场景,「影响」指社群的危险程度;换到你的领域, 这个字段的语义要重新约定(业务重要性?主题相关度?),书里没有展开—— 但记得它是可配置的语义,别被「严重度」这个词锁死。

5. 作者的判断与证据

  • 单层社区的简化是明说的:论文的分层社区在本书被砍成单层, 理由是图太小4——但这意味着书里没有演示「报告的报告」如何生成 (分层场景下高层社区要拿低层报告当原料,这一点在我们的 微软 GraphRAG 源码拆解里有,书里没有);
  • 不确定性的坦白:算法不保证跨次一致、依赖上游抽取结果, 书里原文承认3;
  • 大社区的处理与第 08 章的 super node 同构:按相关性选材,不硬塞7

判断(我们的,不是书里的): 社区报告这个设计的真正巧思在于 粒度可调:全局问题的答案可以只从高层社区报告合成(快、糙), 也可以下钻到低层(慢、细)。书里因为只做单层没有展示这个旋钮, 但它是论文标题「From Local to Global」的另一半含义—— 检索时选哪一层,就是在选答案的粒度与成本。 如果错,会错在: 如果单层社区已经足够答某类系统的问题, 分层就只是成本;粒度旋钮的价值依赖材料规模——材料少时确实是过度设计。

6. 边界与局限

  • 66 实体/9 社区的图太小,分层、模块度调参、社区合并等真实规模问题全部缺席;
  • 报告内容依赖上游摘要质量:实体摘要错,社区报告跟着错——误差(上游的错传到下游)沿管道放大, 书里没有讨论误差传播;
  • 影响分的语义是论文场景的(新闻情报),本书原样搬用,没有领域化讨论;
  • 社区检测算法本身(Louvain/Leiden 的原理与差异)书里只点到名字, 深入要靠 GDS 文档或图算法教材2;
  • 没有评测「社区划分得好不好」的方法——划分的合理性只能靠抽查报告内容。

7. 可带走的

  1. 社区 = 内部比外部连得密的实体群,由算法自动检出,不用人工定义;
  2. Louvain/Leiden 都是优化式算法:结果不确定、依赖上游、有层级——三个性质都影响工程;
  3. 社区报告五字段:标题/摘要/影响分(0-10)/评分理由/5-10 条发现;
  4. 影响分是给机器过滤用的,语义随领域重新约定;
  5. 全局归纳的成本从查询期挪到索引期——这是 GraphRAG 回答「整体在讲什么」的资本;
  6. 社区 ID 不是稳定主键,别拿它当数据库键用;要复现就固化随机种子;
  7. 材料多了分层社区才划算;小图单层足够,书里就是这么取舍的。

8. 原文地图

主题原书章原文位置
社区定义7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:460(搜「more densely connected」)
社区检测图示(含孤立子图)7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:472(搜「figure 7.3」)
Louvain 与 Leiden7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:481(搜「Louvain method」) · text/17-ch07-02-7-2-graph-indexing.txt:482(搜「Leiden was」)
9 个社区、2–13 节点7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:491(搜「9 communities」)
不确定性(两次跑不同)7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:492(搜「not deterministic」)
依赖图结构7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:492(搜「can change depending」)
分层社区、本书简化7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:497(搜「hierarchical nature」) · text/17-ch07-02-7-2-graph-indexing.txt:500(搜「single level」)
报告五字段结构7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:521(搜「Report Structure」) · text/17-ch07-02-7-2-graph-indexing.txt:524(搜「TITLE」)
影响分 0-107.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:529(搜「IMPACT SEVERITY」)
5-10 条发现7.2 Graph indexingtext/17-ch07-02-7-2-graph-indexing.txt:534(搜「5-10 key insights」)
最大社区报告(主走查产物)7.3 Graph retrieverstext/18-ch07-03-7-3-graph-retrievers.txt:17(搜「Ithacan Household」)
按成员数取最大社区7.3 Graph retrieverstext/18-ch07-03-7-3-graph-retrievers.txt:4(搜「count」)
大社区选材框注7.3 Graph retrieverstext/18-ch07-03-7-3-graph-retrievers.txt:25(搜「too large」)
影响分用于过滤(第 10 章兑现)7.3 Graph retrieverstext/18-ch07-03-7-3-graph-retrievers.txt:199(搜「rating_threshold」)
微软实现透传 seed(② 锚)(不在书里)见本章脚注 3

Footnotes

  1. 出处:「7.2 Graph indexing」第 460 段(text/17-ch07-02-7-2-graph-indexing.txt:460,搜「more densely connected」)。原文:社区是彼此连接明显比与图其余部分连接更密的实体群。

  2. 出处:「7.2 Graph indexing」第 481 段(text/17-ch07-02-7-2-graph-indexing.txt:481,搜「Louvain method」)与第 482 段(text/17-ch07-02-7-2-graph-indexing.txt:482,搜「Leiden was」)。原文:代码用 Louvain;原论文实现用 Leiden;两者都在 GDS 库中。 2

  3. 出处:「7.2 Graph indexing」第 492 段(text/17-ch07-02-7-2-graph-indexing.txt:492,搜「not deterministic」)与(text/17-ch07-02-7-2-graph-indexing.txt:492,搜「can change depending」)。原文:Louvain 非确定,同输入两次运行划分可能略异;结果依赖抽出的实体与关系数量。「固化随机种子」与微软实现透传 seed 的确认:补充(不在书里,依据我们的 frontier 书架):开源实现把 random_seed 透传给 Leiden,配 stable 连通分量处理,使同输入结果可复现。依据: shelf=ai-frontier-reference/graphrag#03-communities-and-reports.md 事实=该拆解记录 hierarchical_leiden(edge_list, max_cluster_size, random_seed) 且 seed 用于可复现性。 2 3

  4. 出处:「7.2 Graph indexing」第 497 段(text/17-ch07-02-7-2-graph-indexing.txt:497,搜「hierarchical nature」)与第 500 段(text/17-ch07-02-7-2-graph-indexing.txt:500,搜「single level」)。「高层社区拿低层报告当原料」见我们的微软 GraphRAG 拆解:补充(不在书里,依据我们的 frontier 书架):分层场景下,超大社区的下层报告会替代原始材料作为上层摘要的输入。依据: shelf=ai-frontier-reference/graphrag#03-communities-and-reports.md 事实=该拆解写明「上层社区放不下原料时改用下层报告当输入」。 2

  5. 出处:「7.2 Graph indexing」第 491 段(text/17-ch07-02-7-2-graph-indexing.txt:491,搜「9 communities」)。

  6. 出处:「7.3 Graph retrievers」第 199 段(text/18-ch07-03-7-3-graph-retrievers.txt:199,搜「rating_threshold」)。global_retriever 默认阈值为 5,先过滤 rating 达标的社区。字段语义可配置是我们的引申。

  7. 出处:「7.3 Graph retrievers」第 25 段(text/18-ch07-03-7-3-graph-retrievers.txt:25,搜「too large」)。