深聊"模式化"规格(自动续上 + 开关暂存)
DEEP CHAT MODE
2026-09-17 用户定稿。深聊是模式,不是一次性会话 —— 用户习惯是"上次聊到哪,这次进来接着聊"。
一、目标行为(状态机)
进入对话(同一身份)
│
┌───────────────────┴────────────────────┐
│ 存在"未结束"的深聊 │ 不存在
▼ ▼
自动**接着那次深聊**(无提示) 普通聊天
│ │
│ 点「深聊」= 暂存(dormant,她什么都不说)│ 点「深聊」= 新开一段
▼ │
普通聊天(语境退回常规,关系与记忆不倒退) │
│ │
│ 再点「深聊」= 取回那次深聊 ◀────────────┘
二、锁定的决策
| # | 问题 | 结论 |
|---|---|---|
| 1 | 什么算"活跃" | 只要深聊没结束(status != "ended")就算活跃 —— active 与 dormant 都会在进入时自动续上,不加时间窗 |
| 2 | 自动续上要不要提示 | 不要(用户明确:"不需要提示") |
| 3 | 暂存时她要不要说话 | 不要(暂存是 UI 动作,不产生对话内容) |
| 4 | 身份隔离 | 按**身份(线)**隔离 —— 换身份就是另一条深聊(现有 identity_key 已如此) |
三、现状(为什么现在不是这样)
- 深聊状态机有
active / dormant / ended三态(app/systems/deep_chat.py:76); app/api/chat.py里dormant零命中 —— 进普通聊天完全不碰会话状态;dormant在系统里几乎只有读没有写(查询用status IN ('active','dormant'), 唯一的写入方是"开新会话时结束旧的"那个 helper);- 更微妙:普通聊天会读当前身份的活跃深聊会话来注入关系人格
(
chat.py:1059、1483)→ 现在"深聊没结束时你聊的是普通聊天,但带着深聊的语境", 而玩家不知道自己在哪个语境里(既没续上、也没提示)。
四、实施要点
后端
- 进入时查询:给定 (用户, 干员, 身份) 返回
{has_session: bool, session_id, status, dormant_hours}—— 复用get_active_session(op_name)(它已按身份筛,见chat.py:785的注释),但要把dormant也算进来(现在的语义只取 active); - 两个动作:
park(session_id)→status = "dormant",写last_active_ts;resume(session_id)→status = "active"; (schema 已有status与dormant_hours,缺的是这两个动作与它们的调用点。)
dormant之后,普通聊天还注入深聊的关系人格吗? —— 不注入(语境退回常规); 但记忆与关系不倒退(暂存只影响语境,不影响她记得什么)。
前端
#deep-chat-btn从"进入深聊模式"改成开关(三态:在深聊里 / 已暂存 / 无会话);- 进入对话时先问一次上面的接口:有未结束的深聊就直接进深聊界面(无提示)。
五、已知风险与对策
⚠️ "进对话就掉进深聊"会把只想随口聊两句的用户拽进深聊(深聊的节奏、长度、成本都不同)。
对策(用户已认可"续上"为前提):深聊界面里保留一个显眼的「暂存并退出」 —— 一次点击回到普通聊天,这样"默认续上"不会变成"困在里面"。
六、验证
- 有 active 深聊 → 进入对话:直接进深聊界面(无提示);
- 点「暂存」→ 回到普通聊天;她不说任何话;再看她的普通回复不带深聊语境;
- 再进对话 → 又自动续上那次深聊(因为没结束);
- 点「结束深聊」→ 这次是真的结束;再进对话 → 普通聊天(不再自动进深聊);
- 换身份进入 → 另一条深聊(互不串台)。