7.4 KiB
7.4 KiB
Scoring(软打分与惩罚项)|Tasks
对应计划:
spec_kit/Personalized Reco/modules/scoring/plan.md本清单执行原则:
scoring只做软打分与本模块定义的惩罚项(P_uncertainty、Widget 情绪软降权)。- Hard Filter / 频控重排 / 新鲜度等由其他模块产出,本模块通过
pass与external_terms接收注入(缺省按 0)。
0. 任务标记规则
- 用勾选框标记执行状态:
[ ]未开始[x]已完成
- 每个任务都要求可独立验收(有明确产出/可运行的检查方式)。
1. 文档对齐(先把口径写死,避免实现漂移)
-
1.1 校对
modules/scoring/spec.md与modules/scoring/plan.md一致性- 检查点:
- 输入:
scene/user_profile/content_profile/now/config是否一致 - 输出:
final_score与breakdown字段集合是否一致 - 关键公式:
S_core/S_personal/P_uncertainty是否与设计说明文档/個性化推薦算法規則.md一致
- 输入:
- 验收:两份文档无冲突描述,且关键参数命名统一(例如
enable_uncertainty_penalty、widget_emotion_soft_range)。
- 检查点:
-
1.2 在
modules/scoring/plan.md中“明确写死”V1 的职责边界(若后续有调整再更新)- 变更点(如需微调措辞):
S_fresh/P_fatigue/P_repeat/P_risk为外部注入项,缺省按 0pass来自 Hard Filter,本模块只消费并乘上 (\mathbb{I}[pass])
- 验收:阅读 plan.md 时不会产生“谁负责计算哪一项”的歧义。
- 变更点(如需微调措辞):
2. 目录与骨架(与推荐子模块同级)
- 2.1 新建目录
server/app/features/personalized_reco/scoring/- 包含:
__init__.pytypes.py(ScoreConfig/ScoreBreakdown/ScoreResult/ExternalTerms)defaults.py(场景默认参数)utils.py(clamp、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 - Widget:
widget_emotion_soft_range、widget_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_emotionS_core/S_personal/S_freshP_fatigue/P_repeat/P_risk/P_uncertaintymissing_fieldspass/sceneP_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_context(V1.2 缺失兜底)- 规则:
- need 缺失 →
S_need=0.5;否则取Cᵢ.need_suitability[key] - context 缺失 →
S_context=0.5;否则取Cᵢ.context_suitability[key] - 若内容侧缺 key/值非法 → 兜底为 0.5(防御式)
- need 缺失 →
- 验收:单测覆盖用户缺失与内容缺失两侧情况,且不抛异常。
- 规则:
-
4.3 实现
S_emotion(general=0.8;否则1-|u-c|)- 规则:
U.emotion_score缺失 → 0.8Cᵢ.emotion_score为 general(None)→ 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_powerclamp 到[0,1] - 验收:单测覆盖 power=0/0.5/1,且随
alpha单调变化。
- 规则:
-
4.7 实现
P_uncertainty(Push 默认启用)- 规则:
beta*(1-conf_U)*(1-conf_C)*personalization_power - 默认值:
conf_C缺失→0.7;conf_U缺失→按 1.0(或 0.7,需在代码注释写死;V1 建议按 1.0 避免过惩罚) - 开关:
enable_uncertainty_penalty控制;Push scene 默认 true - 验收:单测覆盖低置信度与关闭开关两类情况。
- 规则:
-
4.8 实现 Widget 情绪区间软降权(适中默认)
- 规则:
scene=widget且content.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.6→P_widget=0emotion_score=0.0/1.0→P_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_risk从external_terms读取,缺省 0pass=false时final_score=0(breakdown 仍输出便于排查)
- 验收:单测覆盖
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-repository与user_profile_scoring逻辑,仅新增 scoring 模块与测试。
- 验收:不修改现有