# Personalized Reco|Overview(大规范总览) > 目的:保留大规范的背景/总览,并作为各子模块规范的索引入口。 > > 依据: > > - `设计说明文档/個性化推薦算法規則.md` > - `设计说明文档/句子文案打分規則.md`(risk_flags 命名与语义的唯一准绳,必须严格对齐) > - `spec_kit/User Profile Scoring/spec.md`(客户端问卷画像输出契约,V1.2) --- ## 1. 背景 需要在后端实现一套可复用、可调参、可观测、可回退的推荐流程,覆盖 Feed / Push / Widget 三种分发场景。推荐模块必须与 API/任务解耦,避免逻辑散落;并在 Push 等高风险场景自动“降个性化/降风险”。 当前约束与确认点(来自需求澄清): - **数据库现状**:数据库尚未设计,当前为空(需要新增 DB 设计与迁移子模块)。 - **规则口径**:risk_flags 等内容画像语义必须严格对齐 `句子文案打分规则`。 - **调用方式**:推荐请求时由客户端传入 `user_profile` 与历史集合(已推荐 ID、已触达/浏览 ID)。 - **Widget 情绪区间**:0.4~0.8 采用**软降权**(非硬过滤)。 - **频控**:Push/Widget 需要冷却与频控(确认要做)。 - **集成形态**:既需要 FastAPI API 接口,也需要 Celery 任务调用(两者都要)。 --- ## 2. 大需求输入/输出(对外契约摘要) - **输入**: - `scene`: `feed | push | widget` - `user_profile`: 客户端问卷画像(V1.2,支持字段缺失/跳过) - `already_recommended_ids`: 已推荐过的文案 ID(本次请求需去重) - `touched_or_viewed_ids`: 已触达/浏览的文案 ID(本次请求需去重/疲劳) - `k`:返回条数(feed 默认 30;push/widget 默认 1) - **输出**: - 推荐句子列表(`content_id` + `text` + `final_score` 等) - `meta`:候选规模、过滤/频控后规模、回退层级、empty_reason 等(用于打点) --- ## 3. 子模块拆分(modules/) > 原则:每个子模块都可独立实现、测试、验收;子模块之间通过明确接口关联。 目录结构: ```text spec_kit/Personalized Reco/ ├ overview.md ├ spec.md └ modules/ ├ db-design/ │ └ spec.md ├ content-repository/ │ └ spec.md ├ reco-engine/ │ └ spec.md ├ scoring/ │ └ spec.md ├ rerank-freqcap/ │ └ spec.md ├ observability/ │ └ spec.md └ integration-api-worker/ └ spec.md ``` 模块关系(逻辑依赖): - `integration-api-worker` → 调用 `reco-engine` - `reco-engine` → 依赖 `content-repository` 拉取候选 - `reco-engine` → 依赖 `hard filter / scoring / rerank-freqcap`(此处拆为独立模块:`scoring`、`rerank-freqcap`) - `content-repository` → 依赖 `db-design` 提供表结构与字段契约 - `observability` → 被 `reco-engine` 与 `integration-api-worker` 共同使用 --- ## 4. 主规范与子规范的职责划分 - `spec.md`:大需求的高层契约与总体约束(面向集成与验收)。 - `modules/*/spec.md`:每块可落地实现的子模块规范(面向工程实现与单测)。 --- ## 5. 模块实现顺序(建议) > 原则:先把“数据可查”打通,再实现“可排序”,最后做“可对外提供(API/任务)”与“可观测”。 1. **`modules/db-design/`(数据库设计与迁移)**已实施 - 交付:表结构 + Alembic 迁移可跑通;能插入/读取最小 `ContentProfile` 字段。 2. **`modules/content-repository/`(数据访问层)**已实施 - 交付:按场景/回退层级拉候选、按 ID(`content_id` 自增 `int`)批量查;risk_flags 旧→新映射与默认值兜底。 - 语言:`text` 按客户端 `locale` 输出(当前仅 EN/TC),且不允许语言回退(缺语言内容直接过滤)。 - 口径:suitability 读取层统一输出稳定结构;缺失时补齐“全 0.5”,key 集合固定为: - context:`family/work/relationship/friends/health` - need:`emotional_support/parenting_pressure/self_worth/anxiety_relief/rest_balance` 3. **`modules/scoring/`(打分)** 已实施 - 交付:`final_score` 与缺失字段保守策略(V1.2)实现;Push 的 `P_uncertainty`;Widget 情绪区间软降权。 4. **`modules/rerank-freqcap/`(去重/重排/频控)** 已实施 - 交付:基于传入历史集合的去重;Feed 的 MMR;Push/Widget 冷却窗口规则(先保证“同句不重复”)。 5. **`modules/observability/`(可观测)** 已实施 - 交付:统一 `meta` 结构与字段;能准确定位候选在何阶段被清空/回退。 6. **`modules/reco-engine/`(引擎编排)** 已实施 - 交付:新增后端 `reco_engine`(编排器 + Hard Filter);串起候选→过滤→打分→重排→回退;输出 items+meta;默认开启轻量 explanations;在画像缺失/候选不足时仍稳定返回。 7. **`modules/integration-api-worker/`(API + Celery 集成)** 已实施 - 交付:新增 `/v1/reco/{feed|push|widget}` 三个推荐接口(含 `Accept-Language→en/tc` 与 `X-Now` 注入);新增按 IP 限流 10/min;新增 Celery 任务 `tasks.reco.generate` 与 `tasks.reco.push_once`,均调用同一 `Reco Engine`。 --- ## 6. 变更记录 - 2026-02-02:完成 `modules/scoring/` 的 `plan.md` 与 `tasks.md`,并新增后端打分模块 `server/app/features/personalized_reco/scoring/` 与单元测试 `server/tests/test_scoring.py`。 - 2026-02-02:完成 `modules/rerank-freqcap/` 的 `plan.md` 与 `tasks.md`,并新增后端重排/频控模块 `server/app/features/personalized_reco/rerank_freqcap/` 与单元测试 `server/tests/test_rerank_freqcap.py`。 - 2026-02-02:完成 `modules/observability/` 的 `plan.md` 与 `tasks.md`,并新增后端可观测模块 `server/app/features/personalized_reco/observability/` 与单元测试 `server/tests/test_observability.py`。 - 2026-02-02:完成 `modules/reco-engine/` 的 `plan.md` 与 `tasks.md`,并新增后端引擎编排模块 `server/app/features/personalized_reco/reco_engine/`(含 Hard Filter + Orchestrator)与单元测试 `server/tests/test_reco_engine.py`。 - 2026-02-02:完成 `modules/integration-api-worker/` 的 `plan.md` 与 `tasks.md`,并新增后端集成: - FastAPI:`server/app/api/v1/reco.py`、`server/app/api/limits.py`、`server/app/main.py` - Celery:`server/app/tasks/reco.py` - 测试:`server/tests/test_integration_api_worker.py` - 依赖:`server/requirements.txt`(新增 `httpx` 用于 API 测试)