补第四批任务契约文档(T15/T16/T17)
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# T16 · 报告流水线·视觉分析与 32 维诊断装配(mock vision)
|
||||
|
||||
> 对应任务:`T-P3-01`(各项返回置信度与质量标记)、`T-P3-06` 🔴(**32 维度**每维四要素完整,缺失显式标注)| 分支:`task/t16-report-diagnosis` | worktree:`/home/xsl/meida_backend-t16`
|
||||
> 先读《README.md(协作规程)》,遵守全部纪律。**第四批拼流水线:T15 定 Stage 接口(协调提交的 pipeline 骨架),你供视觉与诊断两个阶段,文件名与类名已由 T15 的任务契约定死——按下面 §2 的 dotted path 精确落位。**
|
||||
|
||||
## 2. 你要创建的文件(与流水线的挂点,禁差分毫)
|
||||
|
||||
| 文件 | 导出 | 挂进流水线的名字 |
|
||||
| --- | --- | --- |
|
||||
| `packages/report/dimensions.py` | `DIMENSIONS`(32 项冻结结构)等 | —(纯字典) |
|
||||
| `packages/report/vision.py` | `VisionProvider` Protocol、`DeterministicVisionProvider`、`build_vision_provider(settings)` | —(被 vision_stage 用) |
|
||||
| `packages/report/vision_stage.py` | `class VisionStage` | `packages.report.vision_stage:VisionStage` |
|
||||
| `packages/report/diagnosis_stage.py` | `class DiagnosisStage` | `packages.report.diagnosis_stage:DiagnosisStage` |
|
||||
|
||||
Stage 接口以协调提交的 `packages/report/pipeline.py` 骨架 docstring 为准(`name` + `async run(ctx)`;`ctx.report.result[stage.name]` 写产物;`ctx.rp_input.derived_features` 是你的中间态位)。
|
||||
|
||||
## 3. 维度字典(dimensions.py——本任务的事实核心)
|
||||
|
||||
**必读**:`G:\meida\docs\美学报告-需求文档.md` 的 **§4 诊断维度字典**(32 行表)。逐行编码成:
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DimensionSpec:
|
||||
number: int # 1~32(33/34 已永久废弃,不复用)
|
||||
key: str # 稳定英文键,如 body_shape / season_code / face_shape
|
||||
name_cn: str
|
||||
source: str # questionnaire | vision | color | kb | rule | llm(按表「数据来源」列归类)
|
||||
basic_coverage: str # "full" | "label" | "partial" | "none"(按「初级」列的 ✅/标签/部分/❌)
|
||||
```
|
||||
|
||||
- `DIMENSIONS: tuple[DimensionSpec, ...]` 必须恰好 32 项、number 1~32 连续;模块常量 `BASIC_FULL_KEYS`(初级 full 覆盖集,验收「初级 21/32」口径的机器可读形态——**以你逐行统计为准并写注释**)。
|
||||
- key 命名参考 kb/记忆系统已有词汇(body_shape、face_shape、season_code…),全库一致。
|
||||
|
||||
## 4. 视觉分析(vision.py + vision_stage.py)
|
||||
|
||||
1. **`VisionProvider` Protocol**:`async def analyze(photo_meta: dict, questionnaire: dict) -> dict`(返回派生特征 dict:体型、脸型、肤色 Lab 采样、量感/直曲粗判……**形状由你定,写进 docstring**——这是 T9 SPIKE 之后的正式接口位,真实 RTMPose/BiRefNet 实现后续替换)。
|
||||
2. **`DeterministicVisionProvider`**:不读照片字节(V1 骨架根本没有照片下载步骤),从 `questionnaire` + `photo_meta["object_key"]` 的 sha256 派生**确定性**特征(同输入同输出——黄金集与集成测试才能断言)。特征生成规则写注释:哪个问题驱动哪个维度、哈希驱动哪些枚举选择。
|
||||
3. `build_vision_provider(settings)`:按 `settings.report_vision_provider` 选择(当前只认 `"deterministic"`,其它 → `AppError(CONFIG_ERROR)`)。
|
||||
4. **`VisionStage`**(name=`"vision"`):`ctx.rp_input.derived_features` **已存在且非空 → 跳过**(写 `ctx.report.result["vision"] = {"skipped": true, "reused": true}`——这就是 T-P3-09 的实现点);否则 provider.analyze → 写 `derived_features` 并 flush → `result["vision"] = {"status": "ok", "dimensions_touched": [...]}`。质量标记:photo_meta 里可选 `quality_flags`(模糊/背光等,mock 下默认空列表)透传进产物(T-P3-01 的形状)。
|
||||
|
||||
## 5. 诊断装配(diagnosis_stage.py)
|
||||
|
||||
`DiagnosisStage`(name=`"diagnosis"`):
|
||||
1. 输入 = questionnaire(`ctx.rp_input.questionnaire`)+ derived_features;**逐个维度**产四要素(T-P3-06 验收原文):
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class DimensionResult:
|
||||
number: int
|
||||
key: str
|
||||
value: Any # 结论值(枚举/数值/列表)
|
||||
confidence: float # 0~1:问卷自评 0.6、确定性视觉 0.85、规则推导 0.9(口径写注释,对齐记忆系统 §3.5)
|
||||
source: str # questionnaire | vision | rule | derived
|
||||
evidence: str # 一句人话依据(将出现在报告里)
|
||||
rule_hits: list[str] # 命中的 rule_key
|
||||
status: str # "ok" | "skipped"——**缺失/输入不足的维度必须显式 skipped + 原因,不允许缺键**(验收红线)
|
||||
```
|
||||
|
||||
2. 数据流:问卷字段直接映射(性别/身高体重/职业/生日/核心诉求/场景权重/心理风格/偏好禁忌…);视觉字段映射(体型/脸型/肤色档位/季型/量感/直曲/基因风格…);**规则引擎联动**:构造 `RuleContext`(body_shape/face_shape/features/goals…)→ `RulesService` 载入 published 规则 → `evaluate()` → verdict 的 recommend/avoid 聚合进「核心诉求/偏好与禁忌」相关维度的 rule_hits 与 evidence。规则服务接口以 `packages/rules/service.py` 实际代码为准。
|
||||
3. 产物:`ctx.report.result["diagnosis"] = {"dimensions": [32 个 DimensionResult 的 dict], "coverage": {"basic_full": N, "total": 32}}`;序列化用 dataclass `asdict`。
|
||||
4. **色板维度(#19/21)**:V1 骨架从 `kb_color` 读该季型 base/accent/avoid 各取若干(库空则该维度 skipped+「色板未录入」——**显式缺失优于编造**,这正是 skipped 语义的用例)。
|
||||
|
||||
## 6. 测试要求
|
||||
|
||||
- 单测 `tests/unit/test_report_dimensions.py`:32 项、number 连续、33/34 不存在、basic_coverage 枚举合法、`BASIC_FULL_KEYS` 与逐行统计一致。
|
||||
- 单测 `tests/unit/test_report_vision.py`:确定性(同输入同输出)、不同问卷驱动不同体型、工厂未知名拒绝。
|
||||
- 单测 `tests/unit/test_report_diagnosis.py`:四要素齐全性——**构造故意缺问卷+缺视觉的场景,断言缺失维度 status=skipped 且 32 键全在**;规则命中进 rule_hits(用内置最小规则集,不连库——RulesService 若需 DB,把规则求值抽成可注入纯函数 `evaluate_dimensions(ctx_data, verdict)`)。
|
||||
- 集成 `tests/integration/test_report_stages.py`(新文件,**只测你的两个阶段,不测整条流水线**——T15 的集成已覆盖编排):建 rp_report/rp_input + 种 2 条 published 规则 → VisionStage → DiagnosisStage 断言 derived_features 落库、32 维全键、规则 rule_hits 出现、kb_color 为空时色板维度 skipped。
|
||||
|
||||
## 7. 禁改清单
|
||||
|
||||
通用禁改之外:`packages/report/` 除你四个文件外全部(pipeline/service/repo/schemas 归 T15,copy*/validation* 归 T17)、`apps/**`、全部已有测试。
|
||||
|
||||
## 8. 验收标准(T-P3-01/06)
|
||||
|
||||
1. `DIMENSIONS` 与需求文档 §4 逐行一致(32 项、编号连续、初级覆盖口径机器可读);
|
||||
2. 32 维四要素全量输出,缺失显式 skipped——**任何输入组合下 result["diagnosis"]["dimensions"] 恒 32 键**(单测证明);
|
||||
3. 视觉中间态复用:derived_features 存在时 vision 阶段 skipped/reused;
|
||||
4. 规则引擎硬结论进入 rule_hits/evidence;
|
||||
5. 全部检查绿(mypy 范围同 T15 + 你的文件;`packages/report` 整包进列表)。
|
||||
|
||||
## 9. 提交信息
|
||||
|
||||
```
|
||||
feat(report): deterministic vision provider and 32-dimension diagnosis assembly
|
||||
|
||||
dimensions.py 逐行编码需求文档 §4(32 项四要素、缺失显式 skipped)+
|
||||
VisionProvider 接口位与确定性实现 + 规则引擎联动 rule_hits(T-P3-01/06)。
|
||||
|
||||
偏差说明:<如有写在这里,无则写"无">
|
||||
```
|
||||
Reference in New Issue
Block a user