1.簡(jiǎn)述
? ? ? ? 最近訊飛的星火大模型更新了2.0版本,增強(qiáng)了AI的語言生成能力。畢竟是國(guó)產(chǎn)大語言模型,我也嘗試使用了一下星火大模型的應(yīng)用廣場(chǎng),體驗(yàn)還是很不錯(cuò)的。應(yīng)用廣場(chǎng)提供了很多AI助手工具,也支持用戶創(chuàng)建自己的AI助手,能力不局限于自然語言生成,也有一些圖片生成工具、視頻生成工具之類的,總的來說,還是很有意思的。
? ? ? ? 同時(shí),星火大模型也提供有api服務(wù),可以很方便的集成到自己的應(yīng)用里。申請(qǐng)api應(yīng)用的門檻也比較低,簡(jiǎn)單填寫一些信息,就可以申請(qǐng)?jiān)囉?。試用審核大概半個(gè)多小時(shí)就結(jié)束了,官方提供的免費(fèi)token數(shù)量還是比較可觀。針對(duì)星火大模型V1.5版本以及V2.0版本,各提供了200萬的token試用,非常的良心。我的AI二次元小姐姐項(xiàng)目里,使用chatgpt以及一些開源模型的方式,相對(duì)來說還是有一定使用門檻,而接入星火大模型門檻就很低了。
? ? ? ? 本文就簡(jiǎn)單介紹一下unity端集成星火大模型API的代碼實(shí)現(xiàn),讓星火大模型驅(qū)動(dòng)我們的AI二次元小姐姐,與大家聊天吧。
2.開通星火大模型服務(wù)
? ? ? ? 本節(jié)內(nèi)容將簡(jiǎn)單介紹一下如何在訊飛星火大模型官網(wǎng),申請(qǐng)?jiān)囉眯腔鸫竽P?,并?chuàng)建星火大模型的應(yīng)用。
星火大模型官方地址:訊飛星火認(rèn)知大模型-AI大語言模型-星火大模型-科大訊飛 (xfyun.cn)
? ? ? ? 在申請(qǐng)星火大模型服務(wù)之前,需要先注冊(cè)訊飛的賬戶,使用手機(jī)號(hào)碼驗(yàn)證就可以了,這里不多贅述。在星火大模型官方站點(diǎn)主頁,找到【API測(cè)試】按鈕,可以點(diǎn)擊進(jìn)入API試用申請(qǐng)的頁面。
? ? ? ? 點(diǎn)擊【API測(cè)試申請(qǐng)】,即可進(jìn)入API測(cè)試申請(qǐng)界面,如圖所示:
? ? ? ? 在API申請(qǐng)界面中,填寫必填的信息。這里需要注意一下,申請(qǐng)API測(cè)試,需要?jiǎng)?chuàng)建一個(gè)訊飛的應(yīng)用,我們可以填寫一個(gè)自己實(shí)現(xiàn)申請(qǐng)?zhí)柕膽?yīng)用ID,也可以在申請(qǐng)頁面點(diǎn)擊創(chuàng)建一個(gè)新的應(yīng)用,創(chuàng)建應(yīng)用成功之后,我們就能夠獲得應(yīng)用的密鑰,這個(gè)在后面的接口對(duì)接會(huì)使用的到。
? ? ? ? 申請(qǐng)?zhí)峤恢螅托牡却俜綄徍思纯?。時(shí)間不會(huì)太久,我大概是半小時(shí)左右,就完成審批,拿到api的試用服務(wù)了。
3.對(duì)接API服務(wù)
? ? ? ? 星火大模型應(yīng)用申請(qǐng)完成之后,我們就可以拿到應(yīng)用的密鑰。進(jìn)入到訊飛開放平臺(tái)的控制臺(tái)界面,選擇到新創(chuàng)建的星火大模型服務(wù),我們就可以看到服務(wù)剩余的token數(shù),以及應(yīng)用的密鑰信息了。這個(gè)頁面可以切換查看V1.5和V2.0兩個(gè)版本的token使用情況。
3.1 API對(duì)接流程
? ? ? ? 星火大模型的接口對(duì)接,考慮到跨平臺(tái)的兼容性,這里選擇采用web方式對(duì)接,根據(jù)官方文檔的說明,我們首先需要調(diào)用鑒權(quán)接口,獲取到接口授權(quán),然后在使用websocket協(xié)議與服務(wù)端握手,websocket握手成功后,需要在60秒內(nèi)發(fā)送請(qǐng)求。接口采用的是流式輸出模式,需要對(duì)根據(jù)返回的數(shù)據(jù)判斷,并拼接成完整的回復(fù)信息,大致流程如下如所示:
? ? ? ? 接下來,將描述一下具體的代碼實(shí)現(xiàn)。
3.2?接口鑒權(quán)
? ? ? ? 根據(jù)官方文檔的說明,開發(fā)者需要自行先在控制臺(tái)創(chuàng)建應(yīng)用,利用應(yīng)用中提供的appid,APIKey, APISecret進(jìn)行鑒權(quán),生成最終請(qǐng)求的鑒權(quán)url,鑒權(quán)參數(shù)如下:
參數(shù) | 類型 | 必須 | 說明 | 示例 |
---|---|---|---|---|
host | string | 是 | 請(qǐng)求的主機(jī) | aichat.xf-yun.com(使用時(shí)需替換為實(shí)際使用的接口地址) |
date | string | 是 | 當(dāng)前時(shí)間戳,采用RFC1123格式,時(shí)間偏差需控制在300s內(nèi) | Fri, 05 May 2023 10:43:39 GMT |
authorization | string | 是 | base64編碼的簽名信息 | 參考下方生成方式 |
? ? ? ? 以下是在unity端實(shí)現(xiàn)鑒權(quán)url的處理代碼:
/// <summary>
/// 獲取鑒權(quán)url
/// </summary>
/// <returns></returns>
private string GetAuthUrl()
{
string date = DateTime.UtcNow.ToString("r");
Uri uri = new Uri(url);
StringBuilder builder = new StringBuilder("host: ").Append(uri.Host).Append("\n").//
Append("date: ").Append(date).Append("\n").//
Append("GET ").Append(uri.LocalPath).Append(" HTTP/1.1");
string sha = HMACsha256(m_XunfeiSettings.m_APISecret, builder.ToString());
string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", m_XunfeiSettings.m_APIKey, "hmac-sha256", "host date request-line", sha);
string NewUrl = "https://" + uri.Host + uri.LocalPath;
string path1 = "authorization" + "=" + Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(authorization));
date = date.Replace(" ", "%20").Replace(":", "%3A").Replace(",", "%2C");
string path2 = "date" + "=" + date;
string path3 = "host" + "=" + uri.Host;
NewUrl = NewUrl + "?" + path1 + "&" + path2 + "&" + path3;
return NewUrl;
}
public string HMACsha256(string apiSecretIsKey, string buider)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(apiSecretIsKey);
System.Security.Cryptography.HMACSHA256 hMACSHA256 = new System.Security.Cryptography.HMACSHA256(bytes);
byte[] date = System.Text.Encoding.UTF8.GetBytes(buider);
date = hMACSHA256.ComputeHash(date);
hMACSHA256.Clear();
return Convert.ToBase64String(date);
}
3.3?接口請(qǐng)求
? ? ? ?3.3.1 接口費(fèi)用與服務(wù)地址
????????根據(jù)官方文檔說明,星火大模型的1.5版本以及2.0版本的計(jì)費(fèi)模型以及資源地址是不同的,當(dāng)然我們免費(fèi)申請(qǐng)的服務(wù)是不需要額外付費(fèi)的,但超過額度了的話,就需要付費(fèi)了,token的價(jià)格如下所示:
服務(wù)引擎 | 單價(jià) |
---|---|
訊飛星火認(rèn)知大模型V1.5 | 0.18元/萬tokens |
訊飛星火認(rèn)知大模型V2.0 | 0.36元/萬tokens |
? ? ? ? 兩個(gè)版本的api地址分別是:
? ? ? ? ①星火大模型1.5版本請(qǐng)求地址,對(duì)應(yīng)的domain參數(shù)為general
ws(s)://spark-api.xf-yun.com/v1.1/chat
? ? ? ? ②星火大模型1.5版本請(qǐng)求地址,對(duì)應(yīng)的domain參數(shù)為generalv2:
ws(s)://spark-api.xf-yun.com/v2.1/chat
3.3.2 發(fā)送報(bào)文結(jié)構(gòu)? ? ? ??
????????星火大模型的API服務(wù)對(duì)接部分,按照文檔說明,使用websocket協(xié)議握手成功之后,就可以根據(jù)報(bào)文格式發(fā)送信息了。請(qǐng)求參數(shù)參數(shù)部分的接口說明如下:
header部分
參數(shù)名稱 | 類型 | 必傳 | 參數(shù)要求 | 參數(shù)說明 |
---|---|---|---|---|
app_id | string | 是 | 應(yīng)用appid,從開放平臺(tái)控制臺(tái)創(chuàng)建的應(yīng)用中獲取 | |
uid | string | 否 | 最大長(zhǎng)度32 | 每個(gè)用戶的id,用于區(qū)分不同用戶 |
parameter.chat部分
參數(shù)名稱 | 類型 | 必傳 | 參數(shù)要求 | 參數(shù)說明 |
---|---|---|---|---|
domain | string | 是 | 取值為[general,generalv2] | 指定訪問的領(lǐng)域,general指向V1.5版本 generalv2指向V2版本。注意:不同的取值對(duì)應(yīng)的url也不一樣! |
temperature | float | 否 | 取值為[0,1],默認(rèn)為0.5 | 核采樣閾值。用于決定結(jié)果隨機(jī)性,取值越高隨機(jī)性越強(qiáng)即相同的問題得到的不同答案的可能性越高 |
max_tokens | int | 否 | 取值為[1,4096],默認(rèn)為2048 | 模型回答的tokens的最大長(zhǎng)度 |
top_k | int | 否 | 取值為[1,6],默認(rèn)為4 | 從k個(gè)候選中隨機(jī)選擇?個(gè)(?等概率) |
chat_id | string | 否 | 需要保障用戶下的唯一性 | 用于關(guān)聯(lián)用戶會(huì)話 |
payload.message.text部分
注:text下所有content累計(jì)內(nèi)容 tokens需要控制在8192內(nèi)
參數(shù)名稱 | 類型 | 必傳 | 參數(shù)要求 | 參數(shù)說明 |
---|---|---|---|---|
role | string | 是 | 取值為[user,assistant] | user表示是用戶的問題,assistant表示AI的回復(fù) |
content | string | 是 | 所有content的累計(jì)tokens需控制8192以內(nèi) | 用戶和AI的對(duì)話內(nèi)容 |
報(bào)文示例:
{
"header": {
"app_id": "12345",
"uid": "12345"
},
"parameter": {
"chat": {
"domain": "general",
"temperature": 0.5,
"max_tokens": 1024,
}
},
"payload": {
"message": {
# 如果想獲取結(jié)合上下文的回答,需要開發(fā)者每次將歷史問答信息一起傳給服務(wù)端,如下示例
# 注意:text里面的所有content內(nèi)容加一起的tokens需要控制在8192以內(nèi),開發(fā)者如有較長(zhǎng)對(duì)話需求,需要適當(dāng)裁剪歷史信息
"text": [
{"role": "user", "content": "你是誰"} # 用戶的歷史問題
{"role": "assistant", "content": "....."} # AI的歷史回答結(jié)果
# ....... 省略的歷史對(duì)話
{"role": "user", "content": "你會(huì)做什么"} # 最新的一條問題,如無需上下文,可只傳最新一條問題
]
}
}
}
? ? ? ? 3.3.3 響應(yīng)報(bào)文結(jié)構(gòu)
? ? ? ? 接口服務(wù)將采用流式輸出方式,返回回復(fù)信息,我們需要解析返回的報(bào)文信息,拼接成完整的回復(fù)信息。接口響應(yīng)的報(bào)文結(jié)構(gòu)如下所示:
header部分
字段名 | 類型 | 字段說明 |
---|---|---|
code | int | 錯(cuò)誤碼,0表示正常,非0表示出錯(cuò);詳細(xì)釋義可在接口說明文檔最后的錯(cuò)誤碼說明了解 |
message | string | 會(huì)話是否成功的描述信息 |
sid | string | 會(huì)話的唯一id,用于訊飛技術(shù)人員查詢服務(wù)端會(huì)話日志使用,出現(xiàn)調(diào)用錯(cuò)誤時(shí)建議留存該字段 |
status | int | 會(huì)話狀態(tài),取值為[0,1,2];0代表首次結(jié)果;1代表中間結(jié)果;2代表最后一個(gè)結(jié)果 |
payload.choices部分
字段名 | 類型 | 字段說明 |
---|---|---|
status | int | 文本響應(yīng)狀態(tài),取值為[0,1,2]; 0代表首個(gè)文本結(jié)果;1代表中間文本結(jié)果;2代表最后一個(gè)文本結(jié)果 |
seq | int | 返回的數(shù)據(jù)序號(hào),取值為[0,9999999] |
content | string | AI的回答內(nèi)容 |
role | string | 角色標(biāo)識(shí),固定為assistant,標(biāo)識(shí)角色為AI |
index | int | 結(jié)果序號(hào),取值為[0,10]; 當(dāng)前為保留字段,開發(fā)者可忽略 |
payload.usage部分(在最后一次結(jié)果返回)
字段名 | 類型 | 字段說明 |
---|---|---|
question_tokens | int | 保留字段,可忽略 |
prompt_tokens | int | 包含歷史問題的總tokens大小 |
completion_tokens | int | 回答的tokens大小 |
total_tokens | int | prompt_tokens和completion_tokens的和,也是本次交互計(jì)費(fèi)的tokens大小 |
? ? ? ? 接口響應(yīng)報(bào)文結(jié)構(gòu)示例:
# 接口為流式返回,此示例為最后一次返回結(jié)果,開發(fā)者需要將接口多次返回的結(jié)果進(jìn)行拼接展示
{
"header":{
"code":0,
"message":"Success",
"sid":"cht000cb087@dx18793cd421fb894542",
"status":2
},
"payload":{
"choices":{
"status":2,
"seq":0,
"text":[
{
"content":"我可以幫助你的嗎?",
"role":"assistant",
"index":0
}
]
},
"usage":{
"text":{
"question_tokens":4,
"prompt_tokens":5,
"completion_tokens":9,
"total_tokens":14
}
}
}
}
3.3.4?接口對(duì)接代碼示例
? ? ? ? 使用websocket協(xié)議與服務(wù)端握手成功后,按照?qǐng)?bào)文格式要求發(fā)送信息,等待接口響應(yīng),并解析響應(yīng)數(shù)據(jù)拼接成完整的回復(fù)信息。代碼示例如下所示:
#region websocket連接
/// <summary>
/// websocket
/// </summary>
private ClientWebSocket m_WebSocket;
private CancellationToken m_CancellationToken;
/// <summary>
/// 連接服務(wù)器,獲取回復(fù)
/// </summary>
private async void ConnectHost(string text,Action<string> _callback)
{
try
{
stopwatch.Restart();
m_WebSocket = new ClientWebSocket();
m_CancellationToken = new CancellationToken();
string authUrl = GetAuthUrl();
string url = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
//Uri uri = new Uri(GetUrl());
Uri uri = new Uri(url);
await m_WebSocket.ConnectAsync(uri, m_CancellationToken);
//發(fā)送json
string _jsonData = text;
await m_WebSocket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(_jsonData)), WebSocketMessageType.Binary, true, m_CancellationToken); //發(fā)送數(shù)據(jù)
StringBuilder sb = new StringBuilder();
//用于拼接返回的答復(fù)
string _callBackMessage = "";
//播放隊(duì)列.Clear();
while (m_WebSocket.State == WebSocketState.Open)
{
var result = new byte[4096];
await m_WebSocket.ReceiveAsync(new ArraySegment<byte>(result), m_CancellationToken);//接受數(shù)據(jù)
List<byte> list = new List<byte>(result); while (list[list.Count - 1] == 0x00) list.RemoveAt(list.Count - 1);//去除空字節(jié)
var str = Encoding.UTF8.GetString(list.ToArray());
sb.Append(str);
if (str.EndsWith("}"))
{
//獲取返回的數(shù)據(jù)
ResponseData _responseData = JsonUtility.FromJson<ResponseData>(sb.ToString());
sb.Clear();
if (_responseData.header.code != 0)
{
//返回錯(cuò)誤
//PrintErrorLog(_responseData.code);
Debug.Log("錯(cuò)誤碼:" + _responseData.header.code);
m_WebSocket.Abort();
break;
}
//沒有回復(fù)數(shù)據(jù)
if (_responseData.payload.choices.text.Count == 0)
{
Debug.LogError("沒有獲取到回復(fù)的信息!");
m_WebSocket.Abort();
break;
}
//拼接回復(fù)的數(shù)據(jù)
_callBackMessage += _responseData.payload.choices.text[0].content;
if (_responseData.payload.choices.status == 2)
{
stopwatch.Stop();
Debug.Log("ChatSpark耗時(shí):" + stopwatch.Elapsed.TotalSeconds);
//添加記錄
m_DataList.Add(new SendData("assistant", _callBackMessage));
//回調(diào)
_callback(_callBackMessage);
m_WebSocket.Abort();
break;
}
}
}
}
catch (Exception ex)
{
Debug.LogError("報(bào)錯(cuò)信息: " + ex.Message);
m_WebSocket.Dispose();
}
}
#endregion
4.結(jié)束語
? ? ? ? 這次的文章簡(jiǎn)單介紹了訊飛星火大模型的web api的對(duì)接流程,并針對(duì)接口對(duì)接的流程進(jìn)行了介紹,包括接口的鑒權(quán)、websocket握手以及發(fā)送報(bào)文、響應(yīng)報(bào)文的結(jié)構(gòu)說明,并提供了針對(duì)全流程在unity端的實(shí)現(xiàn)代碼示例。通過上述的代碼實(shí)現(xiàn),我們就可以在unity引擎中,使用星火大模型的api來驅(qū)動(dòng)AI二次元小姐姐的對(duì)話交互。
? ? ? ? 上述代碼只包含了核心的代碼實(shí)現(xiàn),完整的代碼工程可以從我的開源項(xiàng)目下載使用,項(xiàng)目包含了針對(duì)多種GPT應(yīng)用的集成工具,以及語音服務(wù)的集成,對(duì)我這個(gè)項(xiàng)目感興趣的朋友,可以上我的B站號(hào)查看,我也做有詳細(xì)的教程,相關(guān)源碼可以在的嗶哩嗶哩主站找到相關(guān)視頻,在視頻介紹以及評(píng)論區(qū)獲取。
國(guó)產(chǎn)星火大模型驅(qū)動(dòng)AI小姐姐聊天,unity開源工具包,手把手打造自己的二次元老婆~
上述項(xiàng)目地址傳送門:
AI二次元老婆開源項(xiàng)目(unity-AI-Chat-Toolkit):
Github地址:https://github.com/zhangliwei7758/unity-AI-Chat-Toolkit文章來源:http://www.zghlxwxcb.cn/news/detail-713564.html
Gitee地址:https://gitee.com/DammonSpace/unity-ai-chat-toolkit文章來源地址http://www.zghlxwxcb.cn/news/detail-713564.html
到了這里,關(guān)于Unity+訊飛星火大模型+Web api,實(shí)現(xiàn)二次元小姐姐AI聊天互動(dòng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!