做自动回复最容易走偏的地方,是把注意力全花在"怎么生成一句好回复"上。我们第一版就是这样,客户刚发"我想咨询一下",机器人立刻回"您好,请问有什么可以帮您"——客户后面半句话还没打完。客服组反馈说机器人答得太快反而添乱。第二版把重心挪到"什么时候该回、什么时候不该回",体验才正常。
接口层用的是Eyun 平台开放的企微 API,凭证在Eyun 平台首页开通,实时监听走 Webhook,回发走 message/sendText。
监听:先落库,再决定回不回
回调进来不直接生成回复,先落库并更新会话状态,把"收到消息"和"要不要回"拆成两件事。
@app.route("/wx-api/webhook/", methods=["POST"]) def webhook(): data = request.json["data"] save_message(data) # 先落库 touch_session(data["conversationId"]) # 更新最近活跃时间 redis.lpush("reply_queue", data["msgId"]) return "ok"消息体字段和事件类型在开发文档里有完整说明。
抑制一:人工在线不抢答
会话表记一个 owner 字段,标记当前由机器人还是人工接管。人工客服在会话里回过消息后(回调里会出现该客服账号发出的消息),把 owner 置为人工,并开一个 10 分钟的静默窗口。窗口内机器人只记录不说话。
def should_reply(conversation_id): session = get_session(conversation_id) if session["owner"] == "human": return False if time.time() - session["human_active_at"] < 600: return False return True抑制二:连发消息合并后再回
客户习惯把一句话拆成三条发。给每个会话设 3 秒缓冲窗口,窗口内的消息合并成一条再处理。窗口用 Redis 延迟队列实现,新消息进来就重置计时。
触发:规则优先,模型兜底
该回的时候先走关键词规则,命中直接回;没命中的交给模型判断意图,置信度低于阈值的直接转人工,不硬答。
兜底与交接
转人工时把客户档案(getUserProfileDetail)和最近几条消息一起带给客服,客服不用重新问一遍。交接完成后把 owner 切回机器人,机器人恢复应答。
写在最后
自动回复做得好不好,一半看内容,一半看时机。人工在聊的时候闭嘴、客户连发的时候等一等、拿不准的时候交给真人,这三条做对,机器人不抢戏,客户和客服都不反感。