Net

那天晚上十一点,我盯着评测报告上一个刺眼的数字看了好久。Qwen3-8B,第一版系统提示词,加权得分80.8。看着还行,可离能上线差着一截。我改一个词,重跑全部case,再改一段规则,再跑一遍。三四个来回之后我崩溃了,根本说不清这一版到底比上一版好了还是坏了。

这是一套给某出行平台做的暑期旺季智能客服意图识别系统。听起来不复杂,真做起来才知道坑有多深。

2026年7月,平台进入暑期出行旺季,机票酒店日均订单大几十万,客服咨询量比淡季翻了将近一倍,单日进线峰值能到几十万通。原来的工单全靠人工分诊,用户一句话甩过来,我得判断是退改签要紧急处理,还是业务咨询要查政策,还是投诉建议要走客服,还是订单操作要改信息。人一忙就开始出错,一个紧急的退票请求被当成普通咨询压了两小时,用户机票眼看就要起飞,这种事出过两次我就坐不住了。

意图识别这个模块,是整个客服链路的翻译层。它把用户说的人话,翻译成下游工单系统能消费的结构化查询。意图判错了,后面派单再准也没用。关键词提错了,知识库召回的东西牛头不对马嘴。模块只占链路一小段,对体验的影响却是决定性的。

我把用户意图拆成五类。REFUND退改签最高优先级,用户说机票要退、酒店要取消,直接走紧急退订通道。INQUIRY业务咨询,行李额度多少、签证怎么办、改签规则是什么,走知识库。COMPLAINT投诉建议,服务不满要反馈。ORDER订单操作,改联系人、确认订单、开发票。剩下IRRELEVANT闲聊,别硬塞工单。

真正需要模型动脑子的不是REFUND这种直白的,是边界case。用户问机票退了行李额度还在吗,这到底是退改签还是业务咨询,人都要想两秒。

选模型不是拍脑袋,得先想清楚约束。用户在对话框等回复,首token必须一两秒内出来,不然人就走了。旺季流量不小,用DeepSeek-V4-Pro级别的按token计费预算扛不住。五种意图的区分不是关键词匹配,模型得理解语义。一次对话system prompt五千token左右,模型上下文32K是合理底线。还有一条,客服侧不持有全部航司酒店的完整政策库,模型只需要做一件事,把用户的自然语言翻译成下游能消费的意图类型加关键词加摘要,它是个翻译官不是个客服小二。

时间窗口只有四个小时。我先去问了三个踩过坑的团队。A团队用Qwen3-14B做意图识别,他们品类集中在自身域内,需要在模型里注入领域特殊知识,对理解能力要求高。B团队用Qwen3-8B,场景是对话式生活助手的导购分流,把链路拆成粗分类加精排两段。C团队用Qwen3-30B。三个团队三种选择,但候选范围迅速收敛到Qwen3系列,8B、14B、30B三个档位都有线上验证。

接下来是筛选。多模态模型先排除,当前客服交互是纯文本,视觉编码器音频编码器完全闲置,你为这些能力付了推理开销却永远用不到。嵌入模型也排除,意图分类不是简单的文本到标签映射,模型还得生成追问文案,嵌入模型只输出向量干不了这个。最后剩下四个纯文本选手,Qwen3-8B、Qwen3-14B,加两个30B的MoE。

评测的第一步不是跑模型,是准备用例集。很多人第一反应是把候选模型拉出来跑benchmark看谁分高选谁。可你拿什么来跑,评测集本身不可信,跑出来的分数就是垃圾进垃圾出。我们按业务规则定向构造用例,每条必须覆盖边界、贴近真实、可标注性强。用户不会说请为我查询退改签相关政策,用户说的是机票退了能退多少钱。连人都纠结的case直接扔掉。

用例集设计核心就一条,边界case比典型case更重要。我要退机票判为REFUND所有模型都能做对,没什么好比的。真正拉开差距的是机票退了行李额度还在吗这种退改签和咨询双重意图怎么判,多轮对话里意图从模糊流转到退改签模型能不能跟上。

四个模型在六十条黄金用例上跑完,我拆了效果、时延、成本、上下文四个维度对比。从评测看14B效果最好,时延也还行,8B效果略低但时延最优。可14B交付有资源风险,最终线上用的是8B。不是因为8B完美,是在所有约束条件下它是最务实的选择。Qwen3-8B FP16显存约16GB,单卡A10 24G就能跑,这个账算得过来。

选完模型只是拿到一把还算趁手的工具,真正让它变锋利的是接下来的系统提示词自进化。

