搭建AI智能语音外呼系统 智能语音外呼机器人

2023-11-14

随着人工智能技术的发展,近半年来涌现了大量基于人工智能的呼叫中心业务服务商和集成商。仅电销机器人这一个方向就至少有近百家公司正在推广运营,包括百度、讯飞、智齿、硅基、百应、箭鱼、容联等。商务上的需求非常强烈,整个市场都飞快地热闹起来。

一套可提供saas服务的智能外呼系统,看起来功能并不复杂。一个网站可注册、充值缴费开票,登录后在后台页面选择或者定制外呼话术脚本,新建外呼任务并导入外呼号码列表,明确外呼策略(时间段、重呼次数),设置外呼机器人数量(同时拨出几个号码),点击开始。然后就可以看着进度条走完,外呼机器人按照列表一个个打电话出去。任务完成后,可以查看外呼结果列表。

那么如何从零开始搭建一套对外可以提供saas服务的智能外呼系统呢?

二、总览

我们先列出,搭建这样一整套系统需要哪些技术和资源:

  • 运营商线路:提供方包括三大运营商、集成线路商,这是我们打电话出去要交电话费,必须涉及的供应商。
  • 呼叫中心设备:商用设备原厂包括avaya、genesys、cisco、华为等,集成商很多,开源的也有一些。在发起外呼任务时,saas平台是把外呼请求发给了呼叫中心设备经由运营商线路而拨出去的。
  • AI能力:包含语音识别、语音合成、语义理解。这就是外呼机器人的核心组成部分,它能听懂接电话的人所说的话、表达的意思,并回复和引导对话。
  • saas服务平台:即用户可以注册、登录、缴费、上传呼叫列表、发起外呼任务、外呼结果查看的网站,这个是终端用户唯一可以看得到的前端界面。

简单关系示意图如下:

上图中四个主要模块,其中一些难以自研,只能选择供应商:

  1. AI能力部分(中文ASR/TTS)基本已经格局稳定,没太多可挑选的。
  2. 运营商资源这块儿,可以选择大牌老厂的码号线路资源多的然后便宜的去谈合作,一方面外呼应用在催收场景时容易被封号,同时话费再便宜也好几分钱一分钟,也是重要的成本。
  3. 呼叫中心设备,因为涉及不少接口对接调试,优先选自己熟悉的,其次选便宜的且技术资料多的。
  4. 最后是外呼saas平台,可能这是各个电销机器人服务商/集成商最容易实现自研的部分。

明确了涉及到的技术和资源之后,再明确一下建设步骤。由于各个厂商都有各自的资源和能力,建设方式也各不相同,简单来说可以分成以下几类:

  1. 有运营商资源的,等着别人找上门来就行了。
  2. 呼叫中心厂商,必然有已长期合作的运营商线路资源,手里也有呼叫中心设备+职场,也有技术人员。于是就选择自研saas平台,然后找AI能力厂商合作提供ASR/TTS/NLU。
  3. AI能力厂商,尤其以NLU起家的在线客服类厂商,通常会选择接入百度/讯飞的语音能力,然后去找呼叫中心类厂商合作。
  4. 啥都没有,只有几个技术人员的,选择自研saas平台,接入呼叫中心设备、AI能力、运营商资源。

作为初学者,为了自行从零开始搭建一套对外可以提供saas服务的智能外呼系统,身份必然是第四种,啥都没有,啥都要干。

以上这四部分,核心角色是呼叫中心。AI只是插上了想象力的翅膀,但是没这翅膀,呼叫中心还是呼叫中心,但是AI就只是空中楼阁了。业务明确可落地的呼叫中心才是想象力的基石,这一点与CV和安防的关系很像。

三、呼叫中心搭建

1. 通信原理

目前对呼叫中心比较普遍接受的定义是:呼叫中心是以计算机电话集成(CTI)技术系统为基础,将计算机的信息处理功能、数字程控交换机的电话接入和智能分配、自动语音处理技术、 Internet技术、网络通信技术、商业智能技术与业务系统紧密结合在一起,将公司的通信系统、计算机处理系统、人工业务代表、信息等资源整合成统一、高效的服务工作平台 。

最新一代呼叫中心架构NGCC(Next Generation Call Center)如下图所示:

具体如何理解呢?

先从最简单的说起:个人A给个人B打了个电话。

  • 流程:A→PSTN→B
  • 解释:PSTN是Public Switched Telephone Network,公共交换电话网络,也就是运营商的电话网络。

