背景痛点:客服小程序的三座大山
做智能客服小程序最怕什么?
- 对话逻辑像毛线团——规则一多就缠在一起,改一句问候语要改五六个 if-else;
- 首句响应超过 2 秒——用户已经退出聊天框,后台还在跑 SQL;
- 多轮会话一刷新就失忆——用户刚说完订单号,重新进来又要重输。
这三座大山把开发周期直接拉长 30%,线上投诉率也跟着涨。去年我们给零售客户做第一版时,用传统规则引擎写了 1 200 条“关键词-回复”映射,结果维护人员离职交接写了 3 天,新同学还是不敢动代码。痛定思痛,第二版全面切到 AI 辅助方案,把“人工写规则”变成“模型产逻辑”,才真正把迭代速度拉回来。
技术选型对比:规则引擎 vs AI 辅助
| 维度 | 传统规则引擎 | AI 辅助(意图模型+槽位抽取) |
|---|---|---|
| 开发量 | 人工穷举关键词,随业务线性增长 | 训练一次,泛化后基本零新增 |
| 可维护性 | 一条规则改动需回归全量 case | 增量数据重训即可,回滚到旧模型 30 秒 |
| 响应耗时 | 本地正则匹配 <50 ms | 云端 NLP 平均 180 ms,缓存后可压到 30 ms |
| 多轮上下文 | 需自建状态机,代码量大 | 模型自带上下文向量,会话状态自动关联 |
| 异常输入 | 遇到口语化/错别字直接失效 | 模型鲁棒性高,可覆盖 85% 口语变形 |
结论:对高频问题、口语化表达、多轮追问,AI 辅助在开发效率和用户体验上全面胜出;规则引擎只剩“白名单兜底”一个场景值得保留。
核心实现:把 NLP 能力塞进小程序
微信小程序并不直接跑模型,真正的做法是把 NLP 作为云函数(或自建微服务)暴露 HTTPS 接口,小程序端只做轻量“收发+渲染”。流程拆成 4 步:
- 用户语音/文字 → 小程序获取 rawText
- 小程序把
openid+rawText+sessionId送到云函数chat - 云函数调用 NLP 服务(我们用的腾讯云 NLP 3.0,支持 24 种意图、128 类槽位)→ 返回
intent、slots、reply、nextAction - 云函数把结果写回云开发数据库(记录会话、统计热点),同时回包给小程序端渲染
会话状态管理靠sessionId+openid做复合键,云开发数据库里存一个ttl: 600 s的文档,保证用户 10 分钟内回来还能继续聊。整个链路无 Cookie、无 WebSocket,天然规避了小程序后台挂起断连问题。
代码示例:Clean Code 示范
以下三段代码直接拷到微信开发者工具可运行,已按 Clean Code 原则拆成“单一职责函数”,并带完整异常分支。
1. 小程序端请求封装(promise 化,带重试)
// utils/request.js const request = (data, retry = 2)两分 return new Promise((resolve, reject) => { wx.cloud.callFunction({ name: 'chat', data, success: res => { if (res.result && res.result.code === 0) resolve(res.result) else reject(res.error || { code: -1, msg: 'empty reply' }) }, fail: err => { if (retry > 0) { console.warn(`retry left ${retry}`) setTimeout(() => request(data, retry - 1).then(resolve).catch(reject), 300) } else reject(err) } }) }) } module.exports = { request }2. 云函数入口(chat/index.js)
const tencentcloud = require('tencentcloud-sdk-nodejs-nlp') const db = wx.cloud.database() const _ = db.command exports.main = async (event) => { const { openid, rawText, sessionId } = event // 1. 取会话上下文 const sessionCol = db.collection('session') const session = await sessionCol.doc(`${openid}_${sessionId}`).get() .catch(() => ({ data: { context: {} } })) // 首次会话无文档 // 2. 调 NLP 接口 const nlp = new tencentcloud.nlp.v20190408.Client({ credential: { secretId, secretKey } }) const nlpRes = await nlp.ChatBot({ Query: rawText, Flag: session.data.context.flag || 0 }) // 3. 更新会话 await sessionCol.doc(`${openid}_${sessionId}`).set({ data: { context: { flag: nlpRes.Flag, lastSlots: nlpRes.Slots }, updateTime: new Date(), ttl: Date.now() + 600000 } }) // 4. 回包 return { code: 0, reply: nlpRes.Reply, intent: nlpRes.Intent } }3. 小程序页面渲染(pages/chat/chat.js)
const { request } = require('../../utils/request') Page({ data: { messages: [], sessionId: '' }, onLoad() { this.setData({ sessionId: wx.getStorageSync('sessionId') || this._genId() }) }, async sendMsg(e) { const rawText = e.detail.value.trim() if (!rawText) return this.data.messages.push({ role: 'user', text: rawText }) const res = await request({ openid: wx.getStorageSync('openid'), rawText, sessionId: this.data.sessionId }).catch(() => ({ reply: '网络开小差,请重试' })) this.data.messages.push({ role: 'bot', text: res.reply }) this.setData({ messages: this.data.messages }) }, _genId() { const id = Date.now().toString(36) wx.setStorageSync('sessionId', id) return id } })要点:
- 小程序端只负责“收发+渲染”,不保存业务状态,符合“展示层薄”原则;
- 云函数里所有异步调用都用
await,避免回调地狱; - 数据库文档带
ttl字段,云开发支持“过期索引”,自动清掉僵尸会话,省存储费用。
性能优化:高并发三板斧
缓存热意图
把“订单查询”“优惠券”这类 Top 50 意图的回复提前算好,放在云函数内存变量(Node 全局缓存),命中后跳过 NLP 调用,平均耗时从 180 ms 降到 20 ms。请求合并
用户连续发 3 条消息时,小程序侧把 3 条打包成数组一次送,云函数循环处理,只写一次数据库,减少 2/3 写入次数。云开发配额错峰
微信小程序云开发默认 100 QPS,超过就 433。我们在云函数入口加令牌桶,每 200 ms 放 20 个令牌,超量请求返回code: 1让前端指数退避,避开瞬时毛刺。
避坑指南:踩过的坑与填坑方案
会话状态丢失
现象:用户切换网络或杀掉小程序,重进后sessionId被覆盖。
解决:sessionId落wx.setStorageSync,同时后台用openid+unionId做兜底合并,保证同一个人换设备也能续聊。API 限流 433
现象:大促高峰直接 433,前端白屏。
解决:云函数里做令牌桶 + 前端退避;关键接口接 CDN 边缘函数做一层缓存,把静态问答结果下沉到边缘节点。NLP 返回空回复
现象:用户输入“哈哈哈”,模型返回空串,页面直接空白。
解决:云函数兜底策略——当reply为空时,随机拉一条“闲聊语料”并记日志,后续用人工标注反哺模型。语音转文字失败
现象:录音 60 秒,腾讯语音识别返回 3003 错误。
解决:前端限制最大 30 秒,并分段上传;同时提示用户“语音过长,请分两次输入”。
结语:把客服做成“自成长”产品
用上 AI 辅助后,客服需求从“写规则”变成“标注数据”,迭代周期由周缩短到天。但模型不是银弹,后续仍有三个方向值得继续深挖:
- 私有化微调:对品牌专有名词(如 SKU、门店地址)做增量训练,减少槽位误识别;
- 多模态交互:把商品图片、小程序码一并送进多模态模型,实现“拍图问库存”;
- 主动服务:结合订阅消息,在物流异常时主动推送“是否需要帮助”,让客服从被动回答转为主动关怀。
如果你已经跑通 MVP,不妨把日志脱敏后定期喂给模型,让客服小程序自己“长”出新能力。下一版迭代,也许就能真正做到“零规则、零等待、零丢失”。祝开发顺利,少踩坑,多复用。