Install
openclaw skills install @flyboat403/knowledge-graph-extraction-skillopenclaw skills install @flyboat403/knowledge-graph-extraction-skill从 docx/pdf 文档中抽取层次化知识节点,标注节点类型和语义关系,输出可直接导入知识图谱系统的结构化文件。
核心能力:
技术架构:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 文档解析 │───→│ LLM 语义抽取 │───→│ 格式验证 │───→│ Excel 生成 │
│ (脚本) │ │ (LLM) │ │ (脚本) │ │ (脚本) │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│ │ │ │
▼ ▼ ▼ ▼
提取纯文本 语义理解+推理 验证格式约束 生成标准输出
解析模板 生成节点+关系 修复格式错误
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| source_document | file | 是 | 待抽取的源文档,支持 docx/pdf 格式 |
| template_xlsx | file | 是 | 字段格式模板 xlsx 文件,需读取 A1 单元格的格式要求 |
MANDATORY - 阅读整个文件: 使用脚本解析模板,获取格式约束:
python scripts/extract_knowledge_graph.py --template template-knowledge-graph.xlsx --dry-run
MANDATORY - 读取完整文件: 阅读 references/output-format.md 了解列结构约束。
此步骤由 LLM 执行语义理解和知识抽取。
MANDATORY - 读取完整文件: 阅读 references/extraction-prompt.md 获取完整 Prompt 模板。
使用 references/extraction-prompt.md (~391 lines) 中的完整 Prompt 模板进行知识抽取。该模板包含所有抽取规则、字段说明和示例。
抽取完成后,LLM 应自检:
MANDATORY - Agent自检并自动修正
MANDATORY - READ ENTIRE FILE: 阅读 references/quality-check-prompt.md (~146 lines) 获取校验方法与修正指导。
抽取完成后,Agent必须执行质量校验。发现问题后,Agent直接修正JSON文件,无需用户干预。
| # | 校验项 | 检查方法 | 问题判定 | 修正方法 |
|---|---|---|---|---|
| 1 | 教学目标覆盖 | Level 4-7节点是否都有objective | level≥4但objective为空或"无" | 根据节点内容生成教学目标,使用行为动词:"能够..." |
| 2 | 教学目标质量 | 是否使用行为动词、是否具体可衡量 | "学会这个"、"了解"等模糊描述 | 改为具体目标:"能够说出..."/"能够操作..."/"能够分析..." |
| 3 | 层级深度 | 最高层级是否达到≥6级 | max(level) < 6 | 在末级知识点下添加细分节点(6-7级) |
| 4 | 层级跳跃 | 是否存在断层(父→孙跳过子) | level从1直接到3,无level 2 | 补充缺失的中间层级节点 |
| 5 | 知识分类约束 | 分类节点category是否为空 | node_type="分类"但category有值 | 清空category字段 |
| 6 | 知识点分类覆盖 | Level 4-7节点是否有category | node_type="知识点"但category为空 | 根据内容填写:事实性/概念性/程序性/元认知 |
| 7 | 节点名称长度 | 是否超过30字 | len(name) > 30 | 缩短名称,保持核心含义 |
| 8 | 关联关系覆盖 | 知识点节点related是否为空数组 | 知识点无任何关联关系 | 补充同类/对比/相似原理的关联节点 |
| 9 | 节点顺序 | 是否按深度优先输出 | 子节点在父节点之前出现 | 调整JSON数组顺序:父→子→兄弟 |
| 10 | 列名结构 | Excel第二行是否与模板列名一致 | 任意列名与模板不符 | 警告提示,不自动修正(脚本硬编码) |
| 11 | 知识点子节点约束 | 知识点节点是否有下级节点 | 知识点有children | 自动修正为分类 |
1. Read 工具读取生成的 JSON 文件
2. 遍历所有节点,逐一检查上述11项
3. 发现问题 → 立即使用 Edit 工具修正
4. 修正完成后重新校验(循环直到全部通过)
5. 输出校验报告,确认所有项✅
如需查看校验示例,阅读 references/quality-check-prompt.md 中的"校验示例"部分。
所有校验项必须全部通过:
| 校验项 | 通过标准 |
|---|---|
| 教学目标覆盖 | Level 4-7节点100%有objective |
| 教学目标质量 | 所有objective包含行为动词 |
| 层级深度 | max(level) ≥ 6 |
| 层级跳跃 | 父子层级连续,无断层 |
| 知识分类约束 | 分类节点category="" |
| 知识点分类覆盖 | 知识点节点category在有效值内 |
| 节点名称长度 | 所有节点名称≤30字 |
| 关联关系覆盖 | >50%知识点节点有related |
| 节点顺序 | 父节点在子节点之前(深度优先) |
| 列名结构 | Excel第二行列名与模板100%一致 |
| 知识点子节点约束 | 知识点节点无children(有children则自动修正为分类) |
如需脚本辅助校验,可运行:
python scripts/extract_knowledge_graph.py \
--json knowledge_nodes.json \
--template template-knowledge-graph.xlsx \
--output output.xlsx \
--validate-only
脚本输出详细问题清单,Agent据此逐一修正。
MANDATORY - READ ENTIRE FILE: 阅读 references/relation-prompt.md (~167 lines) 进行关系推理。模板包含前置关系和关联关系的完整识别规则。
前置关系识别规则:
| 模式 | 示例 |
|---|---|
| 基础概念 → 高级应用 | 电阻 → 欧姆定律 |
| 理论原理 → 实践操作 | 电路原理 → 电路安装 |
| 工具使用 → 应用场景 | 万用表使用 → 电流测量 |
关联关系识别规则:
| 模式 | 示例 |
|---|---|
| 同类并列 | 电阻 ↔ 电容 ↔ 电感 |
| 对比概念 | 直流电路 ↔ 交流电路 |
| 相似原理 | 欧姆定律 ↔ 基尔霍夫定律 |
将 LLM 输出的 JSON 数据传入脚本,生成 Excel 文件:
python scripts/extract_knowledge_graph.py \
--json knowledge_nodes.json \
--template template-knowledge-graph.xlsx \
--output output.xlsx
脚本自动验证:
Excel 第二行的列名是固定不变的,由脚本生成时硬编码写入。列名对应关系如下:
| 列 | 固定列名 | 说明 |
|---|---|---|
| A | 节点类型 | 分类 或 知识点 |
| B | 节点名称 | level1(模块/项目级) |
| C | 节点名称 | level2(章/单元/任务级) |
| D | 节点名称 | level3(节/知识主题/工序级) |
| E | 节点名称 | level4(知识点级) |
| F | 节点名称 | level5(细分级) |
| G | 节点名称 | level6(原子级) |
| H | 节点名称 | level7(精细级) |
| I | 前置节点 | 学习依赖的前置知识点 |
| J | 后置节点 | 前置关系的反向(自动生成) |
| K | 关联节点 | 相关但不构成依赖的知识点 |
| L | 标签 | 重点/难点/考点/课程思政 |
| M | 知识点分类 | 事实性/概念性/程序性/元认知 |
| N | 节点说明 | 知识点简要描述 |
| O | 教学目标 | 学习后应达成的能力 |
重要:请勿修改任何列名。下游系统(超星泛雅等)依赖这些列名进行数据导入。列名不匹配会导致导入失败。
核心原则(必须遵守):
;(不使用中文分号 ;)详细格式规则:开始填充前,MANDATORY - READ ENTIRE FILE:
references/output-format.md (~289 lines)
Do NOT load:如果只是理解流程概念,不需要加载详细格式规则。只有实际生成输出时才需要加载。
绝对禁止做这些 — 会导致导入失败:
❌ 错误: A列="分类", M列="概念性"
✅ 正确: A列="分类", M列="" # 分类节点M列必须留空
Why: 模板规则明确:分类节点不支持填写知识点分类。
❌ 错误: ['一级节点', '二级节点', '三级节点', '', '', '', '', '']
✅ 正确: ['一级节点', '', '', '', '', '', '', ''] # 每行只有一个节点名称
Why: 导入系统使用树结构。每行表示 ONE 节点。位置表示层级。
❌ 错误: 知识节点A;知识节点B;知识节点C
✅ 正确: 知识节点A;知识节点B;知识节点C
Why: 解析器期待 ASCII 分号 (;, U+003B),不是中文分号 (;, U+FF1B)。
❌ 错误: M列 = "事实性;概念性"
✅ 正确: M列 = "事实性" # 单选值
Why: 知识分类字段是单选。多个值会导致导入失败。
❌ 错误:
行1: [B列: 模块]
行2: [D列: 章节] # 跳过了C列
✅ 正确:
行1: [B列: 模块]
行2: [C列: 单元]
行3: [D列: 主题]
Why: 每个知识节点必须有完整的父链。跳跃层级会破坏树结构。
❌ 错误: K列全部为空
✅ 正确: K列包含语义相关的知识点(同类、对比、相似原理)
Why: 关联关系是知识图谱的重要组成部分,缺失会降低图谱质量。
❌ 错误: 修改Excel输出的第二行列名
✅ 正确: 保持脚本生成的标准列名不变
Why: 列名是硬编码的,用于下游系统导入。列名不匹配会导致导入失败。
❌ 错误: "pre_requisites": ["半身裙结构图的绘制"] # 实际节点名缺少"与工业样板的制作"
✅ 正确: "pre_requisites": ["半身裙结构图的绘制与工业样板的制作"] # 与name完全一致
Why: 关系引用(I列前置节点、K列关联节点)按节点 name 字段精确匹配。名称不一致会被视为引用不存在的节点,导致关系丢失。
问题: 这个节点能独立存在吗?
| 情况 | 判断 | 行动 |
|---|---|---|
| 概念过大 ("电路基础") | 太宽 | 拆分为多个子节点 |
| 细节过碎 ("电阻的单位") | 太窄 | 合并到上级节点 |
| 可独立理解 | 合适 | 保留为独立节点 |
问自己三个问题:
Q1: 上级 - 这个节点属于哪个模块/章节?
Q2: 下级 - 这个节点包含哪些具体内容?
Q3: 平级 - 还有哪些同类节点?
根据层级自动判断节点类型:
| 层级 | node_type | M列处理 |
|---|---|---|
| Level 1-3 | "分类" | 留空 |
| Level 4-7 | "知识点" | 填写分类值 |
前置关系 (I列):
关联关系 (K列):
| 文件 | 大小 | 加载时机 | Do NOT Load 情况 |
|---|---|---|---|
| references/output-format.md | ~289行 | 步骤1(必须) | 仅理解概念时 |
| references/extraction-prompt.md | ~15KB | 步骤2(必须) | 不执行抽取时 |
| references/quality-check-prompt.md | ~5KB | 步骤2.4(可选) | 不执行校验时 |
| references/relation-prompt.md | ~4KB | 步骤3(可选) | 不执行关系推理时 |
| 文件 | 大小 | 加载时机 | Do NOT Load 情况 |
|---|---|---|---|
| examples/template-knowledge-graph.xlsx | ~61KB | 步骤1(必须) | 已有用户提供的模板 |
| examples/example-curriculum-office-software.pdf | ~464KB | 演示/测试时 | 实际抽取任务时 |
⚠️ 注意:
脚本在处理过程中会输出以下验证提示:
| 提示类型 | 说明 | 处理方式 |
|---|---|---|
| FILE_FORMAT_ERROR | 上传的文档格式不支持(仅接受 docx/pdf) | 检查文件格式 |
| JSON_PARSE_ERROR | LLM 输出的 JSON 格式无效或根元素不是数组 | 修正 JSON 格式 |
| HIERARCHY_WARNING | 层级深度不足:最高层级低于6级(⚠️ 警告,非硬性要求) | 建议在末级知识点下添加细分节点 |
| NODE_TYPE_INVALID | 节点类型无效:"XX",应为"分类"或"知识点" | 修正 A 列值 |
| CATEGORY_FOR_CLASSIFICATION | 分类节点的知识点分类(M列)必须为空 | 清空分类节点的 M 列 |
| RELATION_LOW_COVERAGE | 关联关系覆盖率低于50%(建议补充同类/对比关联节点) | 补充 K 列关联关系 |
| CHINESE_SEPARATOR | 使用中文分号";",应使用英文分号";" | 替换为英文分号 |
| MULTIPLE_NAMES_PER_ROW | 每行应只有1个节点名称,实际N个 | 每行只填写一个层级节点 |
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
openpyxl 未安装 | 缺少 Python 依赖 | pip install openpyxl python-docx pdfplumber |
| JSON 解析错误 | LLM 输出格式不符合要求 | 检查 JSON 是否为有效数组格式,确保根元素是 [] |
| 模板文件未找到 | --template 路径错误 | 确认模板文件路径,使用 --dry-run 测试 |
| Excel 生成失败 | 数据格式异常 | 检查 JSON 中是否有特殊字符 |
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 层级深度不足(<6级) | 文档内容不够细 | 在末级节点下添加细分,或提供更详细的文档 |
| 节点类型判断错误 | level与node_type不匹配 | 检查 Level 1-3 是否设为"分类",Level 4-7 设为"知识点" |
| 关系引用不匹配 | 名称不完全一致 | 确保 pre_requisites/related 与节点 name 完全一致 |
| 教学管理信息被抽取 | 未遵守排除规则 | 参照"排除内容"清单重新过滤 |
| 问题 | 可能原因 | 解决方法 |
|---|---|---|
| 导入超星平台失败 | 列名被修改 | 重新运行脚本生成,确保第二行列名与标准一致 |
| CSV 乱码 | 编码问题 | 脚本已使用 UTF-8 BOM 编码,检查导入平台编码设置 |
| 关系数超过2000条 | 节点间过度关联 | 减少不必要的关系,只保留有实际教学意义的关联 |