然后来个复杂点的:个人A给呼叫中心400xxxxxxxx打了个电话,拨通后先听到了录音,“您好,找B类接线员说话请按0号键”。按了0,然后听到录音,“排队中,请稍后”。几分钟后接通,B0026号接线员接了电话。

流程:A→PSTN→PBX→IVR→ACD→B

解释:PBX是Private Branch Exchange,用户级交换机,这是企业内部的局端用户级交换机,整个呼叫中心的出入口设备。

PSTN到PBX之间是中继(分成模拟中继、数字中继、IP中继),这是将通讯公司的局端交换机与企业内部的用户级交换机(PBX)相连的通讯线路。

IVR是Interactive Voice Response,互动/交互式语音应答,我们把它叫语音导航。实现的是类似拨打10086后听到录音说,xx业务请按x,这个环节。主要用途是根据业务分流来电,进入对应的排队机。

ACD是Automatic Call Distribution,自动电话分配,也叫排队机。

再来个复杂点的:个人A给呼叫中心400xxxxxxxx打了个电话,拨通后先听到了录音,“您好,您想找哪类接线员?”

个人A说,“B~~”。

然后很快接通,“您好,这是B0026号机器人,有什么可以帮您?”

个人A说,“我不想跟机器人说话,泥奏凯~”

然后听到录音,“为您转接很贵的真人客服,排队中,请稍后”。

几分钟后接通,B1026号真人接线员接了电话。

流程:A→PSTN→PBX→IVR(→ASR→NLU)→ACD(→ASR→NLU→DM→NLG→TTS)→ACD→B

解释:现在智能的部分,也就是我们说的语音机器人的部分,分别在IVR和虚拟坐席处体现。

IVR部分,不再需要提示按键,而是直接问来电方需要办理什么业务,然后识别语音、理解意图后,进入对应的业务队列排队。排队后可以等待真人客服接待,也可以由机器人先行接待。

机器人(实际是服务器资源)资源空闲时,直接接待,进行语音对话,对话过程就是语音识别、语义理解、语音合成的多次调用,部分业务涉及业务数据接口对接调用,比如查询话费、积分。并可以根据需求自动或者选择转人工,再次进入排队,等候真人客服接待。

其中IVR部分示意图如下:

2. 集成实施

上面提到的全部流程中,PBX、IVR、ACD等部分基本都是由我们说的呼叫中心设备商提供,产品有三种类型:板卡式、交换机式、VoIP形式。

交换机式比较适合大型职场,例如三五百人以上,硬件价格五位数。交换机领域,主要有:avaya、genesys、cisco、华为、中兴,其中最常用的两家对比下来,avaya比genesys便宜(参见文章)。

板卡式适合中小型职场,比如几十人到两三百人,硬件价格四位数。基于板卡建设呼叫中心的步骤,可以参考使用三汇板卡的这几篇(主要前4篇讲原理)。

选择板卡之前,先要确定选用哪种中继线路,比如:使用常规的数字中继,那么就需要选择数字板卡,这个找板卡的供应商问就行了。通常来说呼叫中心要购买的一条E1数字中继报价五位数/年,由用户级交换机将局端的光信号转换为30路模拟信号,也就是支持30个人同时接打电话,通话费会另外按照实际呼出分钟数收取。

近期一个实际落地项目是选择了数字中继+Asterisk(开源VoIP PBX纯软方案),(可参考:安装配置调试)示意图如下:

具体的软件业务细节,比如:常规客服中心需要的管理模块、配置模块、工单服务、坐席服务、报表模块、CRM,还有比如:坐席班长监听、通话插入、质检,录音文件管理等整套软件细节,不做详述。

四、AI能力对接

在具体落地中,这个领域的常规参与者通常具备呼叫中心能力或者AI能力其中一种,而主要的对接点也就在于AI能力与呼叫中心设备去对接,而ASR/TTS与呼叫中心设备对接的常规协议主要是mrcp/sip。

媒体资源控制协议(Media Resource Control Protocol, MRCP)是一种通讯协议,用于语音服务器向客户端提供各种语音服务(如语音识别和语音合成)。有两个版本的MRCP协议,版本2使用SIP作为控制协议,版本1使用RTSP。

实际对接的时候,会遇到不少技术问题,有的呼叫中心厂商会要求ASR/TTS引擎做私有云部署,这样避免了内外网穿透时防火墙的诸多设置和语音流的时延。这对基于语义起家(并购买语音能力)的公司是一个小小的难题。

1. 语音识别

