# Step2 生产知识图谱构建 ## 输入与入口 以下为独立构图入口说明。历史默认主键文件 `data/graph_keys.json` 已移除,运行下列独立命令时需追加 `--keys <配置路径>`。日常请使用 `scripts/update_data.py --mode templates`:该流程从 LLM 数据评估获取主键,不依赖此文件。 默认读取 Step1 已导出的 `data/production/<模板名>.xlsx`(“数据”页),以 `data/templates/metadata/*.xlsx` 的“字段来源”页校验表头。不会重新拉取 DMS。 节点标签使用完整模板名,例如“人员信息”“项目信息”,属性保留模板字段原名。 ```powershell # 只做本地预检和关系计算;评分规则会加载本地模型,不调用 Neo4j/LLM uv run python scripts/build_graph.py --check-only # 完整流程:预检 → 关系计算 → LLM 元图谱 → Neo4j → 发布元图谱 uv run python scripts/build_graph.py # 专用入口等效 uv run python scripts/build_production_graph.py ``` 可使用 `--template-dir`、`--production-dir`、`--relations`、`--keys`、 `--output-dir` 指定输入输出。QA 与前端默认消费项目 `output/` 下的发布文件。 显式传入历史 JSON 时,`build_graph.py 配置.json [--clear]` 仍运行旧固定模板流程; 它不属于生产构图。历史 `build_meta.py` 也不属于新流程,含全图清理,不用于生产数据。 ## 主键与合并 独立构图通过 `--keys <配置路径>` 读取显式主键配置,例如 `{"人员信息": ["工号"], "项目信息": ["项目编号"]}`。 该入口增加模板时必须在传入配置中明确主键,也支持复合主键;统一更新入口的主键来源不同,见 README。 同主键记录始终合为一个节点,保留所有来源行号。字段按以下规则合并: - 空值不覆盖非空值;重复值去重;仅一个非空值时保留标量。 - 存在不同非空值时,保留为确定排序的列表,不选取第一条或最后一条覆盖。 - 主键值缺失(含纯空白)的记录输出警告并跳过,不阻断其他有效记录;复合主键提示实际缺失字段。表头或主键配置错误仍阻止入库。属性比较不自动去空格或做业务归一化。 - 异构类型多值因 Neo4j 数组类型限制,在主属性中存 JSON 编码字符串列表; 原始有类型值保留在 _kg_mixed_values_json。关系计算始终使用原始类型值。 关系匹配逐一比较多值列表中的值:任意值对满足规则即连边,同规则同节点对只建一条边; 评分关系取命中值对的最高分。多值不意味着同时任职,也不推断先后时间。 构图报告包含合并行数、合并主键组数、多值字段统计,以及 warnings(文件、工作表、Excel 行号、缺失字段)和 skipped_rows,不输出原始字段值。跳过行不计入合并行数;全部记录缺主键的模板保留为零节点。 原始生产工作簿保持不变。 ## relation.xlsx 规则 读取每个非空工作表的五列:起点、终点、连接字段、判断方法、边名。 空工作表忽略,重复规则、未知模板、错误字段和未知判断方法报错。 连接字段通过已知字段组合解析,允许字段名自身含连字符,但歧义时报错。 | 方法 | 计算 | | --- | --- | | 相等 | 非空属性值完全一致,保留类型和空格差异 | | 包含 | 两者必须为文本,执行 `a in b or b in a` | | 评分 | 本地 `models/Qwen3-Embedding-0.6B` 编码,余弦相似度严格大于阈值 | 空值、空字符串和纯空白值均不参与关系匹配,防止空字符串产生全图误连。 每条规则检查所有候选节点,保留所有匹配,允许一对多、多对多以及规则命中的自环。 边方向严格遵循起点→终点;例如“上级项目编号-项目编号 / 父项目为”是子项目→父项目。 评分使用唯一文本缓存和分块矩阵计算;不会按 top-k 截断,也不会退化成词法匹配。 `.env` 与 `.env.example` 配置 `STEP2_RELATION_SIMILARITY_THRESHOLD=0.8`; 修改阈值后重新执行构图生效,仅支持 [-1, 1] 内的有限数。 ## Neo4j 与失败行为 全部本地校验与 LLM 结构校验通过后才创建节点,然后创建关系并回读节点/边数量。 节点保留 `_kg_id`、`_kg_file`、`_kg_sheet`、`_kg_rows`、`_kg_build`, 边保留规则 id、判断方法,以及评分边的得分与阈值。 新图以独立 build id 暂存;数量校验通过后,单次查询删除之前由本流程拥有的 `_Step2Record` 节点,再发布 JSON。历史固定模板图和其他标签的数据不清理。 必须串行运行构图命令;本版本不支持两个构图进程同时发布到同一数据库。 暂存写入失败会尝试删除本次暂存节点;若清理失败,报告会明确标记。 激活请求响应不明时保留新图供核对,不冒险删除可能已经成为当前版本的数据。 Neo4j 与本地文件系统不能形成跨系统事务:若数据库已写入而 JSON 发布失败, 报告中 `database_written=true`、`schema_published=false`,候选 Schema 保留在 `output/step2_schema_candidate.json`;核对数据库 build id 后重跑可恢复发布。 ## 元知识图谱 LLM 使用现有 `.env` 的 `DEEPSEEK_*` 配置。输入只含节点名、字段名、主键字段名、 关系规则及聚合数量,不发送原始生产单元格值、文件路径、DMS 物理字段或凭据。 真实结构由模板和计算结果确定,LLM 生成语义说明,输出 id 必须完整且唯一, 不得新增节点、关系、属性或改写统计。调用/校验失败不发布伪造的成功结果。 输出延续前端 `nodes/relations/meta` JSON 契约: - `meta_graph_schema.json`:全部模板和规则,含零记录、零匹配项及实际数量。 - `meta_graph_schema_display.json`:仅有节点/关系实例的展示项。 - `step2_build_report.json`:本次阶段、成败、主键校验、合并统计、关系数量和未匹配节点数。 QA 的 `meta/schema.py` 摘要优先读取生产文件;旧导出脚本不会再用固定 Schema 覆盖已发布生产 Schema。生产图不套用旧测试数据的 2026-01~04 时间范围。 **本轮仅接入元图谱上下文**:Step3 的固定检索工具仍用“人员/项目”等历史标签, 后续必须按新标签与属性重构检索并做业务回归,不能据此宣称生产问答已可用。 ## 验证 `uv run python scripts/test_step2_production.py` 使用合成工作簿、可控向量、Fake LLM 和 Fake Neo4j 检查规则、冲突、阈值、元图谱和失败清理,不代表外部服务联调通过。 2026-09-04 用户改为按唯一键合并不同属性;13项离线回归通过。 真实预检通过:人员2806行→2804节点(2组重复),项目213节点,父项目为94边、服务于4344边。 随后用户对具体目标与聚合载荷回复“继续”,真实构图已成功:3017节点、4438边,完整和展示元图谱 JSON 均已发布。 独立数据库回读验证数量与两组多值合并,发布文件 build id 与数据库一致。 本机8000接口未响应,浏览器视觉验证尚未完成。