# M2.1 下一阶段实施计划

> 创建：2026-07-09  
> 背景：功能不完善；AI 与 Live2D/视频**尚未完整联动**；App/Web 为半成品。  
> 对照：`docs/STATUS.md`（现状）· `docs/M2.1_PRD.md`（产品定义）

---

## 0. 目标（本阶段完成的定义）

**可演示的闭环（P0 验收）**

1. 设备开机 → App/Web 可连  
2. 切换角色（至少狗/猫/Live2D 配置）→ 画面与人设同步  
3. 文字对话 → 客户端播 TTS → **画面有“在说话”反馈**  
4. App 按住说话 → 同上  
5. 模型列表可见；切换 LLM 后下一回合生效（失败有明确提示）

**不做本阶段（明确边界）**

- 设备本机麦克风/扬声器直连（硬件未接）  
- 精细口型同步 / 流式打断  
- 数字人/歌姬全套新视频素材制作  
- 云端 LLM 实装  

---

## 1. 现状结论（计划前提）

| 层 | 现状 |
|----|------|
| AI 管线 | 本地 ASR/LLM/TTS 可跑；HTTP `/api/chat/*` 可用 |
| Live2D | 有字幕 `Subtitle`；`live2d_talking` 标志在 HTTP 内，**未驱动嘴部动画** |
| 视频状态机 | 有 `talk_state` 配置字段；**对话不会 ChangeScene** |
| App | 角色/对话/模型页已写；真机旅程未系统验 |
| Web | chat 控制台有入口；HTTP 录音受限 |
| 仓库 | 2026-07-09 已提交整理与骨架改动（见 git log） |

---

## 2. 工作包拆分

### WP-A · AI ↔ 画面联动（核心缺口）

**A1. Live2D 说话态接通（优先）**

| 步骤 | 内容 | 验收 |
|------|------|------|
| A1.1 | 定义共享通道：消息 `Message::Live2dTalking { on: bool }` **或** 注入 Arc 状态到 Live2D 插件 | 二选一，文档写清 |
| A1.2 | HTTP chat 成功路径：开始 `talking=true`，结束按**音频时长或字数**回 `false` | 与 TTS 结束大致对齐（误差 ≤1.5s 可接受） |
| A1.3 | Live2D 渲染循环读 talking → `animation.set_talking` | 说话时嘴部开合，结束后回 idle |
| A1.4 | 字幕路径保持：`Subtitle` 继续走 | 字+嘴同时有反馈 |

**A2. 视频角色 talk 状态（次优先）**

| 步骤 | 内容 | 验收 |
|------|------|------|
| A2.1 | chat 开始：向 video 发 `ChangeScene(config.character.talk_state)` 或等价 trigger | 有 talk 片段则切过去 |
| A2.2 | chat 结束：回 `idle`（或配置的默认态） | 不卡在 talk |
| A2.3 | 无 talk 状态时优雅降级（日志 + 保持当前态，不 500） | 猫狗旧包不炸 |

**A3. 时长与互斥**

| 步骤 | 内容 |
|------|------|
| A3.1 | 优先用回复音频时长驱动 talking 窗口；无音频则字数估算 |
| A3.2 | 对话进行中拒绝二次对话 / 切角色（或排队策略写死一种） |

**负责建议**：内核/HTTP（张明远 or 王浩然）+ Live2D/视频（李思琪）  
**预估**：A1 1～2 天 · A2 1 天 · A3 0.5 天  

---

### WP-B · 设备对齐与回归

| 步骤 | 内容 | 验收 |
|------|------|------|
| B1 | 本机已提交代码同步到设备 `192.168.31.105` | git 一致或 rsync 可追溯 |
| B2 | `cargo check --workspace --all-targets` 零 warning | 贴输出 |
| B3 | `cargo test --workspace` 全绿 | 贴输出 |
| B4 | `systemctl --user restart showen_v2` + BLE ActiveInstances=1 | 服务稳定 |
| B5 | `POST /api/chat/text` 冒烟 | 有 reply_text；Live2D 有嘴/字幕 |

---

### WP-C · App 真机验收与修补

