285 lines
12 KiB
Markdown
285 lines
12 KiB
Markdown
# 数字分身接管聊天功能 — 设计文档
|
||
|
||
## 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 回调替代轮询(需要会会平台支持)
|
||
- 多分身协同接管
|
||
- 接管历史记录和统计
|
||
- 接管效果评估和优化
|