快速跑通

最近更新时间:2025-08-06 15:33:12

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

方案介绍

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

方案架构图





业务流程图





集成指引

前提条件

注意:
AI实时对话调用会产生使用费用,具体详情请参见 AI 实时对话计费说明
2. 开通 语音转文字 服务。
3. 创建腾讯云 TTS(可选,支持第三方)。
4. 创建 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();
在进入房间后,调用 getPusherInstance().start() 或者开启自动推流模式即可开始推流。
enterRoom(options) {
this.setData({
pusher: this.TRTC.enterRoom({
sdkAppID: 1400xxxxx, // 您的腾讯云账号
userID: 'trtc-user', //当前进房用户的userID
userSig: 'xxxxxxx', // 您服务端生成的userSig
roomID: 1234, // 您进房的房间号,
enableMic: true, // 进房默认开启音频上行
}),
}, () => {
this.TRTC.getPusherInstance().start() // 开始进行推流
})
},
说明:
AI 实时对话场景对音频采集端的降噪能力有较高要求,为了获得更好的体验,建议 打开 AI 降噪功能此外,我们还有专门针对 AI 实时对话场景训练的降噪模型,欢迎通过商务或 提交工单 联系我们。

二、发起 AI 对话

开始 AI 对话:StartAIConversation

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

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

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

接收实时字幕

消息格式
{
"type": 10000, // 10000表示是下发的实时字幕
"sender": "user_a", // 说话人的userid
"receiver": [], // 接收者userid列表,该消息实际是在房间内广播
"payload": {
"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 被打断 5 已说完
}
}


示例代码

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 对话 接口,停止该对话任务。
2. 客户端退出 TRTC 房间,建议参见 退出房间

六、其他功能

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