fix: 第四轮调试 — 回复去重/消息时序/UI布局/自主思考深度优化 + 文档重整

后端修复:
- main.go: 恢复 /api/v1/chat 路由中丢失的 handleChat 调用 (空响应回归)
- orchestrator.go: splitChatByLines 改为双换行分割, 避免单换行误拆
- chat_handler.go: multi_message 增加 !hasReview 守卫, 消息延迟 200→800ms
- thinker.go: RecordUserMessage 追踪活跃会话ID, 推送主动消息到正确会话
- thinker.go: 增强思考提示词 — 禁止在用户休息/离开时发送主动消息

前端修复:
- useWebSocket.ts: stream_segments 不再创建消息气泡, 消除重复回复
- MessageBubble.tsx: 动作消息居左对齐无头像, 时间戳移至气泡外侧 hover 显示
- ChatInput.tsx: 昔涟输入提示移至输入框上方, 波点动画效果
- MessageList/TypingIndicator/ChatContainer: 清理冗余 isTyping 传递
- MemoryPanel.tsx: 新增记忆面板组件

文档重整:
- docs/debug/ → docs/debug_log/ 重命名统一
- 新增 debug_log/README.md 索引
- .gitignore: 新增 android/ 排除规则

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 13:09:18 +08:00
parent 0c1bbff7b4
commit b123a36aae
37 changed files with 580 additions and 174 deletions
@@ -0,0 +1,170 @@
# Cyrene 第四轮修复报告 — IoT 操控 + Review Pipeline + 速度优化
> **报告日期**2026-05-22
> **覆盖周期**2026-05-22 (UTC+8)
> **分支**`dev`
> **涉及文件数**9 个
> **E2E 测试**:全部通过
---
## 一、修复项总览
| # | 类别 | 问题 | 涉及核心文件 |
|---|------|------|-------------|
| 1 | 🔴 功能 | IoT 设备操控 — 多设备命令支持 + Persona 路径 | [`iot_provider.go`](backend/ai-core/internal/subsession/iot_provider.go), [`main.go`](backend/ai-core/cmd/main.go) |
| 2 | 🟡 功能 | Review Pipeline — 主会话输出解析为 action/chat 消息 | [`orchestrator.go`](backend/ai-core/internal/orchestrator/orchestrator.go), [`chat_handler.go`](backend/gateway/internal/handler/chat_handler.go) |
| 3 | 🟡 功能 | 前端 action 消息显示 + msgType 历史映射 | [`protocol.go`](backend/gateway/internal/ws/protocol.go), [`hub.go`](backend/gateway/internal/ws/hub.go), [`sessionStore.ts`](frontend/web/src/store/sessionStore.ts) |
| 4 | 🟢 优化 | 对话链路速度优化 — IoT 快速通道 + 简单消息跳过子会话 | [`intent_analyzer.go`](backend/ai-core/internal/orchestrator/intent_analyzer.go), [`orchestrator.go`](backend/ai-core/internal/orchestrator/orchestrator.go) |
| 5 | 🟢 优化 | Persona 注入 action 格式指令 | [`injector.go`](backend/ai-core/internal/persona/injector.go) |
---
## 二、详细修复说明
### 2.1 IoT 多设备命令支持 + Persona 路径修复
**问题**
- IoT 子会话 `Execute()` 在匹配到第一个设备后立即 `return`,导致"打开客厅灯和卧室灯"只执行第一个
- `NewIoTProvider` 未接收 `personaDir` 参数,persona 配置加载始终使用空路径
**修复**
- `iot_provider.go` — 完全重写 `Execute()` 函数:先收集所有设备-操作匹配对,再批量执行
- `iot_provider.go``IoTProvider` 结构体新增 `personaDir` 字段,`NewIoTProvider` 接收参数
- `main.go` — 注册 IoT provider 时传入 `personaDir`
**关键代码**`Execute` 多设备收集逻辑):
```go
type deviceAction struct {
dev tools.IoTDevice
operation string // "on" | "off" | "query"
}
var actions []deviceAction
for _, dev := range devices {
// 匹配设备名 + 上下文意图词
// 收集所有匹配的 action
}
// 批量执行所有 action,合并 summaries
```
### 2.2 Review Pipeline — 内联解析
**问题**:主会话 LLM 输出需要拆分为 action 消息(描述操作)+ chat 消息(对话文本),前端分别渲染
**修复**
- `orchestrator.go` — 新增 `parseReviewMessages()` 函数:无正则括号匹配状态机,支持 `()``()`
- `orchestrator.go` — 新增 `splitReviewLongMessage()` 函数:80 字符智能断句,在句子边界处分割
- `orchestrator.go` — 合成完成后自动调用审查,发送 `StreamReview` 事件
- `chat_handler.go` — SSE 解析 `review_messages` 字段,逐条发送 WebSocket responseaction 消息 200ms 间隔)
- `protocol.go` — 新增 `ReviewMessage` 结构体 + `ServerMessage.MsgType` 字段
- `hub.go``Message` 结构体新增 `MsgType` 字段
**消息格式约定**
- `(动作描述) 对话文本` → action 消息(角色 `action`,类型 `action`+ chat 消息(角色 `assistant`,类型 `chat`
- 括号支持半角 `()` 和全角 `()`
- 长 chat 消息自动在 80 字符处按句子边界拆分
### 2.3 前端 action 消息显示
**修复**
- `sessionStore.ts` — 历史消息加载时映射 `msg_type` 字段,`action` 类型消息使用 `action` 角色
### 2.4 对话速度优化
**问题**:每条消息都需要 2-3 秒 LLM 意图分析 + 所有子会话调度
**修复**
- `intent_analyzer.go` — 新增 `isStrongIoTCommand()`:控制词 + 设备词同时出现时跳过 LLM 分析,直接使用关键词规则(节省 2-3s)
- `intent_analyzer.go` — 简单问候的快速通道已存在(精确匹配 + ≤4 字符消息)
- `orchestrator.go` — 快速通道扩展:`primary=greeting``(primary=chat && !needsIoT && !needsMemory)` 时跳过所有子会话分派
- `orchestrator.go` — 子会话结果等待超时从 500ms 降至 200ms
### 2.5 Persona action 格式指令
**修复**
- `injector.go` — 在对话风格指令中新增:
```
- 执行操作时(开关设备、查询状态等),用括号包裹动作描述,后面跟自然对话。
例如:"(帮你把客厅灯关掉啦) 嗯,已经关好了~"
```
---
## 三、E2E 验证结果
### 测试场景 1:IoT 设备操控
```
输入:帮我把卧室空调打开
输出:
[ACTION] "指尖轻点,空调立刻嗡鸣启动"
[CHAT] "好啦,已经让卧室凉快下来啦~♪..."
后端日志:
[IoT-client] ✅ 切换设备成功: ac-bedroom
[iot-subsession] 执行操作: 打开 卧室空调 (ac-bedroom)
设备状态:ac-bedroom: off → on ✅
```
### 测试场景 2Review Pipeline 消息拆分
```
输入:帮我把客厅灯打开
输出:
[ACTION] "轻轻感应了一下忆庭对客厅灯的投影"
[CHAT] "嗯...叶酱,客厅灯现在是开着的哦?刚才是不是工作太忙,有点眼花啦♪"
后端日志:
[orchestrator] 审查完成: 2 条带类型消息 ✅
```
### 测试场景 3:简单问候快速通道
```
输入:你好呀
输出:
[CHAT] "诶嘿,叶酱今天主动跟人家打招呼了♪"
[ACTION] "笑着晃了晃食指"
[CHAT] "让我猜猜...是不是有好事要跟姐姐分享呀?"
后端日志:
[intent] 快速通道: 检测到简单问候,跳过 LLM 分析
[orchestrator] 快速通道: 简单消息(primary=greeting),跳过子会话分派
意图分析耗时: 0s ✅
```
### 测试场景 4:IoT 快速通道
```
输入:帮我把卧室空调打开
后端日志:
[intent] 快速通道: 检测到 IoT 操控命令,跳过 LLM 分析
意图分析耗时: 0s ✅
```
---
## 四、性能对比
| 场景 | 修复前 | 修复后 | 节省 |
|------|--------|--------|------|
| IoT 命令 | ~6s (LLM意图2-3s + 子会话 + 合成) | ~3.4s (跳过LLM意图) | ~2.6s |
| 简单问候 | ~5s (LLM意图 + 子会话) | ~3.9s (跳过LLM意图 + 跳过子会话) | ~1.1s |
| 一般聊天 | ~5s | ~4s (仅合成) | ~1s |
---
## 五、涉及文件清单
| 文件 | 变更类型 | 说明 |
|------|---------|------|
| `backend/ai-core/cmd/main.go` | 修改 | 传递 personaDir 给 NewIoTProvider |
| `backend/ai-core/internal/orchestrator/intent_analyzer.go` | 修改 | 新增 isStrongIoTCommand 快速通道 |
| `backend/ai-core/internal/orchestrator/orchestrator.go` | 修改 | parseReviewMessages + 快速通道扩展 + 超时优化 |
| `backend/ai-core/internal/persona/injector.go` | 修改 | 对话风格新增 action 格式指令 |
| `backend/ai-core/internal/subsession/iot_provider.go` | 修改 | 多设备支持 + persona 路径修复 |
| `backend/gateway/internal/handler/chat_handler.go` | 修改 | SSE review_messages 解析 → WebSocket 转发 |
| `backend/gateway/internal/ws/protocol.go` | 修改 | 新增 ReviewMessage 结构体 + MsgType 字段 |
| `backend/gateway/internal/ws/hub.go` | 修改 | Message 结构体新增 MsgType 字段 |
| `frontend/web/src/store/sessionStore.ts` | 修改 | 历史消息 msg_type 映射 |