ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.1em;color: rgb(63, 63, 63);visibility: visible;">
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 14px;font-style: normal;padding: 1em;border-radius: 6px;color: rgba(0, 0, 0, 0.5);background: rgb(247, 247, 247);">
ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 1em;display: block;letter-spacing: 0.1em;color: rgb(63, 63, 63);"> ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: inherit;color: rgb(1, 155, 252);">注意:笔者并非此领域专家,本文旨在分享一个探索性项目。欢迎任何形式的反馈与建议,无论是建设性的批评还是其他想法,都将虚心接受。
ingFang SC";font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">知识图谱是一种强大的信息表示工具,通过实体(节点)及其之间的关系(边)来清晰呈现事物间的联系。相比之下,非结构化文本则显得杂乱无章。
ingFang SC";font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">传统上,从原始文本构建知识图谱并非易事,往往需要人工识别实体和关系,并编写提取规则,或者借助专门的机器学习模型完成任务。然而,大语言模型(LLM)的出现带来了转机。LLM 具备强大的灵活性,非常适合这项任务。它们能够读取自由格式的文本并输出结构化信息。正如本文将展示的,我们可以利用 LLM 构建自动化流程来创建知识图谱。
ingFang SC";font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">本文将介绍我创建的一个学习项目,目标是构建一个由 LLM 驱动的流程,将非结构化文本转化为交互式的知识图谱网页。该项目的所有代码都托管在 AI-Knowledge-Graph(https://github.com/robert-mcdermott/ai-knowledge-graph) 项目仓库中。 ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;display: table;padding: 0px 0.2em;color: rgb(255, 255, 255);background: rgb(1, 155, 252);">简单示例
ingFang SC";font-size: 14px;letter-spacing: 0.1em;color: rgb(63, 63, 63);">下面是一个简单的例子,展示了该项目的功能。当输入以下非结构化文本时: ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-feature-settings: normal;font-variation-settings: normal;font-size: 14px;margin: 10px 8px;color: rgb(201, 209, 217);background: rgb(13, 17, 23);padding: 1em;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: left;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">来自加拿大的才华横溢的音乐家亨利,最初在著名指挥家玛丽亚·罗德里格斯的指导下接受古典钢琴训练。后来,亨利与他的妹妹露西组建了一支名为“枫叶乐队”的摇滚乐队,露西曾在多伦多大学学习音乐作曲。“枫叶乐队”于2020年8月12日发行了他们的首张专辑《极光》,因其融合了古典与摇滚元素而广受好评。露西还积极参与环保活动,并加入了“清洁地球”组织担任区域大使,在那里她倡导更严格的野生动物保护法。亨利受到露西对慈善事业热情的启发,开始在家乡的当地动物收容所做志愿者。虽然亨利和露西最初在创作上存在分歧,但他们最终在结合露西的古典作品和亨利的摇滚吉他Riff中找到了和谐。“枫叶乐队”于2021年在欧洲巡演,在巴黎、柏林和罗马等主要城市举办了场场爆满的演出。巡演期间,亨利对国际美食产生了浓厚兴趣,并与当地厨师合作拍摄了一部关于地方烹饪技术的短纪录片。ai-knowledge-graph工具将使用您选择配置的 LLM 从上述文本中提取知识,并创建一个知识图谱 HTML 文件作为输出,其外观类似于下图:
工作原理概览: 1.文本分块 (Text Chunking) :自动将大型文档分割成易于处理的小块。 2.知识抽取 (Knowledge Extraction) :LLM 识别并提取每个文本块中的主谓宾三元组(事实)。 3.实体标准化 (Entity Standardization) :将指向同一实体的不同表述(例如,“AI” 和 “人工智能”)统一为标准名称。 4.关系推理 (Relationship Inference) :通过简单的逻辑规则(如传递性)和 LLM 推理来推断额外的关系,以连接孤立的子图。 5.交互式可视化 (Interactive Visualization) :将生成的图谱在浏览器中以交互式网络图的形式展示。 工作原理详解 文本分块 考虑到 LLM 的上下文窗口有限(以及本地系统的内存限制),该工具会自动将文本拆分为若干片段(每个片段约含 500 个单词,并保留一定重叠部分以保持语义连贯)。每个文本块随后会连同一个指示 LLM 提取 SPO 三元组的提示一起发送给 LLM。
基于 LLM 的抽取 对于每个文本块,工具会要求 LLM 输出一个包含三元组及其来源块信息的 JSON 数组。示例如下:
[ { "subject":"eli whitney",// 伊莱·惠特尼 "predicate":"invented",// 发明了 "object":"cotton gin",// 轧棉机 "chunk":1// 来源块编号 }, { "subject":"Industrial Revolution",// 工业革命 "predicate":"reshapes",// 重塑了 "object":"economic systems",// 经济体系 "chunk":1 }, { "subject":"amazon",// 亚马逊 "predicate":"transformed",// 改变了 "object":"retail",// 零售业 "chunk":3 } ]提示会鼓励 LLM 使用一致的实体命名、简短的关系短语(1-3 个词)并且不使用代词指代。提取出的所有三元组随后被合并以形成初始的原始知识图谱。
跨块实体标准化 为了避免相同实体因不同表述造成节点碎片化或重复,导致 节点碎片化或重复,该工具提供了一个实体标准化步骤。
1.基础规范化: 通过转换为小写、删除多余空格等方式消除明显的重复内容。 2.标准化(可选): 启用此功能后,LLM 会将可能指向同一实体的不同表述进行聚类。例如,“New York”、“NYC” 和 “New York City” 会变成一个规范化的节点 “New York City”;“United States”、“U.S.” 和 “USA” 会变成另一个规范化的节点 “United States”。 这能提高图谱的一致性,因此通常建议启用。当然,如果您有特殊需求,例如需要未经任何修改的原始提取结果,也可以在配置文件中禁用它。
推理隐藏连接以丰富图谱 即使仔细阅读文本,也可能无法捕捉到所有隐含的关系。该工具通过两种方式解决这个问题:
基于规则的推理:
•传递关系: 如果事件 A 导致了事件 B 的发生,事件 B 又导致了事件 C 的发生,那么系统可以推断出事件 A 对事件 C 具有间接影响。 •词汇相似性: 利用词汇相似性,相似名称的实体间可能生成“相关”关系。 大模型辅助推理:
• 该工具可以提示 LLM 在原本不相连的子图之间建立连接。例如,如果一个集群是关于工业革命,另一个是关于人工智能,LLM 可能会推断出历史或概念上的联系(“人工智能是工业革命以来技术创新的延伸”)。 • 这些推断出的边会用不同的样式标记(例如,虚线),以区别于文本中明确陈述的事实。 这个推理步骤通常会增加大量新关系,大大减少孤立的子网络。如果您只想要纯粹从文本派生的图谱,可以在配置文件中禁用它。与块编号不同,推断出的关系会包含一个属性,用于指明该关系是推理得出的。该属性在可视化时会用于以虚线表示推断出的关系边,因此非常重要。示例结构:
[ { "subject":"electrification",// 电气化 "predicate":"enables",// 促成了 "object":"Manufacturing Automation",// 制造业自动化 "inferred":true// 表示该关系是推理得出的 }, { "subject":"tim berners-lee",// 蒂姆·伯纳斯-李 "predicate":"expanded via internet",// 通过互联网扩展了 "object":"information sharing",// 信息共享 "inferred":true } ]LLM 提示 总共会向 LLM 发送四个提示,首先是用于初始主谓宾(SPO)知识抽取的提示。
抽取系统提示 (Extraction System Prompt):
你是一个先进的人工智能系统,专门从事知识抽取和知识图谱生成。 你的专长包括识别文本中一致的实体引用和有意义的关系。 关键指令:所有关系(谓语)最多只能包含 3 个词。理想情况下是 1-2 个词。这是一个硬性限制。抽取用户提示 (Extraction User Prompt):
你的任务:阅读下面的文本(由三个反引号分隔),识别每个句子中所有的主语-谓语-宾语(S-P-O)关系。然后生成一个单一的 JSON 对象数组,每个对象代表一个三元组。请仔细遵循以下规则: -实体一致性:在整个文档中对实体使用一致的名称。例如,如果“John Smith”在不同地方被提及为“John”、“Mr. Smith”和“John Smith”,请在所有三元组中使用单一一致的形式(最好是最完整的形式)。 -原子术语:识别不同的关键术语(例如,物体、地点、组织、缩写、人物、条件、概念、情感)。避免将多个概念合并为一个术语(它们应尽可能“原子化”)。 -统一指代:将任何代词(例如,“他”、“她”、“它”、“他们”等)替换为实际引用的实体(如果可识别)。 -成对关系:如果多个术语在同一句子中共同出现(或在使它们具有上下文关联性的短段落中),为每个具有有意义关系的配对创建一个三元组。 -关键指令:谓语必须最多包含 1-3 个词。绝不能超过 3 个词。保持极其简洁。 -确保文本中所有可能的关系都被识别并捕获为 S-P-O 关系。 -标准化术语:如果同一概念以略微不同的形式出现(例如,“artificial intelligence”和“AI”),请始终使用最常见或规范的形式。 -将 S-P-O 文本全部转为小写,即使是人名和地名。 -如果提到了人名,并且已知其地点、职业以及其闻名之处(发明、写作、创立、头衔等),并且符合信息上下文,则创建相应的关系。 重要考虑因素: -实体命名力求精确——使用能够区分相似但不同实体的特定形式。 -通过在整个文档中对相同概念使用相同的实体名称来最大化连通性。 -在识别实体引用时考虑整个上下文。 -所有谓语必须是 3 个词或更少——这是一个硬性要求。 输出要求: -不要在 JSON 之外包含任何文本或注释。 -只返回 JSON 数组,每个三元组作为一个包含“subject”、“predicate”和“object”的对象。 -确保 JSON 有效且格式正确。这里没有列出另外三个提示,它们分别用于指导 LLM 进行标准化和关系推理。您可以在 src/knowledge_graph/prompts.py(https://github.com/robert-mcdermott/ai-knowledge-graph/blob/main/src/knowledge_graph/prompts.py) 源文件中查看(和调整)所有提示。
交互式图谱可视化 有了全面的 SPO 三元组列表(原始加推断的),该工具会使用 PyVis(Vis.js 的 Python 接口)生成一个交互式的 HTML 可视化文件。在浏览器中打开生成的文件,您将看到:
•颜色区分的社群: 同一个集群中的节点共享一种颜色。集群通常对应文本中的子主题或议题。 •节点大小反映重要性: 连接数多(或中心度高)的节点显得更大。 •边的样式: 实线表示从文本直接提取的关系,虚线表示推断得出的关系。 •交互式控件: 支持平移、缩放、拖拽节点,调整动态效果,切换亮/暗模式,以及筛选视图。 这使得以一种视觉上吸引人的方式探索关系变得容易。
程序流程 下面是程序的基本流程(代码仓库的 README.md 中有一个更详细的程序流程图):
安装 AI-Knowledge-Graph 要在您的计算机上运行此项目,您需要满足以下要求:
要求:
• 一台运行 Windows、Linux 或 MacOS 的计算机 • 安装 Python (3.12 或更高版本) (推荐使用uv) • 能够访问 OpenAI 兼容的 API 端点 (例如 Ollama, LiteLLM, LM Studio, OpenAI 订阅等) 下载并安装依赖项:
将仓库克隆到您要运行它的系统上,并切换到该目录:
gitclonehttps://github.com/robert-mcdermott/ai-knowledge-graph.git cdai-knowledge-graph使用uv安装依赖项:
uvsync 或者使用pip安装:
pipinstall-rrequirements.txt 配置 AI-Knowledge-Graph 编辑config.toml文件以适应您的情况。您需要在此配置 LLM 模型、端点(URL)、最大上下文窗口长度以及 LLM 的温度(temperature)参数,该参数控制模型生成文本的随机性。在下面的示例中,我使用的是通过 Ollama 在本地计算机上托管的 Google 开源 Gemma 3 模型。您还可以在这里调整文档分块大小和重叠量,以及是否启用实体标准化和关系推理来建立更多联系:
[llm] model="gemma3"# 使用的 LLM 模型名称 api_key="sk-1234"# 你的 API 密钥 (如果需要) base_url="http://localhost:11434/v1/chat/completions"# LLM API 端点 URL max_tokens=8192# LLM 的最大 token 限制 (上下文窗口) temperature=0.2# LLM 生成的随机性 (0 表示确定性) [chunking] chunk_size=200# 每个文本块的词数 overlap=20 # 块之间的重叠词数 [standardization] enabled=true # 是否启用实体标准化 use_llm_for_entities=true# 是否使用 LLM 进行额外的实体解析 [inference] enabled=true # 是否启用关系推理 use_llm_for_inference=true# 是否使用 LLM 进行关系推理 apply_transitive=true # 是否应用传递性推理规则 [visualization] edge_smooth=false# 边的线条是否平滑 (true 或 false)注意: 对于本地 LLM,您可以使用 Ollama 或 LM Studio 的 API 端点。要访问任何商业 LLM 提供商(如 AWS Bedrock、Azure、Anthropic、OpenAI 以及许多其他通过 LiteLLM 支持的服务),可以使用 LiteLLM。
创建知识图谱 现在您已经安装并配置好ai-knowledge-graph指向您的 LLM,可以开始创建您的第一个知识图谱了。准备一个您想要为其创建知识图谱的纯文本文档(目前仅支持文本文档)。
接下来,您需要在您的 {Windows/MacOS/Linux} 操作系统上,打开终端并执行generate-graph.py脚本。以下是该脚本的帮助信息:
usage: generate-graph.py [-h] [--test] [--config CONFIG] [--output OUTPUT] [--input INPUT] [--debug] [--no-standardize] [--no-inference] 知识图谱生成器和可视化工具 options: -h, --help 显示此帮助信息并退出 --test 使用示例数据生成测试可视化 --config CONFIG 配置文件路径 --output OUTPUT 输出 HTML 文件路径 --input INPUT 输入文本文件路径 (除非使用 --test, 否则为必需) --debug 启用调试输出 (原始 LLM 响应和提取的 JSON) --no-standardize 禁用实体标准化 --no-inference 禁用关系推理以下是使用当前目录中名为mydocument.txt的文本文档创建知识图谱的示例(如果您使用uv,请将 “python” 替换为 “uv run”):
pythongenerate-graph.py--inputmydocument.txt--outputmydocument.html 以下是上述命令完整流程在控制台中显示的输出:
python generate-graph.py --input mydocument.txt --output mydocument.html 使用文件中的输入文本: mydocument.txt ================================================== 阶段 1:初始三元组提取 ================================================== 处理文本,共 3 个块 (大小: 500 词, 重叠: 50 词) 处理块 1/3 (500 词) 处理块 2/3 (500 词) 处理块 3/3 (66 词) 从所有块中共提取了 73 个三元组 ================================================== 阶段 2:实体标准化 ================================================== 开始时有 73 个三元组和 106 个唯一实体 标准化所有三元组中的实体名称... 对 15 个实体组应用了基于 LLM 的实体标准化 移除了 8 个自引用三元组 将 106 个实体标准化为 101 个标准形式 标准化后: 65 个三元组和 72 个唯一实体 ================================================== 阶段 3:关系推理 ================================================== 开始时有 65 个三元组 推理前排名前 5 的关系类型: -pioneered: 9 次出现 (开创了) -invented: 7 次出现 (发明了) -developed: 6 次出现 (发展了) -develops: 6 次出现 (发展) -was: 4 次出现 (是) 推理实体间的附加关系... 在图谱中识别出 18 个断开连接的社群 在社群之间推断出 27 个新关系 在社群之间推断出 30 个新关系 在社群内部推断出 6 个新关系 基于词汇相似性推断出 8 个关系 添加了 51 个推断关系 推理后排名前 5 的关系类型: -invented: 7 次出现 (发明了) -pioneered: 6 次出现 (开创了) -developed: 6 次出现 (发展了) -develops: 6 次出现 (发展) -related to: 6 次出现 (相关) 添加了 57 个推断关系 最终知识图谱: 116 个三元组 原始知识图谱数据已保存至 mydocument.json 处理 116 个三元组用于可视化 找到 72 个唯一节点 找到 55 个推断关系 使用 Louvain 方法检测到 12 个社群 知识图谱可视化已保存至 mydocument.html 知识图谱统计信息: 节点数: 72 边数: 116 (55 条为推断得出) 社群数: 12 要查看可视化结果,请在浏览器中打开以下文件: file:///Users/robertm/mycode/ai-knowledge-graph/mydocument.html现在,在您的网页浏览器中打开生成的 html 文件即可探索知识图谱。如果您只是阅读本文,想在不亲自创建的情况下查看并与该系统创建的知识图谱进行交互,请点击以下链接查看根据一份关于工业革命的文档创建的可视化示例:Industrial-Revolutions.html (https://robert-mcdermott.github.io/ai-knowledge-graph/)
您可以使用页面顶部的菜单展开控制面板,以调整布局物理效果、隐藏或显示节点/边的标签、查看图谱统计信息或选择/筛选节点和边。还有一个暗黑模式,如下例所示:
尝试不同设置非常重要 我的经验是,把重叠大小设为分块大小的 10% 左右比较合适。如果分块太小(比如 100 到 200 个词),虽然能提取到更多关系,但可能会漏掉一些跨块的重要连接。所以,还是得多试试不同的参数组合才能找到最佳配置!我相信通过调整提示也可以实现很多优化。