# AI Customer Service 功能清单（按钮级任务版）

> 版本：v1.0
> 日期：2026-04-27
> 说明：每个任务 5 分钟可完成，可直接安排进任务管理

---

## Phase 1：Widget 渠道 + RAG 知识库 + 基础对话

### 模块 1.1：网页 Widget 接入

#### 1.1.1 Widget 嵌入
- [ ] **任务**：实现 Widget 组件（HTML snippet + JS），可通过 `<script>` 标签嵌入任意网页
- [ ] **任务**：Widget 组件渲染浮动按钮（右下角，点击展开对话窗口）
- [ ] **任务**：对话窗口渲染：标题栏（"智能客服"）/ 消息区（滚动）/ 输入框（支持 Enter 发送）/ 发送按钮
- [ ] **任务**：实现 Widget 最小化按钮，点击后收起为悬浮球
- [ ] **任务**：实现 Widget 消息气泡：用户消息（右侧蓝色）/ 机器人消息（左侧灰色）
- [ ] **任务**：机器人消息支持 Markdown 格式渲染（支持代码块、粗体、链接）
- [ ] **任务**：机器人消息支持展示链接按钮（点击可跳转外部页面）

#### 1.1.2 Webhook 对接
- [ ] **任务**：实现 Widget Webhook 端点 `POST /api/v1/ai-customer-service/webhook/widget`
- [ ] **任务**：Webhook 接收消息后，解析 `session_id`（从 cookie 或 localStorage 生成）、`user_message`、`channel=widget`
- [ ] **任务**：Webhook 返回 HTTP 200（异步处理模式），消息处理结果通过 WebSocket 推送回 Widget
- [ ] **任务**：实现 WebSocket 连接管理（Widget 端建立长连接 `/ws/widget`）

### 模块 1.2：对话引擎

#### 1.2.1 意图识别
- [ ] **任务**：实现 `IntentEngine.Recognize()` 接口，输入用户消息，输出意图 + 置信度
- [ ] **任务**：实现意图分类列表：api_key_管理 / 模型路由配置 / 配额计费 / 错误码诊断 / 账户问题 / 转人工
- [ ] **任务**：实现置信度计算，阈值：>=0.85 = 高置信 / 0.60-0.85 = 中置信 / <0.60 = 低置信
- [ ] **任务**：低置信度意图自动触发转人工流程
- [ ] **任务**：实现"退款/账户封禁/数据泄露"等敏感意图识别（关键词匹配 + 意图分类），命中时强制转人工

#### 1.2.2 RAG 检索
- [ ] **任务**：实现知识库向量库初始化脚本（使用 Qdrant / PGVector），接入产品文档内容
- [ ] **任务**：实现 `RAGEngine.Retrieve(query, top_k)` 接口，输入用户问题，输出 top_k 相关知识库片段
- [ ] **任务**：RAG 检索使用混合策略：sentence embedding（语义）+ keyword match（关键词兜底）
- [ ] **任务**：实现检索结果重排序（使用 cross-encoder 对 top_k*2 结果重新打分，取 top_k）
- [ ] **任务**：RAG 检索 P99 延迟目标 <200ms

#### 1.2.3 回复生成
- [ ] **任务**：实现 `ReplyGenerator.Generate(ctx, intent, rag_results, conversation_history)` 接口
- [ ] **任务**：Prompt 模板：System Prompt（你是立连桥智能客服，专回答产品使用问题，只引用知识库内容）+ User Query + RAG 结果 + 对话历史
- [ ] **任务**：实现回复 Markdown 渲染（飞书/企微渠道），代码示例使用语法高亮
- [ ] **任务**：涉及用户个人数据查询时，在 Prompt 中注入 `user_id`，强制模型只返回当前用户数据
- [ ] **任务**：实现回复缓存（Redis，相同意图+相同用户问题的回复缓存 5 分钟）

### 模块 1.3：会话管理

#### 1.3.1 会话状态机
- [ ] **任务**：实现会话状态枚举：initializing / waiting / bot_replied / waiting_human / closed
- [ ] **任务**：实现会话超时逻辑：用户 30 分钟无消息 → 自动发送"还在吗？"；仍无回复 → 30 分钟后关闭会话
- [ ] **任务**：实现会话关闭事件记录：用户点击"已解决"或超时关闭 → 记录 `session_resolved`

