1.背景随着公司业务的发展,客户服务业务量不断增加。为了解放人力,提高质检业务的覆盖率,及时有效地发现客服日常工作中存在的问题,需要构建智能质检系统,以满足日益增长的交通质检系统需求.2、针对业务特点的质检体系,主要针对电话通话(二线外呼、400内线)和短信通话(IM通话)以及客服后续操作的内容,具有专注于解决用户需求和检测客服服务。由于客服日常对接的用户需求“五花八门、千奇百怪”,质检系统需要对接的数据源也是多方面的。规则的计算脚本计算出最终的结果。质检指标按数据来源大致可分为以下几类:IM系统IM文本通话内容、通话时长等电话系统二线外呼、400内线通话内容、通话信息和其他工单系统工单操作,如创建工单、重启工单、提醒订单等订单产品类型、订单价格等薪酬系统薪酬记录、用户标签等可分为根据数据类型分为:对话内容语义、意图等交互对话、语速、情绪等属性,如订单金额、产品标签、工单类型等运营客服操作、创建工单、创建补偿单等同时,在不同的场景下,“标准”的判断也会有一定的差异,这就需要系统的去解决具有灵活调整能力的质量检查,规则的制定需要随着业务的发展进行调整。3.技术挑战3.1挑战基于质检系统的业务特点,为保证系统在线功能的正常使用和系统的稳定运行,在系统设计中需要面临一些挑战:a大量的数据对应一个session的质检。检验,每天需要生成相应数量的质检单。每一张质检单都需要对应的质检项目,最终质检系统需要根据配置的质检规则对这些质检项目进行质检。数据来源多种多样。质检系统不仅数据量大,而且质检范围也多种多样。部分质检项目需要获取依赖的工单系统和订单系统的数据。需要保证这些数据能够准确获取,而不是下游。依赖系统。质检项目较多,系统需要支持配置多种质检项目。同时,每个质检项目都有多个质检规则,需要根据业务场景经常调整规则。这就需要系统支持灵活配置和质疑质检项目和质检规则。准确性质检系统的最终结果会影响到用户体验和客服工作,需要保证质检结果的准确性。以上四点是整个质检系统设计过程中需要注意的几点,为系统设计指明了方向。3.2解决方案基于上述挑战,整个质检系统围绕质检项目的采集和配置、数据的采集和质检的完成展开。质检系统整体数据采集流程如下:4.技术选型4.1数据宽表为了减轻下游系统服务的压力,解决大量质检单所需的质检数据采集问题,基于现有质检系统T+1生成质检单的模式,离线采集大而宽的数据表是更优选的方案。4.2质检规则质检系统执行“质检”行为,主要依据质检项上配置的质检规则,质检规则的执行依赖于规则引擎。规则引擎的选择最初考虑的是JDK自带的JavaScriptEngine,但该引擎只支持JavaScript,后来选择了功能更强大的QLExpress。5.技术实现5.1离线采集数据质检系统根据流量类型将质检分为3类,即一线、二线和400,不同类型的质检表通过离线采集数据生成对应的大宽表,用于查询计算。以一线在线为例,数据采集和清洗主要分为以下几个步骤:以IM会话id为主键,以工单号为主键采集组装IM相关数据,采集装配工单、关联订单、支付订单数据是以订单号为主键,收集装配工单相关数据。基础数据采集生成离线表后,质检系统根据质检单中对应的sessionid查询信息,通过关联工单号解析session内容中的订单。号,查询对应的离线数据表,最后组装上下文信息提交给规则引擎计算最终结果。5.2规则执行规则执行主要依赖于规则脚本的配置和规则引擎对脚本的执行。系统选择QLExpress作为脚本引擎。QLExpress是一款动态脚本引擎分析工具,具有以下优点:支持大部分java语法支持+,-,*,/,<,>,<=,>=,==,!=,<>[等于!=],%,mod[取模等同于%],++,--,/in[类似sql],如[sql语法],&&,||,!等运算符支持,break,continue,ifthenelse和其他标准程序控制逻辑逻辑三元运算a>b?一个:乙;no支持try{}catch{}不支持java8lambda表达式不支持for(Itemitem:list)java对象操作的循环集合操作date=newDate();System.out.println(date.getTime());传播运算符重命名runner.addOperatorWithAlias("if","if",null);runner.addOperatorWithAlias("then","then",null);runner.addOperatorWithAlias("else","else",null);express="if(A>B)then{returna;}else{returnb;}";DefaultContextcontext=newDefaultContext();runner.execute(express,context,null,假的,假的,空的);自定义运算符//定义一个连接方法publicclassJoinOperatorextendsOperator{@OverridepublicObjectexecuteInner(Object[]list)throwsException{Objectopdata1=list[0];对象opdata2=列表[1];if(opdata1instanceofList){((List)opdata1).add(opdata2);返回opdata1;}else{列表结果=newArrayList();for(Objectopdata:list){result.add(opdata);}返回结果;}}}5.3系统总体架构主要流程质检系统的主要用户为操作员:负责基础配置,包括抽样规则、质检项目、自动质检规则脚本QC:负责Review系统质检后的质检表,找出系统错误反馈给运维人员,修改相应的规则脚本。用于离线数据自动质检的大宽表是从各个数据源的基础表在dataworks中组装,最后写入es中用于自动质检。查询时,会将大宽表中的数据再次进行组装,最终组装成规则引擎可用的上下文信息。自动质检质检脚本算子质检项的最小单位是算子,每个算子对应至少一个基础指标。配置自动质检时,需要先配置操作员,以操作员为基本单位组合质检规则。配置页面如下:质检规则最后提醒=最近时间(@I,@A,false);承诺提醒=A&&!E;提醒时间=最近时间(@B,@C,true);创建订单时间=最近时间(@D,@C,true);重启时间=最近时间(@F,@C,true);备注时间=最近时间(@G,@C,true);if(承诺提醒){if(分钟差(上次提醒,@A)>10){return(!B||(@J<提醒时间&&分钟差(@J,提醒时间)>10))&&!D&&!F;}else{return(!G||(@J10));}}返回假;脚本执行取决于规则引擎中预定义的用户定义函数和包含各种必需参数的上下文执行。用户自定义函数用户自定义函数是通过QLExpress绑定java对象的方法特性来实现的。以规则中的“分差”为例:首先通过java代码实现需要的自定义函数publicinttimeDiff_Minute(Longt1,Longt2){if(Objects.isNull(t1)||Objects.isNull(t2)){thrownewQlExpressException(4000,"计算分差失败,时间参数为空");}return(int)TimeUnit.MILLISECONDS.toMinutes(timeDiff(t1,t2));}将定义的方法绑定到脚本引擎QlExpressFuncqlExpressFunc=newQlExpressFunc();runner.addFunctionOfServiceMethod("minutedifference",qlExpressFunc,"timeDiff_Minute",newClass[]{Long.class,Long.class},null);contextCONTEXT上下文本质上是一个Map对象,用来传递脚本执行所需的Parameters。一般使用DefaultContext,也可以通过实现IExpressContext接口来自定义上下文。publicclassDefaultContextextendsHashMapimplementsIExpressContext{}6.未来规划6.1实时质检质检系统的目的是发现客服工作中的问题,为提高发现问题的效率及时性,有效拦截外来投诉风险,未来质检模式将从现有的T+1离线数据模式转变为实时质检模式。改版后的质检服务将对客服操作进行分钟级质检,及时预警。同时,修改实时质检模式后,可以有效提升现有服务器资源的利用率,大大提高了整体服务的稳定性。6.2提高语义分析的准确性客服行为的本质可以简单概括为客服通过对话与用户沟通,满足用户需求,而质检是对客服行为的检查。那么质检的结果是由“语义”——客服与用户沟通的内容和“行为”——客服为满足用户需求而进行的操作来决定的。其中,语义分析是影响质检结果的最大瓶颈。对于质检系统而言,要提高质检的准确性,当务之急是提高语义分析的准确性。目前的系统通过文本、正则匹配和算法意图分析来进行语义分析。大多数语义分析都是基于单个句子。未来的目标是通过整合对话的上下文来进行更精细的语义分析。这样可以提高质量检测的准确性。6.3反馈影响SOP质检结果的第二个因素是“行为”。在客服领域,客服能够响应用户需求的操作要遵循SOP。同样,质检系统在进行质检时,也应根据SOP制定质检细则。质检体系与SOP体系应相辅相成。质检系统的目标不是发现问题,而是通过发现问题的反馈建立SOP,防止类似问题的发生。