210 lines
8.9 KiB
Python
210 lines
8.9 KiB
Python
|
||
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
|
||
|