#### 1.3.2 上下文管理
- [ ] **任务**：实现上下文窗口：保留最近 5 轮对话（用户+机器人各 5 条）
- [ ] **任务**：上下文存储在 Redis（Key = `cs:session:{session_id}`，TTL = 24 小时）
- [ ] **任务**：实现跨会话用户识别：Widget 用户首次访问时生成 `anonymous_id` 存入 cookie

### 模块 1.4：知识库管理

#### 1.4.1 知识库后台
- [ ] **任务**：实现知识库管理页路由 `/cs/dashboard/knowledge`
- [ ] **任务**：知识库列表每行显示：条目ID / 标题 / 分类 / 覆盖意图 / 引用次数 / 状态 / 操作
- [ ] **任务**：渲染"新增条目"按钮，点击进入条目编辑器
- [ ] **任务**：知识库编辑器字段：标题（必填）/ 分类（下拉：API Key/路由/配额/错误码/账户/其他）/ 正文（Markdown 富文本）/ 覆盖意图标签（多选）/ 状态（草稿/发布）
- [ ] **任务**：编辑器实现 Markdown 实时预览
- [ ] **任务**：条目发布后，自动触发向量库更新（异步，30 秒内生效）
- [ ] **任务**：每个知识库条目支持上传附件（PDF/图片），附件存储在 OSS
- [ ] **任务**：知识库列表支持按分类筛选 / 按标题搜索 / 按引用次数排序

#### 1.4.2 知识库导入导出
- [ ] **任务**：实现"批量导入"按钮，支持上传 Markdown zip 包批量导入条目
- [ ] **任务**：实现"导出全部"按钮，导出为 Markdown zip 包

---

## Phase 2：Telegram + Discord + 意图识别 + 转人工

### 模块 2.1：多渠道接入适配

#### 2.1.1 Telegram Bot 接入
- [ ] **任务**：申请 Telegram Bot（通过 @BotFather），获取 Bot Token
- [ ] **任务**：实现 Telegram Webhook 端点 `POST /api/v1/ai-customer-service/webhook/telegram`
- [ ] **任务**：Webhook 解析 Telegram Update：提取 `chat.id`（作为 user_id）、`message.text`（作为 user_message）
- [ ] **任务**：实现 Telegram 回复方法：调用 Bot API `sendMessage`，传入 `chat.id` 和回复内容
- [ ] **任务**：实现 Telegram 消息格式化：Markdown → Telegram MarkdownV2 格式转换
- [ ] **任务**：在 Gateway 配置 Telegram Bot Webhook URL 指向本系统

#### 2.1.2 Discord Bot 接入
- [ ] **任务**：创建 Discord Application，开通 Bot 功能，获取 Bot Token
- [ ] **任务**：实现 Discord Webhook 端点 `POST /api/v1/ai-customer-service/webhook/discord`
- [ ] **任务**：Webhook 解析 Discord interaction：提取 `channel_id` / `member.user.id` / `content`
- [ ] **任务**：实现 Discord 回复方法：调用 Discord Webhook API 或 Bot sendMessage
- [ ] **任务**：Discord 支持 slash command（如 `/客服问题`）触发对话
- [ ] **任务**：在 Gateway 配置 Discord Webhook 指向本系统

#### 2.1.3 统一消息格式
- [ ] **任务**：实现 `ChannelAdapter` 接口族（TelegramAdapter / DiscordAdapter / WidgetAdapter / WechatAdapter）
- [ ] **任务**：每个 Adapter 将各自渠道的消息格式统一转换为 `UnifiedMessage`（包含：message_id / channel / open_id / user_id / content / timestamp）
- [ ] **任务**：实现统一会话 ID 生成规则：`{channel}:{open_id}`

### 模块 2.2：身份核验

#### 2.2.1 绑定用户身份识别
- [ ] **任务**：实现 `GET /api/v1/ai-customer-service/auth/check?channel={ch}&open_id={id}` 接口，返回绑定状态
- [ ] **任务**：已绑定用户：返回 `{bound: true, user_id: "xxx"}`
- [ ] **任务**：未绑定用户：返回 `{bound: false}`，触发身份核验流程

