實踐 | 即時通信IM如何接入AI服務(wù)缭保,搭建聊天機(jī)器人

隨著ChatGPT在全球范圍的爆火,AI已成為當(dāng)下開發(fā)者最為關(guān)注的焦點蝙茶,國內(nèi)各大廠商也紛紛跟進(jìn)艺骂,推出了各自的大模型應(yīng)用與產(chǎn)品。很多應(yīng)用都在嘗試與AI結(jié)合隆夯,尋找新的發(fā)力點钳恕。而新一代大語言模型的強(qiáng)大對話交流能力與各類即時通信場景天然契合,這為IM與AI結(jié)合帶來了廣闊的想象空間蹄衷。

那即時通信IM該如何接入AI服務(wù)呢忧额?本文將拆解接入AI服務(wù)的各個步驟,為您詳細(xì)介紹如何通過騰訊云即時通信IM第三方回調(diào)功能宦芦,將AI服務(wù)能力引入到IM應(yīng)用中宙址,創(chuàng)建一個可以智能聊天的AI機(jī)器人,為用戶提供真人般對話體驗调卑,實現(xiàn)智能客服抡砂、創(chuàng)意輔助大咱、工作助手等功能。(文中的實踐步驟以接入MiniMax中文大語言模型為例注益,類ChatGPT服務(wù)均可通過文中介紹的方法實現(xiàn)接入)

準(zhǔn)備工作

注冊賬號

注冊并登錄騰訊云賬號碴巾,進(jìn)入即時通信IM控制臺,創(chuàng)建應(yīng)用丑搔,并獲取應(yīng)用的SDKAppID和密鑰(以下稱為 IM Key)厦瓢,并創(chuàng)建一個管理員賬號administrator。

注冊對應(yīng)AI服務(wù)商賬號

注冊并登錄計劃接入的AI服務(wù)商的相應(yīng)賬號并獲取API密鑰(以下稱為AI_SECRET_KEY)啤月。

創(chuàng)建即時通信IM機(jī)器人賬號

通過REST API創(chuàng)建一個機(jī)器人賬號煮仇。機(jī)器人是一種特殊的用戶,UserID以@RBT#開頭谎仲。

curl -d'{"UserID":"@RBT#001","Nick":"MyRobot"}'"https://console.tim.qq.com/v4/openim_robot_http_svc/create_robot?sdkappid= {}&identifier=administrator&usersig={}&random=123456789&contenttype=json"

復(fù)制

