资讯动态

三层混合架构:规则引擎+小模型+LLM在电商客服意图识别中的工程实践

发布时间:2026/9/12 2:10:04 来源:尧图企业网站定制
1. 为什么电商客服意图识别非要三层混搭而不是一套大模型直接梭哈先聊个真实场景。做电商客服系统的同学应该都有感触每天几万甚至几十万条用户消息涌进来从我的快递到哪了到你们家这个衣服会不会起球再到我要投诉你们客服态度意图五花八门。系统要做的事情就是在用户消息进来的一瞬间判断他到底想干嘛然后决定是自动回复、转人工、还是交给某个处理流程。这个任务业内通常叫意图识别Intent Recognition。听起来简单做起来坑特别多。我见过不少团队一上来就拍板我们直接用GPT/大模型搞定效果好还省事。结果呢线上跑了一个月账单感人、延迟翻车、部分case答得天花乱坠却牛头不对马嘴。也有另一拨团队坚持用传统方案手工写了几百条正则和关键词规则结果业务一改版规则废掉一大半维护成本直线飙升。所以说纯用一种方案在电商客服这种场景下都会出事。真正可落地的做法是把规则、小模型、大模型各放在它最该待的位置上组成一条路由链路能靠规则一分钟内答完的就不要上模型能用小模型高置信度搞定的就不轻易调大模型处理不了的再交给LLM做语义兜底。这就是三层混合架构的核心理由。它不是什么新技术而是一个工程方案设计上的取舍问题。说白了一句话让每一种技术干它最擅长、性价比最高的事。这篇文章我就从选型思路、每一层的细节设计、层与层之间的协作机制到线上踩过的各种坑完整拆一遍我们是怎么落地这套架构的。内容偏实战面向正在做客服系统、对话机器人、工单分类这类场景的工程师和产品同学其他领域做文本分类的也可以参考思路。2. 第一层规则引擎用最低成本吃掉高确定性流量2.1 哪些意图适合在第一层就用规则解决规则层听起来Low-tech但它在整条链路里的作用非常大。我见过很多工程师一上来就跳过规则直接上模型结果各种边缘case把模型搞得焦头烂额准确率一直上不去。反过来如果前期把能确定的流量通通拦在规则层后续模型的压力会小非常多。电商客服场景里有大量意图是高确定性、低语义复杂度的这些就是规则层的菜查询订单物流用户通常会直接丢订单号或手机号比如帮我查一下单号 SF1234567890开具发票能不能开发票需要发票抬头某某公司修改收货地址地址改成北京市朝阳区某某路退款/退货我要退这件衣服怎么申请退款人工客服转人工人工客服在哪里这类消息有个共同特点它们往往带有强信号的结构化信息——订单号、数字串、特定动词退、改、开加特定名词发票、地址、退款。这些信号用正则和关键词就能高置信度命中完全不需要让模型趟这趟水。规则层另外一个妙用是做前置拦截。比如用户发了个脏话骂人或者发了一串乱码asdfjkl在规则层直接打上无效消息或投诉标签避免这些垃圾流量冲进模型层污染统计分布。2.2 规则设计的具体姿势关键词正则优先级先说结构设计。我建议规则层不只是简单的关键词包含判断而是做成一个可编排的规则组。每个意图对应一个规则组规则组内部有多个规则规则之间用优先级和权重排序。举个例子查询物流这个意图的规则组长这样意图: query_logistics 规则1: 包含订单号正则 \b[A-Z]{2}\d{9,}\b 或 \b\d{12,}\b 且 包含(物流,快递,到哪,配送) 规则2: 包含(物流,快递) 且 包含(查,哪里,到哪,进度) 规则3: 包含(单号) 且 包含(查,看,跟,踪)每条规则有自己的匹配逻辑多条件用AND、OR组合。规则之间也不是平级的优先级高的先匹配匹配上就不往下走了。这一点特别重要后面踩坑部分我会专门展开说。正则的坑也不少。电商场景里订单号格式五花八门有的平台是纯数字有的带字母前缀有的快递单号是12位到15位混合编码。如果正则写得太宽容易把手机号、身份证号误判成订单号写得太窄又漏召回。我一般建议订单号正则采用前缀字符长度校验双保险例如\b[A-Za-z]{1,4}\d{9,14}\b同时配上数字出现的位置、上下文动词等条件来减少污染。除了普通关键词还要处理否定表达。规则层最大的盲区就是我不查物流这种话。所以我的建议是规则组里统一预留一个否定词过滤槽如果句子命中了不、别、不需要、不是等词规则命中置信度打折直接降级交给小模型处理不要硬在规则层下结论。2.3 规则覆盖率怎么监控规则不是写完就完事很多团队把规则写完上线就再也不管了这是错误的。规则层本质是一个记忆系统它必须和线上真实流量对齐否则业务一改版规则就失灵。我们在规则层上线了一套覆盖率看板从全量会话中抽样标记哪些消息被规则层成功路由了哪些落到了下一层。每周复盘一次重点看两类case规则命中了但路由错了——说明规则有冲突或写得太宽要收紧。规则没命中但人工标注显示它是这个意图——说明规则有漏召回要补充关键词或正则。另外规则层还要维护一张黑名单词表。电商场景里经常出现品牌词、竞品词、违禁词比如用户发你们是不是卖假货的跟某某平台比你们太贵了这类消息容易被规则误判为普通问价。把这类词收进黑名单命中的直接转人工或者走敏感意图通道能避免不少公关风险。注意规则层的关键词表和正则表达式一定要做成配置化、可热更新的。不要写死在代码里改一次发一次版。客服业务的变化频率是以天为单位的配置热更新是硬需求。3. 第二层小模型垂直意图分类的主力部队3.1 为什么选了BERT系分类模型而不是其他规则拦掉确定性流量之后剩下来的消息有语义多样性、表达不规整的特点比如他家的裤子尺码是不是偏小我平时穿27的东西收到了但是颜色好像跟我买的不太一样你们周六有人工客服吗这种话没有强结构化信号但语义上是明显的咨询尺码售后反馈咨询工作时间类意图。这时候就需要小模型出场了。小模型我特指BERT、RoBERTa、ERNIE这类基于Transformer Encoder的预训练分类模型参数量从几千万到几亿不等网上能找到一堆开源权重。这类模型在文本分类任务上有两个优势一是分类精度很高在标注数据充分的条件下十几个意图类别的F1能做到90以上二是推理成本低上GPU或者好点的CPU都能扛住高并发比LLM便宜一到两个数量级。选型上我们一开始对比过BERT-base和RoBERTa-wwm-ext还有阿里的通义开源的一些小模型最终选了RoBERTa-wwm-ext作为主力底座。原因有两点中文场景下它的全词掩码预训练策略对中文更友好而且同参数量下分类效果普遍比BERT原始权重略好。如果你处理的文本里面专业术语多、行业黑话重也可以考虑在领域语料上做一次MLM继续预训练效果会再涨一点。3.2 数据标注、类别体系与冷启动小模型的关键不在模型结构而在数据。电商客服的意图类别体系怎么定直接决定了模型的上限。我们在定类别时踩过一个大坑一开始按业务部门给的分类表来标结果业务方一口气提了40多个意图很多类别之间边界极度模糊。咨询尺码和咨询材质看起来能分但用户经常一句话里又问尺码又问材质标注员都吵起来。后来我们做了一次合并归纳把40多个类别收敛到18个核心意图 1个兜底类别other边界的重叠度才降下来。我建议意图类别的定义遵循以下原则类间区分度要高两个类在绝大多数语料上能被明确区分每个类别的样本量不低于1500条太少就合并或做数据增强要留一个other类别专门收集长尾和垃圾信息否则模型会把杂七杂八的消息硬塞给某个意图标注质量方面我们搞了标注-审核-分歧仲裁三道流程。两个人标同一批数据Kappa系数低于0.75就要重新讨论标注标准。这里多说一句标注数据的质量远重要于数量5000条高质量标注数据的训练效果可能好过2万条粗标数据。冷启动阶段没有标注数据怎么办我的做法是先用规则关键词从历史会话里捞数据再用领域词替换的方式做数据增强生成一批伪标注数据让模型先跑起来。等小模型有了一版线上结果——哪怕是60分水平——再抽bad case给标注团队精标回流替换伪标注数据。这个循环走两到三轮后模型效果就能稳定下来。3.3 训练细节与置信度阈值的确定数据准备好之后训练本身其实比较常规了。分类模型结构就是在BERT输出层的CLS向量上接一个全连接层做softmax多分类。有几个细节值得分享类别不平衡问题。电商场景长尾意图样本量天然少直接训会倾向于把所有样本都分到大类。我的解法是做加权损失函数小类别的loss权重放大同时训练时做了类别采样平衡。这两个手段一起用长尾类别的召回率能改善不少。阈值校准。模型输出的softmax概率分布并不能直接拿来当置信度。不同类别的分布松紧不一样有的类别模型给0.6就是高置信了有的类别给0.9都不一定靠谱。我建议根据验证集统计每个类别在正确预测和错误预测下的概率分布确定一个类别独立的置信度阈值。这个阈值是路由决策层的输入非常重要。举个例子我们的阈值表长这样意图类别高置信阈值低置信阈值路由决策咨询尺码0.850.65高于0.85直接处理0.65~0.85进LLM复核售后投诉0.900.75触发投诉意图必须转人工优惠咨询0.800.60低于0.60进LLM兜底向量化上如果你们有GPU资源可以顺便把句向量存下来做语义检索后面LLM层做few-shot示例检索时会用到。这个小细节后面统一说。4. 第三层LLM强语义理解和长尾意图的兜底4.1 LLM到底用来解决什么问题规则和小模型都搞不定的流量长什么样我举几个线上真实例子我昨天下的单今天一看地址写错了能帮我改一下吗但是订单好像已经发货了该怎么办这句话是多意图叠加改地址 查发货状态 咨询拦截。你家这个衣服我穿了一次就起球跟图片完全不一样我要一个说法。这句话没有直接说退款退货但语义里包含强烈的售后投诉倾向。能不能把发票抬头改成XX公司啊刚才写错了急这里有改发票 时限紧 情绪急三重信息。这类消息的共同点是需要上下文理解、需要多意图拆分、表达模糊。小模型在这种语料上很难做对——因为它本质是单标签分类器一句多意图的话它会逼自己选一个主标签另一个意图就丢了。这时候LLM就派上用场了。LLM承担了三件事多意图识别把一句混杂的话拆成多个意图并附带各自的关键信息槽位低置信度复核小模型给置信度暧昧的样本让LLM做二次判断长尾意图兜底不在18个核心类别里的冷门意图LLM能通过语义理解给出合理归类4.2 Prompt设计与结构化输出LLM层如果只是简单地把用户消息丢给GPT然后让它判断意图效果肯定不行。工程上的真正难点是怎么让LLM输出稳定、结构化、可控的结果。我们的Prompt模板大概长这样你是电商客服系统的意图识别模块。请根据用户消息输出JSON格式结果。 任务说明 1. 列出用户消息中包含的所有意图情感类型和关键信息槽位 2. 意图列表来自【18类核心意图 other】如果语义匹配不了任何一个核心意图返回other 3. 如果消息中包含多个意图按重要程度从高到低排列 4. 只输出JSON不要解释 用户消息{{user_message}} 历史对话上下文{{dialogue_context}} 输出格式 {intents: [意图1, 意图2], slots: {关键词槽位: 值}, sentiment: positive/neutral/negative}设计Prompt时注意几个坑**一定要限制输出格式。**用JSON约束不要让它自由发挥。如果你用的模型支持function calling或者constrained decoding直接挂上输出稳定性会有质的提升。我们早期吃过不少次它给我输出一段话而不是JSON的亏后来干脆在代码层做了JSON解析重试逻辑——解析失败就重新生成一次两次失败就走人工兜底。要给意图清单和定义。LLM对业务不熟你不给它可选项它会自己发明意图。我们把18个意图的定义 典型示例直接塞进Prompt里还给了如果拿不准就返回other的约束效果立刻明显改善。**慎用角色扮演。**很多人喜欢写你是一个聪明的客服助手这个在意图识别任务里其实有害无益。它会激发LLM的表演欲让它给出带感情色彩的输出而不是冷静的判定结果。我们的实际经验是角色定义越平庸输出越稳定。4.3 缓存、超时、降级与成本控制LLM层的工程化核心就三个字省、稳、降。**省——做语义缓存。**同样的用户消息在客服场景里会出现大量重复比如转人工一周出现几万次。我们用一个向量数据库比如Milvus或者轻量的Chroma存最近7天的用户消息embedding新的query来了先算余弦相似度相似度超过0.97直接命中历史结果不再调LLM。这个操作能砍掉40%以上的调用量。**稳——超时控制。**LLM服务不能保证稳定延迟。我们把LLM调用的超时设置为3秒如果超时就放弃LLM结果直接按置信度降级路由到人工队列。宁可慢一点转人工也不能让用户等出火气来。**降——降级链路。**LLM服务不可用的时候系统不能瘫。我们的降级策略是LLM层挂掉 - 所有低置信度case自动标记为待人工 - 页面客服队列加长。反正兜底是人工这条链路一定要做好否则大模型一抖动客诉就爆了。成本方面我们严格控制LLM只处理双低流量规则层没拦住、小模型置信度又暧昧的样本。高峰期这部分流量大约占总流量的15%-20%。配合语义缓存和复用LLM的开销控制在客服系统总技术成本的10%以内换来的是整体意图识别体验的大幅提升。5. 三层协同路由策略、数据回流与线上效果5.1 路由决策逻辑一条if-else链的科学性三层架构最终要靠一个路由决策器串起来。它的逻辑看似简单但细节里全是学问。function intentRouting(userMessage): result ruleEngine.match(userMessage) if result.isHit: return result result smallModel.predict(userMessage) if result.confidence result.high_threshold: return result if result.confidence result.low_threshold: result2 llmEngine.recheck(userMessage, result) return mergeResult(result, result2) return llmEngine.predict(userMessage)看起来普通但有几个关键点要展开讲。**规则层命中不等于直接结束。**规则层的输出也要带上置信度标记如果规则匹配条件很弱比如只命中了一个订单关键词没有订单号校验也要放行到下一层让小模型复核。规则层是高精准优先它是为了省算力不是为了让规则包办一切。**小模型的低置信度区间不要直接丢弃。**很多团队的做法是置信度高就采用低就进人工这样浪费了很多可挽救流量。我们的做法是低置信度不是进人工而是先让LLM复核一次。LLM复核通过率在80%以上这说明这部分流量语义确实是可识别的只是小模型没见过这类表达人工介入被大幅减少。多意图信号合并。规则层产出的关键词、小模型产出的单标签、LLM产出的多意图列表三者的结果不能简单取一个。比如小模型给出咨询尺码置信度75%LLM同时检测出更换尺码和咨询发货时间两个意图那路由结果是后者。这需要给每个信号设定不同的决策权重我们的经验是规则信号权重大于小模型LLM在低置信度区间作为复核信号时与小模型权重相当在高置信度区间它直接接管决策。5.2 数据回流闭环架构越跑越聪明的关键很多团队做混合架构做到这里就停了其实关键的一环在数据回流。客服场景有一个别的场景羡慕的优势大量的bad case会被用户情绪自动标记。用户对答案不满意就会追问你没听懂吗我问的不是这个你是机器人吧。这些信号都是免费的反馈数据。我们的回流机制是每天凌晨从会话日志中捞取三类数据——LLM覆盖后用户仍不满意的case、路由系统内部置信度分歧大的case、人工客服手动改判过的case。把这些数据丢给标注团队打标每周增量合入小模型的训练集重新训练一版小模型。这个周期我们稳定在两周一版。两三个月跑下来效果就很明显了规则层和小模型的覆盖范围逐步扩大LLM参与判断的流量占比从最初的30%降到15%左右整体意图识别的端到端准确率维持在一个很稳定的水平。这就是数据飞轮。5.3 线上效果怎么评估最后简单说说线上评估体系。意图识别这种模块最忌讳只看离线指标。我们主要监控三个业务级指标自助解决率进入自动流程的用户里有多少比例能完成流程不再追问人工介入率总会话量里需要人工客服介入的比例转人工识别准确率用户想要转人工的消息里系统能识别出来的比例这三项直接反映意图识别模块给业务带来的实际价值。比单纯盯意图分类F1值要真实得多。6. 上线半年后复盘踩过的坑和给同行的大实话6.1 那些只有上线后才会暴露的坑挑几个我们真实踩过的、一踩就是好几个小时的坑说希望能帮你绕开。**规则冲突导致永远进不了人工。**我们的规则层有一条转人工规则又有一条订单号规则。用户发我订单号12345出问题了给我转人工结果先是订单号规则命中进入了物流查询流程用户怒发十句人工人工系统还在给他推物流信息。解法是在规则引擎里把转人工设为基础必检规则优先级提到最高所有其他规则都要先过它这关。小模型过拟合了实时聊天风格。我们的小模型在标注数据上F1有93上线后线上准确率只有78。一查发现标注数据多为客服工单的描述性文体而线上是口语化短文本包括大量错别字、空格、无标点断句。怎么退货和咋退啊前者模型认识后者就糊了。后来我们做了文本归一化——全角转半角、繁体转简体、去多余空格、常见口语词替换表——线上效果立刻提了5个点。LLM幻觉直接误导路由。有一次线上case用户说你们送不送到新疆LLM在输出JSON时附带了一个deliverable: true的额外槽位被下游服务当成了承诺送达信号直接回复可以送结果那个商品根本不发新疆。从那以后我们所有LLM输出必须过一层schema校验——允许的字段名、字段类型、枚举值全部白名单化多出来的字段一律丢弃。宁可信息缺失不能信息污染。**语义缓存命中错context。**我们在向量缓存里存的只有用户当前一句没存对话上下文。结果用户上一句说我不喜欢蓝色下一句说我要退款缓存里相似的我要退款被命中返回了退款引导流程但实际上用户前文说的是我刚下单的蓝色款不想要了情绪和诉求完全不同。这个问题最后的解法是计算缓存相似度时附带对话历史的语义摘要向量两段都相似才允许命中。6.2 什么情况下不建议抄这套三层架构最后说点大实话。三层混合架构不是银弹它有自己的适用边界。如果你的场景满足下面任意一条建议慎重考虑意图类别非常固定且长期不变而且业务体量很小一天就几百条消息。这种情况直接用规则写完事别搞这么多层。你的业务容错度极低比如医疗、法务等场景意图判断错一步后果严重。这种场景哪怕是LLM兜底也不行核心决策链必须人工。团队里没有能维护预训练模型的工程师。小模型的训练、调优、重新上线是一个完整工程流没人维护的话模型会逐渐烂掉到时候效果还不如纯规则。但如果你覆盖的是一个大规模、高并发、意图多样且持续演化的场景——像电商客服、平台客服、SaaS工单系统——那这套三层混合架构的性价比是很高的。它本质上是把贵而全的LLM从每个请求的必选项变成了可选项同时用数据回流不断强化便宜的两层让系统整体成本越来越低、效果越来越好。这个架构目前在我们线上已经稳定运行了半年多中间经历过业务大改版、双11流量高峰、大模型服务商故障等各种情况。每次考验完之后我都有同一个感受**系统设计的稳健性不在于每个模块自己有多先进而在于它们组合起来之后有没有给不可控的因素留好退路。**规则层是可解释的小模型层是可度量的LLM层是可兜底的三层互相递补这套系统才真正跑得长久。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价