You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 16:52:09