def reset_entities_and_relations(entities: list, relations: list, device: str): """ 实体与关系的后处理中心(规则分支入口)。 在此处集中管理所有不需要大模型参与的规则清洗、类型修正和关系调整。 :param entities: 实体列表 (会被原地修改并过滤) :param relations: 关系列表 (会被原地修改) :param device: 设备名称 :return: (filtered_entities, relations) 返回过滤后的实体列表和修改后的关系列表 """ print(f"\n[后处理] 开始执行规则清洗 (Device: {device})...") total_changes = 0 # ========================================== # 配置化规则定义:(旧类型, 新类型, 新关系类型, 名称替换逻辑) # name_transformer: 接收 (old_name, device),返回 new_name # ========================================== standardization_rules = [ { "old_type": "接口关系", "new_type": "接口", "new_rel_type": "配备", "name_transformer": lambda old, dev: f"{dev}的接口" }, { "old_type": "安全警告", "new_type": "安全警告", "new_rel_type": "安全警告", "name_transformer": lambda old, dev: old.replace("安全警告", "注意事项") if "注意事项" in old.replace("安全警告", "注意事项") else f"{dev}的注意事项" }, { "old_type": "技术指标", "new_type": "技术指标参数", "new_rel_type": "具有", "name_transformer": lambda old, dev: ( old.replace("技术指标", "技术指标参数") if "技术指标" in old else f"{old}参数" if old else f"{dev}的技术指标参数" ) }, { "old_type": "安装调试", "new_type": "调试", "new_rel_type": "调试", # 注意:这里原代码逻辑是关系类型也变为"调试" "name_transformer": lambda old, dev: ( old.replace("安装调试", "调试") if "安装调试" in old else f"{dev}的调试" ) }, { "old_type": "系统功能", "new_type": "功能", "new_rel_type": "实现", "name_transformer": lambda old, dev: ( old.replace("系统功能", "功能") if "系统功能" in old else f"{dev}的功能" ) }, { "old_type": "调试细则", "new_type": "调试", "new_rel_type": "调试", "name_transformer": lambda old, dev: ( old.replace("调试细则", "调试") if "调试细则" in old else f"{dev}的调试" ) } ] # ========================================== # 通用处理引擎:执行标准化规则 # ========================================== for rule in standardization_rules: count = 0 old_type = rule["old_type"] new_type = rule["new_type"] new_rel_type = rule["new_rel_type"] transformer = rule["name_transformer"] old_to_new_map = {} # 1. 处理实体 for ins in entities: if ins.get("type") == old_type: old_name = ins["properties"].get("名称", "") # 生成新名称 new_name = transformer(old_name, device) # 兜底检查:如果生成的名字还是空的 if not new_name: new_name = f"{device}的{new_type}" # 应用修改 ins["type"] = new_type ins["properties"]["名称"] = new_name old_to_new_map[old_name] = new_name count += 1 print(f" - [实体] '{old_name}' ({old_type}) -> '{new_name}' ({new_type})") # 2. 处理关联关系 if old_to_new_map: for rel in relations: to_ent = rel.get("to_entity") if to_ent in old_to_new_map: old_rel_type_val = rel.get("type") rel["type"] = new_rel_type rel["to_entity"] = old_to_new_map[to_ent] count += 1 print(f" - [关系] '{rel['from_entity']}' --({old_rel_type_val})--> '{to_ent}' 变更为 --({new_rel_type})--> '{rel['to_entity']}'") if count > 0: print(f" [规则应用] {old_type} -> {new_type}: 共修改 {count} 处") total_changes += count # ========================================== # 特殊逻辑:拆分 "基本情况" # 策略:先收集新生成的实体/关系,循环结束后再添加,避免遍历中修改列表 # ========================================== new_items_buffer = [] basic_info_indices = [] # 记录需要被移除的"基本情况"实体的索引(如果需要彻底移除) for idx, ins in enumerate(entities): if ins.get("type") == "基本情况": gonneng = ins["properties"].get("主要功能", "") gztj = ins["properties"].get("工作条件", "") source_ks = ins.get("knowledge_source") # 构建 "功能" 实体 func_name = f"{device}的功能" entity_func = { "type": "功能", "properties": { "名称": func_name, "内容": gonneng, "knowledge_source": source_ks } } rela_func = { "type": "使用", "from_entity": device, "to_entity": func_name, } # 构建 "环境条件" 实体 env_name = f"{device}的环境条件" entity_env = { "type": "环境条件", "properties": { "名称": env_name, "内容": gztj, "knowledge_source": source_ks } } rela_env = { "type": "适用", "from_entity": device, "to_entity": env_name, } new_items_buffer.extend([entity_func, entity_env, rela_func, rela_env]) # 标记该实体后续需要被过滤掉(根据原代码逻辑,"基本情况"最终不保留在返回的实体列表中) basic_info_indices.append(idx) print(f" [拆分完成] 已从 '基本情况' 生成 '功能' 和 '环境条件' (来源已继承)。") # 将新生成的项加入主列表 # 注意:new_items_buffer 中包含实体和关系,需要分开加 # 前两个是实体,后两个是关系 (根据上面的 extend 顺序) # 为了更安全,我们显式区分 entities_to_add = [item for item in new_items_buffer if item.get("properties")] # 简单判断:有 properties 的是实体 relations_to_add = [item for item in new_items_buffer if not item.get("properties")] # 没有 properties 的是关系 (假设关系结构不同) # 更严谨的区分方式是根据 key 判断,或者上面构建时直接分两个列表 # 这里采用重新构建的方式确保准确,因为 buffer 里混放了 # 实际上,上面的逻辑里 entity 有 properties, relation 没有 (或者结构不同) # 让我们修正一下添加逻辑,直接复用上面构建的变量逻辑会更清晰,但为了适应 buffer: # 重新整理 buffer (刚才的 extend 混合了,这里简单按类型分离) # 由于上面构建时 entity 都有 "properties" 键,relation 没有 (通常 relation 是 from/to/type) for item in new_items_buffer: if "properties" in item: entities.append(item) else: relations.append(item) # ========================================== # 最终过滤:移除 "基本情况" 实体 # 原代码逻辑是:遍历 entities,如果是 "基本情况" 则跳过,否则加入 final_entity # ========================================== final_entities = [ins for ins in entities if ins.get("type") != "基本情况"] # 如果原列表中有被移除的,计算一下数量用于日志(可选) removed_count = len(basic_info_indices) if removed_count > 0: print(f" [过滤完成] 移除了 {removed_count} 个 '基本情况' 实体。") # ========================================== # 总结 # ========================================== if total_changes == 0 and removed_count == 0 and not new_items_buffer: print(f"[后处理] 未命中任何清洗或拆分规则。") else: print(f"[后处理] 全部完成。标准化修改 {total_changes} 次,拆分生成 {len(new_items_buffer)//2} 组新数据,过滤移除 {removed_count} 个旧实体。\n") return final_entities, relations