1.簡(jiǎn)述
? ? ? ? 本篇文章主要介紹一下,在Unity端,集成智譜AI開放平臺(tái)提供的chatglm模型api,實(shí)現(xiàn)AI聊天互動(dòng)相關(guān)的功能。從智譜AI官方站點(diǎn)上看到,提供有chatglm turbo的公共模型服務(wù),能夠?qū)崿F(xiàn)32K超長(zhǎng)上下文,應(yīng)用到我們的AI二次元小姐姐項(xiàng)目中,完全足夠了。
? ? ? ? 價(jià)格方面,官方頁(yè)面上有看到,0.005元/千tokens這樣的價(jià)格,而且目前新注冊(cè)用戶可以獲取18元的API試用金額,核算下來(lái),可以免費(fèi)使用幾百萬(wàn)的token,算是一筆不錯(cuò)的免費(fèi)額度了。那么接下來(lái),咱們來(lái)看一下如何在智譜AI開放平臺(tái)申請(qǐng)API應(yīng)用,并集成到Unity中吧。
2.智譜AI開放平臺(tái)
? ? ? ? 首先,進(jìn)入到智譜AI開放平臺(tái)的官方站點(diǎn),通過(guò)以下鏈接,進(jìn)入到智譜AI開放平臺(tái)網(wǎng)站
https://maas.aminer.cn/pricinghttps://maas.aminer.cn/pricing? ? ? ?
????????進(jìn)入官方站點(diǎn)后,自行注冊(cè)賬號(hào),登錄進(jìn)入到智譜開放平臺(tái)的控制臺(tái)界面。
? ? ? ? 在控制臺(tái)界面,可以看到平臺(tái)贈(zèng)送的18元試用金。點(diǎn)擊查看api key按鈕即可進(jìn)入到應(yīng)用創(chuàng)建頁(yè)面,新增一個(gè)apikey,后續(xù)在Unity端調(diào)用api服務(wù)時(shí),需要用到這個(gè)apikey。
3.接口說(shuō)明
? ? ? ?3.1 接口對(duì)接流程
????????根據(jù)官方文檔說(shuō)明,可以了解到,目前智譜AI開放平臺(tái)針對(duì)Python以及Java提供有SDK,可以自行下載sdk示例。那么我們使用Unity就沒(méi)有sdk可用了,只能根據(jù)官方文檔的說(shuō)明自行實(shí)現(xiàn)相關(guān)功能。
????????官方介紹了http調(diào)用的方式,總體流程上:
? ? ? ? ①接口鑒權(quán),需要根據(jù)標(biāo)準(zhǔn)JWT的規(guī)則,生成token
????????在調(diào)用模型接口時(shí)需要傳鑒權(quán) token 進(jìn)行認(rèn)證;當(dāng)前平臺(tái)鑒權(quán) token 由用戶端生成,鑒權(quán) token 生成采用標(biāo)準(zhǔn) JWT 中提供的創(chuàng)建方法生成(詳細(xì)參考:JSON Web Token Introduction - jwt.io)。
? ? ? ? ②api調(diào)用,采用post訪問(wèn)資源地址即可。
? ? ? ? 這里需要說(shuō)明一下,POST訪問(wèn)的Url地址,chatglm turbo的模型訪問(wèn)地址:
https://open.bigmodel.cn/api/paas/v3/model-api/chatglm_turbo/sse-invokehttps://open.bigmodel.cn/api/paas/v3/model-api/chatglm_turbo/invoke? ? ?
? 注:這里我使用的是官方不推進(jìn)的同步方式,因?yàn)轫?xiàng)目當(dāng)前的情況,所以選擇了這個(gè)方式,官方還提供有異步方式以及SSE兩種方式,可以自行閱讀文檔。
? ? ? ? 官方文檔地址:
https://maas.aminer.cn/dev/api#chatglm_turbohttps://maas.aminer.cn/dev/api#chatglm_turbo
3.2 Unity中的代碼實(shí)現(xiàn)
? ? ? ? 本節(jié)內(nèi)容將介紹在Unity中如何完成接口鑒權(quán)以及api的http訪問(wèn)的代碼實(shí)現(xiàn)。
? ? ? ? 一、接口鑒權(quán)
? ? ? ? 官方文檔在接口鑒權(quán)流程中的token生成規(guī)則的描述不是很清晰,只描述了header和payload的格式,其實(shí)還有一部分Signature的生成規(guī)則,并沒(méi)有在文檔里說(shuō)明,詳細(xì)可以參見JWT的生成規(guī)則。
????????1、header的內(nèi)容規(guī)則
? ? ? ? 根據(jù)官方文檔,header部分的值為:
?{"alg":"HS256","sign_type":"SIGN"}
-
alg
?:?屬性表示簽名使用的算法,默認(rèn)為?HMAC SHA256(寫為HS256) -
sign_type
?:?屬性表示令牌的類型,JWT 令牌統(tǒng)一寫為 SIGN 。
????????2、payload 的內(nèi)容規(guī)則
????????官方示例為
?{"api_key":{ApiKey.id},"exp":1682503829130, "timestamp":1682503820130}
-
api_key
?:?屬性表示用戶標(biāo)識(shí) id,即用戶API Key的{id}
部分 -
exp
?:?屬性表示生成的JWT的過(guò)期時(shí)間,客戶端控制,單位為毫秒 -
timestamp
?:?屬性表示當(dāng)前時(shí)間戳,單位為毫秒
? ? ? ? 這里需要注意一點(diǎn),apikey的部分,前面從站點(diǎn)上創(chuàng)建的api key,觀察api key的結(jié)構(gòu),是這樣的規(guī)則{id}.{secret key},我們拿到apikey時(shí),需要將密鑰拆分成兩部分,一部分就是上面這個(gè)payload需要使用的api_key,而另一部分的secret key,我們?cè)诤竺嫔蒘ignature的時(shí)候要用到。
? ? ? ? 關(guān)于時(shí)間戳,生成13位時(shí)間戳編碼即可。
? ? ? ? 鑒權(quán)token生成部分的代碼如下:
#region 生成api鑒權(quán)token
/// <summary>
/// 生成api鑒權(quán) token
/// </summary>
/// <returns></returns>
private string GetToken()
{
long expirationMilliseconds = DateTimeOffset.Now.AddHours(1).ToUnixTimeMilliseconds();
long timestampMilliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds();
string jwtToken = GenerateJwtToken(m_ApiKey, expirationMilliseconds, timestampMilliseconds);
return jwtToken;
}
//獲取token
private string GenerateJwtToken(string apiKeyId, long expirationMilliseconds, long timestampMilliseconds)
{
// 構(gòu)建Header
string _headerJson = "{\"alg\":\"HS256\",\"sign_type\":\"SIGN\"}";
string encodedHeader = Base64UrlEncode(_headerJson);
// 構(gòu)建Payload
string _playLoadJson = string.Format("{{\"api_key\":\"{0}\",\"exp\":{1}, \"timestamp\":{2}}}", apiKeyId, expirationMilliseconds, timestampMilliseconds);
string encodedPayload = Base64UrlEncode(_playLoadJson);
// 構(gòu)建簽名
string signature = HMACsha256(m_SecretKey, $"{encodedHeader}.{encodedPayload}");
// 組合Header、Payload和Signature生成JWT令牌
string jwtToken = $"{encodedHeader}.{encodedPayload}.{signature}";
return jwtToken;
}
// Base64 URL編碼
private string Base64UrlEncode(string input)
{
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
string base64 = Convert.ToBase64String(inputBytes);
return base64.Replace('+', '-').Replace('/', '_').TrimEnd('=');
}
// 使用HMAC SHA256生成簽名
private string HMACsha256(string apiSecretIsKey, string buider)
{
byte[] bytes = Encoding.UTF8.GetBytes(apiSecretIsKey);
HMACSHA256 hMACSHA256 = new System.Security.Cryptography.HMACSHA256(bytes);
byte[] date = Encoding.UTF8.GetBytes(buider);
date = hMACSHA256.ComputeHash(date);
hMACSHA256.Clear();
return Convert.ToBase64String(date);
}
#endregion
????????二、Http訪問(wèn)
? ? ? ? 獲取到接口鑒權(quán)token后,通過(guò)POST訪問(wèn)api地址,接口地址如下:
https://open.bigmodel.cn/api/paas/v3/model-api/chatglm_turbo/sse-invokehttps://open.bigmodel.cn/api/paas/v3/model-api/chatglm_turbo/invoke? ? ?
????????關(guān)于接口的報(bào)文結(jié)構(gòu),根據(jù)官方提供的接口文檔說(shuō)明,這里做一下詳細(xì)說(shuō)明。
????????請(qǐng)求報(bào)文結(jié)構(gòu):
prompt |
list |
是 |
調(diào)用對(duì)話模型時(shí),將當(dāng)前對(duì)話信息列表作為提示輸入給模型; 按照? |
role |
string |
是 |
本條信息作者的角色,可選擇 |
content |
string |
是 |
本條信息的具體內(nèi)容 |
temperature |
float |
否 |
采樣溫度,控制輸出的隨機(jī)性,必須為正數(shù) |
top_p |
float |
否 |
用溫度取樣的另一種方法,稱為核取樣 |
request_id |
string |
否 |
由用戶端傳參,需保證唯一性;用于區(qū)分每次請(qǐng)求的唯一標(biāo)識(shí),用戶端不傳時(shí)平臺(tái)會(huì)默認(rèn)生成。 |
incremental |
boolean |
否 |
SSE接口調(diào)用時(shí),用于控制每次返回內(nèi)容方式是增量還是全量,不提供此參數(shù)時(shí)默認(rèn)為增量返回 |
return_type |
string |
否 |
用于控制每次返回內(nèi)容的類型,空或者沒(méi)有此字段時(shí)默認(rèn)按照json_string返回 |
ref |
object |
否 |
用于控制請(qǐng)求時(shí)的外部信息引用,目前用于控制是否引用外部信息,空或者沒(méi)有此字段時(shí)默認(rèn)開啟搜索,傳參格式 |
? ????????回復(fù)報(bào)文結(jié)構(gòu):
code |
int |
錯(cuò)誤碼,詳情請(qǐng)查看錯(cuò)誤碼說(shuō)明 |
msg |
string |
錯(cuò)誤信息 |
success |
boolean |
請(qǐng)求成功失敗標(biāo)識(shí),true(成功),false(失?。?/p> |
data |
object |
|
request_id |
string |
用戶在客戶端請(qǐng)求時(shí)提交的任務(wù)編號(hào)或者平臺(tái)生成的任務(wù)編號(hào) |
task_id |
string |
智譜AI開放平臺(tái)生成的任務(wù)訂單號(hào),調(diào)用請(qǐng)求結(jié)果接口時(shí)請(qǐng)使用此訂單號(hào) |
task_status |
string |
處理狀態(tài),PROCESSING(處理中),SUCCESS(成功),F(xiàn)AIL(失?。?br> 注:處理中狀態(tài)需通過(guò)查詢獲取結(jié)果 |
? ? ? ? 接口的調(diào)用,采用POST方式即可,示例代碼如下:
/// <summary>
/// 發(fā)送數(shù)據(jù)
/// </summary>
/// <param name="_postWord"></param>
/// <param name="_callback"></param>
/// <returns></returns>
public override IEnumerator Request(string _postWord, System.Action<string> _callback)
{
stopwatch.Restart();
string jsonPayload = JsonConvert.SerializeObject(new RequestData
{
model=m_Type.ToString(),
prompt = m_DataList
});
using (UnityWebRequest request = new UnityWebRequest(url, "POST"))
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(jsonPayload);
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(data);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", GetToken());
yield return request.SendWebRequest();
if (request.responseCode == 200)
{
string _msg = request.downloadHandler.text;
ResponseData response = JsonConvert.DeserializeObject<ResponseData>(_msg);
if (response.data.choices.Count > 0)
{
string _msgBack = response.data.choices[0].content;
//回調(diào)
_callback(_msgBack);
}
else
{
Debug.Log(_msg);
}
}
}
stopwatch.Stop();
Debug.Log("chatGLM Turbo耗時(shí):" + stopwatch.Elapsed.TotalSeconds);
}
? ? ? ? 數(shù)據(jù)定義:
[Serializable]
private class RequestData
{
[SerializeField] public string model;
[SerializeField] public List<SendData> prompt;
[SerializeField] public float temperature = 0.7f;
}
[Serializable]
private class ResponseData
{
[SerializeField] public int code;
[SerializeField] public string msg = string.Empty;
[SerializeField] public string success = string.Empty;
[SerializeField] public ReData data=new ReData();
}
[Serializable]
private class ReData
{
[SerializeField] public string task_id = string.Empty;
[SerializeField] public string request_id = string.Empty;
[SerializeField] public string task_status = string.Empty;
[SerializeField] public List<SendData> choices=new List<SendData>();
}
4. Unity端數(shù)字人配置
? ? ? ? 項(xiàng)目的源碼已經(jīng)發(fā)布到Github了,我們可以直接下載,并導(dǎo)入到unity中使用,要求unity版本在2020.3.44及以上。導(dǎo)入工具包之后,可以在Scene文件夾下,找到示例場(chǎng)景,在場(chǎng)景中找到LLM->chatglm Turbo對(duì)象,這里就維護(hù)了智譜AI開放平臺(tái)的模型調(diào)用腳本。
? ? ? ? 項(xiàng)目已經(jīng)實(shí)現(xiàn)了智譜AI開放平臺(tái)對(duì)接所需的接口鑒權(quán)以及API訪問(wèn)的代碼,我們只需要在控制臺(tái)中,找到創(chuàng)建好的api key,將密鑰填寫到腳本中的{Key}參數(shù)即可。
? ? ? ? 詳細(xì)配置,可以到我的B站主頁(yè),查看本期視頻的配置過(guò)程。
5.結(jié)束語(yǔ) ? ? ??
????????這次的文章簡(jiǎn)單介紹了智譜AI開放平臺(tái)的API的對(duì)接流程,并針對(duì)接口對(duì)接的流程進(jìn)行了介紹,包括接口的鑒權(quán)、基于JWT的token生成規(guī)則,以及chatglm turbo模型的接口調(diào)用代碼示例等內(nèi)容,通過(guò)上述的代碼實(shí)現(xiàn),我們就可以在unity引擎中,使用智譜AI開放平臺(tái)的api來(lái)驅(qū)動(dòng)AI二次元小姐姐的對(duì)話交互。完整的代碼工程可以從我的開源項(xiàng)目下載使用,項(xiàng)目包含了針對(duì)多種GPT應(yīng)用的集成工具,以及語(yǔ)音服務(wù)的集成,對(duì)我這個(gè)項(xiàng)目感興趣的朋友,可以上我的B站號(hào)查看,我也做有詳細(xì)的教程,相關(guān)源碼可以在的嗶哩嗶哩主站找到相關(guān)視頻,在視頻介紹以及評(píng)論區(qū)獲取。
[Unity+AI Chat+智譜AI]輕松實(shí)現(xiàn)32K超長(zhǎng)上下文對(duì)話, 對(duì)接智譜AI開放平臺(tái)ChatGLM Turbo,簡(jiǎn)單配置AI二次元小姐姐
項(xiàng)目地址傳送門:
AI二次元老婆開源項(xiàng)目(unity-AI-Chat-Toolkit):
Github地址:https://github.com/zhangliwei7758/unity-AI-Chat-Toolkit文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-735186.html
Gitee地址:https://gitee.com/DammonSpace/unity-ai-chat-toolkit文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-735186.html
到了這里,關(guān)于[Unity+智譜AI開放平臺(tái)]調(diào)用ChatGLM Tuobo模型驅(qū)動(dòng)AI小姐姐數(shù)字人的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!