主要变更: - 新增 tests/test_ai_chat.py: AI Agent 对话测试工具 - 优化 core/pydantic_ai_agent.py 和 db/chat_log_db.py - 清理归档文件,更新文档 Made-with: Cursor
13 KiB
13 KiB
AI 客服系统 - 部署与运维文档
版本: v1.0 | 更新日期: 2026-02-28
目录
系统架构
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ 天网服务器 │ ───→ │ AI 客服 API │ ───→ │ 企业微信 │
│ (公网 IP) │ │ (127.0.0.1:6060)│ │ (轻简软件) │
└─────────────┘ └──────────────┘ └─────────────┘
↑ │
└─────────────────────┘
┌──────────────┐
│ SQLite │
│ 任务数据库 │
└──────────────┘
核心组件
| 组件 | 地址 | 说明 |
|---|---|---|
| AI 客服 HTTP API | http://127.0.0.1:6060 |
接收天网任务 |
| 天网服务器 | 公网 IP | 任务调度中心 |
| 轻简软件 | ws://127.0.0.1:9528 |
企业微信连接 |
| 任务数据库 | SQLite 本地存储 | 任务持久化 |
快速部署
步骤 1:环境检查
python3 --version # 需要 3.8+
cd /root/ai_customer_service/ai_cs
pip3 install -r requirements.txt
步骤 2:启动服务
cd /root/ai_customer_service/ai_cs
# 前台运行(测试用)
python3 run.py --api-only
# 后台运行(生产用)
nohup python3 run.py --api-only > /tmp/tianwang.log 2>&1 &
步骤 3:验证
curl http://localhost:6060/api/health
# 预期: {"code":200,"data":{"service":"ai-cs-tianwang-bridge",...},"message":"OK"}
启动方式
统一入口 run.py,通过参数切换模式:
# 仅 HTTP API(天网简化版,推荐)
python3 run.py --api-only
# 完整版(HTTP API + WebSocket + AI Agent)
python3 run.py --tianwang
# WebSocket 客服模式(默认)
python3 run.py
# 多进程模式
python3 run.py --multi --workers 4
# 不启用 AI Agent
python3 run.py --no-agent
# 指定 HTTP 端口
python3 run.py --api-only --port 8080
生产环境部署
方式 1:systemd 服务(推荐)
cat > /etc/systemd/system/ai-cs-tianwang.service << 'SERVICE'
[Unit]
Description=AI Customer Service with Tianwang
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/root/ai_customer_service/ai_cs
ExecStart=/usr/bin/python3 run.py --api-only
Restart=always
RestartSec=10
LimitNOFILE=65535
Environment="HTTP_API_PORT=6060"
StandardOutput=journal
StandardError=journal
SyslogIdentifier=ai-cs-tianwang
[Install]
WantedBy=multi-user.target
SERVICE
systemctl daemon-reload
systemctl enable ai-cs-tianwang
systemctl start ai-cs-tianwang
systemctl status ai-cs-tianwang
journalctl -u ai-cs-tianwang -f
方式 2:Docker 部署
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 6060
CMD ["python3", "run.py", "--api-only"]
docker build -t ai-cs-tianwang .
docker run -d \
--name ai-cs \
-p 6060:6060 \
-v /root/ai_customer_service/ai_cs/db:/app/db \
--restart unless-stopped \
ai-cs-tianwang
方式 3:后台运行(简单场景)
nohup python3 run.py --api-only > /tmp/tianwang.log 2>&1 &
ps aux | grep "run.py"
tail -f /tmp/tianwang.log
pkill -f "run.py" # 停止
多进程架构
架构说明
单进程(默认) 多进程(可选)
┌─────────────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Python 进程 │ │进程 1 │ │进程 2 │ │进程 3 │
│ asyncio Loop │ │客户 A,B │ │客户 C,D │ │客户 E,F │
│ 所有客户 + Agent │ └─────────┘ └─────────┘ └─────────┘
└─────────────────┘
使用方法
# 多进程模式(默认 CPU 核心数)
python3 run.py --multi
# 指定进程数
python3 run.py --multi --workers 4
# 或使用专用启动器
python3 scripts/multi_process_launcher.py --workers 4
分片算法
客户按 acc_id:from_id 的 MD5 hash 值分配到不同进程,同一客户始终在同一进程。
性能对比
| 指标 | 单进程 | 多进程 (4 核) |
|---|---|---|
| 并发客户数 | ~50 | ~200 |
| CPU 使用率 | 25% | 80% |
| 故障影响 | 全局 | 局部 |
API 接口文档
1. 接收任务
POST /api/task/receive
curl -X POST http://localhost:6060/api/task/receive \
-H "Content-Type: application/json" \
-d '{
"task_id": "TASK_20260227_001",
"type": "send_file_after_reply",
"customer": {"id": "customer_123", "name": "小明"},
"trigger": {
"type": "specified_customer_reply",
"customer_id": "customer_123",
"customer_name": "小明",
"keyword": "好的",
"exact_match": false
},
"action": {"type": "send_message", "message": "这是您要的文件"},
"priority": "normal",
"timeout_hours": 24,
"created_by": "设计师 lz"
}'
响应:
{"code": 200, "message": "任务接收成功", "data": {"task_id": "TASK_20260227_001", "status": "pending"}}
2. 查询任务状态
GET /api/task/status/:task_id
curl http://localhost:6060/api/task/status/TASK_20260227_001
3. 取消任务
POST /api/task/cancel
curl -X POST http://localhost:6060/api/task/cancel \
-H "Content-Type: application/json" \
-d '{"task_id": "TASK_20260227_001", "reason": "客户取消订单"}'
4. 任务列表
GET /api/task/list
参数: customer_id(可选)、status(可选)、page(默认1)、page_size(默认20)
curl "http://localhost:6060/api/task/list?status=pending&page=1&page_size=10"
5. 健康检查
GET /api/health
curl http://localhost:6060/api/health
触发条件详解
1. specified_customer_reply(推荐)
指定客户回复指定内容时触发。
{
"trigger": {
"type": "specified_customer_reply",
"customer_id": "customer_123",
"customer_name": "小明",
"keyword": "好的",
"exact_match": false
}
}
| 字段 | 必填 | 说明 |
|---|---|---|
customer_id |
是 | 指定客户 ID |
customer_name |
否 | 指定客户名称 |
keyword |
是 | 回复关键词 |
exact_match |
否 | 是否精确匹配(默认 false) |
exact_match 说明:
false: 消息包含关键词即触发("好的谢谢" 匹配 "好的")true: 消息完全等于关键词才触发
匹配逻辑:
客户发送消息 → 检查客户 ID → 检查客户名称(可选) → 检查关键词 → 触发
2. customer_reply
任意客户回复指定内容。
{"trigger": {"type": "customer_reply", "keyword": "好的"}}
3. customer_keyword
任意客户说某关键词(支持多个)。
{"trigger": {"type": "customer_keyword", "keywords": ["好的", "可以", "行"]}}
4. customer_payment
客户付款时触发。
{"trigger": {"type": "customer_payment", "keywords": ["已付款", "拍下了"]}}
5. time_reach
到达指定时间触发。
{"trigger": {"type": "time_reach", "time": "2026-02-28 09:00:00"}}
数据库
天网任务数据库
路径: db/task_db/tasks.db
CREATE TABLE tasks (
task_id TEXT PRIMARY KEY,
specified_customer_id TEXT,
specified_customer_name TEXT,
type TEXT NOT NULL,
customer_name TEXT,
customer_id TEXT,
trigger_type TEXT,
trigger_keyword TEXT,
trigger_keywords TEXT,
action_type TEXT,
action_file_url TEXT,
action_message TEXT,
priority TEXT DEFAULT 'normal',
timeout_hours INTEGER DEFAULT 24,
status TEXT DEFAULT 'pending',
retry_count INTEGER DEFAULT 0,
max_retry INTEGER DEFAULT 3,
created_at TEXT,
created_by TEXT,
triggered_at TEXT,
completed_at TEXT,
error_message TEXT,
result TEXT
);
任务状态流转: pending → waiting → running → completed / failed
图片任务数据库
路径: db/image_tasks.db(详见 项目功能汇总.md - 图片任务数据库)
配置说明
环境变量
文件: .env.tianwang
AI_CS_HOST=127.0.0.1
AI_CS_PORT=6060
AI_CS_API_URL=http://127.0.0.1:6060
TIANWANG_CALLBACK_URL=http://127.0.0.1:6060/api/task/callback
天网回调配置
在 core/task_scheduler.py 中修改回调 URL:
await client.post('http://tianwang-server/api/task/callback', json={...})
端口说明
| 端口 | 用途 |
|---|---|
| 6060 | HTTP API 服务器 |
| 9528 | 轻简软件 WebSocket(外部) |
防火墙:
firewall-cmd --add-port=6060/tcp --permanent && firewall-cmd --reload
监控与日志
查看进程状态
ps aux | grep "run.py"
netstat -tlnp | grep 6060
systemctl status ai-cs-tianwang # systemd 方式
查看日志
tail -f /tmp/tianwang.log # 文件方式
journalctl -u ai-cs-tianwang -f # systemd 方式
grep "任务" /tmp/tianwang.log # 搜索任务日志
grep "派单" /tmp/tianwang.log # 搜索派单日志
grep "转接人工" /tmp/tianwang.log # 搜索转接日志
查看数据库
sqlite3 /root/ai_customer_service/ai_cs/db/task_db/tasks.db
SELECT task_id, type, status, created_at FROM tasks ORDER BY created_at DESC LIMIT 10;
SELECT * FROM tasks WHERE status='pending';
SELECT task_id, error_message FROM tasks WHERE status='failed';
SELECT status, COUNT(*) as count FROM tasks GROUP BY status;
.exit
故障排查
API 无法访问
ps aux | grep "run.py" # 检查进程
netstat -tlnp | grep 6060 # 检查端口
pkill -f "run.py" # 停止
nohup python3 run.py --api-only > /tmp/tianwang.log 2>&1 &
tail -f /tmp/tianwang.log # 查看日志
任务接收失败(500 错误)
tail -f /tmp/tianwang.log | grep "ERROR"
sqlite3 db/task_db/tasks.db ".schema tasks" # 检查数据库
# 如果数据库损坏:rm db/task_db/tasks.db 然后重启(自动重建)
任务未触发
curl http://localhost:6060/api/task/status/TASK_ID # 检查状态
grep "任务触发" /tmp/tianwang.log # 查看触发日志
# 确认客户消息包含触发关键词
内存占用过高
ps aux | grep run_tianwang | awk '{print $6/1024 " MB"}'
# 建议每天定时重启
crontab -e
# 添加: 0 3 * * * pkill -f "run.py" && sleep 2 && nohup python3 /root/ai_customer_service/ai_cs/run.py --api-only > /tmp/tianwang.log 2>&1 &
Worker 进程退出(多进程模式)
journalctl -u ai-cs-multi -f | grep "Worker.*退出"
systemctl restart ai-cs-multi
文件位置速查
| 文件 | 路径 |
|---|---|
| 启动脚本 | run.py(通过 --api-only / --tianwang 切换模式) |
| HTTP API | api/http_server.py |
| 任务调度 | core/task_scheduler.py |
| 数据模型 | db/task_db/task_model.py |
| 配置文件 | .env.tianwang |
| 日志文件 | /tmp/tianwang.log |
| 任务数据库 | db/task_db/tasks.db |
快速参考
┌─────────────────────────────────────────────┐
│ AI 客服 API - 快速参考 │
├─────────────────────────────────────────────┤
│ 地址:http://localhost:6060 │
│ │
│ POST /api/task/receive - 接收任务 │
│ GET /api/task/status/:id - 查询状态 │
│ POST /api/task/cancel - 取消任务 │
│ GET /api/task/list - 任务列表 │
│ GET /api/health - 健康检查 │
│ │
│ 启动:python3 run.py --api-only │
│ 日志:tail -f /tmp/tianwang.log │
│ 数据库:sqlite3 db/task_db/tasks.db │
└─────────────────────────────────────────────┘