fix: harden image handling and update docs
This commit is contained in:
36
README.md
36
README.md
@@ -16,7 +16,7 @@ Orchestrator (防抖/去重/冷却/路由)
|
||||
CustomerServiceBrain (PydanticAI Agent)
|
||||
├── lookup_chat_history_tool → 查询历史记录
|
||||
├── transfer_to_human_tool → 转接设计师
|
||||
└── check_order_status_tool → 订单查询
|
||||
└── lookup_customer_orders_tool → 订单查询
|
||||
↓
|
||||
QianniuAdapter → WebSocket → 回复客户
|
||||
```
|
||||
@@ -30,10 +30,13 @@ QianniuAdapter → WebSocket → 回复客户
|
||||
| 智能接待 | 自动引导发图、问需求、转接设计师 |
|
||||
| 历史记忆 | AI 可调用工具查询完整聊天历史,避免重复提问 |
|
||||
| 自动转接 | 收到图片+需求后自动派单给在线设计师 |
|
||||
| 待转接池 | 设计师不在线时先入队,上线后自动补转接 |
|
||||
| 转接冷却 | 转接后 120 秒内不再调用 AI,直接安抚 |
|
||||
| 情绪识别 | 客户愤怒/投诉时自动转人工 |
|
||||
| 消息防抖 | 合并短时间内的多条消息,避免重复回复 |
|
||||
| 订单静默 | 订单通知/SKU 信息自动入库,不触发 AI |
|
||||
| 图片兜底 | 识别 `msg_type=1` 图片包;即使无文本也不会被当心跳丢弃 |
|
||||
| 出站防泄露 | 拦截 `<think>`、工具原文、历史摘要、订单摘要等内部内容 |
|
||||
| 时段感知 | 根据时间区分"没上班"/"下班了"/"暂时不在" |
|
||||
| 图片分析 | 后台调用 Gemini 分析图片复杂度 |
|
||||
| 日报统计 | 每日自动生成客服数据报告 |
|
||||
@@ -95,6 +98,7 @@ curl http://localhost:6060/api/health
|
||||
│ ├── chat_log_db.py # 聊天记录(SQLite/MySQL)
|
||||
│ ├── customer_db.py # 客户档案
|
||||
│ ├── image_tasks_db.py # 图片任务
|
||||
│ ├── pending_transfer_db.py # 待转接队列(本地 SQLite)
|
||||
│ └── task_db/ # 任务模型
|
||||
├── services/
|
||||
│ ├── dispatch_service.py # 设计师派单
|
||||
@@ -125,6 +129,8 @@ curl http://localhost:6060/api/health
|
||||
| `OPENAI_MODEL` | 对话模型 |
|
||||
| `DB_TYPE` | 数据库类型(`sqlite` / `mysql`) |
|
||||
| `MYSQL_HOST/PORT/USER/PASSWORD/DATABASE` | MySQL 连接信息 |
|
||||
| `MYSQL_POOL_SIZE` | MySQL 连接池大小,默认 `10` |
|
||||
| `MYSQL_POOL_WAIT_TIMEOUT` | 连接池等待超时(秒),默认 `10` |
|
||||
| `WECHAT_WEBHOOK` | 企业微信通知 Webhook |
|
||||
| `MESSAGE_DEBOUNCE_SECONDS` | 消息防抖时间(秒) |
|
||||
| `DISPATCH_BASE_URL` | 派单服务地址 |
|
||||
@@ -136,11 +142,23 @@ curl http://localhost:6060/api/health
|
||||
## 消息处理流程
|
||||
|
||||
1. **WebSocket 接收** → 千牛原始消息
|
||||
2. **适配器转换** → `StandardMessage`(统一格式)
|
||||
3. **Orchestrator 过滤** → 订单/SKU 静默入库、心跳过滤、商家回复入库
|
||||
4. **防抖合并** → 2 秒窗口内多条消息合并为一条
|
||||
5. **冷却检查** → 转接后 120 秒内直接安抚,不调 AI
|
||||
6. **AI 思考** → PydanticAI Agent 调用工具、生成回复
|
||||
7. **转接截获** → 工具返回转接指令时直接发送,不经 AI 二次加工
|
||||
8. **乱码清理** → 过滤 `<think>`、内部标记等泄露内容
|
||||
9. **发送回复** → 通过 WebSocket 回复客户,同时入库
|
||||
2. **适配器转换** → `StandardMessage`(统一格式,识别 `msg_type`、递归提取图片 URL)
|
||||
3. **图片兜底** → 纯图片包即使无文本/无直出 URL,也会标记为“已收到图片消息”
|
||||
4. **Orchestrator 过滤** → 订单/SKU 静默入库、心跳过滤、商家回复入库
|
||||
5. **防抖合并** → 2 秒窗口内多条消息合并为一条
|
||||
6. **冷却检查** → 转接后 120 秒内直接安抚,不调 AI
|
||||
7. **AI 思考** → PydanticAI Agent 调用工具、生成回复
|
||||
8. **转接截获** → 工具返回转接指令时直接发送,不经 AI 二次加工
|
||||
9. **待转接入池** → 设计师不在线时记录原因,进入待转接队列,稍后自动补转
|
||||
10. **出站安全过滤** → 过滤 `<think>`、历史摘要、订单摘要、工具原文、时间戳转述历史
|
||||
11. **发送回复** → 通过 WebSocket 回复客户,同时入库
|
||||
|
||||
---
|
||||
|
||||
## 运行注意
|
||||
|
||||
- `db/pending_transfer.db` 是待转接池的本地 SQLite 数据文件,用于暂存“设计师不在线”的转接请求。
|
||||
- `db/chat_log_db/chats.db` 是 SQLite 模式下的本地聊天库;当 `DB_TYPE=mysql` 时,线上主库仍然是 MySQL。
|
||||
- 上面两个 `.db` 文件都属于运行时数据,不建议提交到 Git。
|
||||
- 当前待转接池是单机本地队列;如果未来部署成多台应用机,需要改成共享存储,否则无法跨机器补转接。
|
||||
- 出站消息在 Brain、Orchestrator、QianniuAdapter 三层都会做防泄露清洗;如果线上仍出现历史摘要外发,优先确认服务是否已经重启到最新代码。
|
||||
|
||||
Reference in New Issue
Block a user