快速跑通

本文将介绍如何基于 TRTC SDK 实现 AI 实时对话的解决方案。

方案介绍

方案基于 TRTC SDK 调用 TRTC 服务,通过调用 AI 实时对话的接口,可以实现极低延迟的 AI 实时对话服务。本方案为您提供了非常灵活的集成方案,您可以根据业务的实际需求接入第三方的 LLM 和 TTS,实现高效的业务实践效果。在整体方案中,我们针对语音实时降噪、AI 智能打断、上下文管理都有较多的技术优化,不断提升用户体验。

方案架构图



业务流程图



集成指引

前提条件

注意:
联系商务 开通 AI 实时对话服务。
2. 创建腾讯云 TTS(可使用第三方)。
3. 创建 LLM 应用:可以自选适合的大模型厂商进行注册。

一、集成 TRTC SDK

第一步:导入 TRTC SDK 到项目中

第二步:进入 TRTC 房间

第三步:发布音频流

Android&iOS&Flutter
Web&H5
您可以调用 startLocalAudio 来开启麦克风采集,该接口需要您通过 quality 参数确定采集模式。虽然这个参数的名字叫做 quality,但并不是说质量越高越好,不同的业务场景有最适合的参数选择(这个参数更准确的含义是 scene)。
AI 对话场景下推荐使用 SPEECH 模式,该模式下的 SDK 音频模块会专注于提炼语音信号,尽最大限度的过滤周围的环境噪音,同时该模式下的音频数据也会获得较好的差质量网络的抵抗能力,因此该模式特别适合于“视频通话”和“在线会议”等侧重于语音沟通的场景。
Android
iOS&Mac
Flutter
// 开启麦克风采集,并设置当前场景为:语音模式(高噪声抑制能力、强弱网络抗性)
mCloud.startLocalAudio(TRTCCloudDef.TRTC_AUDIO_QUALITY_SPEECH );
self.trtcCloud = [TRTCCloud sharedInstance];
// 开启麦克风采集,并设置当前场景为:语音模式(高噪声抑制能力、强弱网络抗性)
[self.trtcCloud startLocalAudio:TRTCAudioQualitySpeech];
// 开启麦克风采集,并设置当前场景为:语音模式(高噪声抑制能力、强弱网络抗性)
trtcCloud.startLocalAudio(TRTCAudioQuality.speech);
使用 trtc.startLocalAudio() 方法开启麦克风,并发布到房间。
await trtc.startLocalAudio();
说明:
AI 实时对话场景对音频采集端的降噪能力有较高要求,为了获得更好的体验,建议 打开 AI 降噪功能此外,我们还有专门针对 AI 实时对话场景训练的降噪模型,欢迎通过商务或 提交工单 联系我们。

二、发起 AI 对话

开始 AI 对话:StartAIConversation

通过业务后台调用 开始 AI 对话任务 接口,拉机器人进房,来发起 AI 实时对话。
注意:
RoomId 需要和客户端进房的 RoomId 保持一致,并且房间号的类型(数字房间号、字符串房间号)也必须相同(既机器人和用户需要在同一个房间)。
LLMConfigTTSConfig 均为 JSON 字符串,需要正确配置才能成功发起 AI 实时对话。
目前支持的 LLMConfigTTSConfig 配置说明:
推荐第一次调用 开始 AI 对话任务 接口前,通过以下页面来验证LLMConfigTTSConfig的参数,具体如下:
说明:
如果以上步骤都操作正确,现在已经可以和 AI 进行对话啦!

三、接收 AI 对话字幕及 AI 状态

通过 TRTC SDK 接收自定义消息功能,在客户端上监听回调来接收实时字幕与 AI 状态等数据。cmdID 固定是1

接收实时字幕

消息格式
{
"type": 10000, // 10000表示是下发的实时字幕
"sender": "user_a", // 说话人的userid
"receiver": [], // 接收者userid列表,该消息实际是在房间内广播
"payload": {
"text":"", // 语音识别出的文本
"translation_text":"", // 翻译的文本
"start_time":"00:00:01", // 这句话的开始时间
"end_time":"00:00:02", // 这句话的结束时间
"roundid": "xxxxx", // 唯一标识一轮对话
"end": true // 如果为true,代表这是一句完整的话
}
}

接收机器人状态

消息格式
{
"type": 10001, // 机器人的状态
"sender": "user_a", // 发送者userid,这里是机器人的id
"receiver": [], // 接受者userid列表,该消息实际是在房间内广播
"payload": {
"roundid": "xxx", // 唯一标识一轮对话
"timestamp": 123,
"state": 1, // 1 聆听中 2 思考中 3 说话中 4 被打断
}
}


示例代码

