Files
crm-ai/docs/go-live.md
T

560 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CRM-NEW 上线文档
| 项 | 内容 |
|---|---|
| 上线日期 | 2026-10-23 |
| 上线范围 | 方案 A:bridge 接管 Live chat AI;Email/WhatsApp 人工处理 |
| 当前状态 | Live chat 已切 bridge AI;Email/WhatsApp 已切人工团队;Twenty 商机已打通 |
| 变更窗口 | 建议低峰期,预留 30–60 分钟 |
| 负责人 | 待填 |
---
## 1. 上线范围
### 上线内容
- LibreDesk:Live chat / Email / WhatsApp 三个渠道
- bridge AI:Live chat 的 LLM、工具、RAG、OTP、输出护栏、质量指标
- Twenty CRM:联系人、公司、商机、备注、3 天跟进任务
- Email/WhatsApp:不再由 AI 回复,进入 `Wholesale Support` 人工团队
- 旧 bridge KB:Hybrid RAG(parent-child + 向量 + 全文 + RRF)
- 全量商品页 sitemap:www 32,691 / us 22,625
- 质量:逐会话指标、URL/数字审计、质量日报、离线评测
### 不在本次上线范围
- Email / WhatsApp 的 bridge AI 回复
- WhatsApp 模板消息 / 媒体 / 语音
- 邮件每日 digest
- A/B 实验
- 多副本/高可用部署
- PII 自动保留/删除策略
- 真实客户邮件历史 ingest(当前 `kb_mail_docs` 只有测试邮件)
---
## 2. 当前架构
```
Live chat (inbox 1)
LibreDesk widget
→ LibreDesk webhook message.created
→ bridge /libredesk/webhook
→ bridge AI(LLM + 工具 + RAG + OTP + 输出护栏)
→ LibreDesk API 回写 agent 消息
Email (inbox 2) / WhatsApp (inbox 3)
→ LibreDesk 自动化规则
→ assign_team = Wholesale Support
→ 人工团队队列
→ 不调用 AI
```
---
## 2.1 环境差异(本地开发 vs 测试/生产)
> 详见 [environments.md](environments.md)。
- `scripts/rpc-tunnel.sh`:**仅本地开发**,因为 RPC 端口外网不可达
- `scripts/public-https.sh`:**仅本地联调**,Cloudflare Quick Tunnel
- 测试/生产:RPC 直接配内网地址,公网 HTTPS 用正式域名 + Ingress/Nginx/ALB
- 测试/生产不应运行上述两个脚本
---
## 3. 访问入口
| 服务 | 地址 | 备注 |
|---|---|---|
| LibreDesk | `http://localhost:9000` | 管理端 / 工作台 |
| Twenty CRM | `http://localhost:3100` | CRM |
| bridge | `http://localhost:4100` | 内部工具/健康检查 |
| Widget 测试页 | `http://localhost:8088/demo.html` | 本机测试用 |
| 公网入口 | `.env` 的 `PUBLIC_BASE_URL` | Cloudflare Quick Tunnel,**URL 会变** |
| Postgres | `localhost:5440` | 仅本机 |
| Redis | `localhost:6390` | 仅本机 |
| IMAP proxy | `localhost:1993` | 仅本机 |
---
## 4. 当前切流配置
### Live chat
| 项 | 状态 |
|---|---|
| bridge webhook | 启用 |
| LibreDesk 规则 1“分配新会话给 AI Assistant” | 关闭 |
| bridge inbox 过滤 | `LIBREDESK_WEBHOOK_INBOX_IDS=1` |
### Email / WhatsApp
| 项 | 状态 |
|---|---|
| 团队 | `Wholesale Support`(id=1) |
| 团队类型 | `Round robin` |
| 成员 | agent1 (26)、agent2 (27) |
| 规则 4 | Email inbox 2 → assign_team 1 |
| 规则 5 | WhatsApp inbox 3 → assign_team 1 |
| AI Assistant 分配 | 已移除 |
> agent1/agent2 当前是 `offline`。Round robin 只有坐席在线/可用时才会进一步分到个人;离线时停留在团队队列。若希望永远只进团队队列,可把团队类型改为 `Manual`。
---
## 5. 上线前检查
- [ ] `.env` 已备份,且权限为 `600`
- [ ] `docker compose config -q` 通过
- [ ] 本地开发:RPC 隧道可用;测试/生产:RPC 内网地址可直达
- [ ] LibreDesk webhook `Bridge AI` 为启用状态
- [ ] LibreDesk 规则 1 关闭
- [ ] 规则 4/5 指向 `Wholesale Support`
- [ ] agent1/agent2 可登录,必要时设为在线
- [ ] WhatsApp access token 未过期(当前 token 有到期时间)
- [ ] 本地开发:Quick Tunnel 与 Meta webhook 已同步;测试/生产:正式域名与 Meta webhook 已同步
- [ ] 163 SMTP / IMAP 可用
- [ ] 已做数据库备份
- [ ] bridge 测试通过
- [ ] 质量告警 cron 已配置(或本次上线后立即配置)
---
## 6. 部署/启动步骤
### 6.1 当前机器上启动
```bash
cd /home/dev/code/crm-new
# 1) 校验 compose
docker compose config -q
# 2) 启动/更新
docker compose up -d
# 3) 重建 bridge(代码变更时必须)
docker compose up -d --build --force-recreate bridge
# 4) 查看状态
docker compose ps
```
### 6.2 首次部署/新环境
```bash
cd /home/dev/code/crm-new
bash scripts/bootstrap.sh
```
首次部署后还需要:
```bash
node scripts/setup-defaults.js
node scripts/twenty-bootstrap.js
node scripts/register-tools.js
node scripts/configure-email.js
```
> 已有环境不要直接重跑 `bootstrap.sh`,会覆盖 `.env`/配置。
### 6.3 数据准备
#### 有旧 bridge / 旧 products 库时
```bash
# 重建 KB parent-child 索引(KB 更新后;会先备份旧表)
bash scripts/rebuild-kb-index.sh
# 旧 KB 补 text_tsv/parent_id(已执行过,幂等)
node scripts/upgrade-kb-schema.js
```
#### 测试/生产没有旧 bridge 时(推荐)
不要运行 `rebuild-kb-index.sh`。直接导入仓库里的 KB 快照:
```bash
# 默认导入到 crmnew-postgres / bridge 库
bash scripts/import-kb-snapshot.sh
# 或导入到 products 库
TARGET_PG_DB=products bash scripts/import-kb-snapshot.sh
# 验证
docker exec crmnew-postgres psql -U crmnew -d bridge -tAc \
"select count(*), count(*) filter (where chunk_type='parent'), count(*) filter (where chunk_type='child') from kb_docs;"
```
预期:
```
367 | 296 | 71
```
然后把测试环境 `.env` 的 `RAG_PG_URL` 指向该库,例如:
```env
RAG_PG_URL=postgres://crmnew:<password>@postgres:5432/bridge
```
> 快照文件:`deploy/seeds/kb_docs.sql.gz`(只包含 `kb_docs` 知识库,不含邮件/客户数据)
> 当前环境如需重新生成:`bash scripts/export-kb-snapshot.sh`
#### 在线 FAQ 同步(不依赖旧 bridge)
测试/生产如果网络可以访问官网 FAQ,可直接:
```bash
# 在宿主机执行时,RAG_PG_URL 用宿主机可达地址
RAG_PG_URL=postgres://crmnew:<password>@127.0.0.1:5440/bridge \
node scripts/sync-kb-online.js
# 如果脚本跑在 bridge 容器内,则用容器内地址
# RAG_PG_URL=postgres://crmnew:<password>@postgres:5432/bridge
```
建议 cron 每周一次:
```cron
0 3 * * 1 cd /home/dev/code/crm-new && RAG_PG_URL=... node scripts/sync-kb-online.js
```
如果官网抓取被 WAF 拦截,可先用本地源文件重建:
```bash
node scripts/sync-kb-online.js --local-only --force
```
注意:
- 需要 `RAG_PG_URL` 指向目标库
- 需要 `EMB_*`(DashScope embedding)
- 旧的 `kb_docs` 会备份为 `kb_docs_v<timestamp>`
- `bridge/kb/11-site-map.md` 目前是静态类目地图,不随官网自动更新
#### 全量商品页站点地图
```bash
node scripts/build-site-map.js www us
```
### 6.4 RPC 隧道(仅本地开发)
> 测试/生产不需要这一步;直接配置内网 RPC 地址即可。
本地 RPC 端口外网不可达时才需要:
```bash
bash scripts/rpc-tunnel.sh
```
隧道断了会导致 `search_products/search_orders/search_inventory` 失败。
### 6.5 公网 HTTPS / WhatsApp webhook(仅本地联调)
> 测试/生产不要用 Cloudflare Quick Tunnel;使用正式域名 + Ingress/Nginx/ALB + TLS。
本地联调:
```bash
bash scripts/public-https.sh
```
Cloudflare Quick Tunnel URL 每次重启可能变化,需要同步:
- LibreDesk `app.root_url`
- Meta WhatsApp callback URL
---
## 7. 验收清单
### 7.1 基础健康
```bash
curl -s http://localhost:4100/healthz
curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3100/healthz
cd bridge && npm test
```
预期:
- bridge `{"ok":true,...}`
- Twenty `200`
- tests **75/75**
### 7.2 Live chat JWT
```bash
node scripts/e2e-widget-jwt.js "What is the minimum order value?"
```
预期:
- AI 回复 €30
- 调用 `search_kb`
- 回复为 HTML
- 无未验证 URL
### 7.3 匿名 OTP
```bash
node scripts/e2e-anon-otp.js
```
预期:
- AI 先要求验证
- 收到验证码邮件
- 输入后 verified
- 能查订单(或明确无订单)
> 该脚本会读取 163 邮箱并创建测试会话,生产环境谨慎执行。
### 7.4 商机
```bash
node scripts/e2e-widget-jwt.js "I want to buy 500 pieces of stainless steel rings"
```
然后发:
```
Our company is Test Buyer BV, contact name Jan Jansen.
```
到 Twenty 检查:
- Company / Person / Opportunity
- Opportunity 名称为 `<company> — <need>`
- Note 已关联
- Task 3 天后到期
### 7.5 离线评测
```bash
node scripts/eval-offline.js
node scripts/eval-live.js
```
预期:
- 确定性评测 **18/18**
- 真实模型 smoke **4/4**
### 7.6 质量指标
```bash
node scripts/quality-report.js 24
node scripts/quality-alert.js 1 --dry-run
```
预期:
- 无错误/无未验证 URL 告警
- 当前健康时输出 `{"ok":true,...}`
---
## 8. 监控与告警
### 质量告警 cron
```cron
*/30 * * * * cd /home/dev/code/crm-new && node scripts/quality-alert.js 1 >> logs/quality-alert.log 2>&1
```
阈值:
- AI 错误率 > 10%
- 工具错误率 > 10%
- 未验证 URL 占比 > 15%
- 平均延迟 > 8000ms
### 必看日志
```bash
docker logs -f crmnew-bridge
docker logs -f crmnew-libredesk
docker logs -f crmnew-twenty-server
docker logs -f crmnew-cloudflared
```
bridge 关键日志:
- `webhook: message.created`
- `agent: tool`
- `agent: output_guard`
- `agent: replied`
- `crm: stage_advanced`
### 外部依赖巡检
- 本地开发:RPC 隧道进程
- 本地开发:Cloudflare tunnel 状态
- 测试/生产:内网 RPC 可达性、Ingress/证书、WhatsApp token 剩余有效期
- 163 SMTP/IMAP
- 未分配/团队队列积压
---
## 9. 日常运维
```bash
# 重启 bridge
docker compose restart bridge
# 重建 bridge
docker compose up -d --build --force-recreate bridge
# 查看资源
docker stats
# 数据库备份
docker exec crmnew-postgres pg_dump -U crmnew -d libredesk > backup-libredesk-$(date +%F).sql
docker exec crmnew-postgres pg_dump -U crmnew -d bridge > backup-bridge-$(date +%F).sql
docker exec crm-postgres pg_dump -U postgres -d products > backup-products-$(date +%F).sql
```
详细命令见 [runbook.md](runbook.md)。
---
## 10. 回滚方案
### 10.1 Live chat 回滚(最常用)
```bash
# 1) 停用 bridge webhook
# LibreDesk 后台 Webhooks → Bridge AI → 停用
# 2) 重新开启规则 1
# Automations → Assign new conversations to AI Assistant → 启用
# 3) 可选:停止 bridge
docker compose stop bridge
```
效果:Live chat 回到 LibreDesk 自带 AI。
### 10.2 Email / WhatsApp 回滚
```bash
# 规则 4/5 改回 assign_user = AI Assistant(id=3)
```
或直接停用规则 4/5,由人工在未分配队列处理。
### 10.3 数据回滚
- KB 旧表:`kb_docs_v1`
- rebuild 前备份:`kb_docs_backup_20261022`
- 恢复前先确认表结构/索引
- Twenty 测试数据删除需按 ID 精确操作,不要批量删
### 10.4 代码回滚
- 保留上一版 bridge 镜像/commit
- `docker compose up -d --build --force-recreate bridge`
- 回滚后必须重跑:
- `npm test`
- `scripts/eval-offline.js`
- 一条 Live chat smoke
---
## 11. 已知限制与风险
### 高
1. **单点**:bridge 只有一个实例;bridge 挂了 Live chat 无 AI 回复。
2. **RPC 隧道(仅本地开发)**:依赖本机 SSH 隧道,断了商品/订单/库存工具不可用。测试/生产应直连内网 RPC。
3. **公网 URL(仅本地开发)**:Cloudflare Quick Tunnel URL 不固定,重启可能失效。测试/生产使用正式域名。
4. **WhatsApp token**:临时 token 有到期时间,需要提前续期。
5. **Email 历史数据为空**:`kb_mail_docs` 只有测试邮件,真实客户历史未 ingest。
### 中
6. **商机币种**:`USD 1000` 目前存为 EUR。
7. **productNeed**:可能把整句需求写入商机名。
8. **输出护栏是规则型**:可能漏掉未覆盖措辞,或重写后语句略生硬。
9. **告警未落 cron/看板**:需要上线后配置。
10. **PII**:日志/指标可能包含客户消息片段;无自动保留/删除策略。
11. **agent1/agent2 offline**:Email/WhatsApp 会停在团队队列,需要人工上线/认领。
12. **bridge 4100 暴露在局域网**:建议防火墙限制,仅允许 LibreDesk/内网访问。
### 低
13. KB/索引/sitemap 仍以手动脚本刷新为主。
14. 无 A/B、无真实邮件 digest、无 WhatsApp 模板/媒体。
15. 无多副本/跨机高可用。
---
## 12. 上线后待办
| 优先级 | 事项 |
|---|---|
| P0 | 配置质量告警 cron + 确认邮件送达 |
| P0 | 确认 agent1/agent2 上线流程和团队队列 SLA |
| P0 | 续期 WhatsApp token、固定公网域名 |
| P1 | Email/WhatsApp bridge AI 切流 |
| P1 | 真实邮件 ingest + 索引 |
| P1 | 商机币种 + productNeed 归一 |
| P1 | 数据备份自动化 |
| P2 | 告警看板、离线评测接 CI |
| P2 | PII 保留/删除策略 |
| P3 | A/B 实验、WhatsApp 模板/媒体 |
---
## 13. 附录:关键配置
### bridge 关键环境变量
```
LIBREDESK_BASE_URL
LIBREDESK_API_KEY
LIBREDESK_API_SECRET
LIBREDESK_WEBHOOK_SECRET
LIBREDESK_WEBHOOK_INBOX_IDS=1
LLM_BASE_URL / LLM_API_KEY / LLM_MODEL
RAG_PG_URL
EMB_BASE_URL / EMB_API_KEY / EMB_MODEL / EMB_DIM
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_FROM
TWENTY_BASE_URL / TWENTY_API_KEY
```
### 关键数据表
- `libredesk`:conversations、messages、automation_rules、webhooks
- `bridge`:bridge_ai_metrics、bridge_llm_cache、bridge_site_map_urls
- `products`(旧 bridge 库):kb_docs、kb_mail_docs
### 关键脚本
```
scripts/bootstrap.sh
scripts/rpc-tunnel.sh # 仅本地开发
scripts/public-https.sh # 仅本地联调
scripts/build-site-map.js
scripts/rebuild-kb-index.sh
scripts/e2e-widget-jwt.js
scripts/e2e-anon-otp.js
scripts/eval-offline.js
scripts/eval-live.js
scripts/quality-report.js
scripts/quality-alert.js
```
---
## 14. 变更记录
| 日期 | 变更 | 操作人 |
|---|---|---|
| 2026-10-23 | 初版上线文档 | 待填 |