#### 2.2.2 邮箱验证码核验
- [ ] **任务**：未绑定用户输入邮箱后，点击"验证"按钮，POST `/api/v1/ai-customer-service/auth/verify-code/send`
- [ ] **任务**：后端验证邮箱是否存在（调用 `supply-api` 的邮箱查询接口），存在则发送 6 位数字验证码（有效期 5 分钟）
- [ ] **任务**：用户输入验证码，POST `/api/v1/ai-customer-service/auth/verify-code/check`
- [ ] **任务**：验证成功后，将 `{channel, open_id, user_id}` 写入 `cs_user_bindings` 表
- [ ] **任务**：验证失败 3 次后，自动触发转人工工单（标签：identity_verification_failed）

#### 2.2.3 API Key 前缀核验
- [ ] **任务**：用户输入 API Key 前缀，POST `/api/v1/ai-customer-service/auth/apikey/lookup`
- [ ] **任务**：后端用前缀模糊查询 `supply_api_keys` 表（前 8 位），返回匹配到的账户列表（隐藏中间位）
- [ ] **任务**：若匹配到 1 个 → 直接绑定；若匹配到多个 → 要求补充邮箱二次确认；若 0 个 → 提示"未找到账户"
- [ ] **任务**：验证过程不存储用户输入的完整 API Key，仅记录前缀用于关联

### 模块 2.3：转人工流程

#### 2.3.1 触发转人工
- [ ] **任务**：实现转人工触发条件检测：a）用户发送"人工客服/找人工/投诉"关键词 b）意图置信度 <0.60 c）身份核验失败 3 次 d）用户反馈"未解决"累计 3 轮
- [ ] **任务**：触发转人工时，更新会话状态 = waiting_human
- [ ] **任务**：触发转人工时，显示机器人消息："正在为您转接人工客服，请稍候..."

#### 2.3.2 工单生成
- [ ] **任务**：触发转人工时，自动写入 `cs_tickets` 表（字段：ticket_id / session_id / user_id / channel / priority / status=open / created_at / 原始问题 / 会话历史摘要）
- [ ] **任务**：转人工时，若用户处于多轮对话，附加最近 5 轮对话历史到工单 `conversation_history` 字段
- [ ] **任务**：触发转人工时，发送飞书通知到客服群（包含用户ID/渠道/问题摘要/排队位置）
- [ ] **任务**：实现 `GET /api/v1/ai-customer-service/tickets/queue-position?ticket_id={id}`，返回当前排队人数

#### 2.3.3 人工接管
- [ ] **任务**：客服人员点击"接单"按钮，POST `/api/v1/ai-customer-service/tickets/{id}/accept`
- [ ] **任务**：接单后，工单状态更新为 processing，locked_by = 客服ID
- [ ] **任务**：机器人向用户发送："人工客服已接单，预计 {X} 分钟内回复"
- [ ] **任务**：客服在工单处理页发送消息，POST `/api/v1/ai-customer-service/tickets/{id}/reply`，消息推送给用户

---

## Phase 3：微信渠道 + 用户数据查询 + 工单后台

### 模块 3.1：微信接入

#### 3.1.1 微信公众号 Webhook
- [ ] **任务**：配置微信公众号服务器地址（URL + Token + EncodingAESKey）
- [ ] **任务**：实现微信公众号 Webhook 验证（GET 请求，验证 Token）
- [ ] **任务**：实现微信公众号消息接收 `POST /api/v1/ai-customer-service/webhook/wechat`
- [ ] **任务**：解析微信 XML 消息格式：提取 `FromUserName`（作为 open_id）、`MsgType`、`Content`
- [ ] **任务**：实现被动回复（用户发消息后，微信服务端在 5 秒内必须回复，否则重试）
- [ ] **任务**：支持接收事件推送（用户关注/取关）

#### 3.1.2 微信公众号客服消息
- [ ] **任务**：实现模板消息发送（用于通知类消息，如工单状态变更）
- [ ] **任务**：客服在后台发送的消息，通过微信公众号客服消息接口推送（调用 `https://api.weixin.qq.com/cgi-bin/message/custom/send`）

### 模块 3.2：用户数据查询（只读）

