4. 规则优先级与冲突解决
任务说明
在授信规则引擎中,多条规则可能同时命中同一笔申请。本案例为规则增加 priority 字段,当多条规则命中时按优先级(数值越大越优先)选出最终决策,并记录冲突日志,便于审计与调优。
实现思路
- 规则结构:
name、priority、condition(接收申请字典返回布尔)、decision。 - 评估流程:遍历所有规则,收集命中项;若命中数 > 1,写入冲突日志;按
priority降序取第一条作为最终决策。 - 冲突日志记录:命中规则名、各自优先级、最终选中规则,便于回溯。
完整代码
from dataclasses import dataclass, field
from typing import Callable, List, Dict, Any
@dataclass
class Rule:
name: str
priority: int
condition: Callable[[Dict[str, Any]], bool]
decision: str
@dataclass
class DecisionResult:
decision: str
matched: List[str] = field(default_factory=list)
conflict_log: List[str] = field(default_factory=list)
class RuleEngine:
def __init__(self, rules: List[Rule]):
self.rules = rules
def evaluate(self, application: Dict[str, Any]) -> DecisionResult:
hits = [r for r in self.rules if r.condition(application)]
if not hits:
return DecisionResult(decision="REJECT", matched=[], conflict_log=[])
# 按优先级降序排序,数值越大越优先
hits.sort(key=lambda r: r.priority, reverse=True)
matched = [r.name for r in hits]
conflict_log: List[str] = []
if len(hits) > 1:
detail = ", ".join(f"{r.name}(p={r.priority})" for r in hits)
conflict_log.append(
f"冲突: 命中 {len(hits)} 条规则 [{detail}],"
f"最终选择 {hits[0].name}(p={hits[0].priority})"
)
return DecisionResult(
decision=hits[0].decision,
matched=matched,
conflict_log=conflict_log,
)
if __name__ == "__main__":
rules = [
Rule("高负债拒绝", priority=90,
condition=lambda a: a["debt_ratio"] > 0.7,
decision="REJECT"),
Rule("黑名单拒绝", priority=100,
condition=lambda a: a["blacklisted"],
decision="REJECT"),
Rule("低分人工审核", priority=50,
condition=lambda a: a["score"] < 600,
decision="MANUAL_REVIEW"),
Rule("优质客户通过", priority=30,
condition=lambda a: a["score"] >= 750 and a["debt_ratio"] < 0.3,
decision="APPROVE"),
]
engine = RuleEngine(rules)
app = {"score": 580, "debt_ratio": 0.8, "blacklisted": True}
result = engine.evaluate(app)
print("决策:", result.decision)
print("命中规则:", result.matched)
for line in result.conflict_log:
print("日志:", line)
运行与验证
直接运行脚本:python rule_engine.py。示例申请同时命中三条规则(黑名单 p=100、高负债 p=90、低分 p=50),预期输出:
决策: REJECT
命中规则: ['黑名单拒绝', '高负债拒绝', '低分人工审核']
日志: 冲突: 命中 3 条规则 [黑名单拒绝(p=100), 高负债拒绝(p=90), 低分人工审核(p=50)],最终选择 黑名单拒绝(p=100)
判定通过条件:最终决策为优先级最高的命中规则对应决策;matched 按优先级降序排列;命中数 > 1 时 conflict_log 非空且包含最终选中规则。可再构造只命中一条规则的申请,验证 conflict_log 为空。