收尾两批并行开发的文档回写与任务包
- Sprint 执行计划 v1.1:§1.1 补第一批交付实据;T9 SPIKE 结论回写 Sprint 1 表 (T-P0-16 通过 2.8ms;T-P0-12 有条件;T-P0-10 原型 6/6 + 真实照片重验前置); Sprint 2 表标注 T-P2-01~06 交付;新增 §9 两批交付记录 - 开发任务拆解 v1.5:交付回写 + 新风险登记(RTMPose 域差异、BiRefNet 异步化) - 新增 开发任务包/:三批多 agent 并行的协作规程与 14 份任务契约 - 新增 前置开通清单-云资源与资质.md - 清理已用毕的评审报告(文档评审 2026-08-13、项目整体评审 2026-08-14), README 中相应引用改为留痕表述
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# T7 · 知识库·规则引擎
|
||||
|
||||
> 对应任务:`T-P2-02`(规则求值 p95 < 50ms;硬约束可拦截)| 需求:`FR-KB-02`、架构 §8.2 rules-engine、`TD-10` | 分支:`task/t7-rules-engine` | worktree:`/home/xsl/meida_backend-t7`
|
||||
> 先读《README.md(协作规程)》,遵守全部纪律。
|
||||
|
||||
## 1. 目标
|
||||
|
||||
自研数据驱动决策表(TD-10):`kb_rule` 的 JSON DSL 解析 + 纯域求值引擎。**核心结论由规则引擎产出,LLM 只负责表达**(防幻觉红线)——这是整个产品"专业可信"的根基,代码质量按"钱与正确性"标准写。
|
||||
|
||||
## 2. 已就绪的契约(协调提交已提供,禁改 models/migrations)
|
||||
|
||||
### 表 `kb_rule`(ORM `KbRule` 已加)
|
||||
|
||||
`rule_id` PK 雪花、`rule_key` varchar(64) UNIQUE(如 `R-BODY-A-002`)、`category` varchar(32)、`version` int、`status` draft/published/archived、`priority` int、`conditions` JSONB、`effects` JSONB、`is_hard` bool、`confidence` Numeric(4,3)、`evidence` varchar(255)、`author`/`reviewer` varchar(64)、`published_at`;Index(status, priority)。
|
||||
(注:架构 §6.2 写的列名 `conclusions`,协调提交统一为 **`effects`**——与"决策表"术语一致,任务文档以 models.py 实际代码为准。)
|
||||
|
||||
### DSL 规格(知识库文档 §3.2⑩ 原文结构)
|
||||
|
||||
```json
|
||||
{
|
||||
"rule_key": "R-BODY-A-002",
|
||||
"category": "body_shape",
|
||||
"priority": 90,
|
||||
"conditions": {
|
||||
"body_shape": "A型",
|
||||
"features": { "include": ["溜肩"] },
|
||||
"goals": { "include": ["修饰溜肩"] }
|
||||
},
|
||||
"effects": {
|
||||
"recommend": [ { "slot": "top", "attrs": { "shoulder": ["垫肩","自然肩"], "sleeve": ["泡泡袖"] } } ],
|
||||
"avoid": [ { "slot": "top", "attrs": { "shoulder": ["落肩"], "silhouette": ["修身"] } } ],
|
||||
"explanation": "溜肩需要在肩部建立结构感……"
|
||||
},
|
||||
"is_hard": false,
|
||||
"confidence": 0.95
|
||||
}
|
||||
```
|
||||
|
||||
### 优先级分组(知识库文档 §3.2⑩,语义:**数字越大越优先**)
|
||||
|
||||
合规 100 / 用户禁忌 95 / 体型 90 / 色彩 85 / 场景 80 / 温度 75 / 风格 70 / 偏好 60 / 趋势 50。
|
||||
|
||||
### 分层位置
|
||||
|
||||
`packages/rules` 已在 import-linter 第 4 层(kb|retrieval|rules|memory|profile),现只有 README + 空 `__init__`。只准 import `packages.shared`/`packages.domain`。
|
||||
|
||||
## 3. 实现要点
|
||||
|
||||
允许改动:`packages/rules/**`、测试文件。
|
||||
|
||||
1. **`packages/rules/dsl.py`**——纯逻辑(无 IO,重点单测):
|
||||
- `RuleCondition` / `RuleEffect` / `Rule` pydantic 模型(解析校验 DSL;`conditions` 支持的字段:等值匹配(str)、`include`/`exclude` 列表、`min`/`max` 数值区间;未识别的键**拒绝**而非忽略——静默忽略会让规则悄悄失效);
|
||||
- `match(condition: RuleCondition, ctx: RuleContext) -> bool`:`RuleContext` 是 frozen dataclass(`body_shape/season/face_shape/temperature/features/goals/occasion/style/user_taboos…`,缺字段 = 不匹配该子句);
|
||||
- 所有子句 AND 语义。
|
||||
2. **`packages/rules/engine.py`**——纯域求值:
|
||||
- `evaluate(rules, ctx) -> RuleVerdict`:返回 `recommend/avoid/explanation 汇总 + rule_hits`(每条含 rule_key/priority/category/is_hard/confidence/explanation);
|
||||
- 排序:priority 降序,同 priority 按 confidence 降序;
|
||||
- **硬约束语义**:`is_hard=true` 且 avoid 命中 → `RuleVerdict.hard_blocks` 非空,调用方必须用它做硬过滤(禁忌违反 = 0 是发布红线);**用户禁忌(priority ≥95 的 avoid)永远压过专业推荐**——同 slot 冲突时用户禁忌胜出并从 recommend 中剔除冲突项;
|
||||
- p95 < 50ms:求值是纯内存操作,规则量 400 条时远低于此;写一个 400 条规则 × 1000 次求值的基准单测(`time.perf_counter`,断言均值 < 5ms/千次的量级即可,CI 机器差异留裕量)。
|
||||
3. **`packages/rules/service.py` + `repo.py`**——DB 侧:按 status='published' 载入规则(内存缓存 + `invalidate()`;量级 400,直接整表载入),CRUD(draft→published 状态机,同 T6 语义),DSL 写入前用 pydantic 校验。
|
||||
4. **黄金集雏形**(架构 §1081 明确要求):`tests/unit/test_rules_golden.py` 固定 8~10 组「输入画像 → 期望 recommend/avoid/hard_blocks」样本,其中**必须包含**:一条硬禁忌场景(用户禁忌压过专业推荐的用例)、一条多规则叠加场景。
|
||||
|
||||
## 4. 测试要求
|
||||
|
||||
- 单测:DSL 解析(合法/非法结构/未识别键拒绝)、match 矩阵(等值/include/exclude/min-max/缺字段)、排序、硬约束剔除、用户禁忌优先、基准测试、黄金集。
|
||||
- 集成 `tests/integration/test_rules_engine.py`(新文件):插 3 条规则(含 1 条 is_hard)→ service 载入 → 求值命中与拦截正确;draft 规则不被载入。
|
||||
|
||||
## 5. 禁改清单
|
||||
|
||||
通用禁改之外:`packages/kb/**`(表共享但包不共享——**repo 只碰 kb_rule 表**,通过 ORM 模型访问,不改 T6 的文件)、`packages/retrieval/**`、`packages/identity/**`。
|
||||
|
||||
## 6. 验收标准(T-P2-02)
|
||||
|
||||
1. 求值 p95 满足 400 条规则量级远低于 50ms(基准测试证明);
|
||||
2. 硬约束可拦截(hard_blocks 语义 + 黄金集用例);
|
||||
3. 用户禁忌永远压过专业推荐(黄金集用例);
|
||||
4. DSL 非法结构 100% 拒绝(不会静默失效);
|
||||
5. 全部检查绿(mypy 范围同 T6 列表 + `packages/rules`)。
|
||||
|
||||
## 7. 提交信息
|
||||
|
||||
```
|
||||
feat(rules): data-driven decision table engine with hard constraints
|
||||
|
||||
kb_rule DSL 解析 + 纯域求值(优先级分组/硬约束/用户禁忌压过专业推荐)
|
||||
+ 400 条基准 + 黄金集雏形(T-P2-02,TD-10)。
|
||||
|
||||
偏差说明:<如有写在这里,无则写"无">
|
||||
```
|
||||
Reference in New Issue
Block a user