#### 3.2.1 Token 消耗查询
- [ ] **任务**：用户发送"我的 Token 消耗是多少"，识别意图为 quota_check
- [ ] **任务**：后端调用 `GET /api/v1/ai-customer-service/diagnostics/token-usage?user_id={uid}&date=today`
- [ ] **任务**：内部调用 `platform-token-runtime` 的只读接口获取今日 Token 消耗
- [ ] **任务**：机器人回复格式："今日已消耗 {N} Tokens，剩余配额 {M} Tokens（{percent}%）"

#### 3.2.2 错误日志诊断
- [ ] **任务**：用户发送"我的请求报错了"或错误码，识别意图为 error_diagnosis
- [ ] **任务**：后端调用 `GET /api/v1/ai-customer-service/diagnostics/recent-errors?user_id={uid}&limit=5`
- [ ] **任务**：内部调用 `supply-api` 的只读接口获取用户最近 5 条错误日志
- [ ] **任务**：机器人回复展示：请求时间 / 错误码 / 错误描述 / 建议操作

#### 3.2.3 供应商状态查询
- [ ] **任务**：用户发送"供应商X是不是挂了"，识别意图为 supplier_status_check
- [ ] **任务**：后端调用 `GET /api/v1/ai-customer-service/diagnostics/supplier-status?supplier={name}`
- [ ] **任务**：内部调用 `supply-intelligence` 的供应商状态 API
- [ ] **任务**：机器人回复格式："供应商 {X} 当前状态：正常运行（延迟 {N}ms）/ 部分可用（{详情}）"

### 模块 3.3：工单后台

#### 3.3.1 工单列表页
- [ ] **任务**：实现工单列表页路由 `/cs/dashboard/tickets`
- [ ] **任务**：工单列表顶部渲染状态 Tab：全部 / 待处理（open）/ 处理中（processing）/ 已关闭（closed）
- [ ] **任务**：工单列表顶部渲染优先级 Tab：全部 / P1（红色）/ P2（橙色）/ P3（灰色）
- [ ] **任务**：工单列表每行显示：工单ID / 用户ID / 渠道图标 / 问题摘要 / 优先级 / 状态 / 等待时长 / 客服 / 创建时间
- [ ] **任务**：工单行按优先级（P1>P2>P3）和等待时长升序排列
- [ ] **任务**：工单行渲染"接单"按钮（仅 open 状态且未锁定的工单可见）
- [ ] **任务**：工单行渲染"查看"按钮，点击进入工单详情页

#### 3.3.2 工单详情页
- [ ] **任务**：工单详情页路由 `/cs/dashboard/tickets/{ticket_id}`
- [ ] **任务**：详情页左侧渲染会话历史时间线（用户消息+机器人回复+系统消息）
- [ ] **任务**：详情页右侧渲染工单信息面板：用户ID / 渠道 / 优先级 / 状态 / 等待时长 / 关联会话数
- [ ] **任务**：详情页底部渲染回复输入框（支持 Markdown + 附件上传）+ "发送"按钮
- [ ] **任务**：发送回复后，通过对应渠道推送给用户
- [ ] **任务**：详情页渲染"关闭工单"按钮（仅 processing 状态），点击后确认，确认后状态 = closed
- [ ] **任务**：详情页渲染"转交"按钮（选择其他客服接手）

#### 3.3.3 统计分析
- [ ] **任务**：实现统计页路由 `/cs/dashboard/stats`
- [ ] **任务**：统计页渲染转人工原因分布饼图（Top 10）
- [ ] **任务**：统计页渲染每日会话量柱状图（近 30 天）
- [ ] **任务**：统计页渲染自助解决率趋势折线图（近 30 天）
- [ ] **任务**：统计页渲染平均首次响应时长趋势（近 30 天）
- [ ] **任务**：统计页渲染知识库未命中率趋势（近 30 天）

### 模块 3.4：模型 Failover

#### 3.4.1 多模型配置
- [ ] **任务**：实现模型配置页路由 `/cs/dashboard/settings/models`
- [ ] **任务**：模型列表每行显示：模型名称 / 类型（主/备） / 供应商 / 状态（启用/禁用） / 操作
- [ ] **任务**：渲染"添加备选模型"按钮，点击后弹出配置表单（模型名称 / API Endpoint / API Key / 优先级）
- [ ] **任务**：模型配置支持拖拽排序（设置优先级顺序）

