Files
meida_backend/packages/rules/README.md
T
xsl e50a9424a1 feat(rules): data-driven decision table engine with hard constraints
kb_rule DSL 解析 + 纯域求值(优先级分组/硬约束/用户禁忌压过专业推荐)
+ 400 条基准 + 黄金集雏形(T-P2-02,TD-10)。

实现:dsl.py 封闭词汇表 pydantic 校验(未识别键拒绝)+ match 纯逻辑
(等值/include/exclude/min-max,缺字段不命中);engine.py 纯域求值
(priority 降序、confidence 次序、is_hard avoid → hard_blocks、高优先级
avoid 剔除冲突 recommend);service.py+repo.py published 整表载入进程内
缓存 + CRUD + draft→published→archived 状态机(同 T6 语义)。
测试:DSL 解析与 match 矩阵、排序/硬约束/禁忌优先、状态机矩阵、
黄金集 11 组(含用户禁忌压过专业推荐与多规则叠加)、400 条 × 1000 次
基准(实测均值 0.26ms/次、p95 0.41ms,预算 50ms);集成 3 用例
(published 载入命中拦截、draft 不载入、DSL 写入拒绝与状态机守卫)。
单测 310 通过(+72),集成 19 通过(+3)。

偏差说明:
1. 冲突仲裁按通用优先级语义实现(高优先级 avoid 剔除"严格更低"优先级的
   冲突 recommend),任务文档的"用户禁忌(≥95)永远压过专业推荐(≤90)"
   是该规则的特例,黄金集已含该场景用例。
2. include 子句按字段类型取语义:标量字段=命中列表任一值;集合字段=
   列表全部在场(子集,精确命中);文档未区分,此实现两类字段均可用。
3. 单测引擎文件命名为 tests/unit/test_rules_evaluation.py(而非
   test_rules_engine.py):与契约指定的集成文件 tests/integration/
   test_rules_engine.py 同名会导致 pytest 收集冲突(tests 目录非包)。
4. 集成测试每用例独立 engine 并 dispose:pytest-asyncio 每用例一个事件
   循环,直接用全局 session 工厂会让连接跨 loop 污染其它集成用例。
5. 规则不提供物理删除(命中链需可追溯,下线走 archived);kb_rule 契约
   无 reviewing 状态,状态机为 draft→published→archived(draft 可撤稿)。
2026-08-14 20:10:21 +08:00

1.8 KiB
Raw Blame History

packages/rules — 规则引擎(TD-10 自研数据驱动决策表)

架构 §8.1 / ADR-05:结论由规则引擎产出,LLM 只负责表达(防幻觉红线)。

模块

  • dsl.py —— kb_rule DSL 的 pydantic 解析校验 + 画像匹配(纯逻辑)。封闭词汇表: 未识别的键一律拒绝而非忽略,规则不会静默失效。
  • engine.py —— 纯域求值:priority 降序(同序按 confidence)、is_hard 的 avoid 命中进 hard_blocks(调用方必须据此做硬过滤)、高优先级 avoid 剔除严格低优先级 的冲突 recommend(用户禁忌 95 压过专业推荐 ≤90)。
  • repo.py —— kb_rule 表的唯一读写点(经共享 ORM 访问)。
  • service.py —— CRUD、draft→published→archived 状态机(同 T6 语义)、published 规则进程内缓存(量级 ~400,整表载入,管理动作后 invalidate())。

设计约束

  • 规则是数据不是代码。求值器是代码,规则本身在 kb_rule 表里, 顾问在后台维护,改规则不发版(NFR-MAINT-05)。
  • 每次求值必须输出命中链(rule_hits:rule_key/priority/category/is_hard/ confidence/explanation),这是报告与 Agent 可解释性的来源, 也是 pf_diagnosis.rule_hits 与 ag_message.rule_hits 的数据来源。
  • p95 < 50ms(FR-KB-05):求值是纯内存操作,400 条规则量级实测远低于预算 (见 tests/unit/test_rules_engine.py 的基准用例)。
  • 黄金集雏形:tests/unit/test_rules_golden.py(固定画像 → 期望输出,含硬禁忌 与多规则叠加场景),改引擎行为必须先过黄金集。
  • 已发布规则集缓存在进程内;Redis TTL + 发布广播失效(架构 §10)为后续接入项, 失效入口已收敛到 service.invalidate_published_cache()。