lty/docs/好感度系统功能与规则设计.md
pmc 3b7c5c85f5
All checks were successful
Build and Deploy LTY / build-and-deploy (push) Successful in 9m14s
feat: update device interaction views, docs, and CLAUDE.md
- Update device_interaction views
- Update admin README and CLAUDE.md
- Add affinity system design doc
- Add device chat record subtitle storage scheme doc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 17:06:21 +08:00

13 KiB
Raw Permalink Blame History

好感度系统功能与规则设计

文档范围:本文档描述洛天依管理系统中「好感度系统」的全部功能模块与规则设计,用于产品对齐、联调对接与后续服务端落地。

当前状态:管理后台 UI 已完成(见 qy-lty-admin/app/affinity/page.tsx),后端模型骨架已就绪(见 qy_lty/userapp/models.py 第 79115 行),但前端尚未实际调用真实接口,设备端/手机端事件尚未接入好感度逻辑。


一、系统定位

好感度系统用于刻画用户与洛天依之间的亲密度关系。其核心价值:

  • 让用户的互动行为产生持续、可感知的数值反馈
  • 通过等级 + 解锁内容形成长期陪伴动机
  • 对不活跃用户通过衰减机制保留流失预警与召回空间

好感度是一个 [0, max_affinity] 区间的整数(默认上限 100每个用户独立维护记录在 ParadiseUser.favorability 字段。


二、功能模块总览

管理后台分 4 个标签页,对应 5 块功能:

模块 页签 功能说明
系统概览 系统概览 关键指标卡片 + 全局基础参数设置
互动规则 互动规则 管理各类互动行为的好感度变化规则
衰减规则 互动规则页下半 配置不活跃用户的好感度衰减策略
等级奖励 等级奖励 管理好感度等级划分与奖励发放
数据统计 数据统计 好感度分布、互动分析、趋势监控

三、模块 1 — 系统概览与全局参数

3.1 关键指标卡片

指标 含义 数据源
平均好感度 所有用户 favorability 平均值 聚合 ParadiseUser
最高好感度 系统中达到上限的用户数 favorability = max_affinity 计数
互动次数/日 当天触发的所有规则次数总和 聚合 AffinityLog(待建)
活跃用户比例 近 N 天有互动的用户占比 聚合用户活跃状态

3.2 全局参数AffinitySetting

字段 默认值 说明
initial_affinity 10 新用户创建时的初始好感度
max_affinity 100 好感度上限(所有规则累计不会超过此值)
daily_cap 20 单用户每日好感度净增长上限(跨规则汇总)
decay_rate 2 点/天 全局默认衰减速率(衰减规则可覆盖)
decay_threshold 3 天 不互动多少天后开始衰减
enable_notify true 好感度变化是否推送通知
enable_rewards true 是否启用等级奖励发放

规则

  • initial_affinity 只影响新用户,不回溯修改已有用户
  • max_affinity 调低后,已超过的用户保留原值,但不再增加
  • daily_cap跨所有正向规则的顶层限制,触达后当日所有增益无效(衰减不受此限)

四、模块 2 — 互动规则

4.1 规则字段定义

字段 类型 示例 说明
id string rule-2 规则唯一 ID
name string 对话 规则展示名
type / rule_key enum chat 代码标识,服务端事件通过它匹配规则,不可重复
description string 与洛天依进行对话 展示描述
minChange int 1 单次好感度变化最小值
maxChange int 5 单次好感度变化最大值(最终取 [min, max] 的随机整数)
singleCap int 5 单次变化绝对值上限(保护性钳位,防止数据异常)
dailyCap int 15 本规则每日累计变化上限(绝对值)
isNegative bool false 是否负向规则。正向用正数,负向用负数
isEnabled bool true 是否启用,禁用后事件不触发

4.2 默认规则集8 条)