现有技术中实现一次性语音识别典型的流程时序,具体包括一下步骤:

  •  MRCP Client发送INVITE消息给MRCP Server请求建立会话,携带MRCP Client侧的SDP;
  • MRCP Server回复200表示请求已经成功接受处理,携带MRCP Server侧的SDP;
  • MRCP Client随后发送ACK消息证实200消息已经收到,至此一个SIP会话成功建立;
  • MRCP Client发送RECOGNIZE消息给MRCP Server请求语音识别,按照MRCP协议规定的格式携带相关的语音识别控制参数,并且指定语法文件路径;
  • MRCP Server接收RECOGNIZE请求,编译语法文件,回复200消息给MRCP Client;
  • MRCP Client此时开始根据之前协商好的SDP,开始源源不断的发送RTP语音流给MRCP Server;
  • MRCP Server接收RTP语音流,当检测到用户开始说话时,发送START-OF-INPUT事件;
  • 当MRCP Server根据语法文件定义得到识别结果时,通过RECOGNITION-COMPLETE事件返回识别结果;
  • MRCP Client发送BYE消息给MRCP Server结束会话;
  • MRCP Server发送200消息给MRCP Client确认结束;
  • MRCP Client通过上述流程获得MRCP Server提供的一次完整语音识别能力。

电话渠道的语音流采样率一般是8k 16bit,这种语音识别的准确率远远低于app等渠道采集音频的识别率。再加上人在打电话时说话方式相对随意,导致语音识别部分成为了影响电话机器人能力和效果的重要瓶颈。

2. 语音合成

实现语音合成典型的流程时序,具体包括一下部分:

  • SPEAK:向服务器端提供文本,启动语音合成(c→s)。
  • STOP:如果服务器正在语音合成资源,则停止语音合成与语音流(c→s)。
  • PAUSE:通知服务器资源暂停语音合成与语音流(c→s)。
  • RESUME:通知暂停的语音合成资源继续进行语音合成与语音流(c→s)。
  • CONTROL:更改语音合成资源相关参数,从而影响合成的语音流(c→s)。
  • SPEAK-COMPLETE: SPEAK请求已经成功处理(s→c)。
  • SPEECH-MARKER:服务器正在处理语音标签时,遇到请求消息头字段 Speech Marker中标记的tag(s→c)。
  • BARGE-IN-OCCURRED:客户端检测到barg-in-able事件或DTMF数字时,发送该消息通知服务器(c→s)。

现在主流厂商为了使通话效果尽可能模拟真人外呼,除了涉及业务接口调用的数据查询使用了TTS,基本采取整句录音的方式。

3. NLU部分

准确来说,一个简单的对话机器人系统框图,包括语音识别(ASR)、语音合成(TTS)、自然语言理解(NLU)、对话管理(DM)、自然语言生成(NLG)几个模块组成。而这一部分就是智能外呼系统的主流玩家——NLU类(智能客服)厂商的强项了。

对于呼叫中心从业者来说,ASR/TTS/NLU如同黑盒一般,只暴露出接口。而国内语音能力的供应商,要么很土豪,少量QPS不要钱,要么就是非常标准的报价五位数一条线路/年,实在也没有太多可以选择的余地。

对于只有NLU能力的厂商来说局面也是一样,除了需要接入ASR/TTS的能力,还需要去寻找可以合作的呼叫中心,并且想办法拿到尽可能低的话费报价。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

搭建AI智能语音外呼系统 智能语音外呼机器人 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java - 将节点添加到列表的末尾?

    这是我所拥有的 public class Node Object data Node next Node Object data Node next this data data this next next public Object g
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • 操作错误不会显示在 JSP 上

    我尝试在 Action 类中添加操作错误并将其打印在 JSP 页面上 当发生异常时 它将进入 catch 块并在控制台中打印 插入异常时出错 请联系管理员 在 catch 块中 我添加了它addActionError 我尝试在jsp页面中打
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • Mockito when().thenReturn 不必要地调用该方法

    我正在研究继承的代码 我编写了一个应该捕获 NullPointerException 的测试 因为它试图从 null 对象调用方法 Test expected NullPointerException class public void c
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • 为什么HashMap不能保证map的顺序随着时间的推移保持不变

    我在这里阅读有关 Hashmap 和 Hashtable 之间的区别 http javarevisited blogspot sg 2010 10 difference Between hashmap and html http javar
  • 使用Caliper时如何指定命令行?

    我发现 Google 的微型基准测试项目 Caliper 非常有趣 但文档仍然 除了一些示例 完全不存在 我有两种不同的情况 需要影响 JVM Caliper 启动的命令行 我需要设置一些固定 最好在几个固定值之间交替 D 参数 我需要指定
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch

随机推荐