| name | knowledge-graph-extract |
| description | 从教材 markdown 抽取知识图谱。当用户在一个包含 markdown/ 文件夹的目标目录里,需要把教材内容(文件名形如 textbookId_unitId_lessonId.md)抽取成知识图谱 JSON、并生成可视化预览页时使用。逐个 lesson 输出 output/knowledgegraph/{lessonId}.json 与自包含 HTML 预览页。核心红线:data-hash 与正文零丢失、零篡改。 |
知识图谱抽取(knowledge-graph-extract)
把教材 markdown 抽取为分层知识图谱 JSON(层级数见第 0 步门禁,默认 3 层),并渲染精美预览页。
适用于任意科目的教材,只要来自标准导出格式(frontmatter 含 textbookId/unitId/lessonId、
内容块带 {data-hash="fm-doc-id-xxx"}、栏目为 项目/任务/相关知识点 结构)。
下文示例仅用于说明规则,不代表只处理该科目——按实际教材内容判断。
何时使用
用户在某个「目标目录」下需要抽取知识图谱,且该目录含 markdown/ 文件夹,
文件命名为 textbookId_unitId_lessonId.md。
铁律(最高优先级,任何时候不可违背)
- data-hash 零丢失:原文每个知识性内容块都带
{data-hash="fm-doc-id-xxx"}。
不论它在第几层、是标题还是正文,只要是知识性内容,其 hash 就必须出现在输出中,一个都不能丢。
- 正文零篡改:知识点正文(
description[].text)与所有 dataHash 原样复制,
不得改写、补全、翻译、合并、精简。
- hash 与正文由脚本搬运,不靠手抄:先用
parse_md.py 把每个块的 {text, data_hash}
机械切出来,你从解析结果里复制,绝不凭记忆重写。
- 脚本校验兜底:写完 JSON 必须用
validate.py 校验,丢失数必须为 0,否则修正重来。
执行流程
0. 确认最大层级(开跑前门禁,必做)
开始抽取前,先与用户确认图谱的最大层级,三选一:
本次抽取的知识图谱最多分几级?
- 默认 3 级(level 0/1/2,学习通平台允许的最大层级)——不选则按此。
- 指定 4 级或 5 级(教材标题更深时)。
- 模型自判:由我按每个 lesson 的内容繁简自行决定深度,约束:不少于 2 级、最多 6 级,具体级数由我判断。
- 记
N = 生效的最大级数,则图谱层级为 level 0 ~ level (N-1)。
- 默认 →
N=3;用户指定 → N=4/5;模型自判 → 每个 lesson 取 2~6 级(由你按内容定,校验用 --max-level 6 作上限守卫)。
- 超过 N 层的更深知识内容,归集进第 N 层(最深允许层,level N-1)节点的
description,不新建更深节点,hash 照旧零丢失。
- 段落级编号小点可提炼为节点:正文里的并列编号点(如「(1)… / (2)…」这类并列小项)
若各自是独立知识点,你可在层级允许范围内提炼为下一层节点——前提是其 data-hash 一并带入该节点
(dataHash 或 description),绝不丢失。是否提炼由你按内容判断;不提炼则留在上级节点的 description 里,同样不丢 hash。
- 后续所有
validate.py 调用带 --max-level N(默认 3 可省略;模型自判用 --max-level 6 作上限守卫)。
1. 定位输入
在目标目录找到 markdown/ 下的 .md 文件,逐个处理。每个文件 = 一个 lesson = 一个输出 JSON。
2. 机械解析(脚本)
对每个 md 文件运行解析器,得到 blocks 中间结构:
python3 <技能目录>/scripts/parse_md.py markdown/<文件名>.md -o /tmp/blocks.json
blocks.json 里每个块含 {index, kind, heading_level, text, data_hash, raw}。
后续 JSON 里的所有 text 和 dataHash 都从这里复制,不要自己重写。
3. 语义组装(你来判断)
读 blocks,按下列规则组装 nodes + edges。按语义判断,不要按 # 个数
——同一系统不同文件的标题层级可能不一致(如任务标题有时是 H2、有时更深;脚手架层级也会浮动),
所以靠标题的语义角色("任务X"/"相关知识点X"/具体知识点)判断,而非固定的 # 数量。
N 层映射(N = 第 0 步确认的最大级数,默认 3):
- level 0(根,一个 lesson 一个):语义为「任务X」的最高知识标题。
id = frontmatter 的 lessonId(原样数字),label = 去掉「任务X」编号前缀后的标题文本。
- level 1(主题):语义为「相关知识点X:xx」的分组标题。
label = 去掉「相关知识点X:」前缀后的主题名。
- level 2(知识点):level 1 之下的具体知识点标题(去掉序号前缀,如「1.xxx」→「xxx」)。
- level 3 / level 4(仅当 N≥4 / N=5 时):继续按原文更深的知识标题层级向下建节点。
- 超过 N 层(最深允许层为 level N-1):更深的知识标题不新建节点,其内容
归集进所属 level (N-1) 节点的
description 数组(正文与 hash 全保留)。
- 该系统的知识标题通常天然是 3 层(任务→相关知识点→具体知识点),默认 N=3 即可覆盖,
level 2 之下一般即正文段落。
任意层级的直属正文归集(体现铁律 1):
- 每一级节点标题下、到下一个子节点出现之前的正文段落/列表项,
都归入该节点自己的
description 数组,逐项 {text, dataHash}。
- 例:某个「相关知识点」标题下、第一个具体知识点之前的数段正文,归入该 level 1 节点自己的 description。
H1 项目标题(单元级,仅每单元首个 lesson 文件有):
- 项目标题是文件里最高层级的
# 一级标题(heading_level == 1),语义为「项目X xxx」。
它是跨文件的单元级标题,不单独建节点。
- ⚠️ 不要靠「含某关键词」来识别它:知识点标题可能碰巧含同样的字(例如某个具体知识点标题里
也出现"项目"二字,但它是普通 level 1/2 知识点,不是单元级项目标题)。
唯一可靠依据是它的层级最高(H1)。
- 把 H1 项目标题存入根节点(level 0)的元信息:
projectTitle(原文)+ projectDataHash(其 hash)。
- 这样它的 hash 有落点、不丢失,又不破坏「根 = 任务/lesson」的约定。
剔除脚手架(不进图谱):
- 目标领航 / 学习内容(单元导入语)
- 任务目标 / 素质目标 / 知识目标 / 能力目标
- 任务描述
- 任务检验 / 任务小结 / 课后练习 / 思考与练习等「检验·练习」栏目:这类标题下方整块都是练习题
(单选题/多选题/判断题、选项、进度等),整个栏目连同其下所有内容一律剔除,不建任何节点。
⚠️ 一个知识点节点如果它的 description 全是练习题/题目选项,说明它本就是练习栏目误入——不应存在。
- 图片说明(
kind=image)
- 「任务学习」是容器标题,自身不建节点,但其下的「相关知识点」正常进图谱。
- 清单可按教材扩展:不同科目教材有各自的非知识性栏目(活动/导入/互动/案例讨论等,
栏目名因科目而异)。遇到明显是活动/导入/互动栏目而非知识内容的标题,一并剔除;拿不准时宁可保留进图谱,
也不静默丢弃(validate 全覆盖校验会兜底提醒)。
⚠️ 注意:
考点 标签的判定依据(练习题/思考题/任务检验)本身是脚手架、不建节点,但它们指示了
哪些知识点是考点——剔除题目节点的同时,给其考查的知识点打 考点 标签。
节点字段:
id:根 = lessonId;子节点 = {lessonId}_{英文语义后缀}(snake_case,文件内唯一,你生成)。
label:必须是简洁的名词 / 名词短语 / 短标题,去掉序号/分组前缀。不要写成整句。
description:[{text, dataHash}] 数组,收该节点的直属正文段落;每段 text 是完整定义句/解释句,原样复制。
(即 label 是"名字"、description 是"完整说明",二者分工明确。)无直属正文则省略。
- 合并「引导句+编号小点」:当一段是引导句(以「:」结尾)、其后紧跟连续的编号小点
((1)(2)… / ①② / 1. 2. …)时,把引导句和这些小点合并为一个 description 项,
因为它们本是一句被拆开的完整表述。合并项:
text = 各段按原文换行拼接;dataHash = 引导句
(首段)的 hash 作主标识;sourceHashes = [{text, dataHash}, ...] 逐段保留全部原始段
(含引导句自身),一个 hash 都不能丢。validate 用 sourceHashes 做零丢失覆盖+逐段篡改比对。
- 独立的概念段、非「引导句+编号」结构的段落不合并,保持各自
{text, dataHash}。
level:0 ~ (N-1),N 为第 0 步确认的最大级数(默认 3,即 0/1/2)。
dataHash:该节点标题块的 data-hash,原样。level 1/2 一般都有;纯分组若标题无 hash 可省略。
knowledgeCategory:逐节点依据内容判断,不要全填同一个值。四类判据:
事实性:具体事实、术语、分类、名录、参数(如某物的组成部分、某类别的枚举清单、具体数值范围)。
概念性:概念、原理、特性、定义、关系(如某术语的定义、某事物具备的性质、原理阐释)。
程序性:操作步骤、方法、流程、技能(如"如何做某操作"、某项作业流程、某种技巧的实施)。
元认知:对学习本身的认知、总览性主题(通常是 level 0 根节点)。
cognitiveDimension:逐节点依据内容判断,不要全填同一个值。布鲁姆六级判据:
记忆:只需记住事实/名录(能说出某分类、某清单)。
理解:解释、领会概念含义(理解某特性/某定义是什么意思)。
应用:把知识用于操作/实践(步骤、技巧、如何做)。
分析:拆解、比较、辨析关系(分析某事物为何具备某性质、对比几种方案)。
评价:判断、评估优劣(评估某方案的优缺点)。
创造:设计、综合产出新方案。
- ⚠️ 判断锚点:看这个知识点在教「是什么/为什么」(事实/概念 · 记忆/理解/分析),
还是教「怎么做」(程序性 · 应用)。操作步骤/流程类节点必是「程序性/应用」,不要误标成「概念性/理解」。
tags:选择性字段,仅当命中下列标准之一才加;不符合则省略。多个标签用英文分号 ; 分隔。
重点:核心概念 / 基本原则 / 关键定义 / 主要分类(通常是 level 1 主题或 level 2 核心知识点)。
避免给细分例子、步骤、描述性细节加。
难点:仅当文本明确指出该点难理解 / 易混淆 / 操作复杂 / 需深入思考时用。
考点:仅当教材出现练习题 / 思考题 / 任务检验 / 自测题 / 案例分析题时,给与题目直接相关的知识点加。
课程思政:内容涉及职业道德 / 法律法规 / 国家安全 / 社会责任 / 爱国主义 / 工匠精神等思政元素时加。
projectTitle / projectDataHash:仅根节点,承载 H1 项目标题(有则填)。
displayCode(仅根节点,可读展示代码):一个人类友好的短代码,格式为「教材缩写_项目号_任务号」,
例如某教材项目一任务二可生成 XXX_P1T2(XXX 为该教材内容的英文/拼音缩写)。
纯展示用——不参与 id、不参与 edges 引用;合并时的唯一性始终由 id(lessonId)保证,
displayCode 撞不撞都无影响。由你据教材名/项目号/任务号推断生成;无从推断则省略。
边(edges):只产出「父子」边,不产出「关联」边。
- 每条边
{source, target, type: "父子", description},description 简述包含关系(你生成)。
- 由三层归属推出:root→level1、level1→level2。
4. 写出 JSON
写到目标目录 output/knowledgegraph/{lessonId}.json(目录不存在则创建)。
结构参考 references/example.json 与 references/output-schema.md。
5. 校验(脚本,强制)
python3 <技能目录>/scripts/validate.py markdown/<文件名>.md output/knowledgegraph/<lessonId>.json --max-level N
必须看到「丢失(知识−输出) = 0」「无超层节点」且「校验通过」。若有丢失/臆造/篡改/超层,按提示修正 JSON 后重跑,直到通过。
6. 渲染预览页(脚本)
python3 <技能目录>/scripts/render.py output/knowledgegraph/<lessonId>.json
python3 <技能目录>/scripts/render.py --dir output/knowledgegraph
生成自包含 HTML(横向层级树 + 点节点看详情),双击离线可打开;index.html 可切换查看多个 lesson。
7. 提示用户复核(收尾)
全部 lesson 抽取+渲染完成后,不设中途门禁(data-hash 零丢失/零篡改已由 validate.py 硬保证)。
向用户报告产出,并明确提示复核入口:
已完成 N 个 lesson 的抽取,产出在 output/knowledgegraph/。
请打开 index.html 复核层级结构(分层是否合理、脚手架剔除是否得当)。
正文与 data-hash 已通过零丢失/零篡改校验。如发现某处分层或剔除需调整,指出即可,我针对性修正对应 lesson。
复核聚焦「结构判断」(分层、剔除),无需逐字核对正文——那部分脚本已兜底。
8. 二次修改闭环(预览页批注 → 复制 → 反馈)
预览页内置批注功能,用户可直接在页面上标注意见,一键复制后粘回给你,形成精准闭环:
- 节点级意见:点节点 → 右侧详情面板底部文本框写意见 → 保存(节点左上角出现 ✎ 标记)。
- 页面级意见:底部反馈栏输入框,写对整个 lesson 的总体意见。
- 点「📋 复制修改意见」→ 结构化文本进剪贴板。文本按 lesson 分组,每条带定位信息
(lessonId + 对应 json 文件 + 节点 id/label/level)+ 用户意见。
当用户粘来这样一段修改意见时,你据 lessonId 与节点 id 精准定位对应 json,按意见二次修改,
然后重新 validate.py(带 --max-level N)+ render.py。定位信息已足够,正文原文你回读 json 即可。
产出结构
目标目录/output/knowledgegraph/
{lessonId}.json # 图谱数据
{lessonId}.html # 单 lesson 预览页
index.html # 汇总导航页(可切换多个 lesson)
组件
scripts/parse_md.py — 确定性解析:md → blocks(原样切分 text/data-hash)。
scripts/validate.py — 硬约束校验:data-hash 零丢失 + 正文逐字一致 + 层级守卫(--max-level N)。
scripts/render.py — 预览页渲染:json + 模板 → 自包含 HTML。
templates/graph.html — 横向层级树预览模板(内联可视化,无外部依赖);内置批注+一键复制修改意见功能。
references/output-schema.md — 输出 JSON 字段规则。
references/example.json — 结构参考示例。