49c0e5559c
Co-Authored-By: Claude Code <noreply@anthropic.com>
11 KiB
11 KiB
二手汽车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 做样式隔离,不影响宿主页面
- 可配置参数:位置(四角)、主题色、标题文案、自动展开等
<!-- 其他网站只需加这段代码 -->
<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服务设计
模型适配层
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) # 预留
三轮调用机制
每轮客户消息到达后,后端做三件事(对客户透明):
- 主对话调用 → AI回复客户(自然对话,引导收集信息)
- 信息提取调用(后台静默)→ 从对话历史中提取已获得的信息,更新raw_info
- 意向判断调用(后台静默)→ 评估当前信息是否足够,决定是否结束对话
第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) |