49c0e5559c
Co-Authored-By: Claude Code <noreply@anthropic.com>
294 lines
11 KiB
Markdown
294 lines
11 KiB
Markdown
# 二手汽车AI智能客服系统 - 设计文档
|
||
|
||
## 概述
|
||
|
||
为二手车贸易公司构建AI智能客服系统,核心功能是通过自然对话收集客户信息、评估购买意向,将有意向客户推送至邮箱。
|
||
|
||
### 核心需求
|
||
|
||
- AI自然对话收集客户信息,不预设固定字段,自主判断信息是否足够
|
||
- 简单意向分级:interested / not_interested / pending
|
||
- 有意向客户自动发送邮件通知
|
||
- 前端支持三种使用方式:独立页面、iframe嵌入、JS Widget悬浮窗
|
||
|
||
### 约束
|
||
|
||
- 单租户,贸易公司自用
|
||
- 初期使用智谱GLM模型,架构支持多模型切换
|
||
- Docker部署
|
||
- 客户主要来自自有网站
|
||
|
||
## 1. 系统架构
|
||
|
||
采用**全栈一体化**架构,FastAPI托管所有服务。
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────┐
|
||
│ Docker Compose │
|
||
│ │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌────────┐ │
|
||
│ │ FastAPI │ │ Redis │ │SQLite/ │ │
|
||
│ │ (后端+前端) │←→│ (会话缓存) │ │Postgres│ │
|
||
│ │ │ │ │ │(持久化) │ │
|
||
│ │ - REST API │ └──────────────┘ └────────┘ │
|
||
│ │ - WebSocket │ │
|
||
│ │ - 静态页面 │ │
|
||
│ │ - JS Widget │ │
|
||
│ └──────┬───────┘ │
|
||
│ │ │
|
||
│ ┌──────▼───────┐ ┌──────────────┐ │
|
||
│ │ AI Service │ │ Email Service│ │
|
||
│ │ (多模型适配) │ │ (SMTP推送) │ │
|
||
│ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 模块职责
|
||
|
||
- **FastAPI主服务** — REST API + WebSocket + 静态文件托管
|
||
- **AI Service** — 多模型适配层(初期智谱GLM),统一prompt管理和对话管理
|
||
- **Email Service** — SMTP发送,意向客户自动推送
|
||
- **Redis** — 活跃WebSocket会话、对话上下文缓存
|
||
- **SQLite/PostgreSQL** — 持久化对话记录、客户信息、评估结果
|
||
|
||
### 数据流
|
||
|
||
客户打开聊天框 → WebSocket建立连接 → AI自然对话收集信息 → AI判断信息足够 → 评估意向 → 有意向则推送邮件
|
||
|
||
## 2. 数据模型
|
||
|
||
### Conversation(对话)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | UUID | 主键 |
|
||
| session_id | string | 会话标识 |
|
||
| status | enum | active / completed / abandoned |
|
||
| source | enum | standalone / embedded / widget |
|
||
| client_info | JSON | IP、浏览器、来源页面等 |
|
||
| created_at | datetime | 创建时间 |
|
||
| updated_at | datetime | 更新时间 |
|
||
|
||
### Message(消息)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | UUID | 主键 |
|
||
| conversation_id | UUID | 外键 |
|
||
| role | enum | user / assistant / system |
|
||
| content | text | 消息内容 |
|
||
| created_at | datetime | 创建时间 |
|
||
|
||
### CustomerProfile(客户画像 — AI逐步填充)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | UUID | 主键 |
|
||
| conversation_id | UUID | 外键(一对一) |
|
||
| raw_info | JSON | AI自然收集的所有信息,灵活结构 |
|
||
| summary | text | AI生成的客户画像摘要 |
|
||
| updated_at | datetime | 更新时间 |
|
||
|
||
### Evaluation(意向评估 — 对话结束时生成)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | UUID | 主键 |
|
||
| conversation_id | UUID | 外键(一对一) |
|
||
| intent_level | enum | interested / not_interested / pending |
|
||
| reasoning | text | AI的判断依据 |
|
||
| contact_info | JSON | 提取的联系方式(手机/微信/邮箱) |
|
||
| email_sent | boolean | 是否已发送邮件 |
|
||
| evaluated_at | datetime | 评估时间 |
|
||
|
||
## 3. 会话流程
|
||
|
||
```
|
||
客户进入 → 创建 Conversation
|
||
│
|
||
▼
|
||
[对话阶段] AI自然对话,不预设字段
|
||
│ 每轮对话后,AI在后台提取信息填充 raw_info
|
||
│ AI自主判断:信息是否足够评估意向?
|
||
│
|
||
├── 信息不足 → 继续对话(引导提问)
|
||
│
|
||
└── 信息足够 → [评估阶段]
|
||
AI生成客户画像 summary
|
||
判定 intent_level
|
||
│
|
||
├── interested → 提取联系方式 → 发送邮件 → 结束
|
||
├── not_interested → 记录归档 → 结束
|
||
└── pending → 标记待定,不发邮件(信息不足无法判断) → 结束
|
||
```
|
||
|
||
### 关键设计点
|
||
|
||
- `raw_info` 是灵活JSON,不锁死字段,AI对话中发现什么就记什么
|
||
- 联系方式由AI从对话中自然提取,不强求客户填写表单
|
||
- 对话可随时中断,系统保存已有信息,客户回来可继续
|
||
|
||
## 4. 前端设计
|
||
|
||
### 三种使用场景
|
||
|
||
#### 独立聊天页面
|
||
|
||
- 完整的全屏聊天界面
|
||
- FastAPI直接托管静态HTML
|
||
- 访问域名(如 chat.yourdomain.com)直接使用
|
||
|
||
#### iframe嵌入
|
||
|
||
- 在网站任意位置用 `<iframe>` 标签嵌入完整聊天界面
|
||
- 适合官网内嵌
|
||
|
||
#### JS Widget悬浮窗
|
||
|
||
- 一段JS代码嵌入任意网站
|
||
- 右下角悬浮气泡,点击展开聊天窗口
|
||
- 使用 Shadow DOM 做样式隔离,不影响宿主页面
|
||
- 可配置参数:位置(四角)、主题色、标题文案、自动展开等
|
||
|
||
```html
|
||
<!-- 其他网站只需加这段代码 -->
|
||
<script>
|
||
(function(w,d,s,o){
|
||
var j=d.createElement(s);j.async=true;
|
||
j.src="https://your-domain.com/widget.js";
|
||
j.setAttribute('data-position','bottom-right');
|
||
j.setAttribute('data-theme','light');
|
||
j.setAttribute('data-title','AI汽车顾问');
|
||
d.head.appendChild(j);
|
||
})(window,document,'script');
|
||
</script>
|
||
```
|
||
|
||
### Widget技术实现
|
||
|
||
Widget JS加载后:创建 Shadow DOM(样式隔离) → 注入悬浮气泡按钮 → 点击后通过WebSocket连接后端 → 渲染聊天界面。
|
||
|
||
## 5. AI服务设计
|
||
|
||
### 模型适配层
|
||
|
||
```python
|
||
class AIProvider(ABC):
|
||
async def chat(messages, system_prompt) -> str
|
||
async def chat_with_extraction(messages, system_prompt, extract_fields) -> tuple[str, dict]
|
||
|
||
class GLMProvider(AIProvider) # 智谱GLM(初期)
|
||
class OpenAIProvider(AIProvider) # 预留
|
||
class DeepSeekProvider(AIProvider) # 预留
|
||
```
|
||
|
||
### 三轮调用机制
|
||
|
||
每轮客户消息到达后,后端做三件事(对客户透明):
|
||
|
||
1. **主对话调用** → AI回复客户(自然对话,引导收集信息)
|
||
2. **信息提取调用**(后台静默)→ 从对话历史中提取已获得的信息,更新raw_info
|
||
3. **意向判断调用**(后台静默)→ 评估当前信息是否足够,决定是否结束对话
|
||
|
||
第2、3步使用同一个GLM模型和完整prompt,确保提取和判断质量。第3步判断信息足够时,主对话引导收尾并提取联系方式。
|
||
|
||
### Prompt策略
|
||
|
||
- **System Prompt** — AI角色为「二手车顾问」,对话风格专业但亲切,发问策略自然引导
|
||
- **信息提取Prompt** — 从对话历史中提取结构化信息,输出JSON
|
||
- **评估Prompt** — 根据已有信息判断意向等级,输出intent_level + 理由
|
||
|
||
### 会话上下文管理
|
||
|
||
- 短期上下文:Redis缓存最近N轮对话(实时对话用)
|
||
- 完整历史:每轮对话后持久化到数据库
|
||
- 上下文窗口控制:对话过长时自动摘要早期对话,避免token超限
|
||
|
||
### 防流失机制
|
||
|
||
- 客户关闭页面后,Redis会话保留24小时
|
||
- 同一浏览器再次打开,自动恢复上次对话
|
||
- 对话中断但已收集部分信息,标记为`pending`,不发邮件但记录归档
|
||
|
||
## 6. 邮件推送
|
||
|
||
### 流程
|
||
|
||
```
|
||
AI判定意向 = interested
|
||
│
|
||
▼
|
||
组装邮件内容
|
||
├── 客户画像摘要(AI生成)
|
||
├── 关键需求提取(预算、偏好、用途等)
|
||
├── 联系方式(手机/微信/邮箱)
|
||
├── 完整对话记录(可折叠)
|
||
└── 评估理由
|
||
│
|
||
▼
|
||
SMTP发送 → 目标邮箱
|
||
│
|
||
▼
|
||
记录发送状态(成功/失败/重试)
|
||
```
|
||
|
||
### 配置(环境变量)
|
||
|
||
- `SMTP_HOST` / `SMTP_PORT` — SMTP服务器
|
||
- `SMTP_USER` / `SMTP_PASS` — 认证信息
|
||
- `NOTIFY_EMAIL` — 目标通知邮箱
|
||
|
||
## 7. 项目结构
|
||
|
||
```
|
||
cc_ai_kefu/
|
||
├── docker-compose.yml
|
||
├── Dockerfile
|
||
├── .env.example
|
||
├── app/
|
||
│ ├── main.py # FastAPI入口
|
||
│ ├── config.py # 配置管理
|
||
│ ├── api/
|
||
│ │ ├── routes/
|
||
│ │ │ ├── chat.py # WebSocket聊天端点
|
||
│ │ │ └── webhook.py # 回调/状态查询API
|
||
│ │ └── deps.py # 依赖注入
|
||
│ ├── services/
|
||
│ │ ├── ai_service.py # AI模型适配层
|
||
│ │ ├── conversation.py # 对话管理(三轮调用)
|
||
│ │ ├── extractor.py # 信息提取
|
||
│ │ ├── evaluator.py # 意向评估
|
||
│ │ └── email_service.py # 邮件发送
|
||
│ ├── models/
|
||
│ │ ├── conversation.py # SQLAlchemy模型
|
||
│ │ └── schemas.py # Pydantic schemas
|
||
│ ├── providers/
|
||
│ │ ├── base.py # AIProvider基类
|
||
│ │ └── glm.py # 智谱GLM实现
|
||
│ └── prompts/
|
||
│ ├── system.md # 主对话system prompt
|
||
│ ├── extractor.md # 信息提取prompt
|
||
│ └── evaluator.md # 评估prompt
|
||
├── static/ # 前端静态文件
|
||
│ ├── chat.html # 独立聊天页面
|
||
│ ├── css/
|
||
│ ├── js/
|
||
│ │ └── chat.js # 聊天核心逻辑
|
||
│ └── widget.js # 外部嵌入Widget脚本
|
||
├── migrations/ # 数据库迁移
|
||
└── tests/
|
||
```
|
||
|
||
## 8. 技术栈
|
||
|
||
| 层 | 选型 |
|
||
|---|---|
|
||
| 后端框架 | FastAPI + Uvicorn |
|
||
| 数据库 | SQLite(初版)/ PostgreSQL(生产) |
|
||
| 缓存 | Redis |
|
||
| ORM | SQLAlchemy + Alembic |
|
||
| AI SDK | 智谱GLM SDK(zhipuai) |
|
||
| 邮件 | aiosmtplib(异步SMTP) |
|
||
| 前端 | 原生HTML/CSS/JS,无框架 |
|
||
| 部署 | Docker Compose(FastAPI + Redis) |
|