fix:句子問卷個性化推薦規則、

This commit is contained in:
雷汀岚
2026-01-30 18:02:46 +08:00
parent 192008986a
commit 3868bf53d1
6 changed files with 1002 additions and 0 deletions

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "mindfulness",
"lockfileVersion": 3,
"requires": true,
"packages": {}
}

View File

@@ -0,0 +1,190 @@
# User Profile Scoring高层规范
## 1. 背景与目标
本模块用于将 Onboarding 问卷答案转换为标准化、可计算、可版本化的**用户画像User Profile**,供其他模块(个性化推荐 / Push 推送排序 / 内容过滤)统一调用。
该模块的设计原则:
- **不做心理诊断**:只描述「此刻允许被如何对待」
- 区分 **身份(离散)****状态(连续)**
- 允许「通用」与「高个性化」内容并存,并通过置信度控制“个性化力度”
来源规则文档:`设计说明文档/客戶端問卷打分規則.md`V1 / V1.1 工程补充)
## 2. 模块定位与边界
### 2.1 负责In Scope
- 定义**统一画像结构**(字段、类型、取值范围)
- 定义从问卷答案到画像的**映射规则**V1
- 生成画像的**元信息**V1.1:版本、来源、生成时间、置信度)
- 提供最小可复用的“硬规则”输出(用于下游模块做禁推/降风险)
### 2.2 不负责Out of Scope
- 不负责具体推荐算法实现(相似度计算、排序、探索/利用策略等)
- 不负责内容标签的生成与管理(内容画像 Cᵢ 的维护属于内容/推荐模块)
- 不负责长期行为信号融合(行为修正可在后续版本扩展)
## 3. 关键概念
- **用户画像 U**:由问卷生成,描述用户阶段、状态与当下需求
- **内容画像 Cᵢ**:内容侧标签/强度(由内容模块维护)
- **置信度 conf_U**:画像可靠程度(用于推送等高风险场景的降个性化/降风险)
## 4. 输入与输出(对外接口)
### 4.1 输入(问卷答案)
V1 假设每题为**单选**
- `mom_stage``expecting | parenting | unknown`
- `emotion``low | overwhelmed | tired | neutral | calm | joyful`
- `context``family | work | relationship | friends | health`
- `need``emotional_support | parenting_pressure | self_worth | anxiety_relief | rest_balance`
> 说明:多选 `context/need` 可在后续版本扩展,但 V1 输出结构需保持可兼容升级。
### 4.2 输出(用户画像)
输出为一个 JSON 对象(或等价的 TypeScript 类型),包含:
- **元信息V1.1**
- `profile_version`: string`"v1.1"`
- `profile_source`: `"questionnaire"`(后续可扩展 `"behavior"` / `"mixed"`
- `profile_generated_at`: stringISO8601 时间戳)
- `profile_confidence`: number01
- **四个维度V1**
- `stage`: one-hot
- `emotion_score`: number01
- `context`: one-hot
- `need`: one-hot
推荐的最小输出示例(结构示意):
```json
{
"profile_version": "v1.1",
"profile_source": "questionnaire",
"profile_generated_at": "2026-01-30T00:00:00Z",
"profile_confidence": 1.0,
"stage": { "expecting": 0, "parenting": 1, "unknown": 0 },
"emotion_score": 0.4,
"context": { "work": 1 },
"need": { "rest_balance": 1 }
}
```
## 5. 画像字段定义V1
### 5.1 mom_stage母职阶段离散
映射one-hot
- Pregnant / Preparing → `stage.expecting = 1`
- Parenting → `stage.parenting = 1`
- Prefer not to say → `stage.unknown = 1`
语义约束:
- `unknown` 的语义是:**不希望被母职身份定义**(不是“没有孩子”)
### 5.2 emotion当下情绪连续 01
该分数不是“快乐程度”,而是**可承受刺激与吸收内容的能力**。分数越低越需要减压、陪伴、允许停下;分数越高才适合庆祝、提醒珍惜等高能量调性内容。
映射(固定离散值):
| 选项 | tag | emotion_score |
| --- | --- | --- |
| Low | emotion: low | 0.0 |
| Overwhelmed | emotion: overwhelmed | 0.2 |
| Tired | emotion: tired | 0.4 |
| Okay | emotion: neutral | 0.6 |
| Calm | emotion: calm | 0.8 |
| Joyful | emotion: joyful | 1.0 |
输出:`emotion_score ∈ [0,1]`
### 5.3 context影响来源离散
映射one-hot
- Family → `context.family = 1`
- Work or study → `context.work = 1`
- Relationship → `context.relationship = 1`
- Friends → `context.friends = 1`
- Health → `context.health = 1`
语义说明:
- `context` 不是情绪,而是情绪的“触发场景”
- 用于提升内容共感(语境命中),而非硬性过滤
### 5.4 need最需要的支持离散推荐权重最高
映射one-hot
- Emotional support → `need.emotional_support = 1`
- Parenting pressure → `need.parenting_pressure = 1`
- Self-worth → `need.self_worth = 1`
- Anxiety relief → `need.anxiety_relief = 1`
- Rest & balance → `need.rest_balance = 1`
语义说明:
- `need` 是**推荐权重最高的维度**
- 表示“她现在最缺的是哪一种心理资源”
## 6. 元信息与置信度V1.1
### 6.1 profile_version / source / generated_at
- `profile_version`:用于规则升级与兼容(建议从 `"v1.1"` 起步)
- `profile_source`:固定为 `"questionnaire"`(后续可扩展)
- `profile_generated_at`:画像生成时间(用于推送降风险)
### 6.2 profile_confidenceconf_U
默认规则(可配置参数):
- 问卷刚完成:`conf_U = 1.0`
- 随时间衰减(避免用过期状态强个性化推送):
- 07 天:`conf_U = 1.0`
- 730 天:线性衰减到 `0.7`
- 30 天以上:`conf_U = 0.5`(除非用户重新做问卷或有行为信号更新)
下游使用建议:
- Push 推送等高风险场景:当 `conf_U` 低时,应启用不确定性惩罚(例如 `P_uncertainty`)并限制个性化力度上限。
## 7. 跨维度硬规则Hard Rules输出
本模块应向下游暴露“可直接执行”的硬规则结果(例如 `forbidden_tags``content_tone_blacklist`),以保证在任何排序之前先做安全过滤。
V1 核心禁推规则:
1. **`stage.unknown = 1`**
- 禁推:强指向育儿压力的内容(`need: parenting_pressure`
2. **`stage.parenting = 1`**
- 禁推:明确怀孕 / 孕期 / 胎动等内容
3. **`emotion_score ≤ 0.2`low / overwhelmed**
- 禁推高能量庆祝型joyful 调性)内容
原则说明:
- 这些不是“答案不准”,而是“会造成反感或退出”的高风险匹配,应始终优先执行。
## 8. 兼容性与演进策略
- **向后兼容**:新版本字段可新增,但不得破坏 V1 的四维度结构与含义
- **多选扩展**:后续允许 `context/need` 多选时,输出仍可保持 one-hot但可允许多个 key=1并提供归一化规则
- **行为融合**:后续可引入 `profile_source=mixed`,将行为信号用于修正 `emotion_score` 或补全缺失维度,但必须保留 `questionnaire` 原始画像以便可观测与回溯
## 9. 验收标准(模块级)
- Onboarding 填写完成后,能够生成符合本规范的用户画像对象
- 输出包含元信息(版本、来源、时间、置信度)与四维度字段
- 硬规则输出可被推荐/推送模块直接用于过滤(先过滤、后打分)

