闲鱼智能客服机器人架构演进:如何实现高效对话与智能分流

📅 发布时间:2026/7/10 20:50:56 👁️ 浏览次数:
闲鱼智能客服机器人架构演进:如何实现高效对话与智能分流
闲鱼智能客服机器人架构演进如何实现高效对话与智能分流1. 背景痛点高并发下的“慢”与“错”闲鱼每天产生数百万条买家咨询峰值 QPS 能冲到 3k。传统做法是把关键词规则丢进 Redis再让后端服务同步调用。结果两条硬伤响应延迟同步链路 RT 99 线 800 ms用户平均多等 3 秒才收到第一句回复。意图漂移规则冲突、同义词爆炸准确率从 92% 掉到 78%“包邮吗”被识别成“退货”直接把人转售后体验炸裂。老板一句话要么把 RT 压到 200 ms要么把准确率拉回 90%否则人工客服成本 double。于是有了这次重构。2. 技术选型规则引擎 vs 深度学习| 维度 | 规则引擎 | 深度学习 | |---|---|---|---| | 开发成本 | 低运营就能写 | 高要数据GPU | | 准确率 | 78%上线 3 个月后 | 93%BERT-base | | 新意图扩展 | 要加规则、回归测试 | 增量训练、一键热更 | | 响应时间 | 20 ms | 80 msGPU | | 运维复杂度 | 低 | 高要监控漂移、冷启动 |结论规则引擎适合兜底深度学习负责主链路。于是采用“混合路由”——置信度0.85 走模型否则降级规则并异步把日志丢给模型做增量训练形成飞轮。3. 核心实现Transformer Kafka 解耦3.1 模型侧选型中文 BERT-base接一层 128 维分类头输出 32 个业务意图。优化蒸馏到 4 层 TinyBERT推理延迟 80 ms→28 ms。动态 batchGPU 显存 4G 即可扛 2k QPS。部署TorchServe Docker暴露/predictHTTP 接口内部用asyncio线程池防止阻塞。3.2 消息侧Kafka 主题拆分chat.req客户端请求partitionkey%64保证同一用户顺序。chat.resp机器人回复consumer 无状态可水平扩展。异步好处模型推理哪怕抖动 200 ms前端也先收到“正在输入”心跳不会掉线。3.3 整体链路客户端 → Gateway → Kafka(req) → 意图服务 → Kafka(resp) → Gateway → 客户端整条链路纯异步Gateway 只负责转发和超时熔断逻辑解耦压测时 Gateway CPU 只占 15%。4. 代码示例模型推理服务Python 3.9以下代码可直接docker build运行已在线上稳定 30 天无重启。# intent_server.py import json import time import logging from typing import Dict import torch from transformers import BertTokenizer, BertForSequenceClassification from torchserve_handler import BaseHandler, logger class IntentHandler(BaseHandler): def __init__(self): self.model None self.tokenizer None self.device torch.device(cuda:0 if torch.cuda.is_available() else cpu) def initialize(self, ctx): 冷启动时加载模型 properties ctx.system_properties model_dir properties.get(model_dir) self.tokenizer BertTokenizer.from_pretrained(model_dir) self.model BertForSequenceClassification.from_pretrained(model_dir) self.model.to(self.device) self.model.eval() logger.info(Model loaded on %s, self.device) def preprocess(self, data) - Dict[str, torch.Tensor]: 取用户原始文本 body data[0].get(body) or data[0].get(data) if isinstance(body, str): body json.loads(body) text body[text] encoded self.tokenizer( text, paddingmax_length, max_length32, truncationTrue, return_tensorspt, ) return encoded.to(self.device) def inference(self, inputs: Dict[str, torch.Tensor]) - Dict: 前向softmax with torch.no_grad(): outputs self.model(**inputs) probs torch.nn.functional.softmax(outputs.logits, dim-1) top_prob, top_idx torch.max(probs, dim-1) return {intent_id: top_idx.item(), confidence: top_prob.item()} def postprocess(self, data): 加耗时统计 data[cost_ms] round(self.context.get((elapsed_time) * 1000, 2) return [json.dumps(data, ensure_asciiFalse)]异常与监控在initialize()里若模型加载失败会抛RuntimeErrorTorchServe 自动把容器踢掉K8s 重启新 Pod防止半死不活。在inference()捕获CUDA out of memory立即torch.cuda.empty_cache()并返回 503Gateway 收到后降级规则引擎。Prometheus 埋点每次推理记录intent_confidence与cost_msGrafana 看板配 95 线告警100 ms 就人。5. 性能测试数字说话压测环境4 核 8G 容器 * 20GPU T4 * 4Kafka 三节点。指标旧架构新架构峰值 QPS1.8k4.2k平均 RT780 ms190 ms95 线 RT1.2 s260 ms意图准确率78%93.6%机器成本/月12 万8.5 万GPU 按需弹性CPU 利用率从 70% 降到 35%省下的机器把人工客服坐席又加了 30 席老板终于笑了。6. 避坑指南冷启动与状态管理冷启动问题TinyBERT 也要 6 秒初始化K8s readiness 探活超时频繁重启。解决把模型权重提前做torch.jit.trace存成model.pt加载时间 6s→1.2s。采用预热脚本Pod 启动后先跑 100 条随机样本CUDA kernel 编译完成真正流量进来无抖动。对话状态管理别把状态放 JVM 内存高峰重启就丢。用 Redis Hash 存user_id - {intent_history, slots, ttl30min}异步写失败重试 3 次。多轮场景下slot 未收集全就返回澄清话术模型只负责意图不背填槽逻辑职责单一。灰度平滑先按 5% 流量灰度对比准确率与 RT无告警再全量。规则引擎始终作为兜底模型置信度0.5 或请求超时 180 ms 立即切规则用户无感。7. 总结与思考多轮对话还能再卷一点目前单轮意图解决 80% 问题剩下的 20% 需要多轮、个性化、情感检测。下一步打算引入 TOD-BERT 做对话状态跟踪把“还没发货”自动映射到shipping_status0直接查订单接口少问一句是一句。用强化学习做回复排序根据“是否解决问题”实时 reward把“亲亲在的”这类无效回复降权。边缘部署把 8 层蒸馏到 2 层 MobileBERT放到 Arm 盒子让 CDN 节点也能跑就近推理RT 再降 30 ms。如果你也在搭客服机器人不妨试试上面的混合路由 Kafka 异步方案整套代码已整理到 GitHub关键词xianyu-bot-open。踩过的新坑欢迎提 Issue 交流一起把机器人做得更“懂人话”。