Files
mindfulness/spec_kit/Personalized Reco/modules/scoring/tasks.md
2026-02-02 16:47:37 +08:00

7.4 KiB
Raw Blame History

Scoring软打分与惩罚项Tasks

对应计划:spec_kit/Personalized Reco/modules/scoring/plan.md

本清单执行原则:

  • scoring 只做软打分与本模块定义的惩罚项(P_uncertainty、Widget 情绪软降权)。
  • Hard Filter / 频控重排 / 新鲜度等由其他模块产出,本模块通过 passexternal_terms 接收注入(缺省按 0

0. 任务标记规则

  • 用勾选框标记执行状态:
    • [ ] 未开始
    • [x] 已完成
  • 每个任务都要求可独立验收(有明确产出/可运行的检查方式)。

1. 文档对齐(先把口径写死,避免实现漂移)

  • 1.1 校对 modules/scoring/spec.mdmodules/scoring/plan.md 一致性

    • 检查点
      • 输入:scene/user_profile/content_profile/now/config 是否一致
      • 输出:final_scorebreakdown 字段集合是否一致
      • 关键公式:S_core/S_personal/P_uncertainty 是否与 设计说明文档/個性化推薦算法規則.md 一致
    • 验收:两份文档无冲突描述,且关键参数命名统一(例如 enable_uncertainty_penaltywidget_emotion_soft_range)。
  • 1.2 在 modules/scoring/plan.md 中“明确写死”V1 的职责边界(若后续有调整再更新)

    • 变更点(如需微调措辞):
      • S_fresh/P_fatigue/P_repeat/P_risk 为外部注入项,缺省按 0
      • pass 来自 Hard Filter本模块只消费并乘上 (\mathbb{I}[pass])
    • 验收:阅读 plan.md 时不会产生“谁负责计算哪一项”的歧义。

2. 目录与骨架(与推荐子模块同级)

  • 2.1 新建目录 server/app/features/personalized_reco/scoring/
    • 包含
      • __init__.py
      • types.pyScoreConfig/ScoreBreakdown/ScoreResult/ExternalTerms
      • defaults.py(场景默认参数)
      • utils.pyclamp、one-hot 取 key 等纯工具)
      • score.py(核心纯函数 score_content
    • 验收:可通过 app.features.personalized_reco.scoring.* 正常 import。

3. 类型与接口(稳定契约,便于引擎编排调用)

  • 3.1 定义 ScoreConfig(含场景默认值 + 可覆盖)

    • 字段
      • 权重:w_need/w_emotion/w_stage/w_context
      • 系数:alpha/beta
      • 开关:enable_uncertainty_penalty
      • Widgetwidget_emotion_soft_rangewidget_emotion_penalty_gamma
    • 验收:类型完整;能从 scene 推导默认 config或由调用方传入
  • 3.2 定义 ExternalTerms注入项V1 可选)

    • 字段S_fresh/P_fatigue/P_repeat/P_risk
    • 默认值策略:缺省按 0
    • 验收score 函数即使没有 external_terms 也能工作且输出字段稳定。
  • 3.3 定义 ScoreBreakdown(用于可观测/调参)

    • 必须包含
      • S_need/S_context/S_stage/S_emotion
      • S_core/S_personal/S_fresh
      • P_fatigue/P_repeat/P_risk/P_uncertainty
      • missing_fields
      • pass/scene
      • P_widget_emotion_out_of_range(建议保留)
    • 验收:字段集合固定;不会因缺省而缺字段;所有值为有限数(非 NaN/Infinity

4. 纯函数实现(严格对齐公式 + 防御式兜底)

  • 4.1 实现 one-hot 取唯一 key 的工具函数need/context

    • 规则
      • {} 或不存在 → 视为缺失
      • 只有一个 key=1 → 返回该 key
      • 多个 key=1 → 选择“第一个”(写死策略:字典序优先或插入序优先)并记录 debug 日志
    • 验收:单测覆盖空对象/单 key/多 key 的行为,且行为确定。
  • 4.2 实现 S_need/S_contextV1.2 缺失兜底)

    • 规则
      • need 缺失 → S_need=0.5;否则取 Cᵢ.need_suitability[key]
      • context 缺失 → S_context=0.5;否则取 Cᵢ.context_suitability[key]
      • 若内容侧缺 key/值非法 → 兜底为 0.5(防御式)
    • 验收:单测覆盖用户缺失与内容缺失两侧情况,且不抛异常。
  • 4.3 实现 S_emotiongeneral=0.8;否则 1-|u-c|

    • 规则
      • U.emotion_score 缺失 → 0.8
      • Cᵢ.emotion_score 为 generalNone→ 0.8
      • 否则 1-abs(u-c) 并 clamp 到 [0,1]
    • 验收:单测覆盖缺失/general/正常值/越界值。
  • 4.4 实现 S_stage(对齐算法规则口径)

    • 规则
      • content.stage=general → 1
      • 命中用户阶段 → 1
      • 用户 unknown 且内容非 unknown → 0.7
      • 其余 → 0
    • 验收:单测覆盖 general/命中/unknown→非unknown/其余组合。
  • 4.5 实现 S_core(线性加权)

    • 规则S_core=w_need*S_need + w_emotion*S_emotion + w_stage*S_stage + w_context*S_context
    • 验收:单测断言与手算一致;权重可配置。
  • 4.6 实现 S_personal(对齐公式)

    • 规则S_personal=alpha * personalization_power * max(S_need, S_context)
    • 防御personalization_power clamp 到 [0,1]
    • 验收:单测覆盖 power=0/0.5/1且随 alpha 单调变化。
  • 4.7 实现 P_uncertaintyPush 默认启用)

    • 规则beta*(1-conf_U)*(1-conf_C)*personalization_power
    • 默认值conf_C 缺失→0.7conf_U 缺失→按 1.0(或 0.7需在代码注释写死V1 建议按 1.0 避免过惩罚)
    • 开关enable_uncertainty_penalty 控制Push scene 默认 true
    • 验收:单测覆盖低置信度与关闭开关两类情况。
  • 4.8 实现 Widget 情绪区间软降权(适中默认)

    • 规则
      • scene=widgetcontent.emotion_score 非 general
        • 若超出 [0.4,0.8]P_widget = gamma * d/(hi-lo) 并 clamp [0,gamma]
        • 区间内:P_widget=0
      • P_widget 计入总分(建议并入 P_risk),并在 breakdown 中单独暴露
    • 验收:单测断言:
      • emotion_score=0.6P_widget=0
      • emotion_score=0.0/1.0P_widget 接近 gamma
      • 不硬过滤(仍返回分数,只是更低)
  • 4.9 实现 score_content(...) -> ScoreResult(总分与 breakdown

    • 规则
      • final_score = I[pass] * (S_core + S_personal + S_fresh - P_fatigue - P_repeat - P_risk - P_uncertainty)
      • S_fresh/P_fatigue/P_repeat/P_riskexternal_terms 读取,缺省 0
      • pass=falsefinal_score=0breakdown 仍输出便于排查)
    • 验收:单测覆盖 pass=false 与 external_terms 缺省两种情况。

5. 单元测试pytest纯函数为主

  • 5.1 新建测试文件 server/tests/test_scoring.py

    • 包含用例
      • 缺失字段一致性need/context/emotion
      • Push 不确定性惩罚生效(低 conf 时分数更低)
      • Widget 软降权生效(区间外明显更低)
      • pass=false 行为final_score=0
    • 验收pytest -q 能跑通该文件。
  • 5.2 增加“输出稳定性”断言breakdown 字段集合固定)

    • 验收:任意输入(含缺失字段)都返回同一套 breakdown key。

6. 最终自检清单(合入前)

  • 6.1 文档一致性检查

    • 检查点spec.md / plan.md / 实现接口签名三者一致(尤其是 config 字段与默认值策略)。
    • 验收:阅读任一文档都能找到对应实现位置与参数含义。
  • 6.2 回归检查(不影响其他模块)

    • 验收:不修改现有 content-repositoryuser_profile_scoring 逻辑,仅新增 scoring 模块与测试。