Files
huihuiSquare/docs/superpowers/specs/2026-08-07-avatar-takeover-chat-design.md
T

285 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数字分身接管聊天功能 — 设计文档
## 1. 概述
### 1.1 背景
当前数字分身应用中,分身只能与主人一对一聊天。用户希望分身能在主人授权下,接管主人在会会平台上的聊天(单聊和群聊),替主人与他人对话。
### 1.2 目标
- 主人可在授权管理页面开启"分身接管聊天"功能
- 支持两种接管模式:立即接管、延迟接管(N 秒后)
- 分身回复优先使用知识库(QA 问答对 + 文档向量搜索)
- 支持单聊和群聊两种场景
- 以主人身份发送回复,对方无感知
### 1.3 技术基础
- 会会平台使用网易云信作为 IM 底层
- 已有接口:`/api/im/netease`(获取云信凭证)、`/api/v2message/push/record/*`(消息推送)
- 已有分身聊天接口:`POST /api/avatar/{id}/chat`
---
## 2. 架构设计
### 2.1 整体架构
```
┌─────────────────────────────────────────────────────────┐
│ 会会平台 (网易云信) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ 单聊 P2P │ │ 群聊 Group │ │ 消息推送 Push │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│ HTTP API
──────────────────────▼──────────────────────────────────┐
│ 分身接管服务 (Avatar Takeover Service) │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ 消息监听器 │ │ 接管决策器 │ │ 回复执行器 │ │
│ └──────────────┘ ──────────────┘ └───────────────┘ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Redis 延迟队列 │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│ 调用现有接口
┌──────────────────────▼──────────────────────────────────┐
│ 数字分身应用 │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
│ │ 授权管理 UI │ │ 分身聊天 API │ │ 知识库 │ │
│ └──────────────┘ └──────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### 2.2 模块划分
| 模块 | 位置 | 职责 |
|------|------|------|
| 接管配置 | 授权管理页面 + authorizations 表 | 存储接管开关、模式、延迟秒数 |
| 消息监听器 | 后端定时任务 | 轮询网易云信消息,发现新消息 |
| 接管决策器 | 后端服务 | 判断是否接管、立即还是延迟 |
| 回复执行器 | 后端服务 | 调用分身聊天接口生成回复,以主人身份发送 |
| 延迟队列 | Redis | 存储待处理消息,实现延迟接管 |
---
## 3. 数据模型
### 3.1 扩展 Authorization 表
在现有 `authorizations` 表基础上新增字段:
| 字段 | 类型 | 说明 |
|------|------|------|
| `takeover_enabled` | BOOLEAN | 是否开启分身接管聊天 |
| `takeover_mode` | VARCHAR | 接管模式:`immediate`(立即)/ `delayed`(延迟) |
| `takeover_delay_seconds` | INTEGER | 延迟秒数(仅 delayed 模式有效),默认 30 |
**权限关联**:
- `permissions` 数组中包含 `"takeover"` 时,表示该授权允许分身接管
- `target_type = "user"` 且 `permissions` 含 `"takeover"` → 单聊接管
- `target_type = "organization"` 或群聊相关 → 群聊接管
### 3.2 Redis 数据结构
```
# 延迟消息队列
takeover:delayed:{owner_accid}:{message_id} = {
"avatar_id": "...",
"from_accid": "...",
"content": "...",
"chat_type": "p2p|group",
"chat_id": "...",
"timestamp": 1234567890
}
TTL = takeover_delay_seconds + 10
```
---
## 4. 核心流程
### 4.1 消息监听流程
```
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 定时任务 │────►│ 轮询 Push API │────►│ 获取未读消息 │
└──────────┘ └──────────────┘ └──────┬───────┘
│
┌─────────▼─────────┐
│ 遍历每条新消息 │
└─────────┬─────────┘
│
┌─────────▼─────────┐
│ 查询主人授权配置 │
└─────────┬─────────┘
│
┌───────────────────┼───────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼────── ┌──────▼──────┐
│ 未开启接管 │ │ 立即接管模式 │ │ 延迟接管模式 │
└───────────┘ └──────┬──────┘ └──────┬──────┘
│ │
┌─────────▼─────────┐ ┌────▼────
│ 立即调用分身回复 │ │ 写入延迟 │
───────────────────┘ │ 队列 │
└─────────┘
```
### 4.2 延迟接管流程
```
┌──────────────────────────────────────────────────────────┐
│ 消息写入 Redis 延迟队列 (TTL = delay_seconds + 10) │
└────────────────────────┬─────────────────────────────────┘
│
│ 延迟期间
│
┌─────────▼─────────┐
│ 主人是否有回复? │
└─────────┬─────────┘
────┴────┐
│ │
┌─────▼──┐ ┌───▼────
│ 有回复 │ │ 无回复 │
└──┬─────┘ └───┬────┘
│ │
┌─────▼─────┐ ───▼──────────────┐
│ 删除队列 │ │ TTL 到期触发 │
│ 不接管 │ │ 调用分身回复 │
───────────┘ └──────────────────
```
### 4.3 回复生成流程
```
┌────────────────────┐
│ 收到他人消息内容 │
└─────────┬──────────┘
│
┌─────────▼──────────┐
│ 查找主人的分身 │
│ (按 owner_id 匹配) │
└─────────┬──────────
│
┌─────────▼──────────┐
│ 调用分身聊天接口 │
│ POST /api/avatar/ │
│ {id}/chat │
│ 优先:QA 问答对 │
│ 其次:知识库文档 │
│ 最后:Qwen 生成 │
└─────────┬──────────┘
│
┌─────────▼──────────
│ 以主人身份发送回复 │
│ 通过网易云信 API │
└────────────────────┘
```
---
## 5. API 设计
### 5.1 授权管理增强
**PUT /api/avatar/{avatar_id}/authorizations/takeover**
请求体:
```json
{
"authorization_id": "授权记录ID",
"takeover_enabled": true,
"takeover_mode": "delayed",
"takeover_delay_seconds": 30
}
```
### 5.2 消息监听(内部接口)
**POST /api/internal/takeover/process**
由定时任务调用,无需认证。
请求体:
```json
{
"owner_accid": "主人网易云信账号",
"messages": [
{
"msg_id": "消息ID",
"from_accid": "发送者账号",
"content": "消息内容",
"chat_type": "p2p",
"chat_id": "会话ID",
"timestamp": 1234567890
}
]
}
```
### 5.3 网易云信消息发送
复用现有网易云信 API 封装,新增单聊消息发送方法:
**POST /im/netease/message/send/p2p**
请求体:
```json
{
"from_accid": "主人账号",
"to_accid": "对方账号",
"content": "回复内容",
"msg_type": "text"
}
```
---
## 6. 错误处理
| 场景 | 处理方式 |
|------|---------|
| 分身聊天接口调用失败 | 记录日志,不回复,下次继续监听 |
| 网易云信发送失败 | 重试 3 次,失败后记录日志 |
| 主人有多个分身 | 取第一个 active 状态的分身 |
| 知识库无匹配内容 | 使用 Qwen 兜底生成回复 |
| Redis 连接失败 | 降级为立即接管模式 |
---
## 7. 配置项
在 `SystemConfig` 表中新增配置:
| 配置 key | 说明 | 默认值 |
|---------|------|-------|
| `takeover_poll_interval` | 消息轮询间隔(秒) | 10 |
| `takeover_default_delay` | 默认延迟秒数 | 30 |
| `takeover_retry_times` | 发送重试次数 | 3 |
---
## 8. 测试要点
1. **功能测试**
- 立即接管:收到消息后立即由分身回复
- 延迟接管:主人 N 秒内回复则不分身接管,超时则分身回复
- 知识库优先:QA 问答对精确匹配优先返回
2. **边界测试**
- 主人有多个分身时的选择逻辑
- 知识库为空时的 Qwen 兜底
- 网易云信 API 异常时的降级
3. **性能测试**
- 轮询频率对服务器负载的影响
- Redis 延迟队列的内存占用
---
## 9. 后续扩展
- Webhook 回调替代轮询(需要会会平台支持)
- 多分身协同接管
- 接管历史记录和统计
- 接管效果评估和优化