最佳实践 | 基于腾讯云 MRCP-Server 打造简单智能外呼系统
一、智能外呼架构简介
智能外呼在国内已发展多年,整体的技术早已非常成熟。那么一个简单的智能外呼系统应该包含哪些东西呢?
运营商:运营商的线路资源是外呼系统的基础,国内就是移动、联通、电信,也有一些集成商。
呼叫中心:呼叫中心相关的软硬件用来对接运营商线路,市面上成熟产品很多,各大云厂商也都有相关的云服务。
开源方案也有一些,如 freeswitch、asterisk,网上有很多的资料可以参考。
外呼 SAAS 平台:用来串起来整个通话流程,这部分的实现相对来说最容易,国内各厂商基本都是自研
AI 能力:语音识别、语音合成、以及智能对话平台能力,关乎到智能外呼系统核心的体验、是否智能、拟人化等
智能外呼简单流程
上面介绍了智能外呼系统的大概组成,那具体是如何运行的呢?下面是一个简单的疫情调研外呼电话例子。
示例中,存在两轮对话,方框内容为机器人语音播报,两次回答“是否本人”、“是否阳性”是客户回答,走语音识别后进行判定。
在智能外呼系统中,对接语音识别和语音合成的部分,通常来说有两种方式:
1、外呼 SAAS 平台直接调用语音识别、语音合成
这种方式一般用完整的客户音频流去做语音识别(以便支持播报中打断、播报中关键词逻辑、播报中打断 &回复等功能)
2、通过 IVR 调用 MRCP-Server 接口来调用语音识别、语音合成
每次语音识别的音频,是机器人播报后,触发识别的一小段音频(类似上面示例中,就是“是否本人”“是否阳性”两段回答的语音片段)
下面我们分别看下两种方式对应的序列图。
无 MRCP-Server 流程
该方案的开发成本较高,通话流程的控制逻辑很大一部分在“外呼 SAAS 平台”内,且要对接语音识别、语音合成、智能对话平台等部分;
外呼通话接通的时候,客户的音频流就持续推到外呼 SAAS 平台,音频流持续送入语音识别,得到实时识别结果;
完整通话识别结果可以用来实现机器人播报中打断、播报中客户关键词识别 &处理(如转人工、新回复等)等。
有 MRCP-Server 流程
该方案的开发成本相对 2.1 要低不少,对接语音识别、语音合成的 MRCP-Server 一般各大厂商有现成的组件,不用去开发;
该方案只有机器人播报完/被打断后,才会调用 mrcp-server 启动识别,送入客户音频去做语音识别。
MRCP 作为标准协议,基本市面上的呼叫中心都是支持的,对接起来也较容易,下面讲一下笔者对接腾讯云 MRCP-Server 的过程。
二、腾讯云 MRCP-Server 对接
开始对接之前,我们需要先开通腾讯云的语音识别、语音合成服务。
开通语音识别 &语音合成
分别点击 腾讯云语音识别控制台 ,腾讯云语音合成控制台, 点击立即开通服务。
可以点击这里领取一个新人的体验资源包: https://cloud.tencent.com/product/asr/pricing
获取调用服务的 API 密钥
访问腾讯云的服务,都需要一个秘钥,在腾讯云访问管理的 API 密钥管理页面,可以新建一个秘钥,这个一定要保管好,不能泄露出去,防止被盗用。秘钥后面我们要用到。
MRCP-Server 部署
腾讯云的 MRCP-Server 有现成的部署包,不用自己开发对接 ASR&TTS,可以大大节约时间。
只要你有一个干净的 linux 环境,进行部署。部署环节分位以下几步:
1、解压 unimrcp.tar.gz 到部署路径
2、修改配置文件,运行 change.sh 分发配置文件
3、启动 &测试验证
下载 &解压
1、点击 MRCP-Server 部署包 下载部署包,传输到干净的 linux 环境
2、指定一个安装目录,这里使用使用 $project_path 来代表安装目录
3、执行解压命令
修改配置
执行以下命令,打开配置文件:
配置文件中各字段含义,可参考文件中注释,可以按照实际需要修改 server_ip、server_sip_port、server_mrcp_port 等配置。
请将 3.2 章节中,从官网获得的 appid、secretid、secretkey 填写到配置文件中对应位置。
修改完配置后,执行以下命令分发配置。
服务启动
运行以下命令启动服务:
成功启动会有如下提示:
运行如下命令也可确认是否成功启动。
如成功启动,会看到 2 个 tcp 端口,1 个 udp 端口
服务测试
进入 admin 使用 unimrcpclient 来测试 MRCP 服务,执行如下命令:
进入命令行界面,如下:
在交互输入栏输入“run recog” 来测试语音识别功能。
如果执行成功会出现类似如下结果:
如果还想测试语音合成能力,可以在交互输入栏输入“run synth” 可以测试。客户端显示出识别出结果为:“欢迎使用腾讯云语音合成”,则表示客户端发送文本正常。
对于返回的合成音频,可以检查 $project_path/unimrcp/var/synth 中的相应的音频,确认音频是否正常。
MRCP-Server 对接
只需对接 MRCP Server 的 IP 和 SIP 端口即可。
需要注意的是腾讯云 MRCP Server 使用的协议版本为 MRCPv2。
参考 3.3.3 章节,可以获得对应配置,或者去修改对应的端口号。通过 ifconfig 命令获取机器 IP。如下图,5060 是 sip 端口号。
下面给出对接华为 IVR 的一个实例:
如果使用 Freeswitch 来对接的话,在 profile 里面设置即可,如下图:
MRCP 协议识别流程简介
关于 MRCP 协议这里就不多说了,可以参考 MRCP 协议手册:https://www.rfc-editor.org/rfc/rfc6787
目前大家围绕 MRCP 的开发,基本都是基于开源软件 Unimrcp,它完整实现了 MRCP 协议(含 SIP/RTSP/MRCP/RTCP/RTP)
MRCP 使用 SIP 协议来控制整个音频资源的通信流程,RTP 作为实际的音频数据的承载协议,RTCP 负责 RTP 过程中的 Qos。
下面是 MRCP 调用语音识别服务的序列图:
上图描述了整个通信的过程,下面具体描述一下。
MRCP 会话建立
通过 SIP 协议来建立会话。
MRCP Client 的 SIP INVITE 信息包含 Client 侧 SDP 信息。其中“resource:speechrecog”代表请求语音识别资源。
MRCP Server 回复 SIP 200 OK 时会发送 Server 侧的的 SDP 信息,包含 channel 标识等。
SIP INVITE 消息示例:
SIP 200 OK 消息示例:
MRCP DEFINE-GRAMMAR
通过 MRCP DEFINE-GRAMMAR 消息,可以将一些语音识别所需的参数关联进去,来帮助更好的识别(DEFINE-GRAMMAR 必须在 RECOGNIZE 之前发送)
例如下面的 DEFINE-GRAMMAR 消息体中,设置 hotword_id 和 customization_id,发送给腾讯云的 MRCP-Server,就可以分别设置语音识别的热词和自学习参数,来做识别加强。
MRCP RECOGNIZE
MRCP RECOGNIZE 消息用来启动一次语音识别,打开 channel 准备接收数据。
RECOGNIZE 的 Header 有很多种类型,其中以下 4 种是在外呼场景最常见的 4 个。
Start-Input-Timers:是否启动 no-input 计时器,大多数情况下设置 true 即可,配合 No-Input-Timeout 一起使用。
No-Input-Timeout:单位为 ms,当识别开始并在一段时间内没有检测到语音时,向 client 发送一个 RECOGNITION-COMPLETE 事件,Completion-Cause 为“no-input-timeout”,终止识别操作。
如该参数设置 3000,代表外呼中的等待客户回复的时候,超过 3 秒客户一直没说话,触发 no-input-timeout 事件。机器人可以尝试再次播报或者是挂机等操作。
Recognition-Timeout:单位为 ms,识别超时时间,用于语音识别 vad(人声检测)断不开一直识别的情况,向 client 发送一个 RECOGNITION-COMPLETE 事件,Completion-Cause 为“recognition-timeout”,终止识别操作。
如该参数设置 10 秒,代表外呼中客户最多一次不停的说 10 秒的话,10 秒触发 Recognition-Timeout 事件,机器人根据客户说话结果生成回复。
Speech-Complete-Timeout:单位为 ms,静音尾部检测时间。用于设置语音识别 vad 静音检测阈值,一般会设置在 500ms-1000ms 的区间。
下面是一个 RECOGNIZE 消息的实例:
MRCP-Server 给 Client 响应,IN-PROGRESS 表示识别处理中。
MRCP START-OF-INPUT
MRCP START-OF-INPUT 事件表示识别正式开始,数据通过 RTP 持续传输过来。
MRCP RECOGNITION-COMPLETE
MRCP RECOGNITION-COMPLETE 事件表示识别结束,并返回识别结果
三、常见问题
发现有任何异常的时候,可以先去排查下日志。MRCP Server 的日志为:$project_path/unimrcp/log/unimrcpserver_current.log
会话相关
MRCP Client 日志出现 Failed to Create Listening Socket
原因:MRCP 端口被占用
解决方法:使用以下命令检查端口 $(port)(默认 1544)是否被占用,若被其他服务占用,则参考 3.3.2 修改 &分发配置并重启服务。
netstat -anp |grep $(port)
MRCP Server 日志出现 Failed to Create NUA
原因:SIP 端口被占用
解决方法:使用以下命令检查端口 $(port)(默认 5060)是否被占用,若被其他服务占用,则参考 3.3.2 修改 &分发配置并重启服务。
netstat -anp |grep $(port)
MRCP Client 日志出现 Connection refused
原因:MRCP Server 未启动,或者是没有正确配置 MRCP Server 的 ip 和端口。
解决方法:参考 3.3.3 章节,确认 MRCP Server 是启动状态,如果已启动,确认 client 端设置了正确的 ip 和端口。
语音识别相关
MRCP Client 没有拿到识别结果
查看 MRCP Server 日志,如果出现类似“send to asr error, httpcode 0, rsp_code xxx” 这样的日志,说明识别请求发送失败了,可以根据错误码提示排查一下错误。
如果出现类似如下日志,说明语音识别的请求是正常发送了的。
这种情况下没有拿到识别结果,可以往下分析一下日志,一般就是如下两种情况:
1、用户一直没说话,默认 5s 没有说话会话自动超时,发送识别结果为 no-input-timeout。详细可参考 4.3 章节里面的 header 说明。
client 侧发送了 STOP 请求,STOP 请求会中断识别,并关闭链接,导致 client 端无法收到识别结果。
MRCP Server 如何设置热词 &自学习
关于热词和自学习的设置,使用 3.1 章节的账号登陆语音识别控制台,参考下面两个文档进行设置。
自学习设置:https://cloud.tencent.com/document/product/1093/38416
热词设置:https://cloud.tencent.com/document/product/1093/40996
控制台里面可以看到对应的热词 ID 和自学习 ID,参考 4.2 章节, DEFINE-GRAMMAR 消息体中,分别设置 hotword_id 和 customization_id。
这样对应的热词和自学习就可以生效了。
MRCP Server 如何修改识别结果样式
默认的返回结果为如下样式:
如果想改下对应的返回结构,可以修改
默认格式如下:
如果想把识别结果放到 input speech 节点里。则可以修改为:
如果想修改成 JSON 格式,则可以调整为:
修改后对应结果变为:
如何修改语音识别参数
运行如下命令打开 ASR 对应的配置文件:
[tcloud_asr]节点下的内容都是语音识别的参数,参数的详细含义,可以参考官网文档:https://cloud.tencent.com/document/product/1093/48982
配置文件里面的参数都不建议修改,脏词过滤、语气词过滤、标点、数字转换几个可以根据需求来修改。
修改配置后记得重启 MRCP Server 以便生效。
语音合成相关
如何设置音色 &音量 &语速
参考 MRCP 标准协议中相关描述:https://datatracker.ietf.org/doc/id/draft-ietf-speechsc-mrcpv2-22.html#sec.synthesizeHeaders
以上是一个实际调用示例,实际的调用中,最常用的也就是这三个参数。
Voice-Name:音色,对应腾讯云实时合成里面的 VoiceType 参数
Prosody-Volume:音量,对应腾讯云实时合成里面的 Volume 参数
Prosody-Rate:语速,对应腾讯云实时合成里面的 Speed 参数
这几个参数对应的值,可以参考官网文档:https://cloud.tencent.com/document/product/1073/34093
如何实现中断播报
client 发送一个 STOP 消息即可中断语音合成播报。详细参考:https://datatracker.ietf.org/doc/id/draft-ietf-speechsc-mrcpv2-22.html#anchor46
版权声明: 本文为 InfoQ 作者【牵着蜗牛去散步】的原创文章。
原文链接:【http://xie.infoq.cn/article/44b43bcc7441ce191920165f4】。文章转载请联系作者。
评论