EduGraph 是一个面向“教材/讲义/教案”类文本的轻量级知识图谱构建流水线。它用 LLM + 句向量 + 简洁规则,从纯文本快速构出“人类可读”的概念/层级/横向关系,并导出为 JSON / Node-Link JSON / GEXF / HTML(pyvis 交互图) 等格式。
- 端到端流水线:ingest → chunk → extract → dedupe → hierarchy → cross links → summarize → export
- 后端可切换:
mock / openai / azure / ollama(统一LLMClient抽象) - 可读导出:
graph.json(自定义)、graph_node_link.json(可逆)、graph.gexf(Gephi)、graph.html(pyvis 可交互) - API 即用:FastAPI(
/build接口接收文本,产物挂载/outputs/**静态可访问) - 测试齐全:
pytest13+ 用例覆盖主要环节;OpenAI 管线测试 opt-in - 稳健导出:自动“属性消毒”(list/dict/None/ndarray → JSON 友好),避免 GEXF 写出错误
EduGraph/
├─ README.md
├─ configs/
│ └─ default.yaml # 运行参数、关系白名单、阈值、导出文件名等
├─ data/
│ ├─ input/ # 示例教材文本(txt)
│ └─ runtime/ # API/测试临时写入文本(可创建)
├─ outputs/ # 运行输出(json/gexf/html/report)
├─ outputs_openai/ # 运行输入示例(json/gexf/html/report)
├─ src/
│ └─ kg_builder/
│ ├─ __init__.py
│ ├─ pipeline.py # 主流水线:ingest → chunk → extract → dedupe → hierarchy → links → summarize → export
│ │
│ ├─ app/
│ │ ├─ __init__.py # 暴露 get_app()/app,支持 uvicorn src.kg_builder.app:app 启动
│ │ └─ api.py # FastAPI 服务(/health, /config, /build, /graphs/{id} + 静态 /outputs/**)
│ │
│ ├─ core/
│ │ ├─ __init__.py
│ │ ├─ models.py # Node/Edge 数据类
│ │ ├─ llm.py # LLMClient/LLMConfig(mock/openai/azure/ollama)
│ │ ├─ embeddings.py # EmbeddingClient(句向量)
│ │ └─ schemas.py # 结构化输出 Pydantic 模型(抽取/增强)
│ │
│ ├─ io/
│ │ ├─ __init__.py
│ │ ├─ ingestion.py # 加载文本文件
│ │ ├─ chunking.py # 规则化分段(句长、窗口重叠)
│ │ └─ storage.py # 导出/加载:json、node-link、gexf、pyvis HTML、报告(含属性“消毒”)
│ │
│ ├─ ops/
│ │ ├─ __init__.py
│ │ ├─ config.py # 读写 YAML 配置/pretty 打印
│ │ ├─ logging_utils.py # 带颜色日志/进度打印
│ │ └─ utils.py # gen_id/normalize_text/now_ts 等工具
│ │
│ └─ algorithms/
│ ├─ __init__.py
│ ├─ extraction.py # LLM 结构化抽取(nodes/edges)
│ ├─ linking.py # 去重/合并(名称/jaccard/embedding)
│ ├─ hierarchy.py # 层级整理(支持无root;阈值 attach)
│ ├─ relations.py # 横向关系(similar_to 等;向量+字符兜底)
│ ├─ summarization.py # 节点/边摘要增强(LLM)
│ └─ evaluation.py # 简单图指标与报告段落
│
└─ tests/
├─ test_alg_extraction_linking.py
├─ test_alg_hierarchy_relations.py
├─ test_alg_summarization_evaluation.py
├─ test_core_llm_and_embeddings.py
├─ test_io_ingestion_and_chunking.py
├─ test_ops.py
├─ test_pipeline_smoke.py # 冒烟(mock 后端,默认跑)
└─ test_pipeline_openai_optin.py # 整条流水线(OpenAI,显式 opt-in 运行)
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -U pip
pip install -r requirements.txt # 如果没有,请至少安装:fastapi uvicorn pyvis networkx pydantic numpy pyyaml需要的主要依赖:
fastapi,uvicorn[standard],networkx,pydantic,numpy,pyyaml,pyvis使用 OpenAI 时:OPENAI_API_KEY环境变量(或在configs/default.yaml中设置)。
把需要处理的片段(*.txt)放到 data/input/。项目已附了示例。
python -c "from src.kg_builder.ops.config import load_config; from src.kg_builder.pipeline import run; G=run(load_config('configs/default.yaml'))"结果文件默认在 outputs/:
graph.json— 自定义可读 JSON(nodes/edges 数组)graph_node_link.json— Node-Link 标准 JSON(NetworkX/D3 可读回)graph.gexf— Gephi/Cytoscape 可视化graph.html— pyvis 交互图(双击打开、拖拽、缩放、悬停查看属性)report.md— 简要统计与 Top 度节点
uvicorn src.kg_builder.app:app --reload --port 8000-
健康检查:
GET /health -
查看配置:
GET /config?config_path=configs/default.yaml -
一键构建:
POST /build{ "backend": "mock", "texts": [ "牛顿运动定律包含三条:……", "斜面实验验证了……" ] }响应含
graph_id与产物 URL:{ "graph_id": "a1b2c3d4e5", "nodes": 12, "edges": 18, "outputs": { "json": "/outputs/a1b2c3d4e5/graph.json", "node_link": "/outputs/a1b2c3d4e5/graph_node_link.json", "gexf": "/outputs/a1b2c3d4e5/graph.gexf", "html": "/outputs/a1b2c3d4e5/graph.html", "report": "/outputs/a1b2c3d4e5/report.md" } } -
获取某次构建信息:
GET /graphs/{graph_id}
核心段落示例(节选):
io:
input_dir: data/input
output_dir: outputs
chunking:
chunk_size: 900
overlap: 150
min_sentence_len: 8
max_sentence_len: 300
llm:
backend: mock # openai/azure/ollama/mock
model: gpt-4o-mini
temperature: 0.2
timeout: 60
max_retries: 3
embeddings:
model: sentence-transformers/all-MiniLM-L6-v2
thresholds:
parent_attach_sim: 0.55
merge_name_jaccard: 0.6
merge_semantic_sim: 0.82
crosslink_similar_to: 0.86
crosslink_name_char_sim: 0.70
relations:
allowed:
- is_a
- part_of
- refers_to
- similar_to
- causes
- supports
- contradicts
export:
json_filename: graph.json
node_link_filename: graph_node_link.json
gexf_filename: graph.gexf
pyvis_filename: graph.html
report_filename: report.md
logging:
level: INFO
color: true想扩充关系(如
has_part / equivalent_to / prerequisite_of / example_of),可把名字加到relations.allowed。 若使用 OpenAI:把llm.backend: openai并配置OPENAI_API_KEY(或 YAML 指定api_key)。如直连官方接口,不要设置自定义base_url。
- ingestion:读取
data/input/下的*.txt - chunking:按字符数与句长约束切块
- extraction:LLM 生成
nodes[] / edges[](严格 JSON) - linking:结点去重/合并(名称 Jaccard + 语义相似)
- hierarchy:层级整理(无根模式;父候选为 Topic/Concept,过阈才连
part_of) - relations:横向关系(
similar_to:向量相似 + 字符相似兜底;避免与层级边冲突) - summarization:节点/边“一句话摘要/要点/注释”
- export:JSON / Node-Link / GEXF / HTML(pyvis) / 报告
- evaluation:节点/边数量、Top 度节点等基础指标
pytest -q tests/test_pipeline_smoke.py需要你先替换'configs\default.yaml'中的对应的API-KEY设置
# PowerShell 示例
pytest -q tests/test_pipeline_openai_optin.py提示:若你加了根目录的
pytest.ini设置pythonpath = .,可省去PYTHONPATH环境变量。
-
graph.json(自定义):
{ "nodes": [{"id":"...","name":"...","ntype":"Concept", ...}, ...], "edges": [{"src":"...","dst":"...","rel_type":"...", ...}, ...] } -
graph_node_link.json(标准,可逆):
networkx.readwrite.json_graph.node_link_graph可直接读回 -
graph.gexf:Gephi/Cytoscape 直接打开(已处理 list/dict/None 等复杂属性)
-
graph.html(pyvis):交互可视化;颜色区分 ntype;
similar_to虚线;supports/contradicts绿/红;箭头方向 -
report.md:节点/边数量、Top 度节点、简单指标