View File

@@ -75,3 +75,14 @@
- 新增 `SheetModal``ThemeModal``ProfileModal` 并在 Home 中接入 - 新增 `SheetModal``ThemeModal``ProfileModal` 并在 Home 中接入
- 新增 `DailyReminderModal` 并从个人主页弹窗打开 - 新增 `DailyReminderModal` 并从个人主页弹窗打开
- Home右上角 icon 按钮、主题切换背景、喜欢/讨厌 icon + 动效 - Home右上角 icon 按钮、主题切换背景、喜欢/讨厌 icon + 动效
## User Profile Scoring
- **目标**:将 Onboarding 问卷答案映射为标准化“用户画像 U”并输出硬规则与置信度元信息供推荐/Push 等模块统一复用
- **核心范围**mom_stage离散、emotion_score01 连续、context离散、need离散四维度以及 `profile_version/source/generated_at/confidence`V1.1
- **主要约定**
- 输出结构稳定可版本化,便于规则演进
- 置信度随时间衰减,用于推送场景降个性化/降风险
- 硬规则优先于任何分数计算(例如 `unknown` 禁推育儿压力内容等)
- **阶段产物**
- `spec_kit/User Profile Scoring/spec.md`

View File

@@ -0,0 +1,319 @@
# 正念 APP三種分發場景推薦算法方案Feed / Push / Widget · V1
> **目標**
> 針對三種分發方式Feed、App Push、Widget 每日一句)制定一套一致但可調參的推薦流程。
>
> **共用基礎**
>
> * 用戶畫像Umom_stage one-hot、emotion_score、context one-hot、need one-hot
> * 文案畫像Cᵢstage、emotion_score、context/need suitability、personalization_power、risk_flags建議含 content_id/author_id/template_id/review_confidence
> * 推薦骨架Hard Filter → Soft Scoring → Rerank多樣性/新鮮度/疲勞)
---
## 一、先說整體流程與思路(適用三種場景)
### 1) 核心理念:同一個用戶同一天需要「不同強度」的個性化
* **Push**:最容易翻車 → **高精準 + 低風險**Precision-first
* **Widget**:每天唯一一句 → **穩定、代表性、可長期持續**Consistency-first
* **Feed**:可上下滑探索 → **可試探、可擴展、多樣性**Exploration-first
### 2) 共用三段式 Pipeline
1. **Candidate Generation候選集生成**
* 依 U 取一個「候選池」:匹配 need/context/stage 的內容 + 一部分通用內容
2. **Hard Filter硬性過濾**
* 依 risk_flags 與產品規則剔除高風險內容
3. **Soft Scoring軟性打分**
* 用加權模型計算核心匹配分
4. **Rerank重排**
* 去重、作者/模板多樣性、頻控、時間衰減
5. **Serve分發**
* 依場景不同策略選 TopK 或組成序列
### 3) 工程必備:候選不足回退策略 + 可觀測指標V1.1
#### 3.1 候選不足回退Fallback Ladder
> 目的:避免「過濾/頻控後候選為空」導致體驗斷崖;同時在回退時**自動降個性化與降風險**(尤其 Push
共用定義:
* `fallback_level`:從 0 開始遞增0=不回退)
* 回退原則:**先放寬匹配,再放寬探索,再回退到通用安全池**;同時限制 `personalization_power` 上限
建議梯度(可按場景調整):
* **L0正常**:按原候選配比取候選
* **L1放寬匹配**`need/context``1 → ≥0.5``personalization_power` 上限降為 `≤0.5`
* **L2回退通用池**:加入更多 `general`/低風險句;`personalization_power` 上限降為 `0`
* **L3兜底**:僅從「通用安全句庫」抽取(需單獨維護白名單/安全池)
每次請求需輸出最終使用的 `fallback_level`(用於分析覆蓋率與風險)。
#### 3.2 可觀測指標(必打點)
每次生成推薦Feed Session / 每次 Push / 每日 Widget至少打點
* `candidate_pool_size_raw`:初始候選池大小
* `candidate_pool_size_after_hard_filter`
* `candidate_pool_size_after_dedup`
* `candidate_pool_size_after_freqcap`
* `fallback_level_final`
* `served_k`:實際下發條數
* `empty_reason`:若 served_k=0記錄原因如 hard_filter_all / freqcap_all / pool_empty / unknown
核心監控衍生指標(報表層計算):
* **覆蓋率**`served_k > 0` 的比例(按場景分開)
* **回退率**`fallback_level_final > 0` 的比例
* **頻控後候選數分布**`candidate_pool_size_after_freqcap` 的 P50/P90/P99
---
## 二、總分結構Score Decomposition
對任意文案 Cᵢ
[
\textbf{final_score}(U,Cᵢ) = \mathbb{I}[\text{pass filters}] \times \Big(
S_{core} + S_{personal} + S_{fresh} - P_{fatigue} - P_{repeat} - P_{risk} - P_{uncertainty}
\Big)
]
其中
[
S_{core} = w_{need}S_{need} + w_{emotion}S_{emotion} + w_{stage}S_{stage} + w_{context}S_{context}
]
* `S_need = Cᵢ.need_suitability[U.need]`
* `S_context = Cᵢ.context_suitability[U.context]`
* `S_stage`general=1命中=1unknown對非unknown=0.7;其餘=0
* `S_emotion`:若文案 general→0.8;否則 `1-|U.emotion_score-Cᵢ.emotion_score|`
個性化加成:
[
S_{personal} = \alpha \cdot Cᵢ.personalization_power \cdot \max(S_{need}, S_{context})
]
不確定性懲罰Push 建議啟用):
[
P_{uncertainty} = \beta \cdot (1-\text{conf}_U) \cdot (1-\text{conf}_{Cᵢ}) \cdot Cᵢ.personalization\_power
]
> 說明:
>
> * `conf_U`:用戶畫像置信度(建議由問卷生成後隨時間衰減;見「用戶畫像」文件 V1.1
> * `conf_{Cᵢ}`:內容標註置信度(`Cᵢ.review_confidence`;缺省可給 0.7
> * `P_{uncertainty}` 可併入 `P_risk`(工程上更簡單),但需保留獨立打點便於調參
---
## 三、Hard Filter共用禁推規則
### 3.1 risk_flags內容自帶
> V1.1 起risk_flags 命名/語義以「句子文案打分規則」為準(`unsafe_for_*` / `block_*` / `soft_*`)。
* `U.stage.unknown=1` → 禁推 `unsafe_for_stage_unknown`
* `U.stage.parenting=1` → 禁推 `unsafe_for_stage_parenting`
* `U.emotion_score≤0.2` → 禁推 `unsafe_for_emotion_low`
* `U.context.health=1` → 禁推 `block_health_medical`(僅擋「醫療/診斷/嚴重暗示」)
> `soft_health_sensitive` 不做 Hard Filter改由 Soft Penalty見 Push 的 P_risk
### 3.2 產品規則(跨維度)
* `U.stage.unknown=1``Cᵢ.need_suitability[parenting_pressure]=1``Cᵢ.personalization_power=1` → 禁推
---
# 四、Feed 模式App 內上下滑)— Exploration-first
## 4.1 目標
* 讓用戶快速感到「被理解」
* 同時探索更多題材,避免內容疲乏
* 允許一定程度的試探(比 Push 寬鬆)
## 4.2 流程Feed Session
1. **建候選池**(大)
* 60%:匹配 need/context 的內容(含 personalization_power=0.5/1
* 30%通用內容general
* 10%:探索內容(與 context/need 邊緣相關)
2. Hard Filter仍嚴格
3. Soft Scoring偏多樣性
4. Rerank用 MMR 做序列
## 4.3 Feed 打分權重(建議)
* `w_need=0.35, w_emotion=0.20, w_stage=0.15, w_context=0.30`
> Feed 更重視「語境共鳴」與內容多樣性,所以 context 權重上調。
## 4.4 Feed 序列重排MMR
* Top1最高分確保第一眼命中
* 後續:在高分候選中,最大化與已選內容的差異(作者/模板/need/context
### 4.5 Feed 的 MMR 定義工程側定義V1.1
選擇第 t 個內容:
[
\text{MMR}(c)=\lambda \cdot \text{Rel}(c) - (1-\lambda)\cdot \max_{s \in S_{t-1}} \text{Sim}(c,s)
]
建議預設:`λ = 0.7`(更偏相關性,仍保留多樣性)
* `Rel(c)`:使用 `final_score(U,c)`(或 Soft Scoring 後的分數)
* `Sim(c,s)`:相似度定義(無 embedding 也可落地)
相似度(離散特徵版,推薦 V1 上線):
*`content_id` 相同 → `Sim=1`
*`template_id` 相同且非空 → `Sim += 0.6`
*`author_id` 相同且非空 → `Sim += 0.3`
* `need/context/stage` 標籤重合Jaccard`Sim += 0.1 * Jaccard(tags_c, tags_s)`
* 最終 `Sim` clamp 到 `[0,1]`
字段依賴與回退:
*`template_id/author_id` 時,只用 tags 相似度Sim 仍可算)
* 若後續引入文本 embedding可將 embedding cosine 加權合併V2
---
# 五、App Push可設定 05 次)— Precision & Safety-first
## 5.1 目標
* Push 是「打擾」:錯一次就掉留存
* 追求「準、溫柔、少翻車」
## 5.2 流程(每次 Push
1. **候選池**(小而精)
* 70%need 命中S_need=1的內容
* 20%emotion 命中(距離小)的內容
* 10%通用安全句general + 低風險)
2. Hard Filter最嚴格
3. Soft Scoring偏 need + emotion
4. 冷卻與頻控(必做)
* 同一句/同作者/同模板至少 X 天不重複
5. 發送
> Push 追加規則V1.1):若 `fallback_level_final > 0` 或 `conf_U` 偏低,需自動「降個性化」:
>
> * `personalization_power` 上限降為 `≤0.5`L1或 `0`L2/L3
> * 若候選不足,優先回退到「通用安全句庫」,而不是擴大高個性化內容
## 5.3 Push 打分權重(建議)
* `w_need=0.45, w_emotion=0.35, w_stage=0.15, w_context=0.05`
> Push 更在乎「此刻需要」與「語氣安全」。context 權重降低。
## 5.4 Push 風險懲罰P_risk
*`Cᵢ.personalization_power=1``S_need<1``S_context<1` → 額外扣分
* 若 content 涉及健康敏感(`soft_health_sensitive`)→ 扣分Soft Penalty不做禁推
* 不確定性懲罰:`P_uncertainty`(或併入 `P_risk`),用於在 `conf_U/conf_C` 偏低時自動降權高個性化內容
## 5.5 05 次推送的排程策略
* 使用者設定次數 N
* 第 1 條need 命中 + 安全
* 第 2 條emotion 修復
* 第 3 條self-worth / rest_balance視 need 而定)
* 第 45 條:通用句補位,避免疲勞
---
# 六、Widget每日一句— Consistency & Brand-first
## 6.1 目標
* Widget 是「代表你這個 App 的一句話」
* 需要:穩定、可持續、低風險、避免太私密
## 6.2 流程(每日生成)
1. 候選池:以 **general + personalization_power≤0.5** 為主
2. Hard Filter嚴格
3. Soft Scoring偏 stage 安全 + emotion 中性/平靜
4. 跨日多樣性7 日內不重複作者/模板/同一句
> 若候選不足:同樣走回退梯度(優先增加 general 安全句;不提高個性化力度)。
## 6.3 Widget 打分權重(建議)
* `w_need=0.25, w_emotion=0.25, w_stage=0.30, w_context=0.20`
> Widget 需要「身份語境安全」與「普適」stage 權重更高。
## 6.4 Widget 的情緒區間約束
* 建議限制 `Cᵢ.emotion_score`**0.40.8**tired→calm
* 避免太低(沉重)
* 避免太高(過嗨)
---
## 七、場景差異總結(快速對照)
| 場景 | 目標 | 候選池 | 風險容忍 | 權重重點 | 序列策略 |
| ------ | ----- | --- | ---- | ------------------- | ------ |
| Feed | 探索+共鳴 | 大 | 中 | context↑、diversity↑ | MMR 序列 |
| Push | 準+安全 | 小 | 低 | need↑、emotion↑ | 頻控+冷卻 |
| Widget | 穩+代表性 | 中小 | 低 | stage↑、emotion中性 | 跨日多樣性 |
---
## 八、(後段解釋預告)提及的算法/概念
* Candidate Generation混合召回命中 + 通用 + 探索)
* Hard Filter規則引擎
* Linear Weighted Scoring加權線性模型
* MMRMaximal Marginal Relevance多樣性重排
* Time Decay時間衰減
* Frequency Capping頻控
* Cooldown Keys去重鍵句子/作者/模板)
> 工程側去重鍵定義V1.1
>
> * `sentence_key = content_id`(若無 content_id需生成 stable hash但建議補 content_id
> * `author_key = author_id`(可空)
> * `template_key = template_id`(可空)
>
> 冷卻/頻控同時支持三層 key避免只靠單一 key 造成過度重複或過度稀釋。
---
## 九、V1 可直接上線的預設參數
* FeedTop1 命中 + MMR 序列 30 條
* Push每次 Top1冷卻 7 天不重複作者14 天不重複同句
* Widgetemotion_score 限制 0.40.87 日不重複作者/模板
V1.1 補充(工程預設):
* FeedMMR `λ=0.7`
* Push啟用 `P_uncertainty`(或併入 `P_risk``fallback_level>=1``personalization_power` 上限降為 `≤0.5`
* HealthHard Filter 僅擋 `block_health_medical``soft_health_sensitive` 走 Soft Penalty
> 一句話:
> **同一套 U×Cᵢ 打分,按場景調候選池、權重與重排約束。**

View File

@@ -0,0 +1,255 @@
# 正念 APP文案畫像打分標準Content Profile · Cᵢ · V1
> **用途**
> 本文件定義「每一句文案如何被轉換為可計算的內容畫像Content Profile」。
> 該畫像將與 **用戶畫像 U** 進行匹配,用於個性化推薦與推送排序。
>
> **使用對象**
>
> * AI Reviewer自動打分
> * 人工內容審稿/校準
> * 推薦系統selector / ranker
---
## 一、核心原則(請務必遵守)
1. **不是評價文案好不好**,而是:
> 這句話「適合對誰說、在什麼狀態下說」
2. **能不標就不標**
* 沒有明確指向,就標為 `general`
* 不要為了打分而硬塞標籤
3. **高個性化 = 高風險**
* 指向越具體(孕吐、育兒比較、婆媳),越需要搭配禁推規則
---
## 二、Content Profile 結構總覽
每一句文案 Cᵢ需產出以下欄位
```text
C_i.stage // general / expecting / parenting / unknown
C_i.emotion_score // 01 或 general
C_i.context_suitability // 各 context 的 {0, 0.5, 1}
C_i.need_suitability // 各 need 的 {0, 0.5, 1}
C_i.personalization_power // 0 / 0.5 / 1
C_i.risk_flags // 風險標記可多個Hard Filter / Soft Penalty 會使用)
// Rerank / 去重 / 頻控所需(若資料源可提供,強烈建議補齊)
C_i.content_id // 句子唯一 ID建議 stable不隨文案微調而變
C_i.author_id // 作者/來源 ID可為空
C_i.template_id // 模板 ID可為空用於多樣性與頻控
// 置信度(可選;用於 Push 的「不確定性懲罰 / 降個性化」)
C_i.review_confidence // 01AI/人工對標註結果的置信度(缺省可按流程給預設值)
```
---
## 三、mom_stage母職階段定位規則
### 可選值
* `general`(預設)
* `expecting`
* `parenting`
* `unknown`
### 判斷標準
#### `expecting`
**必須出現以下任一類語義**
* 懷孕、孕期、孕吐、胎動、產檢、待產
* 明確指向「即將成為媽媽」的心理狀態
> 若只是提到「未來」「新階段」,不算 expecting
---
#### `parenting`
**必須出現以下任一類語義**
* 已有孩子的日常(哄睡、尿布、育兒、學校、教養)
* 明確「身為媽媽正在照顧孩子」
---
#### `unknown`
**僅在以下情況使用**
* 文案明確「不論你在哪個階段」「不管你是否是媽媽」
* 明確避免母職角色語言
---
#### `general`
* 沒有任何明確母職階段指向(**最常見**
---
## 四、emotion_score情緒調性— 連續型
### 對齊用戶 emotion 軸
| 調性 | emotion_score |
| --------- | ------------- |
| 安撫低落 / 陪伴 | 0.00.2 |
| 減壓、縮小世界 | 0.20.4 |
| 疲累修復 | 0.4 |
| 中性穩定 | 0.6 |
| 平靜、呼吸 | 0.8 |
| 慶祝、喜悅 | 1.0 |
### 打分規則
* 若文案同時包含多種調性,取**主導語氣**
* 若無明確情緒調性 → 設為 `general`
---
## 五、context_suitability影響來源適配
### 可選 context
* family / work / relationship / friends / health
### 打分方式(對每一個 context
| 分數 | 含義 |
| --- | -------- |
| 1.0 | 明確命中該情境 |
| 0.5 | 通用可推 |
| 0.0 | 不適合/可能刺痛 |
### 示例
* 提到「老公/婆婆/孩子」→ family = 1
* 提到「上班/職場拉扯」→ work = 1
* 完全抽象支持 → 所有 context = 0.5
---
## 六、need_suitability支持需求適配— **最重要**
### 可選 need
* emotional_support
* parenting_pressure
* self_worth
* anxiety_relief
* rest_balance
### 打分方式(對每一個 need
| 分數 | 含義 |
| --- | ---------- |
| 1.0 | 明確回應此 need |
| 0.5 | 部分相關/通用支持 |
| 0.0 | 無關或反向 |
### 判斷原則(舉例)
* 「你不需要撐著,我在」→ emotional_support = 1
* 「你已經做得夠好了」→ self_worth = 1
* 「慢一點、休息一下」→ rest_balance = 1
* 「不是你做錯,只是育兒真的很難」→ parenting_pressure = 1
---
## 七、personalization_power個性化力度
> 用於控制「專屬程度 vs 風險」
| 值 | 定義 |
| --- | ------------ |
| 0.0 | 完全通用(任何人都可推) |
| 0.5 | 弱指向(稍微貼近某情境) |
| 1.0 | 強指向(高度具體) |
### 判斷依據
* 是否提及具體角色/場景/困境
* 是否假設用戶正在經歷某件事
---
## 八、risk_flags禁推規則標記
> 用於 **Hard Filter**,優先於任何分數
### 重要語義(工程側必讀)
1. `risk_flags` **描述的是「這句話對哪些用戶/狀態不安全」或「需要降權」**,而不是內容的 `stage`
2. **命名規範(工程側定死)**:一律使用 `unsafe_for_*` / `block_*` / `soft_*` 前綴。
- `unsafe_for_*`:對特定用戶狀態不安全,通常進 Hard Filter場景不同可調
- `block_*`:高風險健康/醫療等,進 Hard Filter特別是 Push
- `soft_*`不做硬性過濾但在排序中做風險懲罰Soft Penalty
3. 若不確定,寧可標更保守的 flagPush 安全優先)。
### 標準 flagsV1.1,推薦使用)
* `unsafe_for_stage_unknown`
* 文案假設用戶正在育兒 / 有孩子 / 以「你作為媽媽」為前提(對 `mom_stage=unknown` 容易冒犯)
* `unsafe_for_stage_parenting`
* 文案明確懷孕語境(對 `mom_stage=parenting` 可能刺痛)
* `unsafe_for_emotion_low`
* 高昂慶祝型、過嗨、強刺激(對 `emotion_score ≤ 0.2` 不適合)
* `block_health_medical`Hard Block
* 具「醫療/診斷/嚴重暗示」:疾病確診、用藥、治療方案、醫囑、手術、急重症、危險警示等
* 這類內容在 **Health 情境** 下特別容易翻車,建議 Hard Filter
* `soft_health_sensitive`Soft Penalty
* 健康/身心照顧相關,但不含診斷/治療/嚴重暗示:疲憊、睡眠、壓力、呼吸、覺察身體、日常照護
* 不做禁推,但在 Push/Widget 需降權,避免過度私密或觸發
### 舊 flagsV1已棄用但需兼容
> 若歷史資料仍使用舊 flag工程側需在入庫/讀取時做一次映射,避免語義漂移。
* `block_stage_unknown``unsafe_for_stage_unknown`
* `block_stage_parenting``unsafe_for_stage_parenting`
* `block_emotion_low``unsafe_for_emotion_low`
* `block_health_sensitive``block_health_medical``soft_health_sensitive`
* 判斷原則:含診斷/治療/嚴重暗示 → `block_health_medical`;否則 → `soft_health_sensitive`
> AI Reviewer 若不確定,寧可標記 flag
---
## 九、AI Reviewer 打分流程(強烈建議)
1. **先判斷是否 general**(能 general 就 general
2. 再標註stage若有
3. 再決定 emotion_score主導語氣
4. 再填 context / need suitability
5. 最後判斷 personalization_power
6. 若有任何「可能翻車」風險 → 加 risk_flag
---
## 十、設計總結(一句話)
> Content Profile 的目的不是把話分門別類,
> 而是避免在錯的時間,用錯的方式,對錯的人說話。
本文件為 V1可隨實際推送數據進行校準與升級。

View File

@@ -0,0 +1,221 @@
# 正念 APP用戶畫像打分標準User Profile Scoring Spec · V1
> **用途**
> 本文件定義「問卷完成後如何將答案轉換為可計算的用戶畫像User Profile
> 該畫像將用於後續的 **個性化內容推薦 / 推送排序**。
>
> **設計原則**
>
> * 不做心理診斷,只描述「此刻允許被如何對待」
> * 區分 **身份(離散)** 與 **狀態(連續)**
> * 允許「通用」與「高個性化」內容並存
---
## 一、整體結構概覽
問卷完成後,系統需生成一個用戶畫像 **U**,包含四個維度:
1. **mom_stage**(母職階段|離散型)
2. **emotion**(當下情緒|連續型)
3. **context**(影響來源|離散型)
4. **need**(當下最需要的支持|離散型)
該畫像將與內容畫像 **Cᵢ** 進行匹配,計算推薦分數。
### V1.1 工程補充欄位(用於不確定性控制/可觀測)
> 目的:在 Push 等高風險場景,當用戶畫像可能過期或不可靠時,自動「降個性化 / 降風險」。
建議在 U 中補充以下元資訊(不影響原有四維度打分):
* `profile_version`:如 `"v1.1"`
* `profile_source``questionnaire`(後續可擴展 `behavior` / `mixed`
* `profile_generated_at`ISO8601 時間戳
* `profile_confidence`= `conf_U``01`
`profile_confidence` 建議規則V1.1 默認,可調參):
* 問卷剛完成:`conf_U = 1.0`
* 隨時間衰減(避免用過期狀態強個性化推送):
* 07 天:`conf_U = 1.0`
* 730 天:線性衰減到 `0.7`
* 30 天以上:`conf_U = 0.5`(除非用戶重新做問卷或有行為信號更新)
> Push 推送時若 `conf_U` 偏低,推薦系統需啟用 `P_uncertainty` 並限制 `personalization_power` 上限見「個性化推薦算法規則」V1.1)。
---
## 二、mom_stage母職階段— 離散型
### 問卷題目
**Which stage of motherhood are you in?**
選項與對應標籤:
* Pregnant / Preparing → `mom_stage: expecting`
* Parenting → `mom_stage: parenting`
* Prefer not to say → `mom_stage: unknown`
### 打分方式One-Hot
| 欄位 | 值 |
| ----------------- | ----- |
| U.stage.expecting | 1 或 0 |
| U.stage.parenting | 1 或 0 |
| U.stage.unknown | 1 或 0 |
> **說明**
>
> * `mom_stage` 是「身份 / 階段」,不是強度,不做連續軸線
> * `unknown` 的語義是:**不希望被母職身份定義**(不是「沒有孩子」)
### 推送原則(高層)
* `unknown`:避免任何「你應該怎麼當媽媽」的內容
* `expecting`:避免「已經有孩子」的育兒細節
* `parenting`:可接受具體育兒壓力、現實困境相關內容
---
## 三、emotion當下情緒— 連續型01
### 問卷題目
**How are you feeling right now?**
### 映射為數值軸(能量/情緒穩定度)
| 選項 | tag | emotion_score |
| ----------- | -------------------- | ------------- |
| Low | emotion: low | 0.0 |
| Overwhelmed | emotion: overwhelmed | 0.2 |
| Tired | emotion: tired | 0.4 |
| Okay | emotion: neutral | 0.6 |
| Calm | emotion: calm | 0.8 |
| Joyful | emotion: joyful | 1.0 |
生成:`U.emotion_score ∈ [0,1]`
### 語義說明
* 這不是「快樂程度」,而是 **可承受刺激與吸收內容的能力**
* 分數越低,內容越需要「減壓、陪伴、允許停下」
* 分數越高,才適合「慶祝、提醒珍惜」
---
## 四、context影響來源— 離散型
### 問卷題目
**Whats been influencing how you feel?**
| 選項 | tag |
| ------------- | --------------------- |
| Family | context: family |
| Work or study | context: work |
| Relationship | context: relationship |
| Friends | context: friends |
| Health | context: health |
### 打分方式One-Hot
| 欄位 | 值 |
| ----------------------------------------------------- | ----- |
| U.ctx.family / work / relationship / friends / health | 1 或 0 |
### 語義說明
* context **不是情緒**,而是情緒的「觸發場景」
* 用於提升內容共感(語境命中),而非硬性過濾
---
## 五、need最需要的支持— 離散型(最關鍵)
### 問卷題目
**What kind of support do you need most right now?**
| 選項 | tag |
| ------------------ | ------------------------ |
| Emotional support | need: emotional_support |
| Parenting pressure | need: parenting_pressure |
| Self-worth | need: self_worth |
| Anxiety relief | need: anxiety_relief |
| Rest & balance | need: rest_balance |
### 打分方式One-Hot
| 欄位 | 值 |
| ------------------------------------------------------------------------------------------ | ----- |
| U.need.emotional_support / parenting_pressure / self_worth / anxiety_relief / rest_balance | 1 或 0 |
### 語義說明
* `need`**推薦權重最高的維度**
* 表示「她現在最缺的是哪一種心理資源」
---
## 六、跨維度約束Hard Rules
以下規則在推薦時 **優先於任何分數計算**
### 核心禁推規則V1
1. **mom_stage = unknown**
* ❌ 禁推:`need: parenting_pressure`(強指向)
2. **mom_stage = parenting**
* ❌ 禁推:明確懷孕 / 孕期 / 胎動等內容
3. **emotion_score ≤ 0.2low / overwhelmed**
* ❌ 禁推高能量慶祝型joyful 調性)內容
> 原則:
>
> * 這些不是「不準」,而是「會造成反感或退出」
---
## 七、用戶畫像最終輸出結構(示例)
```json
{
"profile_version": "v1.1",
"profile_source": "questionnaire",
"profile_generated_at": "2026-01-30T00:00:00Z",
"profile_confidence": 1.0,
"stage": {
"expecting": 0,
"parenting": 1,
"unknown": 0
},
"emotion_score": 0.4,
"context": {
"work": 1
},
"need": {
"rest_balance": 1
}
}
```
---
## 八、設計總結給產品工程AI Reviewer
* **mom_stage / context / need**:描述「你現在允許我用什麼身份、從哪個角度對你說話」
* **emotion_score**:描述「你現在能承受多強的刺激與建議」
* 推薦的本質不是猜你是誰,而是 **避免用錯語氣對你說話**
> 本文件為 V1後續可疊加
>
> * 多選 context / need
> * 行為信號(點擊、收藏)對 emotion 的動態修正