|
@@ -416,6 +416,8 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
"""将分析结果转换为图谱格式"""
|
|
"""将分析结果转换为图谱格式"""
|
|
|
nodes = {}
|
|
nodes = {}
|
|
|
edges = {}
|
|
edges = {}
|
|
|
|
|
+ # 特征名到节点ID的映射(用于修正 LLM 返回的类型名不匹配问题)
|
|
|
|
|
+ name_to_node_id = {}
|
|
|
|
|
|
|
|
for result in all_results:
|
|
for result in all_results:
|
|
|
target_input = result.get("输入", {})
|
|
target_input = result.get("输入", {})
|
|
@@ -433,6 +435,7 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
"domain": "帖子",
|
|
"domain": "帖子",
|
|
|
"detail": {}
|
|
"detail": {}
|
|
|
}
|
|
}
|
|
|
|
|
+ name_to_node_id[target_name] = node_id
|
|
|
|
|
|
|
|
# 添加候选特征节点
|
|
# 添加候选特征节点
|
|
|
for candidate in target_input.get("候选特征", []):
|
|
for candidate in target_input.get("候选特征", []):
|
|
@@ -447,14 +450,15 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
"domain": "帖子",
|
|
"domain": "帖子",
|
|
|
"detail": {}
|
|
"detail": {}
|
|
|
}
|
|
}
|
|
|
|
|
+ name_to_node_id[c_name] = c_node_id
|
|
|
|
|
|
|
|
# 构建推导边
|
|
# 构建推导边
|
|
|
for result in all_results:
|
|
for result in all_results:
|
|
|
target_name = result.get("目标特征", "")
|
|
target_name = result.get("目标特征", "")
|
|
|
- target_input = result.get("输入", {})
|
|
|
|
|
- target_info = target_input.get("目标特征", {})
|
|
|
|
|
- target_type = target_info.get("特征类型", "关键点")
|
|
|
|
|
- target_node_id = f"帖子:{target_type}:标签:{target_name}"
|
|
|
|
|
|
|
+ # 使用映射获取正确的节点ID
|
|
|
|
|
+ target_node_id = name_to_node_id.get(target_name)
|
|
|
|
|
+ if not target_node_id:
|
|
|
|
|
+ continue
|
|
|
|
|
|
|
|
# V4 的推理分析在顶层,不是在 输出 下面
|
|
# V4 的推理分析在顶层,不是在 输出 下面
|
|
|
reasoning = result.get("推理分析", {})
|
|
reasoning = result.get("推理分析", {})
|
|
@@ -462,8 +466,10 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
# 单独推理的边
|
|
# 单独推理的边
|
|
|
for item in reasoning.get("单独推理", []):
|
|
for item in reasoning.get("单独推理", []):
|
|
|
source_name = item.get("来源特征", "")
|
|
source_name = item.get("来源特征", "")
|
|
|
- source_type = item.get("来源特征类型", "关键点")
|
|
|
|
|
- source_node_id = f"帖子:{source_type}:标签:{source_name}"
|
|
|
|
|
|
|
+ # 使用映射获取正确的节点ID(而非LLM返回的类型名)
|
|
|
|
|
+ source_node_id = name_to_node_id.get(source_name)
|
|
|
|
|
+ if not source_node_id:
|
|
|
|
|
+ continue
|
|
|
probability = item.get("可能性", 0)
|
|
probability = item.get("可能性", 0)
|
|
|
|
|
|
|
|
edge_id = f"{source_node_id}|推导|{target_node_id}"
|
|
edge_id = f"{source_node_id}|推导|{target_node_id}"
|
|
@@ -481,16 +487,30 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
# 组合推理的边
|
|
# 组合推理的边
|
|
|
for item in reasoning.get("组合推理", []):
|
|
for item in reasoning.get("组合推理", []):
|
|
|
members = item.get("组合成员", [])
|
|
members = item.get("组合成员", [])
|
|
|
- member_types = item.get("成员类型", [])
|
|
|
|
|
probability = item.get("可能性", 0)
|
|
probability = item.get("可能性", 0)
|
|
|
|
|
|
|
|
- # 创建组合虚拟节点
|
|
|
|
|
- member_pairs = list(zip(members, member_types)) if len(member_types) == len(members) else [(m, "关键点") for m in members]
|
|
|
|
|
- sorted_pairs = sorted(member_pairs, key=lambda x: x[0])
|
|
|
|
|
- sorted_members = [p[0] for p in sorted_pairs]
|
|
|
|
|
- sorted_types = [p[1] for p in sorted_pairs]
|
|
|
|
|
|
|
+ # 验证所有成员都存在于映射中
|
|
|
|
|
+ member_node_ids = []
|
|
|
|
|
+ valid = True
|
|
|
|
|
+ for m in members:
|
|
|
|
|
+ m_node_id = name_to_node_id.get(m)
|
|
|
|
|
+ if not m_node_id:
|
|
|
|
|
+ valid = False
|
|
|
|
|
+ break
|
|
|
|
|
+ member_node_ids.append((m, m_node_id))
|
|
|
|
|
+ if not valid:
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ # 按名称排序
|
|
|
|
|
+ sorted_member_ids = sorted(member_node_ids, key=lambda x: x[0])
|
|
|
|
|
+
|
|
|
|
|
+ # 从节点ID中提取实际的维度类型(帖子:灵感点:标签:xxx -> 灵感点)
|
|
|
|
|
+ combo_parts = []
|
|
|
|
|
+ for m_name, m_node_id in sorted_member_ids:
|
|
|
|
|
+ parts = m_node_id.split(":")
|
|
|
|
|
+ m_dimension = parts[1] if len(parts) > 1 else "关键点"
|
|
|
|
|
+ combo_parts.append(f"{m_dimension}:{m_name}")
|
|
|
|
|
|
|
|
- combo_parts = [f"{sorted_types[i]}:{m}" for i, m in enumerate(sorted_members)]
|
|
|
|
|
combo_name = " + ".join(combo_parts)
|
|
combo_name = " + ".join(combo_parts)
|
|
|
combo_node_id = f"帖子:组合:组合:{combo_name}"
|
|
combo_node_id = f"帖子:组合:组合:{combo_name}"
|
|
|
if combo_node_id not in nodes:
|
|
if combo_node_id not in nodes:
|
|
@@ -500,8 +520,8 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
"dimension": "组合",
|
|
"dimension": "组合",
|
|
|
"domain": "帖子",
|
|
"domain": "帖子",
|
|
|
"detail": {
|
|
"detail": {
|
|
|
- "成员": sorted_members,
|
|
|
|
|
- "成员类型": sorted_types
|
|
|
|
|
|
|
+ "成员": [m for m, _ in sorted_member_ids],
|
|
|
|
|
+ "成员类型": [m_node_id.split(":")[1] for _, m_node_id in sorted_member_ids]
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -519,9 +539,7 @@ def build_origin_graph(all_results: List[Dict], post_id: str) -> Dict:
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
# 成员到组合节点的边
|
|
# 成员到组合节点的边
|
|
|
- for i, member in enumerate(sorted_members):
|
|
|
|
|
- m_type = sorted_types[i]
|
|
|
|
|
- m_node_id = f"帖子:{m_type}:标签:{member}"
|
|
|
|
|
|
|
+ for m_name, m_node_id in sorted_member_ids:
|
|
|
m_edge_id = f"{m_node_id}|组成|{combo_node_id}"
|
|
m_edge_id = f"{m_node_id}|组成|{combo_node_id}"
|
|
|
if m_edge_id not in edges:
|
|
if m_edge_id not in edges:
|
|
|
edges[m_edge_id] = {
|
|
edges[m_edge_id] = {
|