rule_key 名称 范围 单次/日 正负 触发来源
card 使用卡片 +1 ~ +3 3 / 10 手机端(使用卡片 API
chat 对话 +1 ~ +5 5 / 15 设备端 + 手机端(聊天消息)
feed 喂食 +2 ~ +8 8 / 16 手机端(喂食动作)
touch 抚摸 +1 ~ +3 3 / 9 手机端 / 设备端(抚摸信号)
dress 换装 +2 ~ +6 6 / 12 手机端(换装 API
prop 使用道具 +1 ~ +4 4 / 12 手机端(道具使用)
gift 送礼物 +5 ~ +15 15 / 20 手机端(赠礼 API
decay 无互动衰减 1 ~ 3 3 / 5 定时任务

4.3 触发计算流程

收到事件 (user_id, rule_key, 来源上下文)
  │
  ▼
① 取规则 → 若 is_enabled=false丢弃
  │
  ▼
② 冷却检查Redisaffinity:cd:{user}:{rule_key}
  │  未到冷却 → 丢弃
  ▼
③ 本规则日上限检查affinity:daily:{user}:{rule_key}:{date}
  │  已满 → 丢弃
  ▼
④ 全局日上限检查(正向事件才检查)
  │  已满 → 丢弃
  ▼
⑤ 计算变化值 = random(min, max)
     ↓ 按 single_cap 钳位
  │
  ▼
⑥ 原子更新 ParadiseUser.favorability
     ↓ 钳位到 [0, max_affinity]
  │
  ▼
⑦ 写 AffinityLog、更新计数器
  │
  ▼
⑧ 判断是否跨越等级边界
  │  是 → 触发等级变更事件(发奖励 + 推通知)
  ▼
⑨ 通过 WebSocket 向用户的所有在线端推送 affinity_update

4.4 规则设计约定

  • 单一写入入口:所有好感度变化必须经由服务端统一入口,客户端不能直接增减。
  • rule_key 即契约:客户端事件不携带分值,只报「我触发了 gift 规则」,具体加多少由服务端按规则算。规则可被管理员随时调整,客户端无需改动。
  • 幂等防护:同一 rule_key + 同一设备事件 ID 在冷却窗口内只生效一次,防抖防重复。
  • 禁用规则的兜底:管理员禁用某规则后,客户端若继续上报该事件,服务端静默丢弃(不报错、不扣冷却)。

五、模块 3 — 衰减规则

衰减是本质为 rule_key=decay 的负向规则,但由于业务语义特殊,在后台独立配置。

5.1 衰减字段

字段 默认值 说明
decay_start_days 3 不互动多少天后开始衰减
decay_rate_per_day 2 点/天 平均每日衰减点数
min_decay 1 单日衰减最小值
max_decay 3 单日衰减最大值
decay_cap 5 点/天 单日衰减上限(保护性)
min_floor 0 衰减下限,好感度不会低于此值
notify_decay true 是否通知用户「好感度下降了」

5.2 衰减执行

  • 频次:每日 00:30 由定时任务统一跑一次
  • 命中对象last_active_at < now - decay_start_days 的用户
  • 落库:衰减也写 AffinityLogsource='system_decay'
  • 下限保护:若用户当前好感度 ≤ min_floor 则跳过
  • 与互动的关系:用户当天有互动即重置不活跃计数,次日不衰减

5.3 设计权衡

  • 衰减不占用 daily_cap 全局日上限(因为它是扣减,不是增益)
  • 衰减日志会产生大量记录,可考虑按天合并写一条,减少 AffinityLog 膨胀
  • 若「当日互动」和「当日衰减」同时命中,先执行衰减再执行互动(让用户感受到「我回来了 → 好感度止跌回升」)

六、模块 4 — 等级奖励

6.1 等级字段

字段 示例 说明
level 3 等级序号,唯一
name 熟悉 等级名
minAffinity / maxAffinity 41 / 60 等级好感度区间(闭区间)
unlockContent 更多服装、特殊对话 文案描述,前端展示
rewardType unlock / item / currency / mixed 奖励类型
rewardCurrency 100 虚拟货币数量rewardType 含 currency 时生效)
rewardItems [{item_id, qty}] 道具列表rewardType 含 item 时生效)
isEnabled true 是否启用该等级

6.2 默认等级5 档)

等级 名称 区间 解锁内容
1 初识 0 ~ 20 基础对话功能
2 相识 21 ~ 40 基础服装、道具使用
3 熟悉 41 ~ 60 更多服装、特殊对话
4 亲密 61 ~ 80 限定服装、特殊互动
5 挚友 81 ~ 100 专属内容、特殊剧情

6.3 等级变化规则

  • 等级由好感度区间自动映射,不是独立字段
  • 跨级判定:每次好感度变动后,取当前值所属区间,与上一次等级比较
    • 升级 → 发放目标等级的奖励(只发最终落点等级,跳级不补发中间等级)
    • 降级(衰减导致) → 不追回奖励,但取消解锁内容访问权限
  • 奖励幂等:同一用户同一等级的「首次达到奖励」只发一次;降级后再升级不重复发放

