顶顶通呼叫中心中间件(mod_cti基于FreeSWITCH)-大模型电话机器人

语音流直接对接Realtime API(音频输入输出)多模态大模型

直接把音频流输出给大模型,大模型返回音频流。

顶顶通CTI对Realtime API 的支持

提供了以下2个APP可对接任意音频输入输出(比如RTC)的大模型

  • cti_audio_stream 通过TCP推流和播放流,适合用于人机对话场景。

  • cti_unicast_start 通过旁路的方式UDP或者TCP推流和播放流,对接Realtime API 的同时还支持对通道进行放音操作。 适合于质检,机器人辅助场景。

通过TCP推流和播放流,适合用于人机对话场景

app: cti_audio_stream
参数 remote-ip:remote-port <native> <param>

  • native 可选参数 如果不设置,流格式为 8000hz 16位,如果设置了,就是原始的音频格式
  • param 自定义参数

推流协议

  1. 前面4字节 引导数据长度 网络字节顺序
  2. 时间戳 8字节
  3. 引导数据 {"uuid":"","codec":"","param":"自定义参数"}
  4. 数据流

连接断开后会自动重连,并且重发引导数据。
返回的放音流需要和推流的编码一样,不需要引导数据。

旁路的方式UDP或者TCP推流和播放流,适合于质检,机器人辅助场景

app: cti_unicast_start 启动推流
参数 tcp|udp remote-ip remote-port <local-ip> <local-port> <play|mix>

  • tcp|udp 使用tcp还是udp协议推流
  • remote-ip 远端 ip
  • remote-port 远端端口,不设置用0.0.0.0
  • local-ip 本地端口,不设置好用0,随机端口
  • play|mix
    • play 支持播放远端返回的流,发送方必须是远端IP和远端端口
    • mix 把远端的流和本地放音混音

api: uuid_cti_unicast_start 启动推流
参数 uuid tcp|udp remote-ip remote-port <local-ip> <remote-ip> <play|mix>

api: uuid_cti_unicast_stop 停止推流
参数 uuid

文字方式对接文本大模型

mod_cti先把声音转换成文字,然后把文字提交给大模型,根据大模型返回执行放音,顶顶通mod_cti话术引擎用的就是这种方式。

视频教程

顶顶通大模型电话机器人用法讲解-基本部分

顶顶通大模型电话机器人用法讲解-如何使用大模型

顶顶通大模型电话机器人用法讲解-让大模型提取说话内容到变量

顶顶通话术引擎对接大模型原理和用法说明

顶顶通话术引擎充分发挥大模型prompt的强大功能,把关联节点和知识库可以自动带入prompt。
如果节点开启了大模型匹配,会根据大模型匹配设置生成 ${playtext}${prompttext}
${playtext} 所有关联节点的放音内容。
${prompttext} 所有关联节点的意向Prompt,也就是节点的进入规则。
如果大模型匹配包含了子流程,就会把关联的子流程的文本放音加入${playtext},意向Prompt加入${prompttext}
如果大模型匹配包含了知识库,就会把关联的知识库的文本放音加入${playtext},意向Prompt加入${prompttext}
如果大模型匹配包含了全局流程,就会把关联的全局流程的子流程的文本放音加入${playtext},意向Prompt加入${prompttext}

用大模型判断意向选择分支,代替关键词匹配

适合场景:需要严格按流程执行,比如电话回访,电话调查。

## 任务描述 ## 
根据给定的对话上下文及产品信息,从候选回答中选择最合适的回答。

## 产品信息 ##
请在这里描述产品信息

## 候选回答列表 ##
${playtext}

## 选择规则 ##
${prompttext}

## 输出格式示例 ##
- id_0f1
- id_0k0
- unmatch

## 输出说明 ##
如果存在合适的候选回答,只要输出其ID,不要输出其他信息;
若没有合适的候选回答,必须输出"unmatch"。

如果有匹配的回答分支,大模型会输出回答ID,话术引擎切换到流程节点,播放节点预先设置的放音;

如果没有匹配的回答分支,大模型会输出unmatch,话术引擎会忽略模型返回,继续执行兜底(any)匹配,如果设置了兜底流程就会进入兜底流程节点。