Android
iOS
Web&H5
@Override
public void onRecvCustomCmdMsg(String userId, int cmdID, int seq, byte[] message) {
String data = new String(message, StandardCharsets.UTF_8);
try {
JSONObject jsonData = new JSONObject(data);
Log.i(TAG, String.format("receive custom msg from %s cmdId: %d seq: %d data: %s", userId, cmdID, seq, data));
} catch (JSONException e) {
Log.e(TAG, "onRecvCustomCmdMsg err");
throw new RuntimeException(e);
}
}
func onRecvCustomCmdMsgUserId(_ userId: String, cmdID: Int, seq: UInt32, message: Data) {
if cmdID == 1 {
do {
if let jsonObject = try JSONSerialization.jsonObject(with: message, options: []) as? [String: Any] {
print("Dictionary: \(jsonObject)")
// handleMessage(jsonObject)
} else {
print("The data is not a dictionary.")
}
} catch {
print("Error parsing JSON: \(error)")
}
}
}
trtcClient.on(TRTC.EVENT.CUSTOM_MESSAGE, (event) => {
let data = new TextDecoder().decode(event.data);
let jsonData = JSON.parse(data);
console.log(`receive custom msg from ${event.userId} cmdId: ${event.cmdId} seq: ${event.seq} data: ${data}`);
if (jsonData.type == 10000 && jsonData.payload.end == false) {
// 字幕中间状态
} else if (jsonData.type == 10000 && jsonData.payload.end == true) {
// 一句话说完了
}
});
说明:
我们有更多 AI 对话客户端上的回调,具体可参见:AI 对话状态回调AI 对话字幕回调AI 对话指标回调AI 对话错误回调

四、发送自定义消息

统一通过端上发送 TRTC 自定义消息,cmdID 固定是2
可以通过发送自定义的文本,跳过 ASR 过程,直接跟 AI Service 进行文字沟通。
{
"type": 20000, // 端上发送自定义文本消息
"sender": "user_a", // 发送者userid, 服务端会check该userid是否有效
"receiver": ["user_bot"], // 接受者userid列表,只需要填写机器人userid,服务端会check该userid是否有效
"payload": {
"id": "uuid", // 消息id,可以使用uuid,排查问题使用
"message": "xxx", // 消息内容
"timestamp": 123 // 时间戳,排查问题使用
}
}
可以通过发送打断信令来进行打断。
{
"type": 20001, // 端上发送打断信令
"sender": "user_a", // 发送者userid, 服务端会check该userid是否有效
"receiver": ["user_bot"], // 接受者userid列表,只需要填写机器人userid,服务端会check该userid是否有效
"payload": {
"id": "uuid", // 消息id,可以使用uuid,排查问题使用
"timestamp": 123 // 时间戳,排查问题使用
}
}

示例代码

Android
iOS
Web&H5
public void sendInterruptCode() {
try {
int cmdID = 0x2;

long time = System.currentTimeMillis();
String timeStamp = String.valueOf(time/1000);
JSONObject payLoadContent = new JSONObject();
payLoadContent.put("timestamp", timeStamp);
payLoadContent.put("id", String.valueOf(GenerateTestUserSig.SDKAPPID) + "_" + mRoomId);

String[] receivers = new String[]{robotUserId};

JSONObject interruptContent = new JSONObject();
interruptContent.put("type", AICustomMsgType.AICustomMsgType_Send_Interrupt_CMD);
interruptContent.put("sender", mUserId);
interruptContent.put("receiver", new JSONArray(receivers));
interruptContent.put("payload", payLoadContent);

String interruptString = interruptContent.toString();
byte[] data = interruptString.getBytes("UTF-8");

Log.i(TAG, "sendInterruptCode :" + interruptString);

mTRTCCloud.sendCustomCmdMsg(cmdID, data, true, true);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JSONException e) {
throw new RuntimeException(e);
}
}

@objc func interruptAi() {
print("interruptAi")
let cmdId = 0x2
let timestamp = Int(Date().timeIntervalSince1970 * 1000)
let payload = [
"id": userId + "_\(roomId)" + "_\(timestamp)", // 消息id,可以使用uuid,排查问题使用
"timestamp": timestamp // 时间戳,排查问题使用
] as [String : Any]
let dict = [
"type": 20001,
"sender": userId,
"receiver": [botId],
"payload": payload
] as [String : Any]
do {
let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])
self.trtcCloud.sendCustomCmdMsg(cmdId, data: jsonData, reliable: true, ordered: true)
} catch {
print("Error serializing dictionary to JSON: \(error)")
}
}
const message = {
"type": 20001,
"sender": "user_a",
"receiver": ["user_bot"],
"payload": {
"id": "uuid",
"timestamp": 123
}
};

trtc.sendCustomMessage({
cmdId: 2,
data: new TextEncoder().encode(JSON.stringify(message)).buffer
});
注意:
目前小程序端暂不支持接收和发送自定义消息,如果您想在小程序端实现接收字幕或发送消息等功能,需要使用 IM 提供的即时通信来实现,可通过商务或 提交工单 联系我们开通 IM 信令通道。

五、停止 AI 对话,退出 TRTC 房间

1. 服务端停止 AI 对话任务。
通过业务后台调用 停止 AI 对话 接口,拉机器人进房,来发起 AI 实时对话。
2. 客户端退出退出 TRTC 房间,建议参见 退出房间(Android&iOS&Windows&Mac)

六、其他功能

1、其他服务端接口

查询 AI 对话任务状态:DescribeAIConversation
可以查询 AI 对话任务状态。有 4 个值:
1.1 Idle表示任务未开始。
1.2 Preparing表示任务准备中。
1.3 InProgress表示任务正在运行。
1.4 Stopped表示任务已停止,正在清理资源中。
更新 AI 对话启动参数:UpdateAIConversation
可以在对话过程中,动态更新 TTS 的音色。
控制 AI 对话任务:ControlAIConversation
当您想让机器人主动播报文本的时候,可以使用该接口。

2、开启服务端回调

注意:
回调地址在 TRTC 控制台设置,AI 实时对话回调。
可配合 TRTC 房间与媒体回调 配合使用,丰富功能。

3、其余高级功能介绍

功能
操作指引
智能打断
实现上下文管理
调用 function call