第一版prompt跑完加权80.8,我开始手动调。改两个词重跑全部case,肉眼对比输出差异。三四个来回就崩溃了,手动调prompt真正的毛病是没有反馈回路,你只有一双会疲劳的眼睛和一个会自我欺骗的大脑。

于是搭了一套自动化闭环。框架自动扫描轮次,从prompt版本号反推当前版本,进入评测打分收敛判断改写四个阶段。跑起来之后我终于从人工调参里解放出来,每次改完prompt跑一轮,分数自动出来,badcase自动归类,自动改进系统提示词。

但第一版框架跑了几轮暴露了致命问题,所有评测打分改写都在同一批数据上进行,改出来的prompt越来越像背答案,系统提示词耦合了太多训练集用例的字样。

解决方案很直接,像训练深度学习模型一样训练系统提示词。把用例集切分成训练集和测试集,训练集用于发现badcase驱动改写,测试集只验证泛化能力不参与改写。收敛条件升级成双门槛,train达到90且test达到92两者同时达标才算收敛。train涨了test跌了,框架标注可能过拟合。这个设计倒逼改写器生产真规则而不是背答案。

test_split解决了数据层面的过拟合,改写器本身设计不好也会过拟合。改写器做的事很简单,把当前prompt、评分反馈、badcase列表、意图混淆模式拼成一条消息发给GLM-5.1让它输出改进版。怎么让它改得好是门手艺。我在改写器层面加了四条规矩。案例服务于规则不是规则服务于案例,存在多个badcase必须先抽象共同判定规则写进Rules,严禁堆砌few-shot刷指标。每条规则本轮最多新增一条示意性案例,而且必须说明边界不能穷举。区分train和test信号,两端共现的是真实规则缺口必须优先修复,仅测试集的是泛化不足要往判定原理上改,仅训练集的大概率是噪声禁止单独加规则。得分达标的维度原样不动只改不满足的。

评分是这套框架的心脏,我设计了六个维度。规则打分管对不对,意图类型对不对字符串比对就能判,格式合不合规JSON schema校验,一百条case毫秒级出结果。LLM打分管好不好,关键词提取得好不好追问是否自然摘要是否准确,这些需要语义理解规则写不出来只能靠LLM,四并发跑完一百条约两三分钟。规则打分管对不对,LLM打分管好不好,这两句话我现在面试候选人都会问。业务侧最在意意图别判错和关键词别提取歪,这两项各占30%权重,因为下游派单和知识库召回完全依赖这两个字段。

上线前两天出了个要命的badcase。用户问行李延误怎么理赔,模型识别成INQUIRY业务咨询,可知识库召回失败走了兜底,给用户推了八竿子打不着的退改签政策。用户在机场等着行李,收到这种回复直接炸了。

最优雅的方案是召回侧也做相关度打分去掉兜底逻辑。可一期还在线上跑,为二期做到极致体验不现实。最终方案是让意图识别模块多判一步,非客服属性的输入直接识别成无关,不进召回链路。道理都懂,改prompt没那么简单。先新增调整训练集,再人工确认修改方向写一版粗版本,然后Loop Loop Loop,最后评测标准同步改。

上线后跑了一周数据。意图识别模块日均承接百万次级调用,准确率从手工调参的80.8拉到93.6,工单首次分诊准确率提升明显,紧急退改签的平均首响时间压缩了近三成。更值钱的是那套自进化框架本身,它后来成了我们团队做任何LLM项目的标配。

回头看这五天,有两条经验我特别想说。

重复了三遍就要造轮子。AI时代造轮子成本大幅降低了,以前写个脚本半天,现在对着coding agent说一句话三十秒就出来。我写了个增量单测脚本,每次AI写完PR跟master做diff只跑改动涉及的Java类,单测效率直接翻倍。又写了个评测可视化脚本,把reports目录下所有轮次读出来生成趋势图雷达图,跑完Loop打开HTML看一眼就知道这轮是进步还是退步。一个顺手脚本五分钟,能帮你减少五十次重复操作的心智损耗。

频繁上下文切换累,但值得。这五天典型节奏是一个窗口写Java代码两三个worktree并行,一个窗口开发提示词调优框架,一个窗口跑评测数据。每次切换都要重新加载大脑里的当前状态。可这件事值得做,AI时代你的角色从执行者变成调度者,工作吞吐量不取决于你打字多快,取决于你能同时让多少个AI在正确方向上运转。

我带学员的时候反复强调一件事,简历上写做过意图识别的人太多了,能把系统提示词自进化、双轨评分、反过拟合这几层讲清楚的不到一成。面试官真正想听的从来不是我用了Qwen3,是你在这套系统里踩过什么坑、做了什么取舍、留下什么方法论。这些才是别人抄不走的竞争力。