用大模型判断意向选择分支和兜底回答

适合场景:大部分场景都合适

## 任务描述 ## 
根据给定的对话上下文及产品信息,从候选回答中选择最合适的回复。
如果存在完全符合情境的候选回答,只输出其ID,不要输出其他信息;
若没有合适的候选回答,基于对话上下文和产品信息模仿真人说话口吻编写一条简短且恰当的新回复。

## 候选回答列表 ##
${playtext}

## 选择规则 ##
${prompttext}

如果有匹配的回答分支,大模型会输出回答ID,话术引擎切换到流程节点,播放节点预先设置的放音;

如果没有匹配的回答分支,大模型会生成一个回答,话术引擎调用流TTS播放这个回答,不会切换流程。

用大模型判断意向选择分支和兜底回答以及优化话术设置的回答内容

适合场景:既要按预先设置的流程步骤执行,又要充分利用大模型生成合适的回答。

## 任务描述 ## 
根据给定的对话上下文及产品信息,从候选回答中选择最合适的回复。
如果存在完全符合情境的候选回答,输出其ID,回答内容输出空;
如果有接近但不完全合适的候选回答,输出该候选回答ID,并提供一个优化后的回答内容,优化后的回答必须和候选回答类似含义;
若没有合适的候选回答,候选回复id设置为null,并基于对话上下文和产品信息模仿真人说话口吻编写一条简短且恰当的新回复。

## 候选回答列表 ##
${playtext}

## 选择规则 ##
${prompttext}

## 输出格式要求 ##
id:候选回答ID content: 回答内容

注意输出格式要求: 必须要求大模型输出“id:候选回答ID content: 回答内容” 这样的格式,不然输出格式要求不对,话术引擎解析不了。

如果有完全符合情境的回答分支,大模型会输出回答ID,不会优化回答内容,话术引擎切换到流程节点,播放节点预先设置的放音;

如果有接近但不完全合适回答分支,大模型会输出回答ID,和输出优化后的回答内容,话术引擎切换到流程节点,播放大模型优化后的回答内容;

如果没有匹配的回答分支,大模型会生成一个回答,话术引擎调用流TTS播放这个回答,不会切换流程。

让大模型来收集数据和确定输入

视频讲解

比如有这样一个流程

机器人:你需要多少资金?

用户:我需要30万。

机器人:确定一下,你需要的资金是30万对吧。

## 任务描述 ## 
根据给定的对话上下文及产品信息,从候选回答中选择最合适的回复。并把输入的金额设置到JSON格式的money属性。
如果存在完全符合情境的候选回答,输出其ID,回答内容输出为空;
若没有合适的候选回答,基于对话上下文和产品信息模仿真人说话口吻编写一条简短且恰当的新回复。


## 候选回答列表 ##
${playtext}

## 选择规则 ##
${prompttext}

## 输出格式示例 ##
{
"id": "id_0f0",
"content": "回答内容",
"variables": {
"money": "资金数额"
}
}

可以通过设置输出格式为json, 通过例子设置要收集的数据内容。

顶顶通话术引擎会把variables的所有成员加入通道变量。

放音时候播放文字里面加入通道变量名(这个例子是 ${money})就可以复述出收集的数据了。

让大模型只根据意向Prompt来选择

有时候候选回答会干扰大模型的理解,设置以下prompt让大模型只根据意向Prompt来选择

## 任务描述 ## 
根据给定的选择规则,选择一个最符合的
如果存在符合的,输出其ID,不要输出其他信息;
若没有符合的,输出"unmatch"。


## 选择规则 ##
${prompttext}

${prompttext} 就是所以关联节点的意向Prompt的集合。

让大模型根据历史记录来选择

比如历史对话问了用户年龄和身高,需要根据年龄和身高走不同的节点,可以在节点的意向Prompt设置复合规则,见下面的示例

  • 身高大于170并且体重大于50公斤,选择这个

  • 身高大于160并且体重大小于40公斤,选择这个

可以多次重复测试prompt或者使用prompt优化工具来优化prompt, 在大模型时代,能写出高质量的prompt才可以用好大模型。