6.4 区间约束

  • 区间不得重叠,管理端保存时做校验
  • 区间不得有空隙(如等级 2 的 max=40则等级 3 的 min 必须是 41
  • 最低等级 min=0,最高等级 max=max_affinity

七、模块 5 — 数据统计

7.1 概览指标

  • 平均好感度 / 中位数 / 最高好感度
  • 活跃用户数(近 7 日有互动)
  • 今日互动次数、今日新增好感度总量

7.2 分布分析

  • 好感度区间分布0-20、21-40…
  • 各等级用户数占比
  • 各互动规则触发频次 Top N

7.3 趋势分析

  • 日/周/月的平均好感度变化曲线
  • 日互动量趋势
  • 衰减命中用户数趋势

7.4 用户级查询

  • 按用户 ID 查询其好感度当前值、等级、近期变化日志
  • 管理员手动调整(加减好感度,走 source='admin_adjust' 记 log

八、多端触发点一览

好感度变化可由以下端点触发,所有端都走同一个服务端入口

触发来源 规则 通道 位置参考
设备端上报「用户发起对话」 chat WebSocket device_interaction/consumers.py chat_message
设备端对话结束(陪伴时长) chat 或独立 companion_time WebSocket conversation_status 的 begin/end
手机端点击「唱歌/跳舞/抚摸」 对应 rule_key WebSocket consumers.py sing / dance / touch
手机端赠礼 / 喂食 / 换装 / 用道具 对应 rule_key HTTP 对应业务 ViewSet 钩子
管理员手动调整 无 rule HTTP Admin API 管理后台
衰减定时任务 decay 后台任务 定时调度

身份识别

  • 设备端MAC 登录获取 token → 服务端通过 UserDevice 找到 user_id
  • 手机端Redis token 认证 → 直接拿到 user_id
  • 服务端只认 user_id,与触发端无关

九、数据契约(接口层摘要)

9.1 管理端

接口 方法 用途
/api/admin/affinity/rules/ GET/POST/PATCH/DELETE 互动规则 CRUD
/api/admin/affinity/levels/ GET/POST/PATCH/DELETE 等级 CRUD
/api/admin/affinity/settings/ GET/PUT 全局参数(单例)
/api/admin/affinity/logs/ GET 变化日志查询(可按 user、rule、时间过滤
/api/admin/affinity/stats/ GET 统计聚合
/api/admin/affinity/adjust/ POST 管理员手动调整(必须留审计)

9.2 客户端(手机端 / 设备端共用)

接口 方法 用途
/api/user/me/affinity/ GET 当前好感度、等级、下一级进度、近期变化
/api/user/me/affinity/claim-reward/ POST 领取等级奖励

9.3 WebSocket 实时推送

事件 方向 payload
affinity_update 服务端 → 用户 {change, before, after, rule_key, source}
level_up 服务端 → 用户 {old_level, new_level, reward}
level_down 服务端 → 用户 {old_level, new_level}(衰减导致降级)

十、待开发拼板

模块 前端 后端模型 后端接口 触发埋点
互动规则 CRUD UI 完成 ⚠️ 缺字段 ⚠️ 需扩展
等级 CRUD UI 完成 ⚠️ 缺字段 ⚠️ 需扩展
全局设置 UI 完成 无表 无接口
衰减配置 UI 完成 无表 无接口 无定时任务
变化日志 无 UI 无表 无接口
数据统计 ⚠️ Mock 展示 无聚合接口
客户端查询 无接口
WS 实时推送 未接入
设备/手机事件埋点 未接入

图例: 已完成 ⚠️ 部分完成  未开始


十一、术语表

术语 含义
rule_key 互动规则的代码级标识(如 chat),客户端事件通过它匹配规则
single_cap 单次变化绝对值上限(保护性钳位)
daily_cap 单规则每日累计变化上限
全局日上限 跨所有正向规则的顶层日增长上限(AffinitySetting.daily_cap
冷却 同一用户同一规则的最小触发间隔
source 变化来源:device_event / mobile_event / system_decay / admin_adjust
跨级 好感度变化使得用户从一个等级区间移动到另一个