如何用Python规则引擎生成可解读的流程图?
如何为PyKnow规则引擎生成清晰的流程图
我希望将规则引擎中定义的规则生成流程图,使用了PyKnow和Pydot编写了代码,但生成的图表无法解读,请问如何生成清晰易用的流程图?
原代码:
from pyknow import * import pydot class Wine(Fact): """Wine characteristics""" pass class Quality(Fact): """Wine quality""" pass class WineExpert(KnowledgeEngine): @Rule(Wine(color='red')) def rule1(self): self.declare(Quality(color='red', quality='rich')) @Rule(Wine(color='white')) def rule2(self): self.declare(Quality(color='white', quality='crisp')) @Rule(AND( Wine(color='red'), Wine(body='light'), Wine(tannin='low') )) def rule3(self): self.declare(Quality(color='red', quality='smooth')) @Rule(AND( Wine(color='red'), Wine(body='full'), Wine(tannin='high') )) def rule4(self): self.declare(Quality(color='red', quality='bold')) # Create a new knowledge engine instance engine = WineExpert() # Create a Pydot graph graph = pydot.Dot(graph_type='digraph', comment='Wine Expert Rules') # Add nodes for each rule for rule in engine.get_rules(): node = pydot.Node(rule.__name__) graph.add_node(node) # Check for AND conditions if isinstance(rule.new_conditions, AND): for condition in rule.new_conditions.args: label = str(condition).replace("<", "\\<").replace(">", "\\>") edge = pydot.Edge(label, rule.__name__) graph.add_edge(edge) else: label = str(rule.new_conditions).replace("<", "\\<").replace(">", "\\>") edge = pydot.Edge(label, rule.__name__) graph.add_edge(edge) # Save the graph to a file graph.write_png('wine_expert_rules.png')
核心问题分析
原代码生成的图难以解读,主要原因是:
- 节点标签使用原始代码字符串(如
Wine(color='red')),可读性差 - 缺少规则最终输出的结果节点,无法直观看到规则触发后的结论
- 节点无分类、样式区分,布局混乱
改进方案与代码实现
1. 定义节点标签映射
把代码中的条件和结果转换为人类易懂的文本,降低理解门槛。
2. 分类设置节点样式
给不同类型的节点设置不同形状和颜色,直观区分条件、规则、结果。
3. 构建完整流程链路
形成「条件 → 规则 → 结果」的清晰流向,符合逻辑阅读习惯。
修改后的代码:
from pyknow import * import pydot class Wine(Fact): """Wine characteristics""" pass class Quality(Fact): """Wine quality""" pass class WineExpert(KnowledgeEngine): @Rule(Wine(color='red')) def rule1(self): self.declare(Quality(color='red', quality='rich')) @Rule(Wine(color='white')) def rule2(self): self.declare(Quality(color='white', quality='crisp')) @Rule(AND( Wine(color='red'), Wine(body='light'), Wine(tannin='low') )) def rule3(self): self.declare(Quality(color='red', quality='smooth')) @Rule(AND( Wine(color='red'), Wine(body='full'), Wine(tannin='high') )) def rule4(self): self.declare(Quality(color='red', quality='bold')) # 将代码条件转为可读文本 def get_condition_label(condition): if isinstance(condition, Wine): attrs = condition.as_dict() parts = [] if 'color' in attrs: parts.append(f"{attrs['color']}葡萄酒") if 'body' in attrs: parts.append(f"酒体{attrs['body']}") if 'tannin' in attrs: parts.append(f"单宁{attrs['tannin']}") return " + ".join(parts) return str(condition) # 映射规则对应的结果文本 def get_result_label(rule): result_map = { 'rule1': "浓郁型红葡萄酒", 'rule2': "清爽型白葡萄酒", 'rule3': "顺滑型红葡萄酒", 'rule4': "强劲型红葡萄酒" } return result_map.get(rule.__name__, "未知结果") # 创建引擎实例 engine = WineExpert() # 创建有向图,设置从左到右的布局方向 graph = pydot.Dot(graph_type='digraph', rankdir='LR', comment='Wine Expert Rules') graph.set_node_defaults(fontname='SimHei') # 支持中文显示 # 遍历规则构建图形 for rule in engine.get_rules(): # 添加规则节点:矩形,浅灰填充 rule_node = pydot.Node(rule.__name__, label=f"规则:{rule.__name__}", shape='box', style='filled', fillcolor='#e0e0e0') graph.add_node(rule_node) # 添加结果节点:圆角矩形,浅绿填充 result_label = get_result_label(rule) result_node = pydot.Node(f"result_{rule.__name__}", label=result_label, shape='box', style='rounded,filled', fillcolor='#c8e6c9') graph.add_node(result_node) # 连接规则到结果 graph.add_edge(pydot.Edge(rule_node, result_node)) # 处理规则条件 conditions = rule.new_conditions.args if isinstance(rule.new_conditions, AND) else [rule.new_conditions] for cond in conditions: cond_label = get_condition_label(cond) # 添加条件节点:椭圆,浅蓝填充 cond_node = pydot.Node(cond_label, shape='ellipse', style='filled', fillcolor='#bbdefb') # 避免重复添加相同条件节点 if not graph.get_node(cond_label): graph.add_node(cond_node) # 连接条件到规则 graph.add_edge(pydot.Edge(cond_node, rule_node)) # 保存为优化后的流程图 graph.write_png('wine_expert_rules_improved.png')
改进效果说明
- 所有节点标签使用自然语言,无需懂代码也能快速理解
- 节点按「条件-规则-结果」分类,形状和颜色区分明显
- 布局设置为从左到右,符合常规阅读习惯
- 重复条件仅生成一个节点,避免冗余混乱
内容的提问来源于stack exchange,提问作者merkle
相关产品推荐
相关产品推荐