將上述命令的sdkappid={}和usersig={}替換成您的SDKAppID和使用IM Key生成的Usersig浙垫。Usersig的生成可以參考官網(wǎng)文檔(https://cloud.tencent.com/document/product/269/32688)。在Linux環(huán)境運行上述命令后郑诺,云服務(wù)器返回:

{"ActionStatus":"OK","ErrorCode":0,"ErrorInfo":""}

復(fù)制

表示成功創(chuàng)建了一個昵稱為MyRobot的機(jī)器人@RBT#001夹姥。

配置即時通信IM第三方回調(diào)

即時通信 IM 第三方回調(diào)即云IM后臺會在某一事件發(fā)生之前或者之后,向 App 的后臺服務(wù)器發(fā)送請求辙诞,App 后臺可以據(jù)此進(jìn)行必要的數(shù)據(jù)同步辙售,或者干預(yù)事件的后續(xù)處理流程。我們將使用“機(jī)器人事件回調(diào)”監(jiān)聽用戶發(fā)消息給機(jī)器人飞涂,或者在群聊中@機(jī)器人的事件旦部,并對其做出反應(yīng)。在即時通信IM控制臺中找到“機(jī)器人事件回調(diào)”封拧,點擊開啟并保存志鹃。

編寫APP后臺服務(wù)

以單聊為例夭问,總體上的工作流程如下:

用戶user1發(fā)消息“hello”給機(jī)器人@RBT#001泽西;

云IM后臺發(fā)送第三方回調(diào)將事件通知App后臺;

App后臺收到事件通知缰趋,通知內(nèi)容包含發(fā)送方user1捧杉,接收方@RBT#001,消息內(nèi)容hello以及其他信息秘血;

App后臺調(diào)用AI服務(wù)接口(即MiniMax API)味抖,并得到響應(yīng)回復(fù)內(nèi)容,如nice to meet you灰粮;

App后臺調(diào)用云IM REST API接口(單聊為sendmsg接口仔涩,群聊為send_group_msg接口),將回復(fù)內(nèi)容以@RBT#001的身份發(fā)送給user1粘舟。


以Golang為例熔脂,App后臺的關(guān)鍵代碼大概如下(請注意佩研,本代碼僅作為展示用途,省略了大量異常處理代碼霞揉,不可直接用于生產(chǎn)環(huán)境):

分發(fā)處理回調(diào)命令

我們創(chuàng)建一個監(jiān)聽在80端口的http服務(wù)旬薯,注冊一個url為/im的處理函數(shù)handler,所有發(fā)送給http://<your.domain.com>/im的請求都會被handler處理适秩。所有云IM發(fā)送的回調(diào)請求都帶有CallbackCommand參數(shù)绊序,不同的值代表不同的回調(diào)命令。在handler中秽荞,根據(jù)云IM設(shè)置的參數(shù)CallbackCommand進(jìn)行對應(yīng)的處理骤公。

funchandler(w http.ResponseWriter, r *http.Request) {? command := r.URL.Query().Get("CallbackCommand")? reqbody, _ := io.ReadAll(r.Body)varrspbody []byteswitchcommand {case"Bot.OnC2CMessage":// 機(jī)器人C2C回調(diào)命令字dealC2c(context.Background(), reqbody)? ? rspbody = []byte("{\"ActionStatus\": \"OK\", \"ErrorCode\": 0, \"ErrorInfo\": \"\"}")default:? ? rspbody = []byte("invalid CallbackCommand.")? }? w.Write(rspbody)}funcmain() {// 注冊一個handler,處理發(fā)送給App后臺的回調(diào)命令http.HandleFunc("/im", handler)? http.ListenAndServe(":80", nil)}

復(fù)制

處理機(jī)器人接收到單聊消息事件

處理單聊消息時扬跋,我們先檢查發(fā)送方是不是機(jī)器人(一般不會出現(xiàn)這種機(jī)器人發(fā)送消息給機(jī)器人的情況)淋样,以防止無限的回調(diào)循環(huán)。接著胁住,我們解析消息體趁猴,拿到用戶發(fā)送給機(jī)器人的消息內(nèi)容text,將發(fā)送方UserID保存到context中以方便后續(xù)調(diào)用REST API回復(fù)彪见,最后調(diào)用askAI請求AI服務(wù)儡司。

funcdealC2c(ctx context.Context, reqbody []byte) error {? root, _ := simplejson.NewJson(reqbody)? jFromAccount := root.Get("From_Account")? fromAccount, _ = jFromAccount.String()// 檢查發(fā)送方ID,不處理機(jī)器人發(fā)送給機(jī)器人的請求余指,防止無限循環(huán)ifstrings.HasPrefix(fromAccount,"@RBT#") {returnnil? }? 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)ifmsgType !="TIMTextElem"{continue}? ? msgContent, _ := msgBody["MsgContent"].(map[string]interface{})? ? text, _ := msgContent["Text"].(string)? ? ctx = context.WithValue(ctx,"from", fromAccount)? ? ctx = context.WithValue(ctx,"to", toAccount)? ? goaskAI(ctx, text)? }returnnil}

復(fù)制

調(diào)用AI服務(wù)接口

在這一步我們使用第三方AI服務(wù)公司MiniMax實現(xiàn)智能聊天的功能捕犬,您可以將MiniMax服務(wù)替換成任意的其它AI服務(wù)。需要注意的是這里演示的是簡單的completion接口酵镜,沒有保存對話的上下文碉碉,其他接口可按需查閱MiniMax文檔。

typeMiniMaxRspstruct {Replystring`json:"reply"`}// 請求MiniMax并得到回復(fù)funcaskAI(ctx context.Context, prompt string) {? url :="https://api.minimax.chat/v1/text/completion"varreqData = []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回復(fù)的內(nèi)容發(fā)送給用戶

}

復(fù)制

將AI返回的結(jié)果返回給用戶

從AI服務(wù)得到回復(fù)之后淮韭,我們只需調(diào)用云IM的REST API接口sendmsg垢粮,制定消息發(fā)送方為@RBT#001,接收方為user1靠粪,模擬機(jī)器人回復(fù)用戶蜡吧。

// 發(fā)送一個REST API請求funcdoRestAPI(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)iferr != nil {? ? log.Printf("REST API failed. %s", err.Error())return}? defer rsp.Body.Close()? rsptext, _ := io.ReadAll(rsp.Body)? log.Printf("rsp:%s", rsptext)}// 調(diào)用騰訊云IM的REST API,回復(fù)用戶funcreply(ctx context.Context, text string) {? rsp :=make(map[string]interface{})? msgbody := []map[string]interface{}{{"MsgType":"TIMTextElem","MsgContent": map[string]interface{}{"Text": text},? }}// GenUserSig 的實現(xiàn)可以參考騰訊云文檔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"] =2rsp["MsgLifeTime"] =60*60*24*7rsp["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))}

復(fù)制

通過以上步驟占键,我們便實現(xiàn)了即時通信IM在服務(wù)端和MiniMaxAI開放平臺的單聊對接昔善,接入其他AI服務(wù)商也可參照上述步驟,僅需將askAI函數(shù)替換成其他AI服務(wù)商的對應(yīng)API調(diào)用即可畔乙。對于群聊機(jī)器人君仆,開發(fā)者僅需補(bǔ)充實現(xiàn)Bot.OnGroupMessage回調(diào)命令處理即可。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市返咱,隨后出現(xiàn)的幾起案子氮帐,更是在濱河造成了極大的恐慌,老刑警劉巖洛姑,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件上沐,死亡現(xiàn)場離奇詭異,居然都是意外死亡楞艾,警方通過查閱死者的電腦和手機(jī)参咙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硫眯,“玉大人蕴侧,你說我怎么就攤上這事×饺耄” “怎么了净宵?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裹纳。 經(jīng)常有香客問我择葡,道長,這世上最難降的妖魔是什么剃氧? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任敏储,我火速辦了婚禮,結(jié)果婚禮上朋鞍,老公的妹妹穿的比我還像新娘已添。我一直安慰自己,他們只是感情好滥酥,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布更舞。 她就那樣靜靜地躺著,像睡著了一般坎吻。 火紅的嫁衣襯著肌膚如雪缆蝉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天禾怠,我揣著相機(jī)與錄音返奉,去河邊找鬼。 笑死吗氏,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雷逆。 我是一名探鬼主播弦讽,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了往产?” 一聲冷哼從身側(cè)響起被碗,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仿村,沒想到半個月后锐朴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蔼囊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年焚志,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畏鼓。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡酱酬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出云矫,到底是詐尸還是另有隱情膳沽,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布让禀,位于F島的核電站挑社,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏巡揍。R本人自食惡果不足惜滔灶,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吼肥。 院中可真熱鬧录平,春花似錦、人聲如沸缀皱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啤斗。三九已至表箭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钮莲,已是汗流浹背免钻。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留崔拥,地道東北人极舔。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像链瓦,于是被迫代替她去往敵國和親拆魏。 傳聞我的和親對象是個殘疾皇子盯桦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容