一、方案概述
| 场景 | 具体应用 |
| 社交娱乐场景 | 情感陪伴:AI 虚拟伙伴提供 1v1 聊天陪伴。角色扮演:定制化 AI 人设进行1v1 陪伴沟通,AI 主播分身。娱乐互动:游戏、直播等场景的 AI 互动体验。 |
| 在线教育场景 | AI 老师 :根据学生知识能力和提问进行在线答疑。 |
| 智能销售、客户场景 | AI 销售、客服:7×24小时自动回复用户咨询。 |
二、接入方案
腾讯云即时通信 IM 提供两种接入 AI 能力方案供你参考:
方案一:AI 通道接入【推荐】,只需将你的 AI 服务配置在 IM 后台,IM 云端后台完成 IM 会话 与 AI 的后台部分交互,大幅减少开发工作量。
方案二:AI 自集成接入,即需客户业务后台自行通过接收机器人第三方消息回调,完成将 IM 消息发送给 AI 服务获取回复 ,并将 AI 回复内容通过接口到 IM 会话中的整个流程开发。
| 对比项 | AI 通道方案 | AI 自集成方案 |
| AI 机器人角色数量 | 默认20个,如需提升可联系我们 | 20个 |
| 支持聊天类型 | 单聊 | 单聊和群聊 |
| 接入开发难度 | 低 | 高 |
| 消息投递 AI | 客户侧无需处理,IM 后台打通会话和 AI 服务 | 客户侧基于 IM 消息回调后自行处理 |
| 是否支持流式消息 | UIKit 接入默认支持,无需开发 | 需调用发送流式响应消息接口实现 |
| AI 输出内容审核 | AI 生成的内容均由机器人账号输出,可使用 AI 内容理解及审核对违规内容进行拦截 | |
| 费用 | 免费内测中 | 无额外费用 |
注意:说明:
注意:另外通过腾讯云提供的智能客服接入 AI 能力,通过智能机器人也可实现 FAQ 智能问答、闲聊、数据运营看板等 AI 能力,结合腾讯云即时通信 IM 产品,你可以快速实现多平台跨终端互通的聊天机器人,更多请前往 智能客服。
三、步骤1:创建 AI 机器人
集成 AI 聊天机器人功能之前,请先在完成 AI 机器人创建,详见创建机器人。
四、步骤2:集成源码
1. 从 GitHub 下载 TUIKit 源码。使 TUIKit 文件夹跟自己的工程文件夹同级,例如:
2. 在 settings.gradle 中添加 TUIChat 组件:
// 引入内部组件通信模块 (必要模块)include ':tuicore'project(':tuicore').projectDir = new File(settingsDir, '../TUIKit/TUICore/tuicore')// 引入 IM 组件公共模块(必要模块)include ':timcommon'project(':timcommon').projectDir = new File(settingsDir, '../TUIKit/TIMCommon/timcommon')// 引入聊天功能模块 (基础功能模块)include ':tuichat'project(':tuichat').projectDir = new File(settingsDir, '../TUIKit/TUIChat/tuichat')
3. 在 App 模块中添加 TUIChat 依赖:
api project(':tuichat')
4. 添加 Maven 仓库 和 Kotlin 支持,在 root 工程的 build.gradle 文件(与 settings.gradle 同级)中添加以下内容:
buildscript { repositories { mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.0.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" }}
注意:说明:
注意:如果你使用 Gradle 8.x,则需要添加以下代码。
buildscript { repositories { mavenCentral() maven { url "https://mirrors.tencent.com/nexus/repository/maven-public/" } } dependencies { classpath 'com.android.tools.build:gradle:8.0.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0" }}
五、步骤3:开始使用
1. 添加好友。
使用 RestAPI 添加 步骤1 中创建的机器人为好友。
注意:为避免你的 AI 资源被恶意消耗,现只支持使用 RestAPI 添加机器人好友,用户无法主动添加 AI 机器人为好友。
2. 组件登录。
TUIChat 组件登录成功之后才能正常使用 AI 聊天功能。其中,SDKAppID 需要在 即时通信 IM 控制台 创建并获取,userSig 需要按规则计算,详细步骤请参见文档 跑通 Demo > Android。
示例代码如下所示:
// 在用户 UI 点击登录的时候调用TUILogin.login(context, sdkAppID, userID, userSig, new TUICallback() { @Override public void onSuccess() { } @Override public void onError(final int code, final String desc) { }});
3. 跳转到聊天窗口 Activity。
在控制台上获取 AI 机器人 的 userID,传入参数并跳转到聊天界面。
示例代码如下所示:
经典版简约版Intent intent = new Intent(this, TUIC2CChatActivity.class);// chatID 是机器人的 UserIDintent.putExtra(TUIConstants.TUIChat.CHAT_ID, "chatID");intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_C2C);startActivity(intent);Intent intent = new Intent(this, TUIC2CChatMinimalistActivity.class);// chatID 是机器人的 UserIDintent.putExtra(TUIConstants.TUIChat.CHAT_ID, "chatID");intent.putExtra(TUIConstants.TUIChat.CHAT_TYPE, V2TIMConversation.V2TIM_C2C);startActivity(intent);
你也可以将 TUIChat 聊天界面,嵌入到自己的 Activity 中。
示例代码如下所示:
经典版简约版Fragment fragment;// chatID 是机器人的 UserIDC2CChatInfo c2cChatInfo = new C2CChatInfo();c2cChatInfo.setId(chatID);TUIC2CChatFragment tuic2CChatFragment = new TUIC2CChatFragment();tuic2CChatFragment.setChatInfo(c2cChatInfo);fragment = tuic2CChatFragment;getSupportFragmentManager().beginTransaction() .add(R.id.chat_fragment_container, fragment).commitAllowingStateLoss();Fragment fragment;// chatID 是机器人的 UserIDC2CChatInfo c2cChatInfo = new C2CChatInfo();c2cChatInfo.setId(chatID);TUIC2CChatMinimalistFragment tuic2CChatFragment = new TUIC2CChatMinimalistFragment();tuic2CChatFragment.setChatInfo(c2cChatInfo);fragment = tuic2CChatFragment;getSupportFragmentManager().beginTransaction() .add(R.id.chat_fragment_container, fragment).commitAllowingStateLoss();
六、步骤1:后台接入流程
整体接入流程如下:
下文中的实践步骤以接入 MiniMax 中文大语言模型为例,类 ChatGPT 服务均可通过文中介绍的方法实现接入。
1. 创建即时通信 IM 应用
登录 即时通信 IM 控制台,创建应用,并获取应用的 SDKAppID 和密钥(以下称为 IM Key)。
2. 注册 AI 服务商账号
注册并登录计划接入的 AI 服务商,并获取 API 密钥(以下称为 AI_SECRET_KEY)。
3. 创建机器人账号
通过 REST API 创建一个机器人账号。机器人账号是一种特殊的用户账号,它也通过 UserID 来唯一标识(但是其 UserID 必须以@RBT#开头),具有昵称、头像、签名等基本属性。假设你成功创建了一个昵称为 MyRobot 的机器人@RBT#001。
4. 配置第三方回调
即时通信 IM 第三方回调即云 IM 后台会在某一事件发生之前或者之后,向 App 的后台服务器发送请求,App 后台可以据此进行必要的数据同步,或者干预事件的后续处理流程。我们将使用“机器人事件回调”监听用户发消息给机器人,或者在群聊中@机器人的事件,并对其做出反应。在腾讯云 IM 控制台中找到“机器人事件回调”,点击开启并保存。
5. 开发 App 后台服务
以单聊为例,总体上的工作流程如下:
5.1 用户 user1 发消息 "hello" 给机器人 @RBT#001。
5.2 云 IM 后台通过第三方回调将事件通知到 App 后台,通知内容包含发送方 user1,接收方 @RBT#001,消息内容 "hello" 以及其他信息。
5.3 App 后台调用 AI 服务接口(这篇示例 MiniMax API),并得到响应回复内容,如 "nice to meet you";
5.4 App 后台调用 REST API 接口(单聊为 sendmsg 接口,群聊为 send_group_msg 接口),将回复内容以 @RBT#001 的身份发送给 user1。
下面我们使用 Golang ,向你展示 App 后台的关键代码。
注意:说明:
注意:下文代码仅作示例,省略了大量异常处理代码,请勿直接用于生产环境。
分发处理回调命令
我们创建一个监听在80端口的 HTTP 服务,注册一个 URL 为 /im 的处理函数 handler,所有发送给 http:///im 的请求都会被 handler 处理。所有云 IM 发送的回调请求都带有 CallbackCommand 参数,不同的值代表不同的回调命令。在 handler 中,根据云 IM 设置的参数 CallbackCommand 进行对应的处理。
func handler(w http.ResponseWriter, r *http.Request) { command := r.URL.Query().Get("CallbackCommand") reqbody, _ := io.ReadAll(r.Body) var rspbody []byte switch command { case "Bot.OnC2CMessage": // 机器人C2C回调命令字 dealC2c(context.Background(), reqbody) rspbody = []byte("{\\"ActionStatus\\": \\"OK\\", \\"ErrorCode\\": 0, \\"ErrorInfo\\": \\"\\"}") default: rspbody = []byte("invalid CallbackCommand.") } w.Write(rspbody)} func main() { // 注册一个handler,处理发送给App后台的回调命令 http.HandleFunc("/im", handler) http.ListenAndServe(":80", nil)}
处理机器人接收到单聊消息事件
处理单聊消息时,我们先检查发送方是不是机器人(一般不会出现这种机器人发送消息给机器人的情况),以防止无限的回调循环。接着,我们解析消息体,拿到用户发送给机器人的消息内容 text,将发送方 UserID 保存到 context 中以方便后续调用 REST API 回复,最后调用 askAI 请求 AI 服务。
func dealC2c(ctx context.Context, reqbody []byte) error { root, _ := simplejson.NewJson(reqbody) jFromAccount := root.Get("From_Account") fromAccount, _ = jFromAccount.String() // 检查发送方ID,不处理机器人发送给机器人的请求,防止无限循环 if strings.HasPrefix(fromAccount, "@RBT#") { return nil } jToAccount := root.Get("To_Account") toAccount, _ := jToAccount.String() msgBodyList, _ := root.Get("MsgBody").Array() for _, m := range msgBodyList { msgBody, _ := m.(map[string]interface{}) msgType, _ := msgBody["MsgType"].(string) if msgType != "TIMTextElem" { continue } msgContent, _ := msgBody["MsgContent"].(map[string]interface{}) text, _ := msgContent["Text"].(string) ctx = context.WithValue(ctx, "from", fromAccount) ctx = context.WithValue(ctx, "to", toAccount) go askAI(ctx, text) } return nil}
调用 AI 服务接口
在这一步我们使用第三方 AI 服务公司 DeepSeek 实现智能聊天的功能,你可以将 DeepSeek 服务替换成任意的其它 AI 服务。需要注意的是这里演示的是简单的 completion 接口,没有保存对话的上下文,其他接口可按需查阅 MiniMax 文档。
type MiniMaxRsp struct { Reply string `json:"reply"`}// 请求MiniMax并得到回复func askAI(ctx context.Context, prompt string) { url := "https://api.minimax.chat/v1/text/completion" var reqData = []byte(`{ "model": "abab5-completion", "prompt": prompt }`) request, _ := http.NewRequest("POST", url, bytes.NewBuffer(reqData)) request.Header.Set("Content-Type", "application/json; charset=UTF-8) request.Header.Set("Authorization", API_SECRET_KEY) client := &http.Client{} response, _ := client.Do(request) defer response.Body.Close() body, _ := ioutil.ReadAll(response.Body) rsp := &MiniMaxRsp{} json.Unmarshal(body, rsp) reply(ctx, rsp.Reply) // 将AI回复的内容发送给用户}
将 AI 返回的结果返回给用户
从 AI 服务得到回复之后,我们只需调用云 IM 的 REST API 接口 sendmsg,指定消息发送方为 @RBT#001,接收方为 user1,模拟机器人回复用户。
// 发送一个REST API请求func doRestAPI(host string, sdkappid int, admin, usersig, command, body string) { url := fmt.Sprintf("https://%s/v4/%s?sdkappid=%d&identifier=%s&usersig=%s&random=%d&contenttype=json", host, command, sdkappid, admin, usersig, rand.Uint32()) req, _ := http.NewRequest("POST", url, bytes.NewBufferString(body)) req.Header.Set("Content-Type", "application/json") cli := &http.Client{} rsp, err := cli.Do(req) if err != nil { log.Printf("REST API failed. %s", err.Error()) return } defer rsp.Body.Close() rsptext, _ := io.ReadAll(rsp.Body) log.Printf("rsp:%s", rsptext)}// 调用腾讯云IM的REST API,回复用户func reply(ctx context.Context, text string) { rsp := make(map[string]interface{}) msgbody := []map[string]interface{}{{ "MsgType": "TIMTextElem", "MsgContent": map[string]interface{}{"Text": text}, }} // GenUserSig 的实现可以参见腾讯云文档 usersig, _ := GenUserSig(IM_SDKAPPID, IM_KEY, "administrator", 60) rsp["From_Account"] = ctx.Value("to").(string) //"@RBT#001" rsp["To_Account"] = ctx.Value("from").(string) rsp["SyncOtherMachine"] = 2 rsp["MsgLifeTime"] = 60 * 60 * 24 * 7 rsp["MsgSeq"] = rand.Uint32() rsp["MsgRandom"] = rand.Uint32() rsp["MsgBody"] = msgbody rspbody, _ := json.Marshal(rsp) doRestAPI("console.tim.qq.com", IM_SDKAPPID, "administrator", usersig, "openim/sendmsg", string(rspbody))}
注意:说明:
注意:以上教程仅实现接入三方 API 发送文本消息,如需发送流式响应消息,请参见 发送流式响应消息 REST API。
七、步骤2:客户端接入流程
1. 请你参见 Web & H5 集成指引 集成 TUIKit 到你的项目。
注意:说明:
注意:v2.3.6 起支持机器人回复消息的流式效果展示,Markdown 解析。
2. 流式响应消息规则
·流式响应消息均为自定义消息。
·当客户端接收到的机器人自定义消息的 payload 中的 data 字段符合以下规则时,自动展示 Markdown 格式的流式输出效果。
·这篇说说的自定义消息的 payload 中的 data 字段为 JSON 结构体经过序列化后的值,详情请参见 CustomPayload 。
·TUIKit 内部会通过监听 MESSAGE_MODIFIED 事件监听消息内容的变更,此处你无需额外处理。
·TUIKit 机器人消息解析在客服插件之后,请务必保证该机器人账号没有被配置为客服账号,否则将无法进入机器人消息解析逻辑。
// 以下为自定义消息 payload 字段中的 data 字段格式规则{ // 机器人自定义消息标识字段,此字段为 1 时,表示此自定义消息为机器人自定义消息 "chatbotPlugin": 1, // chunks 代表流式消息的内容 "chunks": [ "", "你", "可以在", "管理", "端", "左侧", "菜单", ], // isFinished 为 0 时表示流式消息未输出结束,1 代表流式输出结束 "isFinished": 1,}
八、常见问题
·通道方案集成中,提示 "Manifest merger failed : Attribute application@allowBackup value=(true) from AndroidManifest.xml" 如何处理?
IM SDK 中默认 allowBackup 的值为 false ,表示关闭应用的备份和恢复功能。
你可以在你的 AndroidManifest.xml 文件中删除 allowBackup 属性,表示关闭备份和恢复功能;也可以在 AndroidManifest.xml 文件的 application 节点中添加 tools:replace="android:allowBackup" 表示覆盖 IM SDK 的设置,使用你自己的设置。
例如:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.tencent.qcloud.tuikit.myapplication"> <application android:allowBackup="true" android:name=".MApplication" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication" tools:replace="android:allowBackup"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application></manifest>
·通道方案集成中,提示 "NDK at /Users/***/Library/Android/sdk/ndk-bundle did not have a source.properties file" 如何处理?
只需要在 local.properties 文件中加入你的 NDK 路径,例如:
ndk.dir=/Users/***/Library/Android/sdk/ndk/16.1.4479499
·通道方案集成中,提示 "Cannot fit requested classes in a single dex file" 如何处理?
出现此问题可能是你的 API 级别设置比较低,需要在 App 的 build.gradle 文件中开启 MultiDex 支持, 添加 multiDexEnabled true 和对应依赖:
android { defaultConfig { … minSdkVersion 19 targetSdkVersion 30 multiDexEnabled true } …}dependencies { implementation "androidx.multidex:multidex:2.0.1"}
同时,在你的 Application 文件中添加以下代码:
public class MyApplication extends SomeOtherApplication { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); }}
·提示 "Plugin with id 'kotlin-android' not found." 如何处理?
因为 TUIChat 组件使用了 Kotlin 代码,所以需要添加 Kotlin 构建插件。请参考 集成 TUIChat 源码第 4 步。
·Debug 版本的 App 功能正常,Release 版本的 App 功能出现异常 ?
出现此问题很大概率是混淆导致的,请尽量不要混淆 TUIKit 。可以添加如下混淆规则:
# 避免删除代码逻辑-dontshrink-dontoptimize# 避免混淆 TUIKit-keep class com.tencent.qcloud.** { *; }
·自集成接入中,如何实现机器人欢迎语?(打开机器人聊天对话,机器人自动发送欢迎消息)
客户端可以在用户打开机器人聊天对话框时,客户端发送一条静默的自定义消息,设置 onlineUserOnly 为 true(设置该 flag 表示消息不存漫游),App 后台通过回调接收到此自定义消息后,调用 REST API 发送欢迎消息。
·自集成接入中,如何发送流式响应消息?
请参见发送流式响应消息 REST API。如你需和 Web TUIKit 搭配使用,请务必保证你的 WebTUIKit 版本是 v2.3.6 或更高,且机器人发送的自定义消息符合 流式响应规则。