"""诊断维度字典(需求文档《美学报告-需求文档》§4 的机器可读形态)。 32 个维度是报告产出的**事实核心**:diagnosis_stage 逐维装配四要素(T-P3-06), 任何输入组合下都必须输出全部 32 个维度——缺失只能显式 skipped,不允许缺键。 逐行口径(与需求文档 §4 表格一一对应,2026-08-14 版): - ``source`` 按表「数据来源」列归类到六类:questionnaire(问卷)/ vision (视觉分析)/ color(色彩算法)/ kb(知识库映射)/ rule(规则)/ llm。 「视觉 + 问卷」「规则 + LLM」这类复合来源取**主生产方**(视觉、规则), 复合事实写进对应维度的 name_cn 与注释。 - ``basic_coverage`` 按表「初级」列归类:✅→full(完整输出)、标签/Top1→label (仅标签)、部分/粗判/8 色/3 色→partial(粗判或子集)、❌→none(不输出)。 逐行统计(验收「初级 21/32」口径的来源,见需求文档 §4 表格下方统计): - full(10 项):#1 gender、#2 height_weight、#3 birthday、#5 body_shape、 #8 face_shape、#12 skin_tone、#17 season_code、#26 psyche_style、 #27 fusion_style_name、#28 core_goals; - label(3 项):#9 face_proportions、#10 facial_details、#25 gene_style; - partial(8 项):#6 body_features、#13 face_hue、#14 face_lightness、 #19 best_colors、#21 avoid_colors、#22 volume、#23 curve_straight、 #30 preferences_taboos; - none(11 项):#4 occupation、#7 body_ratio、#11 face_depth、#15 face_chroma、 #16 face_contrast、#18 season_detailed、#20 neutral_colors、#24 motion、 #29 occasion_weights、#31 hair_status、#32 hair_color。 合计 10 + 3 + 8 + 11 = 32;初级覆盖(非 none)= 10 + 3 + 8 = **21/32**。 编号 33(五行分布)/34(幸运色)已于 2026-08-13 随 TD-31 永久移除,**不复用**: 避免历史数据与文档交叉引用错位。 """ from __future__ import annotations from dataclasses import dataclass #: basic_coverage 的合法取值(封闭枚举,防止拼写漂移出机器可读口径)。 BASIC_COVERAGE_VALUES: frozenset[str] = frozenset({"full", "label", "partial", "none"}) #: source 的合法取值(按需求文档「数据来源」列归类的六类)。 DIMENSION_SOURCES: frozenset[str] = frozenset( {"questionnaire", "vision", "color", "kb", "rule", "llm"} ) @dataclass(frozen=True, slots=True) class DimensionSpec: """单个诊断维度的静态定义(字典行)。 只描述「这个维度是什么、数据从哪来、初级报告覆盖到什么程度」; 具体取值与置信度由 diagnosis_stage 装配成 DimensionResult。 """ number: int # 1~32(33/34 已永久废弃,不复用) key: str # 稳定英文键,与 kb/记忆系统词汇对齐(body_shape/face_shape/season_code…) name_cn: str source: str # questionnaire | vision | color | kb | rule | llm basic_coverage: str # "full" | "label" | "partial" | "none" #: 32 个维度,按需求文档 §4 表格逐行编码;number 恰好 1~32 连续。 DIMENSIONS: tuple[DimensionSpec, ...] = ( # -- 问卷直采(基础信息) -------------------------------------------------- DimensionSpec(1, "gender", "性别", "questionnaire", "full"), DimensionSpec(2, "height_weight", "身高/体重", "questionnaire", "full"), DimensionSpec(3, "birthday", "生日", "questionnaire", "full"), DimensionSpec(4, "occupation", "职业", "questionnaire", "none"), # -- 视觉分析(体型与比例) ------------------------------------------------ DimensionSpec(5, "body_shape", "体型", "vision", "full"), DimensionSpec(6, "body_features", "身体局部特征", "vision", "partial"), DimensionSpec(7, "body_ratio", "上下身比例", "vision", "none"), # -- 视觉分析(面部) ------------------------------------------------------ DimensionSpec(8, "face_shape", "脸型", "vision", "full"), DimensionSpec(9, "face_proportions", "三庭五眼", "vision", "label"), DimensionSpec(10, "facial_details", "五官细节", "vision", "label"), DimensionSpec(11, "face_depth", "面部立体度", "vision", "none"), # -- 色彩(肤档与季型,视觉 Lab 采样 + 色彩算法) -------------------------- DimensionSpec(12, "skin_tone", "肤色档位", "vision", "full"), DimensionSpec(13, "face_hue", "面部色相", "color", "partial"), DimensionSpec(14, "face_lightness", "面部亮度", "color", "partial"), DimensionSpec(15, "face_chroma", "面部色度", "color", "none"), DimensionSpec(16, "face_contrast", "面部对比度", "color", "none"), DimensionSpec(17, "season_code", "四季季型", "color", "full"), DimensionSpec(18, "season_detailed", "十二季细分", "color", "none"), # -- 知识库映射(色板) ---------------------------------------------------- DimensionSpec(19, "best_colors", "最佳色板", "kb", "partial"), DimensionSpec(20, "neutral_colors", "中性色板", "kb", "none"), DimensionSpec(21, "avoid_colors", "避雷色", "kb", "partial"), # -- 视觉分析(风格量感) -------------------------------------------------- DimensionSpec(22, "volume", "量感", "vision", "partial"), DimensionSpec(23, "curve_straight", "直曲(轮廓)", "vision", "partial"), DimensionSpec(24, "motion", "动静", "vision", "none"), # 表列「视觉 + 问卷」,主生产方为视觉 DimensionSpec(25, "gene_style", "基因风格", "vision", "label"), # 初级 Top1 # -- 问卷偏好(心理侧) ---------------------------------------------------- DimensionSpec(26, "psyche_style", "心理风格", "questionnaire", "full"), DimensionSpec(27, "fusion_style_name", "融合风格命名", "rule", "full"), # 表列「规则 + LLM」 DimensionSpec(28, "core_goals", "核心诉求", "questionnaire", "full"), # 问卷 + 推导 DimensionSpec(29, "occasion_weights", "场景权重", "questionnaire", "none"), DimensionSpec(30, "preferences_taboos", "偏好与禁忌", "questionnaire", "partial"), # -- 视觉分析(毛发现状) -------------------------------------------------- DimensionSpec(31, "hair_status", "发长与卷度现状", "vision", "none"), DimensionSpec(32, "hair_color", "发色现状", "vision", "none"), ) #: 初级报告**完整输出**(basic_coverage == "full")的维度键集合,共 10 项。 #: 这是验收「初级 21/32」口径里 21 = 10 full + 3 label + 8 partial 的机器可读形态。 BASIC_FULL_KEYS: frozenset[str] = frozenset( spec.key for spec in DIMENSIONS if spec.basic_coverage == "full" ) #: 初级报告**有产出**(full/label/partial,即 basic_coverage != "none")的维度键集合。 #: len == 21,对应需求文档 §4 统计表的「初级报告覆盖合计 21/32」。 BASIC_COVERED_KEYS: frozenset[str] = frozenset( spec.key for spec in DIMENSIONS if spec.basic_coverage != "none" ) #: number → spec(诊断装配按编号稳定排序输出用)。 DIMENSION_BY_NUMBER: dict[int, DimensionSpec] = {spec.number: spec for spec in DIMENSIONS} #: key → spec(视觉/诊断阶段按维度键反查定义用)。 DIMENSION_BY_KEY: dict[str, DimensionSpec] = {spec.key: spec for spec in DIMENSIONS}