5.1 KiB
5.1 KiB
子模块:Content Repository(候选查询与数据访问层)|Spec
1. 目标描述
提供推荐算法可注入的、与 ORM/SQL 解耦的数据访问接口:
- 按场景与用户画像拉取候选内容画像(Cᵢ)。
- 按
content_id批量获取内容画像(去重/重排/补字段)。 - 对 risk_flags、suitability JSON 等“存储形态”做统一解析与兼容(对上提供稳定结构)。
规则口径:risk_flags 命名与语义严格按
句子文案打分规则;若历史数据存在旧 flag,需在读取层做一次映射(避免语义漂移)。存储形态对齐
modules/db-design/plan.md:读取层需要将contents+content_profiles+content_risk_flags组装为上层稳定的ContentProfile结构。
2. 输入 / 输出定义
2.1 输入
scene:feed | push | widgetuser_profile: 客户端问卷画像(V1.2;字段允许缺失)fallback_level:0|1|2|3limit: 候选条数上限(由引擎配置)- (可选)排除集合:
exclude_content_ids(用于 DB 层先排一部分,减少传输;类型为List[int],与 MySQL 自增content_id对齐) - 数据库会话/连接(实现层使用
AsyncSession注入)
2.2 输出
List[ContentProfile](稳定字段契约):content_id:int(MySQL 自增主键)text:文案文本stage:general | expecting | parenting | unknownemotion_score:float | None(约定:None表示 general)context_suitability:Dict[str, float](见 4.1 的 key 集合;值为0/0.5/1)need_suitability:Dict[str, float](见 4.1 的 key 集合;值为0/0.5/1)personalization_power:float(对上稳定口径为0/0.5/1;若 DB 存0/5/10,读取层需映射)risk_flags:List[str](已做旧→新映射、去重;命名只允许unsafe_for_* / block_* / soft_*)- 可选:
author_id、template_id、review_confidence
2.3 数据存储形态(对齐 DB 设计)
对齐:
spec_kit/Personalized Reco/modules/db-design/plan.md
contents:提供content_id、text、(可选)author_id、template_idcontent_profiles:提供stage、emotion_score、context_suitability_json、need_suitability_json、personalization_power(推荐存0/5/10)、(可选)review_confidencecontent_risk_flags:通过关联表提供风险标记集合(同一 content 下按uniq_content_flag(content_id, flag)去重)
3. 接口(建议)
推荐模块对该子模块只依赖抽象接口(Python Protocol/ABC 均可):
fetch_candidates(scene, user_profile, fallback_level, limit, exclude_content_ids=None) -> List[ContentProfile]fetch_contents_by_ids(content_ids: List[int]) -> List[ContentProfile]
4. 关键规则与实现约束
4.1 字段缺失与默认值
- 若
review_confidence缺失:输出时默认按0.7(对齐句子文案打分规则V1.2 约定)。 context_suitability/need_suitability若缺失:读取层必须补齐为“全 0.5 的通用可推”结构(稳定输出,避免上层分支判断)。context_suitability必须包含 5 个 key:family/work/relationship/friends/healthneed_suitability必须包含 5 个 key:emotional_support/parenting_pressure/self_worth/anxiety_relief/rest_balance- 补齐时上述 key 的默认值均为
0.5
personalization_power:若 DB 采用0/5/10存储,读取层必须映射为0.0/0.5/1.0对上输出。
4.2 risk_flags 兼容映射(若存在历史旧数据)
对齐 句子文案打分规则 的旧→新映射:
block_stage_unknown→unsafe_for_stage_unknownblock_stage_parenting→unsafe_for_stage_parentingblock_emotion_low→unsafe_for_emotion_lowblock_health_sensitive→block_health_medical(读取层默认采用更保守的硬拦截映射;除非未来引入可判定的细分字段再放宽为soft_health_sensitive)
输出约束:
- 输出的 flags 必须已去重,且不得包含任何旧命名。
4.3 性能约束
- 不得产生 N+1 查询:候选与字段必须一次或少量批量查询获取。
fetch_candidates必须支持 limit,并在 DB 层尽量过滤(减少应用层扫描)。fetch_contents_by_ids/fetch_candidates推荐查询形态:contentsJOINcontent_profiles,再 LEFT JOINcontent_risk_flags(或先批量取 profiles,再批量取 flags 并在应用层聚合),避免按content_id循环查 flags。
5. 验收标准(可验证)
fetch_contents_by_ids:- 输入任意
content_id列表,返回包含完整字段的ContentProfile列表(无重复、可缺省字段按约定兜底)。
- 输入任意
fetch_candidates:- 在不同
scene与fallback_level下能返回候选(即便画像缺失也不报错)。 - risk_flags 映射正确:输出的 flag 名称集合只包含新命名(
unsafe_for_* / block_* / soft_*)。
- 在不同
- 性能:
- 单次调用不出现按 content_id 循环查库的行为(可通过日志/测试断言查询次数)。