企业微信AI客服系统做到能答几句话,一周就够;做到能长期跑、能扩场景、能在改动之后不悄悄变坏,卡住的从来不是模型,是四件配套的事:知识按什么单位入库、一条消息该由谁来答、模型挂了整个系统变成什么样、怎么判断上周的改动是变好还是变坏。这篇按 wecomapi 的接入方式,把这四块的取舍讲清楚。
先定答案来源,再谈路由
搭这套系统时最先该画的不是流程图,是一张答案来源清单。客户问的每一个问题,答案最终只可能来自四个地方:一段固定话术、企业沉淀的知识、业务系统里的实时数据、一个人。这四类的时效性、准确性责任人和失败方式完全不同,把它们混进同一条链路处理,是后面所有麻烦的源头。
- 固定话术:营业时间、政策入口、开场与结束语。答案不需要生成,也不该由模型生成
- 知识:产品能力、常见故障处理、资费说明。来源是企业文档,需要检索,答错的代价是误导
- 实时数据:这个客户的订单到哪了、这台设备什么状态。必须查业务系统,绝不能让模型凭记忆答
- 人:涉及金额、承诺、投诉与例外。这类问题不该由机器结束
很多系统把路由做成意图分类:先训一个分类器把消息分成三十个意图,每个意图配一套处理。这个做法在第三个月失控,因为意图会无限细分,新意图出现时也没人知道该归到哪个已有类。按答案来源分只有四个桶,桶的数量不随业务复杂度增长,新问题进来只需要回答一句「这个答案从哪来」。
知识的单位不是文档,是一条有主人的知识
「把文档丢进向量库」是知识库最常见的第一版,也是最常见的翻车点。文档的组织方式是给人读的:有目录、有前后文、有「见上一节」。切片之后这些结构全部丢失,检索出来的片段经常是一段没有主语的说明。
更好的入库单位是一条能独立成立的知识:一个问题加一段脱离原文也读得懂的答案。它可以从文档里提炼,也可以从历史工单里沉淀,但入库时必须能单独成立。这个转换是人力活,没有捷径,也正是这套系统真实成本的大头 —— 向量库那点开销相比之下可以忽略。
- 1每条知识要有 owner。没有主人的知识没人会更新,半年后它就是一条会被自信引用的错误答案。
- 2每条知识要有有效期或复核日期。过期不等于删除,但要能被筛出来复核。
- 3每条知识要有适用身份。对内和对外的答案经常不同,检索时必须按身份过滤,不能靠提示词约束。
- 4每条知识要有出处。让回答带上出处,客户能自己核对,坐席接手时也知道机器依据了什么。
冲突处理要有明确规则。同一个问题在三份文档里有三个说法,是知识库最常见的状态,而模型只会忠实地在里面挑一个。规则可以简单粗暴 —— 按有效期取最新、按 owner 层级取更权威的那条 —— 但必须有,且必须能在检索结果里看出来这次用的是哪一条。
路由:一次便宜的分流加一次昂贵的生成
路由要解决的是「这条消息交给谁答」,它跑在每一条消息上,所以必须便宜。用一次大模型调用来做分流,等于给每条消息加一次完整的推理成本和延迟,还多引入一个出错点。
可行的顺序是先做确定性判断,再让模型接手。用 wecomapi 的事件回调拿到消息后,先过四类不需要理解语义的裁决:人工接管标记、显式的转人工意图、敏感词命中、固定话术的精确匹配。这四类毫秒级出结果,能吃掉相当一部分流量。剩下的才进检索,检索结果为空或相似度明显偏低时直接判为「知识覆盖不到」,也不必调模型。
什么时候必须上模型做分流?当「该查知识还是该查业务系统」本身需要理解语义时。这种情况下正确的做法不是单独调一次模型分类,而是把业务系统查询做成工具交给同一次生成去决定,省掉一次往返 —— 多步任务与工具调用的编排另有讲究,站内单独有一篇展开。
- 分流的每一档都要记录命中量。某一档长期零命中,说明规则写错了,或者流量根本不长那样
- 灰度按客户分桶,不要按消息分桶。同一个客户在一次会话里体验到两套策略,反馈会完全没法用
- 分流结果要写进会话记录。排查「为什么这个问题没走知识库」时,你需要的就是这条记录
兜底要分三层,最被忽略的是第三层
兜底常被理解成一件事:答不出来就转人工。实际要分三层,触发条件和处置完全不同。第一层是答不出:检索空手而归或置信不足,处置是转人工 —— 阈值怎么定、交接包带什么,站内讲转人工那篇有完整展开。第二层是答错了:答案发出去之后才发现不对,处置是发现机制加纠正话术,靠抽检和坐席一键标记,不靠实时判断。
第三层最被忽略:系统挂了。模型服务超时、检索不可用、上游限流 —— 这些时候整套系统会变成什么样?没有预案的默认表现是沉默,而沉默在 IM 里是最糟的一种失败,客户不知道你还在不在。这一层的失败域还要往外扩一格:出向本身也会失败。答案生成对了、消息没发出去,在客户那边和没答一模一样,所以是否送达要以 wecomapi 的调用返回为准记一笔,别把「生成完成」当成「已送达」。
- 1定义一个明确的降级形态:关闭生成,只保留固定话术与关键词匹配,其余一律给出「已为您转接」并真的进人工队列。
- 2降级开关必须是配置,不能靠发版。真出事那天你在等发布窗口,这是最贵的一种延误。
- 3降级要能按能力粒度切:生成挂了不代表检索挂了,别一次全关。
- 4恢复要人工确认。自动恢复会在服务抖动时反复切换,客户连着收到两种风格的回复。
// 示意逻辑,函数与字段均为自拟;精确字段与端点以 wecomapi 文档为准
async function answer(input) {
const mode = await degrade.current(); // 配置驱动,改它不需要发版
if (mode === "off") return canned.queued(); // 全降级:固定话术 + 真的进人工队列
const hit = canned.match(input.text); // 来源一:固定话术,毫秒级
if (hit) return hit;
const docs = await kb.search(input); // 来源二:知识,带身份过滤
if (!docs.length) return handoff("no_coverage");
if (mode === "kb_only") { // 生成挂了但检索还在
return canned.excerpt(docs[0]);
}
return generate(input, docs); // 来源三、四由工具调用与转人工承接
}降级预案要真的演练一次。把模型服务的地址改成一个不通的地址,看客户侧到底收到什么 —— 多数团队第一次演练时发现客户侧什么都没收到,而监控面板一片正常。
评估:三类信号各回答一个问题
评估是四块里最容易被砍掉的,因为它不产生新功能。砍掉的后果也不是立刻可见:系统会在一次次「小改动」里慢慢变坏,直到某天运营说「最近答得不如以前」,而你没有任何数据能确认是哪次改动造成的。
- 1离线评测集回答「这次改动有没有变坏」。它是唯一能在上线前给出判断的信号,也是唯一需要你先付出标注成本的信号。规模不必大,覆盖到每一类答案来源即可。
- 2线上指标回答「现在跑得怎么样」。自助解决率、按触发源分开看的转人工率、拒答率、端到端时延,四个一起看才有意义。
- 3人工抽检回答「指标没覆盖到什么」。每天抽一批会话人读,重点看转人工前的最后三轮,以及客户没再回复就走掉的会话 —— 这两类在指标上看不出来。
评测集从哪来,站内讲 AI 接口设计那篇已经说过 —— 把线上进入模型的输入原样落一份就够了。这里只补一条这套系统特有的采样纪律:分层要按答案来源分,四类各留够样本,并且必须包含拒答和转人工的会话。只按问题类型采样会漏掉这两类,而它们恰恰是改动之后最容易悄悄变坏的部分。
还有一条纪律:评测要有回归门槛。定一个分数线,低于线不允许上线,哪怕改动本身看起来无害。没有门槛的评测集会退化成一个每次都跑、但没人看结果的仪式。
第一个月该做到哪一步
顺序错了会浪费两个月,所以给一条具体路径。
- 1第一周把链路跑通但保持沉默:接上 wecomapi 的消息事件,走完检索与生成,结果只写日志不发给客户。这一周产出的是第一批真实输入样本。
- 2第二周上副驾驶模式:把生成的答案推给坐席作为建议,由坐席决定用不用。这个用法答错不会打到客户身上,而坐席的采纳率就是最早的质量信号。
- 3第三周挑一个答案来源单一、答错代价小的场景放给客户,比如售前的产品能力咨询。同时把降级开关和转人工链路先接好。
- 4第四周做评测集和抽检机制。到这一步系统才算能长期维护,之后每扩一个场景重复三、四两步。
不建议的顺序是反过来 —— 先把所有场景接上,再补评测和降级。那样你会在扩场景的过程中失去判断能力,只能靠客诉来发现问题,而客诉的样本量小、延迟大、还带情绪。
本文讲的是系统组成与落地顺序,不涉及具体接口定义。消息、事件的精确字段与端点以 wecomapi 线上接口文档为准。
常见问题
- 一定要自己搭知识库吗,把文档整份交给模型不行吗?
- 能跑,但你会失去三样东西:每条知识的主人、有效期、适用身份。文档形态下没人说得清哪一段过期了、哪一段只能对内讲,于是模型会把过期的内部口径一并讲出去,而这类错误看起来很流畅,最难被发现。知识库真正的价值不在检索,在于它逼你把这三样标注出来 —— 标注做了之后,用不用向量检索反而只是实现选择。
- 企业微信AI机器人开发和 AI 客服系统是一回事吗?
- 机器人是形态,客服系统是职责。一个机器人可以只做群内播报;客服系统必须回答「答错了谁负责、答不出怎么办、系统挂了变成什么样」这三个问题。用 wecomapi 的消息与事件能力把机器人跑起来是第一步,剩下的四块配套才是它能不能对外承接客户的分界线。
- 拒答率是不是越低越好?
- 不是。拒答率掉得太低,通常意味着系统开始对超出知识范围的问题硬答,而这类回答的错误最难被发现 —— 它们看起来很流畅。合理做法是给拒答率设一个下限,低于下限就去抽检那些「本该拒答却答了」的会话,而不是庆祝覆盖率上升。
准备好动手了?
精确字段、鉴权与端点以线上文档为准;可在控制台创建密钥后联调。
