1. 授信规则引擎最小原型

授信规则引擎最小原型 学习卡片

任务说明

本案例实现一个最小可用的授信规则引擎原型:规则以字典列表配置,每条规则包含规则ID、字段名、比较运算符和阈值。输入客户属性字典,函数逐条匹配规则,返回是否通过授信以及命中的规则ID列表。

规则语义:所有规则均为"必须满足"(AND 关系),任一规则不满足即拒绝授信,并记录该规则ID为命中(触发拒绝)的规则。

规则配置与匹配函数

# 规则配置:每条规则为 dict,字段 field 与客户属性对应
RULES = [
    {"rule_id": "R001", "field": "age",         "op": ">=", "value": 18},
    {"rule_id": "R002", "field": "credit_score", "op": ">=", "value": 600},
    {"rule_id": "R003", "field": "debt_ratio",   "op": "<=", "value": 0.5},
    {"rule_id": "R004", "field": "overdue_count","op": "==", "value": 0},
]

# 运算符映射表
OPS = {
    ">=": lambda a, b: a >= b,
    "<=": lambda a, b: a <= b,
    "==": lambda a, b: a == b,
    ">":  lambda a, b: a > b,
    "<":  lambda a, b: a < b,
}

def evaluate(customer, rules=RULES):
    """返回 (是否通过, 命中规则ID列表)。
    命中规则 = 未满足的规则(触发拒绝)。全部满足则通过,命中列表为空。"""
    hit_ids = []
    for rule in rules:
        field = rule["field"]
        if field not in customer:
            hit_ids.append(rule["rule_id"])  # 缺字段视为不满足
            continue
        op_func = OPS[rule["op"]]
        if not op_func(customer[field], rule["value"]):
            hit_ids.append(rule["rule_id"])
    passed = len(hit_ids) == 0
    return passed, hit_ids

if __name__ == "__main__":
    # 用例1:全部满足
    c1 = {"age": 30, "credit_score": 720, "debt_ratio": 0.3, "overdue_count": 0}
    print("c1:", evaluate(c1))

    # 用例2:信用分不足 + 有逾期
    c2 = {"age": 25, "credit_score": 550, "debt_ratio": 0.4, "overdue_count": 2}
    print("c2:", evaluate(c2))

    # 用例3:缺少字段
    c3 = {"age": 40, "credit_score": 680}
    print("c3:", evaluate(c3))

运行方式

python rule_engine.py

验证方法与通过条件

  • 用例1全部字段满足阈值,预期输出 c1: (True, [])。
  • 用例2信用分 550 < 600 触发 R002,逾期 2 ≠ 0 触发 R004,预期输出 c2: (False, ['R002', 'R004'])。
  • 用例3缺少 debt_ratio 与 overdue_count 字段,按"缺字段视为不满足"处理,预期输出 c3: (False, ['R003', 'R004'])。
  • 判定通过:三个用例输出与上述预期一致,即说明规则匹配、运算符分派、缺字段处理均正确。

扩展点

如需支持 OR 组合或规则分组,可在 evaluate 外层增加分组遍历;如需新增运算符,只需在 OPS 中追加映射,无需改动匹配主逻辑。