Kmatch项目中用户对于新领域的知识点答题后,无法生成知识图谱
已确认根因
动态域会话 submit 组装的 learning_path 含重复 node_id(实测 AI 域 12 节点中 AI-003/004/010 ×2)→ 前端 useGraphData.g6Nodes 直接喂 G6 → "Node already exists" 渲染崩溃。后端 BFS 结果循环是唯一无防重的口子(弱项补丁分支已有 path_ids 防重)。工作区已有的 seen_ids 修复方向正确,但从未验证(后端未重启过),且注释归因("按 (start,n) 分组")与 Cypher 语义矛盾,需实库取证修正——若库里真有同 id 双实体还需清库。
执行步骤
1. 起环境 + 实库取证
-
docker-compose up -d起 Neo4j,等健康 -
cypher-shell 只读查询:
MATCH (n:KnowledgeNode) WITH n.id AS id, count(*) AS c WHERE c>1 RETURN id, c— 同 id 双实体?SHOW CONSTRAINTS—kb_unique_id唯一约束是否存在- 直跑 BFS Cypher(known_ids=AI-001..007)数每个 id 的返回行数 — 实锤重复行来源
- 节点总数(期望 252)
2. 根因处置
- 若有双实体:清重复(保留
updated_at最新)+ 确保kb_unique_id约束在 - 依据取证结果改写 engine.py 修复注释的归因描述(删掉未经证实的"按 (start,n) 分组"说法,写实测结论)
3. 验证后端修复
- 重启 uvicorn(加载含
seen_ids的 engine.py) POST /api/graph/path(known=AI-001..007, weak=AI-001..010, level=1, max_nodes=12,复现 20:44 场景)→ 断言返回路径 node_id 唯一、难度 ≤3
4. 前端防御(治本加固)
frontend/src/composables/useGraphData.js:g6Nodes按node_id去重(保首个)——G6 对重复 id 直接抛错,前端单点兜底后任何后端回归都不再炸渲染- 新增
frontend/src/__tests__/useGraphData.test.js(重复 node_id → g6Nodes 唯一)
5. 回归测试
- 后端:
pytest tests/test_engine_learning_path.py -q→ 全量pytest -q - 前端:
npm run test(vitest 全量,281 个)
6. E2E 浏览器验证(browser-use)
- 浏览器打开学习会话,输入"人工智能"(已入库,秒级命中复用)→ 答题(全错模拟零基础)→ 提交 → 断言第 4 阶段"专属知识图谱"正常渲染(无 Node already exists,节点可点)
- 不再新建全新域:动态建域本身已 3 次 E2E 验证过(JV/CS/AI),本次坏的是路径组装+渲染
7. 文档 + 提交
-
devlog 追加到
docs/devlogs/A_后端/2026-08-14_动态建域.md:实锤根因 + 修复 + 前端防御 + E2E 结果 -
分 3 个 commit 推送:
fix(graph): assemble_learning_path BFS 重复节点 seen_ids 去重 - 修动态域 G6 "Node already exists" 渲染失败(engine.py + 测试 + devlog)fix(ide): useGraphData g6Nodes 按节点 id 去重防御 - 后端任何回归不再炸图谱渲染(useGraphData.js + 测试)chore(data): AI 动态域演示数据入库 (E2E 实测 10 节点 20 题, source=llm_generated 可识别)(_manual_nodes.json + AI 题目文件)
备注
- 若用户实际在安装包(sidecar exe)里复现:sidecar 是旧代码打的包,需重跑 PyInstaller 才含修复(本次不打包,验证以 dev 模式为准)