| 步骤 | 内容 | 验收 |
|------|------|------|
| C1 | 安装 debug APK，配置 `192.168.31.105:5000` | 能连 |
| C2 | 角色页切换 3 套配置 | 画面+人设变 |
| C3 | 文字对话 + 自动播 TTS + 重播 | 有声有字 |
| C4 | 按住说话一轮 | 转写+回复（允许慢） |
| C5 | 模型页列表/切换 | 失败有文案 |
| C6 | 按失败项修 Flutter（超时、503、权限） | 不再静默失败 |

**依赖**：WP-A 至少完成 A1 后再验“说话联动”。  

---

### WP-D · Web 验收与修补

| 步骤 | 内容 |
|------|------|
| D1 | 角色/文字对话/模型三页真机点通 |
| D2 | HTTP 下录音禁用时的固定文案（与 PRD 一致） |
| D3 | 切角色清空会话上下文 |

---

### WP-E · 产品化收尾（P1，A～D 之后）

| 步骤 | 内容 |
|------|------|
| E1 | App 对话历史本地持久化 + 一键清空 |
| E2 | 模型下载进度轮询/失败重试 UX |
| E3 | release APK 签名与安装说明 |
| E4 | M1.2 tag `m1.2`（老板） |
| E5 | 素材：数字人/歌姬 talk/idle（外部依赖，可并行） |

---

## 3. 推荐执行顺序

```text
Day 0  本计划评审（老板/CEO）
Day 1  WP-A1 Live2D talking 接通 + B 设备同步回归
Day 2  WP-A2 视频 talk 降级策略 + A3 互斥
Day 3  WP-C App 真机四旅程 + 修洞
Day 4  WP-D Web 点通 + 文档 STATUS 更新
Day 5+ WP-E 按优先级穿插
```

---

## 4. 技术要点备忘（实现时）

### 4.1 Live2D talking 推荐实现

```
HTTP chat 开始
  → state.set_live2d_talking(true)
  → tx.send(Message::Live2dTalking { on: true })  // 或等价
  → tx.send(Message::Subtitle { text })

Live2DPlugin::handle_message
  → renderer.set_talking(on)

HTTP chat 结束（spawn 延迟）
  → set_live2d_talking(false) + Live2dTalking { on: false }
```

避免 Live2D 去轮询 HTTP 内部 AtomicBool（跨插件耦合差）。

### 4.2 视频 talk

```
render_type == video 时:
  chat 开始 → PlayerCommand::ChangeScene(talk_state)
  chat 结束 → ChangeScene("idle")  // 或配置 default_idle
无该 scene 时: 忽略并 log，不返回 5xx
```

### 4.3 验证命令（设备）

```bash
ssh -p 2222 showen@192.168.31.105
systemctl --user status showen_v2
curl -sS -m 60 -X POST http://127.0.0.1:5000/api/chat/text \
  -H 'Content-Type: application/json' \
  -d '{"text":"你好","session_id":"plan_test"}'
# 同时观察 Live2D 嘴部与字幕
```

---

## 5. 风险

| 风险 | 应对 |
|------|------|
| 对话延迟 5～15s 体感差 | 先保证正确联动；优化单独立项（锁核/更小模型） |
| 宠物包无 talk 片段 | 强制降级，不阻塞 Live2D 路径 |
| 设备与 git 漂移 | B1 强制对齐后再验 |
| 录音权限/机型差异 | App 明确权限引导；失败可走文字 |

---

## 6. 完成检查清单（勾选）

- [ ] Live2D：对话时嘴部动画 + 字幕  
- [ ] 视频：有 talk 则切 talk，无则降级  
- [ ] App：角色 / 文字 / 语音 / 模型 四旅程通过  
- [ ] Web：角色 / 文字对话 / 模型通过  
- [ ] 设备 `cargo test --workspace` 全绿  
- [ ] `docs/STATUS.md` 矩阵更新为与实机一致  
- [ ] （可选）release APK  

---

## 7. 变更记录

| 日期 | 说明 |
|------|------|
| 2026-07-09 | 初稿：联动缺口 + 分 WP 计划；对应 git 提交含骨架与整理 |
