模型 / 数据集
stair-lab/kg-gen avatar
stair-lab/kg-gen

kg-gen:把任意纯文本抽成知识图谱的 Python 包

[NeurIPS '25] Knowledge Graph Generation from Any Text

1,270 个 Star199 个 ForkPython许可证因项目而异

秒懂

它是什么?
kg-gen 用 LLM 从字符串或对话消息里抽出实体、边和三元组,支持分块、聚类与多图合并。它的核心价值在于实体去重和关系归一化,代价是对模型输出质量和调用成本的直接依赖。
适合谁用?
如果你的输入是散文、对话记录或没有既定 schema 的文档,并且你能接受把抽取质量交给所选模型,kg-gen 值得先跑一遍 tests/test_basic.py 验证链路。如果你的数据本身已经是结构化三元组,或者你需要确定性、可复现的抽取结果,这个工具不合适,因为它每次输出的实体集合和边标签都由模型生成,温度设为 0 也不改变这一点。
能商用吗?
未经许可不能。GitHub 在这个仓库里没有找到许可证文件;没有许可证,默认即「保留所有权利」:你可以阅读代码,但不能复用。使用前请看看 README,或先征得作者同意。
还在维护吗?
在维护。仓库最近一次提交在 175 天前。
用什么语言写的?
主要是 Python(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

谁需要把一段话变成一张图

这个包解决的问题很具体:手上有一段自然语言,但下游程序要的是结构化的实体和关系。README 列出的用途包括为 RAG 建图、生成图结构的合成数据、把任意文本结构化,以及分析源文本中概念之间的关系。这四类需求有一个共同点,输入没有固定格式。

它面向的是已经选定了一个 LLM 提供商、并且愿意把抽取环节外包给模型的开发者。README 给的例子是家庭关系这类小样本,也给了神经网络与机器学习这类概念层级。真正需要它的场景是第三种和第四种:文本里没有明确的字段边界,你不知道该抽哪些实体,也不知道关系该怎么命名,只能让模型先给出一版,再靠聚类去收敛。

如果文本本身已经有 schema,比如数据库导出的记录、带标注的 JSON,那用这个包属于绕远路。它的价值恰恰在于输入没有结构。

抽取、分块、聚类三步走

kg-gen 的输出是一个包含 entities、edges、relations 三个集合的对象。README 的示例里,输入 Linda is Josh's mother 这类句子后,entities 是四个名字的集合,edges 是 is brother of 这类关系标签的集合,relations 则是 (Ben, is brother of, Josh) 这样的三元组。三者分开存的意义在于,边标签和实体名可以各自被聚类,而不必绑定在具体三元组上。

长文本走的是另一条路径。调用 generate 时传入 chunk_size=5000,文本按 5000 字符切块,每块单独抽取,之后再合并。README 明确说 cluster=True 会聚类相似的实体和关系,示例输出里 entity_clusters 把 AI 和 artificial intelligence 归到一组,edge_clusters 把 is type of、is a type of、is a kind of 归到一组。这一步是必要的,因为分块之后同一个概念在不同块里很可能被写成不同形式,不聚类的话图里会散落大量近义节点。

多图合并是第三条路径。aggregate 接收一个图列表,把多个图并成一个,之后可以再调 cluster 传入 context 做一次带上下文的归一化。示例里 Joe 和 Joseph 被合并到同一个实体簇,靠的正是这一步。值得注意的是,聚类发生在抽取之后,也就是说模型先自由生成,再由聚类去纠正不一致,这个顺序决定了错误只能被收敛、不能被完全消除。

安装与最小可运行链路

从 PyPI 安装:pip install kg-gen。从仓库安装则先 clone,再执行 pip install -e '.[dev]',dev 这个 extra 是跑测试和实验需要的。

初始化时至少要传 model。README 的写法是 kg = KGGen(model="openai/gpt-4o", temperature=0.0, api_key="YOUR_API_KEY")。api_key 是可选的,如果已经写进环境变量或者用的是本地模型就可以省略。模型字符串的格式由 LiteLLM 决定,README 说是 {model_provider}/{model_name},给的例子包括 openai/gpt-5、gemini/gemini-2.5-flash 和 ollama_chat/deepseek-r1:14b。注意本地 Ollama 用的是 ollama_chat 而不是 ollama,这个前缀写错会直接报错。自定义 API 地址通过 base_url 传入,README 指向 tests/test_custom_api_base.py 作为示例。

验证安装是否正常,在仓库根目录执行 python tests/test_basic.py,README 说这会顺带在 tests/test_basic.html 生成一个可视化页面。可视化本身用 KGGen.visualize(graph, output_path, open_in_browser=True) 调用。

输入支持两种形式,单个字符串,或者一个 Message 对象列表,每个对象带 role 和 content。示例里 messages 数组传的是 user 问法国首都、assistant 回答巴黎,输出就是 France 和 Paris 两个实体加一条 has capital 关系。对话格式对聊天记录类数据是直接可用的。

结构化输出靠 DSPy,模型选择决定一切

README 说明结构化输出由 DSPy 负责,模型调用由 LiteLLM 路由。这个分工意味着 kg-gen 本身不实现抽取逻辑,它做的是提示编排、分块调度、结果归并和聚类。真正决定抽取质量的是你传进去的模型。

这带来一个直接的后果:换模型就等于换一套抽取行为。同一个文本用 gpt-4o 和用本地 14B 模型跑,实体粒度和边标签风格可能完全不同,而 kg-gen 不会告诉你哪个更对。temperature 默认 0.0,README 的示例也显式设成 0.0,但温度为零只减少采样随机性,不保证跨版本、跨提供商的输出一致。

聚类这一步也有代价。把 AI 和 artificial intelligence 合并成一个节点是想要的,但如果模型把两个真正不同的概念抽成了相近的字符串,聚类会把它们错误地并在一起,而且合并之后原始区分就丢了。README 没有说明聚类用什么阈值、是否可调,这一层对使用者是不透明的。

什么时候它帮不上忙

最明显的边界是输入本身已经有结构。如果数据来自数据库或者带 schema 的标注文件,抽取这一步是多余的,直接映射成三元组更准确也更便宜,还省掉一次模型调用。

第二个边界是需要确定性输出的场景。知识图谱如果要做成可审计的资产,每次重跑都得到不同的实体集合和边标签就很难接受。kg-gen 的抽取结果由模型生成,聚类结果由相似度决定,这两层都不提供可复现的保证。

第三个边界是成本与长文本的交互。chunk_size=5000 意味着文本越长,模型调用次数越多,聚类阶段还要再算一遍相似度。仓库的发布记录里有一个 MINE-deduplication-scikitlearn-vs-faiss 的 release,标题说明去重环节存在 Scikit Learn 与 Faiss 两种实现路径,这暗示聚类在数据量增大时是有性能考量的,但 README 没有给出规模上限或推荐配置,这部分需要自己压测。

最后是许可证。仓库元数据里 License 一栏是空的,README 也没有提到许可证。对个人实验影响不大,但对要把它放进产品链路的团队,这是必须先向维护者确认的事,本文不构成法律意见。

和直接让模型输出 JSON 的差别在哪

最直接的替代做法是写一个提示词,让模型返回 JSON 格式的三元组列表,自己解析。这个做法在单段短文本上完全够用,代码量也小。

差别出现在文本变长、图变多之后。手写方案要自己处理分块边界上的实体重复,自己决定 is a type of 和 is a kind of 算不算同一条边,自己把多批结果合并。kg-gen 把这些都做成了 API:chunk_size 管切分,cluster 管归一化,aggregate 管合并,entity_clusters 和 edge_clusters 把合并结果显式返回出来供检查。这是它相对裸提示词的主要增量。

另一个替代方向是使用已有的图数据库或图构建工具链,但那些工具通常假设你已经有了三元组,解决的是存储和查询,不是从文本里把三元组挖出来。kg-gen 处在更前面的一环。

仓库还提供了 MCP server,通过 pip install kg-gen 之后执行 kggen mcp 启动,README 说是给需要持久记忆能力的 AI agent 用的,可以配合 Claude Desktop 或自定义 MCP 客户端。这属于另一条集成路径,和 Python 库的用法不冲突。

维护状态与升级时要看什么

仓库未归档,最近一次 push 是 2026 年 3 月。发布记录里有三个带日期的 tag:MINE-evaluations-expanded、MINE-deduplication-scikitlearn-vs-faiss 和 WikiQA-evaluations,时间集中在 2025 年 10 月到 11 月。这些 tag 的名字都指向评测和实验,不是常规的版本号,所以从发布记录看不出稳定的语义化版本节奏。

对使用者的含义是,升级时不能只看版本号。真正会影响行为的是三处外部依赖:LiteLLM 的 provider 前缀规则、DSPy 的结构化输出接口、以及聚类环节的实现。前两者是第三方库,它们的变更会直接传导到 kg-gen 的调用方式上。仓库提供了 experiments/ 和 MINE/ 目录,README 指向 experiments/MINE 说明如何跑 MINE 基准,如果要评估升级前后的抽取质量变化,这是仓库内可用的对照手段。

配套资源方面,论文在 arXiv 2502.09956,数据集发布在 Hugging Face 的 belindamo/wiki_qa_kggen,MCP 相关代码在仓库的 mcp/ 目录下。这些都是升级或复现时可以先查的位置。

编辑结论

如果你的输入是散文、对话记录或没有既定 schema 的文档,并且你能接受把抽取质量交给所选模型,kg-gen 值得先跑一遍 tests/test_basic.py 验证链路。如果你的数据本身已经是结构化三元组,或者你需要确定性、可复现的抽取结果,这个工具不合适,因为它每次输出的实体集合和边标签都由模型生成,温度设为 0 也不改变这一点。上手前先确认三件事:目标模型在 LiteLLM 下的 provider 前缀写法、长文本下 chunk_size 与 cluster 的配合是否会让实体被错误合并、以及仓库未声明许可证这一事实对你所在组织的合规要求意味着什么。

官方来源

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. stair-lab/kg-gen on GitHub
社区笔记

社区笔记