背景:客服“三高一低”的困局
去年双十一,我们团队被客服工单“淹没”——人均日接待 380 人次,平均响应 45 秒,夜间无人值守导致退货超时直接吃了一个平台扣分。人力、时效、体验、成本,四个维度全在报警。老板拍板:必须上一套 7×24 小时可用的智能客服,预算只有 1.5 个后端人力。于是,我们把目光投向了低代码 Bot 平台。
技术选型:为什么最后选了 Coze
| 维度 | Dialogflow ES | Rasa 3.x | Coze |
|---|---|---|---|
| 中文 NLU 预训练 | 通用模型,电商实体识别 F1 仅 0.72 | 需自训,标注 5k 条起步 | 内置电商领域模型,F1 0.89 |
| API 集成 | 需通过 Google Cloud 鉴权,OAuth2 刷新 token 容易掉线 | 自己写 Action Server,版本升级常断 | 一键填 Header,支持动态取 token |
| 可视化编排 | 基本只能线形树 | YAML 手写,多人协作易冲突 | 画布式,分支可复用子流程 |
| 并发配额 | 默认 600 QPS,超量直接 429 | 取决于机器规格,自己扩 | 免费 1000 QPS,峰值自动弹 |
| 运维成本 | 按调用计费,夜间突增 3 倍价格 | 24h 守着 GPU 机器 | 0 运维,日志自动落盘 30 天 |
一句话总结:Rasa 太“重”,Dialogflow 太“贵”,Coze 在中文场景下“刚刚好”。
核心实现:30 天落地三部曲
1. 多轮对话流程设计
在 Coze Studio 里先画三条主流程:
- 商品推荐 → 收集“品类+价格区间”槽位 → 调搜索 API → 返回 Top5 图文卡片
- 订单查询 → 校验手机号后四位 → 调订单 API → 返回物流节点图
- 退货流程 → 选退货原因 → 上传图片 → 生成退货单号 → 短信通知
每个主流程再埋“返回首页”兜底节点,防止用户“迷路”。
2. 对接电商数据库的 REST API
Coze 的“Action”支持直接写 Python,官方运行时 3.9,下面是一段带重试 + 鉴权的订单查询示例:
import requests, os, time, hmac, hashlib, json, logging logging.basicConfig(level=logging.INFO) BASE = "https://api.shop.example.com/v1" def gen_sign(secret, params: dict): """按平台要求做 HMAC-SHA256""" payload = "&".join([f"{k}={v}" for k, v in sorted(params.items())]) return hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest() def query_order(phone_tail: str, order_no: str) -> dict: headers = {"Content-Type": "application/json"} params = { "phone_tail": phone_tail, "order_no": order_no, "timestamp": int(time.time()) } params["sign"] = gen_sign(os.getenv("API_SECRET"), params) try: resp = requests.get(f"{BASE}/order", params=params, headers=headers, timeout=3) resp.raise_for_status() data = resp.json() if data["code"] != 0: logging.warning(f"biz error: {data}") return {"error": data["msg"]} return data["data"] except requests.exceptions.RequestException as e: logging.exception("network error") return {"error": "网络开小差,请稍后再试"}把这段代码粘进 Action,输出字段映射到order_status、logistics_info,前端卡片就能直接引用。
3. 知识库配置与语义匹配优化
- 先把历史客服 Excel 导出,按“问-答”两列清洗,去重后 4.2 万条。
- 在 Coze 知识库面板选“电商领域”增强模型,开“语义+关键词”双路召回。
- 上线后发现“优惠”与“优惠券”两个词居然召回不同答案,调大“同义词词典”把“优惠≈优惠券≈代金券”,准确率从 0.81 提到 0.91。
- 冷门长尾问题(如“是否支持 Dogecoin 支付”)如果连续 3 天命中低于 0.65,自动转人工标注,回流到知识库,周更一次。
性能考量:别让 Bot 在流量高峰“掉链子”
1. 并发压测脚本(Locust)
from locust import HttpUser, task, between class CozeBotUser(HttpUser): wait_time = between(1, 2) host = "https://api.coze.com" def on_start(self): self.headers = {"Authorization": f'Bearer {os.getenv("COZE_TOKEN")}'} @task def ask_order(self): payload = { "bot_id": "7381xxx", "user_id": "test_{{random}}", "query": "我的订单 123456 到哪儿了?" } with self.client.post("/v3/chat", json=payload, headers=self.headers, catch_response=True) as resp: if resp.status_code != 200 or "物流" not in resp.text: resp.failure("unexpected answer")本地 4 核 8 G 能轻松压到 800 QPS,RT 中位数 220 ms,p99 580 ms,满足业务 3 倍峰值。
2. 上下文记忆的 TTL 设置
- 商品推荐分支:用户 15 分钟没回复即清空,防止第二天继续推荐
- 退货流程:涉及上传图片,TTL 拉长到 2 小时,中途换设备也能续聊
- 全局最大轮次 50 轮,防止内存泄漏;超过即提示“会话过长,正在刷新”
避坑指南:上线前必须踩的 3 个坑
1. 敏感词过滤
Coze 自带基础敏感词库,但电商场景还要加“广告引流+虚假中奖”两类。我们在“后置过滤器”里再串一层:
def sensitive_check(text: str) -> bool: with open("kw.txt", encoding="utf-8") as f: kw = {line.strip() for line in f if line.strip()} for word in kw: if word in text: logging.warning(f"hit sensitive: {word}") return True return False命中后直接返回“涉及敏感内容,已转人工客服”,同时把用户 ID 写进 Redis 1 小时静默队列,避免刷屏。
2. 人工客服无缝接管
在每个流程节点放“转人工”按钮,用户输入“人工”或“人工客服”关键词即触发。Coze 支持返回特殊 JSON:
{ "transfer": true, "skill_group": "after_sale", "priority": 1 }前端收到后调自家 IM 的“技能组分配”接口,并带上历史消息列表,客服端能看到完整上文,平均接续时长 8 秒。
3. 对话日志合规存储
- 日志字段:user_id、query、answer、intent、slots、timestamp、ip
- 存储:写进独立 MongoDB 集群,开“到期自动删”索引,180 天 TTL
- 加密:phone、address 做 AES 字段级加密,密钥放 KMS;内部审计需双人授权才能解密
- 查询:只开放脱敏接口,返回内容把中间 4 位手机替换为 ****
总结与展望
四周跑下来,Bot 解决率 68%,夜间零工单积压,相当于省下 4 名全职客服。但意图识别准确率在高频促销季会掉到 0.83,主要因为“定金”“尾款”等新词爆发。下一步,我们准备把近 30 天订单、浏览、加购数据拼成用户画像,用 Coze 的“动态词典”接口每日更新实体,预计可把准确率再拉 5 个点。如果你也在用 Coze,不妨先跑 A/B:一半用户走静态词典,一半走实时画像,对比转人工率,相信会有惊喜。