系统架构设计
搭建基于n8n的在线客服系统需结合自动化流程与人工介入机制。核心组件包括:用户接口层、自动化处理层、人工切换层。系统通过Webhook接收用户请求,自动流程判断问题复杂度,触发人工转移条件时调用第三方通讯工具API(如Slack、钉钉)。
环境准备
安装n8n服务器,推荐使用Docker部署以简化环境配置。确保主机开放3000端口或自定义端口。数据库选择PostgreSQL/MySQL,持久化存储工作流数据。准备SSL证书启用HTTPS,保障通讯安全。
docker run -d \
--name n8n \
-p 3000:5678 \
-v ~/.n8n:/home/node/.n8n \
-e N8N_BASIC_AUTH_ACTIVE=true \
-e N8N_BASIC_AUTH_USER=<username> \
-e N8N_BASIC_AUTH_PASSWORD=<password> \
n8nio/n8n
用户接口配置
在n8n中创建Webhook节点作为用户请求入口。配置GET/POST方法,生成唯一URL接入前端页面。建议启用响应数据功能,返回标准JSON格式:
json
{
"status": "processing",
"ticket_id": "{{$node["Webhook"].json["body"]["query"]}}"
}
自动化应答模块
- 关键词识别:使用Function节点编写JavaScript逻辑,匹配用户问题中的关键词。预设常见问题库,采用Levenshtein算法模糊匹配:
javascript
const questions = {
"退款政策": "https://example.com/refund",
"配送时间": "3-5个工作日"
};
return { matches: Object.keys(questions).filter(k =>
levenshteinDistance(input.query, k) < 3 ) };
- 知识库查询:当匹配成功时,通过HTTP Request节点调用内部知识库API获取标准答案。设置超时时间500ms,失败时转入备选流程。
人工转移逻辑
-
复杂度评估:组合多个判断条件:
- 关键词匹配失败
- 用户连续追问3次
- 包含"转人工"等特定短语
- 情感分析结果低于阈值(调用NLU API)
-
工单生成:满足任一条件时,触发Create Ticket节点:
- 通过Zapier连接Zendesk
- 或直接调用Freshdesk API
- 写入数据库时包含会话上下文
javascript
const ticketData = {
user_id: body.user,
transcript: $node("ChatHistory").json.messages,
priority: $node("Sentiment").score < 0.2 ? "high" : "medium"
};
人工通知机制
- 即时通讯推送:配置Slack节点的Incoming Webhook,发送结构化消息:
json
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": `*新工单 #${ticketId}*\\n用户: ${userEmail}\\n问题: ${summary}`
}
}
]
}
- SMS备用通道:通过Twilio节点发送短信通知,设置重试机制,首次失败后间隔30秒重发。
状态同步方案
-
双向状态追踪:当人工客服接手后:
- 修改Redis中的会话状态
- 前端通过WebSocket接收状态变更
- 自动化流程终止后续应答
-
会话移交协议:人工处理完成后,调用n8n的REST API触发后续流程:
- 发送满意度调查
- 记录解决结果到数据库
- 关闭自动化会话
监控与优化
-
性能指标收集:在关键节点添加Telemetry节点,记录:
- 响应延迟
- 转人工率
- 问题解决率
-
AB测试配置:使用Split节点分流不同应答策略,比较转化效果。动态调整阈值:
math
\lambda_{new} = \lambda_{current} \times \frac{N_{auto}}{N_{total}}
异常处理机制
-
熔断设计:当知识库API错误率超过5%时:
- 自动切换至本地缓存应答
- 发送告警到PagerDuty
- 记录错误上下文到Sentry
-
会话恢复:通过Cookie/SessionID保持会话连续性,意外中断后:
- 查询未完成工单
- 推送历史记录给人工客服
- 前端显示恢复提示
安全合规措施
- 数据脱敏:在Function节点中对PII信息做哈希处理:
javascript
const crypto = require('crypto');
const hashedPhone = crypto.createHash('sha256')
.update(body.phone).digest('hex');
- 审计日志 :所有人工介入操作写入不可变存储,包含:
- 时间戳
- 操作人员ID
- 修改前/后的数据快照
部署扩展建议
-
负载均衡:当并发量超过50/s时:
- 部署多个n8n实例
- 配置NGINX轮询分发
- 共享Redis会话存储
-
CI/CD管道:使用n8n CLI工具实现工作流版本控制:
n8n export:workflow --id=123 --output=backups/
n8n import:workflow --input=new_version.json