7.2 KiB
7.2 KiB
Rerank & Freqcap(重排 / 去重 / 频控)|Tasks
对应计划:
spec_kit/Personalized Reco/modules/rerank-freqcap/plan.md本清单执行原则:
- 本模块只做 Dedup / Freqcap / Feed MMR 重排,不做 Soft Scoring 与 Hard Filter。
- V1 冷却窗口以“输入集合代表窗口内历史”为准(后续接入服务端历史再按天计算)。
0. 任务标记规则
- 用勾选框标记执行状态:
[ ]未开始[x]已完成
- 每个任务都要求可独立验收(有明确产出/可运行的检查方式)。
1. 文档对齐(先把口径写死,避免实现漂移)
-
1.1 校对
modules/rerank-freqcap/spec.md与modules/rerank-freqcap/plan.md一致性- 检查点:
- 输入:
scene/scored_candidates/history/k/config字段与命名一致 - 输出:
ranked_items与meta字段集合一致 - 去重键:
sentence_key=content_id、author_key、template_key口径一致 - Feed:MMR λ=0.7 与 Sim 规则一致
- 输入:
- 验收:两份文档不存在冲突描述,且“V1 冷却窗口语义”写清楚(集合代表窗口内历史)。
- 检查点:
-
1.2 在
plan.md中补充/固定“标签构造策略”与“候选截断策略”(若后续要改再更新)- 变更点:
- 明确
tags的 V1 定义:stage + need_argmax + context_argmax - 明确
top_n_for_mmr默认值与作用(性能兜底)
- 明确
- 验收:实现时不会出现“标签到底取哪些 key”的二义性。
- 变更点:
2. 目录与骨架(与推荐子模块同级)
- 2.1 新建目录
server/app/features/personalized_reco/rerank_freqcap/- 包含:
__init__.pytypes.py(ScoredCandidate、RerankConfig、RerankMeta、RerankResult)defaults.py(按 scene 的默认参数:λ、cooldown_*、top_n_for_mmr)utils.py(ID 归一化、Jaccard、tag 构造等)rerank.py(主入口rerank_and_freqcap)
- 验收:可通过
app.features.personalized_reco.rerank_freqcap.*正常 import。
- 包含:
3. 类型与接口(稳定契约,便于 reco-engine 调用)
-
3.1 定义
ScoredCandidate(最小字段集合)- 必须字段:
content_id: intfinal_score: float
- 建议字段(用于多样性/频控):
author_id: str | Nonetemplate_id: str | Nonecontent_profile(至少能取到 stage/need_suitability/context_suitability;缺失时需降级)
- 验收:能承载 MMR 相似度计算所需数据;缺失字段不会导致异常。
- 必须字段:
-
3.2 定义
RerankConfig(可调参)- 字段:
- Feed:
mmr_lambda(默认 0.7)、top_n_for_mmr(默认 200) - Push/Widget:
cooldown_sentence_days/cooldown_author_days/cooldown_template_days(用于配置与可观测)
- Feed:
- 验收:能从 scene 推导默认 config(或由调用方传入覆盖)。
- 字段:
-
3.3 定义
RerankMeta与RerankResult- meta 必须字段:
candidate_pool_size_after_dedupcandidate_pool_size_after_freqcapmissing_history_fields
- 建议字段:
freqcap_filtered_counts(sentence/author/template)
- 验收:字段集合固定;任何输入都能产出 meta(包括候选为空)。
- meta 必须字段:
4. 核心算法实现(V1 最小集合)
-
4.1 实现历史 ID 归一化(避免 str/int 混用漏过滤)
- 规则:
already_recommended_ids/touched_or_viewed_ids尽量转为int集合- 转换失败的值忽略并记录 debug
- 验收:单测覆盖
["1", 2, "bad"]等混合输入,过滤结果正确且稳定。
- 规则:
-
4.2 实现 Dedup(必做)
- 规则:过滤
content_id ∈ seen_ids的候选 - 产出:
meta.candidate_pool_size_after_dedup - 验收:输出不包含历史出现过的
content_id。
- 规则:过滤
-
4.3 实现 Freqcap(Push/Widget 必做;Feed 可选)
- V1 策略:
- 句子维度(必做):同句硬过滤(使用 dedup 的 seen_ids 即可)
- 作者/模板维度(增强项):
- 若提供
recent_author_ids:命中则硬过滤;否则在missing_history_fields记录author - 若提供
recent_template_ids:命中则硬过滤;否则在missing_history_fields记录template
- 若提供
- 产出:
candidate_pool_size_after_freqcapfreqcap_filtered_counts(建议)
- 验收:在有/无
recent_*_ids输入时行为一致且可解释。
- V1 策略:
-
4.4 实现 Feed:tag 构造与相似度
Sim- tag 规则(V1 写死):
stage:<stage>need:<argmax_key>(从need_suitability取最大值 key;为空则跳过)context:<argmax_key>(从context_suitability取最大值 key;为空则跳过)
- Jaccard:
|A∩B|/|A∪B|,空集合时返回 0 - Sim 累加规则:
- 同 content_id → 1
- template_id 相同且非空 → +0.6
- author_id 相同且非空 → +0.3
- +0.1 * Jaccard(tags)
- clamp 到
[0,1]
- 验收:单测覆盖缺失字段(无 author/template/tags)时仍能算出稳定 Sim。
- tag 规则(V1 写死):
-
4.5 实现 Feed:MMR 选序列
- 规则:
- Top1:按
final_score最大 - 后续:按
MMR(c)=λ*Rel(c)-(1-λ)*maxSim选择 Rel=final_score
- Top1:按
- 性能兜底:先截断候选到
top_n_for_mmr再做 MMR - 验收:
- Top1 恒等于最高分
- 候选足够时,序列不出现大量同作者/同模板紧邻重复(可用阈值断言)
- 规则:
-
4.6 实现 Push/Widget:最终 TopK
- 规则:dedup+freqcap 后按
final_score降序取前 k 条 - 验收:输出长度 ≤ k,且分数单调不增(允许相等)。
- 规则:dedup+freqcap 后按
-
4.7 实现主入口
rerank_and_freqcap(...) -> RerankResult- 规则:
- 三场景共用 dedup
- Feed:MMR;Push/Widget:TopK
- 必须输出 meta(即使 ranked_items 为空)
- 验收:任何输入(含空候选)不抛异常,并输出稳定结构。
- 规则:
5. 单元测试(pytest,纯函数为主)
- 5.1 新建测试文件
server/tests/test_rerank_freqcap.py- 用例覆盖:
- dedup:历史集合过滤正确(含 str/int 混用)
- freqcap:有/无 recent_author/template 的分支与 meta 缺失标记
- feed mmr:Top1=最高分;后续避免同作者/模板紧邻(构造数据断言)
- push/widget:TopK 输出正确
- 验收:
pytest -q tests/test_rerank_freqcap.py通过。
- 用例覆盖:
6. 最终自检清单(合入前)
-
6.1 文档一致性检查
- 验收:
spec.md/plan.md/ 实现接口签名三者一致(尤其 meta 字段与默认参数)。
- 验收:
-
6.2 回归检查(不影响已实施模块)
- 验收:不修改
content-repository与scoring的既有逻辑;仅新增rerank-freqcap模块与测试。
- 验收:不修改
-
6.3 全量测试通过
- 命令(在
server/):pytest -q
- 验收:所有用例通过。
- 命令(在
-
6.4 全部完成后更新大规范
overview.md- 变更点:
- 将
modules/rerank-freqcap/标记为“已实施” - 增加一条变更记录(日期 + 交付物:plan/tasks/代码/测试)
- 将
- 验收:
spec_kit/Personalized Reco/overview.md中模块状态与交付记录准确。
- 变更点: