自研智能质检系统探索之路

开发 后端
随着公司业务的发展,客服的业务量不断增加,为了解放人力,提升质检业务的覆盖率,及时有效的发现客服日常工作中的问题,需要建设智能质检系统,满足日益增长的话务质检系统需求。

1、背景

随着公司业务的发展,客服的业务量不断增加,为了解放人力,提升质检业务的覆盖率,及时有效的发现客服日常工作中的问题,需要建设智能质检系统,满足日益增长的话务质检系统需求。

2、业务特征

质检系统主要针对的是电话(二线外呼,400内呼)和文本会话(IM会话)内容,以及客服的后续操作进行质检,以解决用户需求为核心,检验客服的服务。由于客服日常对接的用户诉求“千奇百怪”,质检系统需要对接的数据来源也是多方面的,这就要求质检系统需要对接各个系统,将多方数据进行串联,以算子为基础,使用配置化的规则计算脚本进行最终结果的计算。

质检的各项指标,按照数据的来源划分大致可以分为以下几种:

  • IM系统

IM文本会话的内容,会话的时间等

  • 电话系统

二线外呼,400内呼电话通话内容,通话信息等

  • 工单系统

工单操作,比如创建工单,重启工单,催单等

  • 订单商品

商品类型,订单价格等

  • 赔付系统

赔付记录,用户标签等

按照数据类型可以分为以下几种:

  • 话术类

会话内容的语义,意图等

  • 交互类

通话语速,情绪等

  • 属性类

订单金额,商品标签,工单类型等

  • 操作类

客服各类操作,创建工单,创建赔付单等

同时,在不同的场景下,“标准”的判定会有一定的差别,这就要求系统的质检,具有可以灵活调整的能力,规则的制定需要随着业务发展进行调整。

3、技术挑战

3.1 挑战

基于质检系统的业务特征,为了保证系统上线功能的正常使用,同时保证系统的稳定运行,在系统的设计时需要面临一些挑战:

  • 数据量较大

    按照一通会话对应一次质检,每天需要生成对应数量的质检单。针对每条质检单还需要有对应的质检项,最终质检系统需要对这些质检项,按照配置好的质检规则进行质检。
  • 数据源多样
    质检系统不光数据量较大,质检的范围也多种多样,有的质检项需要获取依赖的工单系统,订单系统的数据,需要保证能够准确的获取这些数据并且不对下游依赖的系统造成影响。
  • 质检项多且杂
    系统需要支持多种质检项的配置,同时每个质检项又存在多条质检规则,且根据业务场景需要经常性的调整规则,这就要求系统可以支持灵活的配置,挑战质检项和质检规则。
  • 准确性
    质检系统最终的结果会影响到用户的体验以及客服的工作,需要保证质检结果的准确性。

以上这4点就是整个质检系统在设计过程中着重需要注意的点,为系统设计指明了方向。

3.2 解决思路

基于前面提到的这些挑战,整体的质检系统围绕如何采配置质检项,如何采集数据并完成质检开展。

质检系统整体数据采集的流程如下:

图片

4、技术选型

4.1 数据大宽表

为了减少对下游系统服务的压力,解决大量质检单所需质检数据的采集问题,基于现有质检系统T+1生成质检单的模式,数据大宽表采用离线采集是比较优选的方案。

4.2 质检规则

质检系统执行“质检”行为,主要基于在质检项上配置的质检规则进行,而质检规则的执行就依赖于规则引擎。

图片

规则引擎的选择,最初考虑JDK自带的Java Script Engine,但该引擎只支持JavaScript,后期选择了扩展性更加强大的QLExpress。

5、技术实现

5.1 离线数据采集

质检系统根据话务类型将质检分为3大类,分别是一线,二线和400。不同类型的质检单通过离线采集数据生成对应的大宽表用于查询计算。以一线在线为例,数据的采集,清洗主要分为以下几个步骤:

  • 以IM会话id为主键,采集,组装IM相关数据
  • 以工单号为主键,采集组装工单,以及关联的订单,赔付单等数据
  • 以订单号为主键,采集组装订单相关数据

基础数据采集生成离线表后,质检系统根据质检单中对应的会话id查询信息,并通过关联工单号,解析会话内容中的订单号,查询对应关联的离线数据表,最终组装成上下文信息并提交给规则引擎计算最终结果。

5.2 规则执行

规则执行主要依赖于规则脚本的配置和规则引擎执行脚本,系统选用了QLExpress作为脚本引擎,QLExpress是一门动态脚本引擎解析工具,具有以下的一些优点:

  • 支持大部分java语法
支持 +,-,*,/,<,>,<=,>=,==,!=,<>【等同于!=】,%,mod【取模等同于%】,++,--,
/in【类似sql】,like【sql语法】,&&,||,!,等操作符
支持for,break、continue、if then else 等标准的程序控制逻辑
逻辑三元操作 a > b ? a : b;
不支持try{}catch{}
不支持java8的lambda表达式
不支持for循环集合操作for (Item item : list)
  • java对象操作
date = new Date();
System.out.println(date.getTime());


  • 扩展操作符
  • 重命名
runner.addOperatorWithAlias("如果", "if", null);
runner.addOperatorWithAlias("则", "then", null);
runner.addOperatorWithAlias("否则", "else", null);
express = "如果 (A > B) 则 {return a;} 否则 {return b;}";
DefaultContext<String, Object> context = new DefaultContext<String, Object>();
runner.execute(express, context, null, false, false, null);


  • 自定义操作符
//定义一个join方法
public class JoinOperator extends Operator {
@Override
public Object executeInner(Object[] list) throws Exception {
Object opdata1 = list[0];
Object opdata2 = list[1];
if (opdata1 instanceof List) {
((List)opdata1).add(opdata2);
return opdata1;
} else {
List result = new ArrayList();
for (Object opdata : list) {
result.add(opdata);
}
return result;
}
}
}


5.3 系统实现

  • 总体架构

图片


  • 主流程

质检系统的主要用户为

  • 运营人员:负责基础配置,包括抽检规则,质检项以及自动质检的规则脚本。
  • QC :负责对系统质检完的质检单进行复核,找出系统差错并反馈给运营人员,修改对应的规则脚本。

图片


  • 离线数据

用于自动质检的大宽表是在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 || (@J < 备注时间 && 分钟差(@J,备注时间)>10));
}
}
return false;


  • 脚本执行

脚本执行依赖于规则引擎中预先定义好的自定义函数和包含各种所需参数的上下文context执行。

  • 自定义函数

自定义函数通过QLExpress的绑定java对象的method特性实现。以规则中“分钟差”为例:

首先通过java代码实现所需的自定义函数

public int timeDiff_Minute(Long t1,Long t2){
if(Objects.isNull(t1) || Objects.isNull(t2)){
throw new QlExpressException(4000,"计算分钟差失败,时间参数为空");
}
return (int)TimeUnit.MILLISECONDS.toMinutes(timeDiff(t1,t2));
}

将定义的method绑定至脚本引擎

QlExpressFunc qlExpressFunc = new QlExpressFunc();
runner.addFunctionOfServiceMethod("分钟差", qlExpressFunc, "timeDiff_Minute",
new Class[]{Long.class, Long.class}, null);


  • 上下文CONTEXT

上下文context本质为Map对象,用于传递脚本执行时所需的参数。一般使用DefaultContext,也可通过实现IExpressContext接口自定义context。

public class DefaultContext<K,V> extends HashMap<K,V> implements IExpressContext<K,V>
{ }


6、未来规划

6.1 实时质检

质检系统的目的是发现客服工作中的问题,为了提升发现问题的时效,并有效拦截外诉风险,未来质检的模式将从现有的基于T+1的离线数据模式改为实时质检模式。修改后的质检服务将在分钟级的尺度上对客服操作进行质检并及时发出预警。同时,修改实时质检模式后,可以有效的提升现有服务器资源的利用率,对整体服务的稳定性有很大的提升。

6.2提升语义解析准确率

客户服务行为的本质可以简单的归纳为客服通过会话与用户交流并满足用户诉求,而质检则是对客服这一服务行为的检查。那么质检的结果就是由“语义”——客服与用户交流的内容和“行为”——客服满足用户诉求的操作来决定。其中语义的解析是现在影响质检结果的最大的瓶颈。对于质检系统来说,提高质检的准确率,当务之急就是提升语义解析的准确率。现在的系统通过文本,正则匹配和算法意图解析来进行语义的解析,这其中大部分语义解析都是基于单句话来执行,未来的目标是通过整通会话的上下文,进行更加精细的语义解析,以此来提升质检的准确率。

6.3反哺SOP

质检结果的第二个影响因素“行为”,在客服域内,客服可以应答用户诉求的操作应该遵循SOP。同样,质检系统在进行质检时,也应该根据SOP来制定质检规则。质检系统和SOP系统应该是相辅相成,质检系统发现问题并不是目标,而通过发现问题反馈建立SOP,杜绝相似问题的发生才是目的。

责任编辑:庞桂玉 来源: 得物技术
相关推荐

2024-08-29 14:44:01

质检埋点

2023-08-09 20:43:32

2022-09-29 15:24:11

物联网MQTT

2022-09-30 15:15:03

OpusRTC 领域音频编码器

2023-10-07 06:51:41

OpenAIAI 芯片

2016-11-02 13:11:26

亚太创新日华为

2020-06-30 17:27:06

RPA应用

2023-02-09 08:08:01

vivoJenkins服务器

2020-06-11 17:48:58

苹果Mac芯片

2019-02-14 10:10:11

系统厂商芯片

2017-06-19 15:05:20

2019-03-28 11:19:36

存储

2015-10-20 17:06:52

2023-09-21 16:27:25

deepin大模型人工智能

2018-04-23 09:03:30

操作系统WindowsLinux

2021-03-08 15:55:16

办公

2019-05-22 17:49:16

Android 华为操作系统

2020-04-16 11:36:59

PixelGoogle芯片
点赞
收藏

51CTO技术栈公众号