#### 3.4.2 Failover 执行
- [ ] **任务**：主模型 API 调用超时（5 秒内无响应）→ 自动切换到优先级最高的可用备模型
- [ ] **任务**：主模型 API 返回 5xx → 自动切换到备模型，记录 failover 事件
- [ ] **任务**：备模型也失败时（双故障）→ 返回兜底静态回复 + 生成工单
- [ ] **任务**：Failover 事件写入 `cs_model_failover_events` 表（字段：session_id / from_model / to_model / reason / occurred_at）

#### 3.4.3 兜底回复
- [ ] **任务**：预配置兜底回复模板（静态文本，不依赖大模型）
- [ ] **任务**：双故障时返回兜底回复："抱歉，当前客服系统繁忙，请稍后再试，或联系 support@example.com"
- [ ] **任务**：双故障时，飞书通知技术负责人（P1 告警）

---

## 全局模块

### 模块 G1：权限与认证
- [ ] **任务**：实现 JWT 认证中间件（与立连桥统一认证打通）
- [ ] **任务**：实现客服角色：客服（处理工单）/ 运营（知识库+统计）/ 管理员（全部）
- [ ] **任务**：权限不足返回 HTTP 403，错误码 `CS_AUTH_1001`

### 模块 G2：健康检查
- [ ] **任务**：实现 `GET /actuator/health` / `/actuator/health/live` / `/actuator/health/ready`
- [ ] **任务**：Readiness probe 检查：PostgreSQL 连接 + Redis 连接 + Qdrant 连接

### Module G3: OpenAPI
- [ ] **任务**：实现 Swagger UI 路由 `/docs`
- [ ] **任务**：实现 OpenAPI 3.0 spec 端点 `/openapi.json`

### 模块 G4：Webhook 安全
- [ ] **任务**：实现 Telegram Webhook Secret Token 校验（X-Telegram-Bot-Api-Secret-Token）
- [ ] **任务**：实现 Discord Request Signature 校验（X-Signature-Ed25519）
- [ ] **任务**：实现微信消息体签名校验（msg_signature）
- [ ] **任务**：校验失败返回 HTTP 403

---

## 技术基础设施

### T1：项目骨架
- [ ] **任务**：初始化 Go module `github.com/lijiaoliao/ai-customer-service`
- [ ] **任务**：创建 `cmd/ai-customer-service/main.go`，支持 `api` 和 `worker` 两种运行模式
- [ ] **任务**：创建 `internal/` 目录结构（domain/service/handler/infrastructure/repository）
- [ ] **任务**：配置 Viper 读取 `config.yaml`
- [ ] **任务**：配置 `log/slog` 结构化日志
- [ ] **任务**：创建 PostgreSQL schema migration，表前缀 `cs_`
- [ ] **任务**：配置 Redis 连接池
- [ ] **任务**：配置 Dockerfile 和 docker-compose.yml

### T2：单元测试
- [ ] **任务**：为 domain 层函数编写单元测试，覆盖率 >= 70%
- [ ] **任务**：为 service 层函数编写单元测试，覆盖率 >= 80%
- [ ] **任务**：配置 GitHub Actions CI

### T3：IntegrationPlugin 接口
- [ ] **任务**：实现 `IntegrationPlugin` 接口
- [ ] **任务**：实现插件模式下各渠道的开关配置
- [ ] **任务**：实现 Webhook 路径前缀可配置（默认 `/api/v1/ai-customer-service/`）

---

## 任务估算汇总

| Phase | 模块 | 任务数 | 估计工时 |
|-------|------|--------|---------|
| Phase 1 | 1.1 Widget + 1.2 对话引擎 + 1.3 会话 + 1.4 知识库 | 38 | 5 人天 |
| Phase 2 | 2.1 TG/Discord + 2.2 身份核验 + 2.3 转人工 | 30 | 4 人天 |
| Phase 3 | 3.1 微信 + 3.2 数据查询 + 3.3 工单后台 + 3.4 Failover | 38 | 5 人天 |
| 全局 | G1 权限 + G2 健康 + G3 文档 + G4 Webhook安全 | 14 | 1.5 人天 |
| 技术基础设施 | T1 骨架 + T2 测试 + T3 插件 | 12 | 1.5 人天 |
| **合计** | | **132** | **~17 人天** |
