国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity 訊飛 之 訊飛星火大模型的簡單封裝和使用(補充訊飛大模型識圖功能)

這篇具有很好參考價值的文章主要介紹了Unity 訊飛 之 訊飛星火大模型的簡單封裝和使用(補充訊飛大模型識圖功能)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Unity 訊飛 之 訊飛星火大模型的簡單封裝和使用(補充訊飛大模型識圖功能)

目錄

Unity 訊飛 之 訊飛星火大模型的簡單封裝和使用(補充訊飛大模型識圖功能)

一、簡單介紹

二、實現(xiàn)原理

三、注意事項

四、效果預覽

五、案例簡單實現(xiàn)步驟

六、關鍵代碼

七、案例下載地址

補充、訊飛大模型-圖像識別


一、簡單介紹

Unity 工具類,自己整理的一些游戲開發(fā)可能用到的模塊,單獨獨立使用,方便游戲開發(fā)。

這里簡單的介紹訊飛大模型的封裝和使用,進行聊天。

“訊飛星火認知大模型”是科大訊飛發(fā)布的產品,具有7大核心能力,即文本生成、語言理解、知識問答、邏輯推理、數(shù)學能力、代碼能力、多模態(tài)能力。

星火v1.5、v2.0地址: http://spark-api.xf-yun.com/v1/completions

星火v3.0地址: http://spark-api.xf-yun.com/v3/completions

星火v1.5和v2.0使用的是同一個URL,domain參數(shù)配置如下:

# domain = "general"       # v1.5版本
#domain = "generalv2"    # v2.0版本
domain = "generalv3"    # v3.0版本
  • 星火認知大模型 WebAPI 接口調用示例 接口文檔(必看):星火認知大模型Web API文檔 | 訊飛開放平臺文檔中心
  • 錯誤碼鏈接:星火認知大模型服務說明 | 訊飛開放平臺文檔中心

二、實現(xiàn)原理

1、申請星火大模型的 APP_ID 等相關信息

2、通過使用的大模型版本,以及當前的時間,結合 申請星火大模型的 APP_ID 等相關信息,生成需要的 URL

3、通過對應的 json 數(shù)據(jù)格式,websocket 進行建立連接請求

4、這里是流式返回,對應解析數(shù)據(jù)格式,得到返回的信息

5、返回的關鍵信息結構,有些類似 gpt 的數(shù)據(jù)格式,用過的話,使用起來會很快

三、注意事項

1、注意 code 返回碼,不同的返回碼可以進行不同處理,避免產生意想不到的問題

2、注意 sid 的區(qū)分,如果上一次返回沒有結束,關閉連接后,重新發(fā)起新的訪問,可能會同時接收到上一次的未結束的數(shù)據(jù)流,和當次的數(shù)據(jù)流;如果不想接收到,注意通過 sid 進行區(qū)分;

3、注意在 LLMConfig 配置你的 APP_ID 等相關信息

四、效果預覽

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

五、案例簡單實現(xiàn)步驟

1、首先到訊飛官網獲取對應的星火大模型的 APP_ID 等相關自己星火大模型的信息

訊飛星火認知大模型-AI大語言模型-星火大模型-科大訊飛

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

2、打開Unity ,簡單搭建一個場景

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

3、可以參考星火大模型的相關demo,完成對應的訊飛大模型接口封裝

這里包括 IIFlyLLMHandler(接口類,可以根據(jù)自己需要重新定義接口),BaseIFlyLLMHandler(基類),IFlyLLMHandler(基本的訊飛接口大模型類),AutoReConnectIFlyLLMHandler(待自動重連的訊飛接口大模型類)

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

4、完成對應接口的封裝之后,添加一個簡單的測試類 TestIFlyLLMHandler

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

5、把 TestIFlyLLMHandler? 添加到場景中,比對應賦值

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

6、運行結果如上

星火大模型 unity,Unity,unity,訊飛大模型,IFlyLLM,星火大模型

六、關鍵代碼

1、TestIFlyLLMHandler

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestIFlyLLMHandler : MonoBehaviour
{
    public Text TagrgetText;
    public InputField TagrgetInputField;
    public Button TagrgetButton;

    List<string> m_StrLst = new List<string>() { 
        "你是誰",
        "最近天氣"
    };

    IIFlyLLMHandler m_Handler;

    // Start is called before the first frame update
    void Start()
    {
        m_Handler = new IFlyLLMHandler();
        m_Handler.Initialized();
        TagrgetText.text = "";
        m_Handler.OnMessageReceivedAction = (jsonResponse) => { TagrgetText.text += jsonResponse.payload.choices.text[0].content; };

        TagrgetButton.onClick.AddListener(() => {
            TagrgetText.text = "";
            m_Handler.SendMsg(TagrgetInputField.text);
        });
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.anyKeyDown) {
            //m_Handler.SendMsg(m_StrLst[Random.Range(0,m_StrLst.Count)]);
        }
    }
}

2、IFlyLLMHandler

using BestHTTP.WebSocket;
using System;
using UnityEngine;

/// <summary>
/// 使用訊飛大模型
/// </summary>
public class IFlyLLMHandler : BaseIFlyLLMHandler
{
    #region Data
    
    /// <summary>
    /// 發(fā)送連接服務器失敗事件
    /// </summary>
    int m_TimerServerAccessFailure = -1;
    const float INTERVAL_TIME_SEND_SERVER_ACCESS_FAILURE = 4.0f;

    #endregion

    #region interface function

    /// <summary>
    /// 初始化
    /// </summary>
    public override void Initialized()
    {
        base.Initialized();
    }

    /// <summary>
    /// 發(fā)送數(shù)據(jù)
    /// </summary>
    /// <param name="askContent"></param>
    public override void SendMsg(string askContent)
    {
        try
        {
            CacheHistory(askContent);

            Connect();
        }
        catch (Exception e)
        {
            Debug.LogError($"e.ToString() {e.ToString()}\ne.Message {e.Message}");
        }
    }

    #endregion

    #region Websocket回調

    /// <summary>
    /// 建立連接事件
    /// </summary>
    /// <param name="ws"></param>
    protected override void OnWebSocketOpen(WebSocket ws)
    {
        Debug.Log("WebSocket Connected!");
        Send();
    }

    /// <summary>
    /// 連接錯誤信息
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="ex"></param>
    protected override void OnWebSocketError(WebSocket ws, Exception ex)
    {
        base.OnWebSocketError(ws, ex);
        SendServerAccessFailure(1005);
    }

    /// <summary>
    /// 連接關閉事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="code"></param>
    /// <param name="message"></param>
    protected override void OnWebSocketClosed(WebSocket ws, ushort code, string message)
    {
        base.OnWebSocketClosed(ws, code, message);
        SendServerAccessFailure(code);
    }

    #endregion

    #region private function

    /// <summary>
    /// 發(fā)送服務器連接失敗錯誤
    /// </summary>
    /// <param name="code"></param>
    private void SendServerAccessFailure(UInt16 code)
    {
        if (code == 1005) // 連接失敗錯誤碼
        {
            if (m_TimerServerAccessFailure != -1) return;
            m_TimerServerAccessFailure = Timer.Instance.Post2Scale((index) => {
                Debug.Log("[BubbleChatUseIFlyLLMHandler] SendServerAccessFailure");
                m_TimerServerAccessFailure = -1;
            }, INTERVAL_TIME_SEND_SERVER_ACCESS_FAILURE);
        }
    }

    #endregion
}

3、BaseIFlyLLMHandler

using Newtonsoft.Json;
using System;
using UnityEngine;
using System.Text;
using BestHTTP.WebSocket;
using System.Collections.Generic;

/**
 * 星火認知大模型 WebAPI 接口調用示例 接口文檔(必看):https://www.xfyun.cn/doc/spark/Web.html
 * 錯誤碼鏈接:https://www.xfyun.cn/doc/spark/%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E.html (code返回錯誤碼時必看)
 * @author iflytek
 */


/// <summary>
/// 訊飛大模型基類
/// </summary>
public class BaseIFlyLLMHandler : IIFlyLLMHandler
{
    #region Data

    /// <summary>
    /// WebSocket
    /// </summary>
    protected WebSocket m_WebSocket;

    /// <summary>
    /// 緩存的歷史數(shù)據(jù)的隊列
    /// </summary>
    protected List<IIFlyLLMHandler.Content> m_CacheHistory = new List<IIFlyLLMHandler.Content>();

    /// <summary>
    /// 是否讀完
    /// </summary>
    protected bool m_ReadEnd = true;

    /// <summary>
    /// 是否需要重發(fā)
    /// </summary>
    protected bool m_NeedSend = false;

    /// <summary>
    /// 大模型的配置
    /// </summary>
    protected LLMConfig m_Config;

    /// <summary>
    /// 記錄上一個老的 sid ,因為打斷后,如果上一次的沒有傳輸完,下一次連接依然會接收到該 sid 的數(shù)據(jù)流
    /// </summary>
    protected string m_OldSid = "";

    /// <summary>
    /// // 用來記錄中間的sid ,因為可能被打斷(不一定每次都能完全正常流程接收完數(shù)據(jù))
    /// </summary>
    protected string m_RcdSid = ""; 

    /// <summary>
    /// 接收到數(shù)據(jù)的事件
    /// </summary>
    public Action<IIFlyLLMHandler.JsonResponse> OnMessageReceivedAction { get; set; }

    #endregion

    #region interface function

    
    /// <summary>
    /// 初始化
    /// </summary>
    public virtual void Initialized()
    {
        m_Config = new LLMConfig();
        
    }

    /// <summary>
    /// 連接
    /// </summary>
    public virtual void Connect()
    {

        if (m_WebSocket != null)
        {
            Close();
        }
        string authUrl = GetAuthUrl();
        string url = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
        m_WebSocket = new WebSocket(new Uri(url));
        m_WebSocket.OnOpen += OnWebSocketOpen;
        m_WebSocket.OnMessage += OnWebSocketMessage;
        m_WebSocket.OnError += OnWebSocketError;
        m_WebSocket.OnClosed += OnWebSocketClosed;
        m_WebSocket.Open();

    }


    /// <summary>
    /// 關閉
    /// </summary>
    public virtual void Close()
    {
        m_OldSid = m_RcdSid;
        m_WebSocket?.Close();
        m_WebSocket = null;
    }

    /// <summary>
    /// 重置
    /// </summary>
    public virtual void Reset()
    {
        m_CacheHistory.Clear();
    }

    /// <summary>
    /// 發(fā)送消息
    /// </summary>
    /// <param name="history"></param>
    public virtual void SendMsg(string askContent)
    {
        try
        {
            CacheHistory(askContent);

            if (m_WebSocket != null && m_WebSocket.IsOpen)
            {
                if (m_ReadEnd)
                {
                    Send();
                }
                else
                {
                    //中斷websocket,然后再發(fā)送
                    Close();
                    m_NeedSend = true;
                }
            }
            else
            {
                m_NeedSend = true;
                Connect();
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.Message);
        }
    }

    

    #endregion

    #region Websocket回調

    /// <summary>
    /// 建立連接的事件
    /// </summary>
    /// <param name="ws"></param>
    protected virtual void OnWebSocketOpen(WebSocket ws)
    {
        Debug.Log("WebSocket Connected!");
        if (m_NeedSend) Send();
    }

    /// <summary>
    /// 接收到數(shù)據(jù)的事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="message"></param>
    protected virtual void OnWebSocketMessage(WebSocket ws, string message)
    {
        // 處理接收到的消息
        // 這里你可以根據(jù)需要進行相應的處理
        Debug.Log($"Received message: {message}");
        IIFlyLLMHandler.JsonResponse jsonResponse = JsonConvert.DeserializeObject<IIFlyLLMHandler.JsonResponse>(message);

        if (jsonResponse.header.code == 10013) // 錯誤碼 10013:輸入內容審核不通過,涉嫌違規(guī),請重新調整輸入內容
        {
            Debug.LogError($"OnWebSocketMessage message {jsonResponse.header.message} ");
        }
        else
        {
            Debug.Log($"OnWebSocketMessage m_OldSid {m_OldSid}, jsonResponse.header.sid {jsonResponse.header.sid} jsonResponse.header.code {jsonResponse.header.code}");
            // 判斷不是上一次的 sid 的舊的數(shù)據(jù)流在做出反應
            if (jsonResponse.header.sid.Equals(m_OldSid) == false)
            {
                if (jsonResponse.header.code == 10014) // 錯誤碼 10014:輸出內容涉及敏感信息,審核不通過,后續(xù)結果無法展示給用戶
                {
                    jsonResponse=GetHandleJsonResponse(jsonResponse);
                }
                OnMessageReceivedAction?.Invoke(jsonResponse);
                m_RcdSid = jsonResponse.header.sid;
            }
        }

        if (jsonResponse.payload.choices.status == 0)
        {
            Debug.Log("Get First IFlyLLM Response");
        }

        if (jsonResponse.payload.choices.status == 2)
        {
            m_ReadEnd = true;
            Debug.Log("Get Last IFlyLLM Response");
            m_OldSid = jsonResponse.header.sid;
        }
    }

    /// <summary>
    /// 連接發(fā)生錯誤的事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="ex"></param>
    protected virtual void OnWebSocketError(WebSocket ws, Exception ex)
    {
        Debug.LogError($"WebSocket Error: {ex.Message}");
    }

    /// <summary>
    /// 連接關閉的事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="code"></param>
    /// <param name="message"></param>
    protected virtual void OnWebSocketClosed(WebSocket ws, UInt16 code, string message)
    {
        Debug.LogFormat("WebSocket Closed!: code={0}, msg={1}", code, message);
    }

    #endregion

    #region protected function

    /// <summary>
    /// 真正發(fā)送數(shù)據(jù)
    /// </summary>
    protected virtual void Send()
    {
        m_NeedSend = false;
        m_ReadEnd = false;
        IIFlyLLMHandler.JsonRequest request = CreateRequest();
        string jsonString = JsonConvert.SerializeObject(request);
        Debug.LogError(jsonString);
        m_WebSocket?.Send(jsonString);
    }


    /// <summary>
    /// 創(chuàng)建一個連接請求
    /// </summary>
    /// <returns></returns>
    protected virtual IIFlyLLMHandler.JsonRequest CreateRequest()
    {
        return new IIFlyLLMHandler.JsonRequest
        {
            header = new IIFlyLLMHandler.Header
            {
                app_id = m_Config.IFLY_APPID,
                uid = Guid.NewGuid().ToString().Substring(0, 10)
            },
            parameter = new IIFlyLLMHandler.Parameter
            {
                chat = new IIFlyLLMHandler.Chat
                {
                    domain = "generalv3",
                    temperature = 0.01,
                    max_tokens = 480
                }
            },
            payload = new IIFlyLLMHandler.Payload
            {
                message = new IIFlyLLMHandler.Message
                {
                    text = m_CacheHistory
                }
            }
        };
    }



    /// <summary>
    /// 緩存歷史記錄數(shù)據(jù)結構,優(yōu)化性能
    /// (緩存需要自己額外補充,這里先做簡單的提問)
    /// </summary>
    protected virtual void CacheHistory(string askContent)
    {
        m_CacheHistory.Clear();
        IIFlyLLMHandler.Content content = new IIFlyLLMHandler.Content();
        content.role = "user";
        content.content = askContent;
        m_CacheHistory.Add(content);
    }

    /// <summary>
    /// 敏感輸出內容后的處理
    /// 重新組織數(shù)據(jù)(涉及敏感內容不予展示)
    /// </summary>
    /// <param name="jsonResponse"></param>
    /// <returns></returns>
    protected virtual IIFlyLLMHandler.JsonResponse GetHandleJsonResponse(IIFlyLLMHandler.JsonResponse jsonResponse) {
        int status = 2;

        IIFlyLLMHandler.HeaderResponse header = new IIFlyLLMHandler.HeaderResponse() { code = 0, message = "Success", sid = jsonResponse.header.sid, status = status };
        
        IIFlyLLMHandler.Text text = new IIFlyLLMHandler.Text() {content="***(涉及敏感內容不予展示)。",role= "assistant",index=0 };
        List<IIFlyLLMHandler.Text> textlst = new List<IIFlyLLMHandler.Text>();
        textlst.Add(text);

        IIFlyLLMHandler.Choices choices = new IIFlyLLMHandler.Choices() { status= status, seq=999,text=textlst};
        IIFlyLLMHandler.PayloadResponse payload = new IIFlyLLMHandler.PayloadResponse() { choices=choices};

        IIFlyLLMHandler.JsonResponse reorganizingInformationJRspn = new IIFlyLLMHandler.JsonResponse() {header=header,payload=payload };

        return reorganizingInformationJRspn;
    }

    #endregion

    #region 字符串操作

    /// <summary>
    /// 生成得到授權的 URL 
    /// </summary>
    /// <returns></returns>
    private string GetAuthUrl()
    {
        string date = DateTime.UtcNow.ToString("r");
        Uri uri = new Uri(m_Config.IFLY_HOST_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_Config.IFLY_API_SECRET, builder.ToString());
        string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", m_Config.IFLY_API_KEY, "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;
    }

    /// <summary>
    /// HMACsha256 
    /// </summary>
    /// <param name="apiSecretIsKey"></param>
    /// <param name="buider"></param>
    /// <returns></returns>
    private 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);
    }

    #endregion

}

4、IIFlyLLMHandler

using System;
using System.Collections.Generic;

/// <summary>
/// 訊飛大模型接口類
/// </summary>
public interface IIFlyLLMHandler
{
    /// <summary>
    /// 初始化
    /// </summary>
    void Initialized();
    /// <summary>
    /// 連接
    /// </summary>
    void Connect();
    /// <summary>
    /// 關閉連接
    /// </summary>
    void Close();
    /// <summary>
    /// 重置
    /// </summary>
    void Reset();
    /// <summary>
    /// 發(fā)送信息
    /// </summary>
    /// <param name="askContent"></param>
    void SendMsg(string askContent);
    /// <summary>
    /// 接收到數(shù)據(jù)事件
    /// </summary>
    Action<JsonResponse> OnMessageReceivedAction { get; set; }

    #region Request數(shù)據(jù)類定義

    public class JsonRequest
    {
        public Header header { get; set; }
        public Parameter parameter { get; set; }
        public Payload payload { get; set; }
    }

    public class Header
    {
        public string app_id { get; set; }
        public string uid { get; set; }
    }

    public class Parameter
    {
        public Chat chat { get; set; }
    }

    public class Chat
    {
        public string domain { get; set; }
        public double temperature { get; set; }
        public int max_tokens { get; set; }
    }

    public class Payload
    {
        public Message message { get; set; }
    }

    public class Message
    {
        public List<Content> text { get; set; }
    }

    public class Content
    {
        public string role { get; set; }
        public string content { get; set; }
    }

    #endregion

    #region Response數(shù)據(jù)類型定義

    public class JsonResponse
    {
        public HeaderResponse header { get; set; }
        public PayloadResponse payload { get; set; }
    }

    public class HeaderResponse
    {
        public int code { get; set; }
        public string message { get; set; }
        public string sid { get; set; }
        public int status { get; set; }
    }

    public class PayloadResponse
    {
        public Choices choices { get; set; }
    }

    public class Choices
    {
        public int status { get; set; }
        public int seq { get; set; }
        public List<Text> text { get; set; }
    }

    public class Text
    {
        public string content { get; set; }
        public string role { get; set; }
        public int index { get; set; }
    }

    #endregion
}

5、LLMConfig

public class LLMConfig
{
    #region 訊飛

    /// <summary>
    /// 應用APPID(必須為webapi類型應用,并開通星火認知大模型授權)
    /// </summary>
    public readonly string IFLY_APPID = "YOUR_IFLY_APPID";

    /// <summary>
    /// 接口密鑰(webapi類型應用開通星火認知大模型后,控制臺--我的應用---星火認知大模型---相應服務的apikey)
    /// </summary>
    public readonly string IFLY_API_SECRET = "YOUR_IFLY_API_SECRET";

    /// <summary>
    /// 接口密鑰(webapi類型應用開通星火認知大模型后,控制臺--我的應用---星火認知大模型---相應服務的apisecret)
    /// </summary>
    public readonly string IFLY_API_KEY = "YOUR_IFLY_API_KEY";

    /// <summary>
    /// 訊飛大模型訪問地址
    /// </summary>
    public readonly string IFLY_HOST_URL = "https://spark-api.xf-yun.com/v3.1/chat";

    /// <summary>
    /// 訊飛圖像識別
    /// </summary>
    public readonly string IFLY_IMAGE_RECOGNIZE_URL = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image";

    #endregion
}

6、AutoReConnectIFlyLLMHandler

using BestHTTP.WebSocket;
using System;
using UnityEngine;

/// <summary>
/// 帶自動重連的訊飛大模型訪問
/// </summary>
public class AutoReConnectIFlyLLMHandler : BaseIFlyLLMHandler
{

    #region Data

    /// <summary>
    /// m_ReconnectTimerId :自動重連的 TimerId
    /// </summary>
    int m_ReconnectTimerId = -1;

    /// <summary>
    /// m_ReconnectDelay :  自動重連的 時間
    /// </summary>
    float m_ReconnectDelay = 0.5f;

    #endregion

    #region interface function

    /// <summary>
    /// 初始化
    /// </summary>
    public override void Initialized()
    {
        base.Initialized();
        Connect();
    }

    /// <summary>
    /// 關閉連接
    /// </summary>
    public override void Close()
    {
        CancelReconnectTimer();
        base.Close();
    }

    /// <summary>
    /// 自動重連
    /// </summary>
    internal void AutoReconnect()
    {
        Connect();
    }

    /// <summary>
    /// 發(fā)送請求
    /// </summary>
    /// <param name="askContent"></param>
    public override void SendMsg(string askContent)
    {
        try
        {
            CacheHistory(askContent);

            if (m_WebSocket != null && m_WebSocket.IsOpen)
            {
                if (m_ReadEnd)
                {
                    Send();
                }
                else
                {
                    //中斷websocket,然后再發(fā)送
                    Close();
                    m_NeedSend = true;
                }
            }
            else
            {
                m_NeedSend = true;
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.Message);
        }
    }

    #endregion

    #region Websocket回調

    /// <summary>
    /// 關閉連接事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="code"></param>
    /// <param name="message"></param>
    protected override void OnWebSocketClosed(WebSocket ws, ushort code, string message)
    {
        base.OnWebSocketClosed(ws, code, message);
        RunReconnectTimer();
    }

    /// <summary>
    /// 連接發(fā)生錯誤的事件
    /// </summary>
    /// <param name="ws"></param>
    /// <param name="ex"></param>
    protected override void OnWebSocketError(WebSocket ws, Exception ex)
    {
        base.OnWebSocketError(ws, ex);
        RunReconnectTimer();
    }
    #endregion
    #region 計時器

    /// <summary>
    /// 計時自動重新連接
    /// </summary>
    private void RunReconnectTimer()
    {
        Debug.Log($"Scheduling reconnect in {m_ReconnectDelay} seconds...");
        CancelReconnectTimer();
        m_ReconnectTimerId = Timer.Instance.Post2Really((v) => { AutoReconnect(); }, m_ReconnectDelay);
    }

    /// <summary>
    /// 取消重新連接計時
    /// </summary>
    private void CancelReconnectTimer()
    {
        if (m_ReconnectTimerId != -1)
        {
            Timer.Instance.Cancel(m_ReconnectTimerId);
            m_ReconnectTimerId = -1;
        }
    }

    #endregion
}

七、案例下載地址

https://download.csdn.net/download/u014361280/88565465

補充、訊飛大模型-圖像識別

1、IFlyLLMImageHandler

using UnityEngine;
using System;
using System.Text;
using Newtonsoft.Json;
using BestHTTP.WebSocket;
using System.Collections.Generic;

public class IFlyLLMImageHandler 
{
    private WebSocket m_WebSocket;

    private int m_ReconnectTimerId = -1;
    private float m_ReconnectDelay = 0.5f;
    private List<Content> m_CacheHistory = new List<Content>();

    public Action<JsonResponse> OnMessageReceivedAction;
    private bool m_ReadEnd = true;
    private bool m_NeedSend = false;

    private LLMConfig m_Config;

    public void Initialized()
    {
        m_Config = new LLMConfig();
        Connect();
    }

    /// <summary>
    /// 連接
    /// </summary>
    public void Connect()
    {

        if (m_WebSocket != null)
        {
            Close();
        }
        string authUrl = GetAuthUrl();
        string url = authUrl.Replace("http://", "ws://").Replace("https://", "wss://");
        m_WebSocket = new WebSocket(new Uri(url));
        m_WebSocket.OnOpen += OnWebSocketOpen;
        m_WebSocket.OnMessage += OnWebSocketMessage;
        m_WebSocket.OnError += OnWebSocketError;
        m_WebSocket.OnClosed += OnWebSocketClosed;
        m_WebSocket.Open();

    }

    /// <summary>
    /// 關閉
    /// </summary>
    public void Close()
    {
        CancelReconnectTimer();
        m_WebSocket?.Close();
        m_WebSocket = null;
    }

    public void Reset()
    {
        m_CacheHistory.Clear();
    }

    /// <summary>
    /// 自動重連
    /// </summary>
    private void AutoReconnect()
    {
        Connect();
    }

    /// <summary>
    /// 發(fā)送消息
    /// </summary>
    /// <param name="history"></param>
    public void SendMsg(string base64,string ask)
    {
        try
        {
            ImageDataAsk(base64, ask);

            if (m_WebSocket != null && m_WebSocket.IsOpen)
            {
                if (m_ReadEnd)
                {
                    Send();
                }
                else
                {
                    //中斷websocket,然后再發(fā)送
                    Close();
                    m_NeedSend = true;
                }
            }
            else
            {
                m_NeedSend = true;
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.Message);
        }
    }

    private void Send()
    {
        m_NeedSend = false;
        m_ReadEnd = false;
        JsonRequest request = CreateRequest();
        string jsonString = JsonConvert.SerializeObject(request);
        Debug.LogError(jsonString);
        m_WebSocket?.Send(jsonString);
    }

    #region Websocket回調

    private void OnWebSocketOpen(WebSocket ws)
    {
        Debug.Log("WebSocket Connected!");
        if (m_NeedSend) Send();
    }

    private void OnWebSocketMessage(WebSocket ws, string message)
    {
        // 處理接收到的消息
        // 這里你可以根據(jù)需要進行相應的處理
        Debug.Log($"Received message: {message}");
        JsonResponse jsonResponse = JsonConvert.DeserializeObject<IFlyLLMImageHandler.JsonResponse>(message);
        OnMessageReceivedAction?.Invoke(jsonResponse);

        if (jsonResponse.payload.choices.status == 0)
        {
            Debug.Log("Get First IFlyLLM Response");
        }

        if (jsonResponse.payload.choices.status == 2)
        {
            m_ReadEnd = true;
            Debug.Log("Get Last IFlyLLM Response");
        }
    }

    private void OnWebSocketError(WebSocket ws, Exception ex)
    {
        Debug.LogError($"WebSocket Error: {ex.Message}");
        RunReconnectTimer();
    }

    private void OnWebSocketClosed(WebSocket ws, UInt16 code, string message)
    {
        Debug.LogFormat("WebSocket Closed!: code={0}, msg={1}", code, message);
        RunReconnectTimer();
    }

    #endregion

    private JsonRequest CreateRequest()
    {
        return new JsonRequest
        {
            header = new Header
            {
                app_id = m_Config.IFLY_APPID,
                uid = Guid.NewGuid().ToString().Substring(0, 10)
            },
            parameter = new Parameter
            {
                chat = new Chat
                {
                    domain = "general",
                    temperature = 0.5,
                    top_k= 4,
                    max_tokens = 2048,
                    auditing = "default"

                }
            },
            payload = new Payload
            {
                message = new Message
                {
                    text = m_CacheHistory
                }
            }
        };
    }

    private void ImageDataAsk(string base64,string ask) {
        m_CacheHistory.Clear();
        Content content = new Content();
        content.role = "user";
        content.content = base64;
        content.content_type = "image";
        m_CacheHistory.Add(content);

        content = new Content();
        content.role = "user";
        content.content = ask;
        content.content_type = "text";
        m_CacheHistory.Add(content);
    }


    #region 計時器

    private void RunReconnectTimer()
    {
        Debug.Log($"Scheduling reconnect in {m_ReconnectDelay} seconds...");
        CancelReconnectTimer();
        m_ReconnectTimerId = Timer.Instance.Post2Really((v) => { AutoReconnect(); }, m_ReconnectDelay);
    }

    private void CancelReconnectTimer()
    {
        if (m_ReconnectTimerId != -1)
        {
            Timer.Instance.Cancel(m_ReconnectTimerId);
            m_ReconnectTimerId = -1;
        }
    }

    #endregion

    #region 字符串操作

    private string GetAuthUrl()
    {
        string date = DateTime.UtcNow.ToString("r");
        Uri uri = new Uri(m_Config.IFLY_IMAGE_RECOGNIZE_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_Config.IFLY_API_SECRET, builder.ToString());
        string authorization = string.Format("api_key=\"{0}\", algorithm=\"{1}\", headers=\"{2}\", signature=\"{3}\"", m_Config.IFLY_API_KEY, "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;
    }

    private 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);
    }

    #endregion

    #region Request數(shù)據(jù)類定義

    public class JsonRequest
    {
        public Header header { get; set; }
        public Parameter parameter { get; set; }
        public Payload payload { get; set; }
    }

    public class Header
    {
        public string app_id { get; set; }
        public string uid { get; set; }
    }

    public class Parameter
    {
        public Chat chat { get; set; }
    }

    public class Chat
    {
        public string domain { get; set; }
        public double temperature { get; set; }
        public int top_k { get; set; }
        public int max_tokens { get; set; }
        public string auditing { get; set; }
    }

    public class Payload
    {
        public Message message { get; set; }
    }

    public class Message
    {
        public List<Content> text { get; set; }
    }

    public class Content
    {
        public string role { get; set; }
        public string content { get; set; }
        public string content_type { get; set; }
    }

    #endregion

    #region Response數(shù)據(jù)類型定義

    public class JsonResponse
    {
        public HeaderResponse header { get; set; }
        public PayloadResponse payload { get; set; }
    }

    public class HeaderResponse
    {
        public int code { get; set; }
        public string message { get; set; }
        public string sid { get; set; }
        public int status { get; set; }
    }

    public class PayloadResponse
    {
        public Choices choices { get; set; }
        public Usage usage { get; set; }
    }

    public class Choices
    {
        public int status { get; set; }
        public int seq { get; set; }
        public List<Text> text { get; set; }
    }

    public class Text
    {
        public string content { get; set; }
        public string role { get; set; }
        public int index { get; set; }
    }

    public class Usage
    {
        public UsageText text { get; set; }
    }

    public class UsageText { 
        public int completion_tokens { get; set; }
        public int question_tokens { get; set; }
        public int prompt_tokens { get; set; }
        public int total_tokens { get; set; }
    }

    #endregion
}

2、TestIFlyLLMImageHandler


using UnityEngine;

public class TestIFlyLLMImageHandler : Singleton<TestIFlyLLMImageHandler>
{
    public void Test() {

        IFlyLLMImageHandler imageHandler = new IFlyLLMImageHandler();
        imageHandler.Initialized();
        imageHandler.OnMessageReceivedAction += (str) => {
            Debug.Log(" TestIFlyLLMImageHandler OnMessageReceivedAction " + str.payload.choices.text[0].content);
        
        };

        CameraCaptureImageForBase64.Instance.OnGetBase64ImageSuccess = (base64) =>
        {
            imageHandler.SendMsg(base64, "這是什么,盡可能詳細的回答");
        };
        CameraCaptureImageForBase64.Instance.OnGetBase64ImageFailed = async (str) =>
        {
            string base64 = await ImageLoader.Instance.LoadImageAndConvertToBase64();
            imageHandler.SendMsg(base64, "這是什么,盡可能詳細的回答");
        };
        CameraCaptureImageForBase64.Instance.CaptureImage();
    }
}

3、CameraCaptureImageForBase64


using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Android;

/// <summary>
/// 打開 Camera  捕捉圖片,獲取圖片 base64 信息
/// </summary>
public class CameraCaptureImageForBase64 : MonoSingleton<CameraCaptureImageForBase64>
{
    #region data
    
    /// <summary>
    /// 獲取圖片成功事件
    /// </summary>
    public Action<string> OnGetBase64ImageSuccess;
    /// <summary>
    /// 獲取圖片失敗事件
    /// </summary>
    public Action<string> OnGetBase64ImageFailed;

    private WebCamTexture webcamTexture; // 用于獲取相機圖像
    private Coroutine m_Coroutine;

    #endregion

    /// <summary>
    /// 捕捉圖片
    /// </summary>
    public void CaptureImage()
    {
        m_Coroutine = StartCoroutine(CaptureRoutine());
    }

    /// <summary>
    /// 停止捕捉
    /// </summary>
    public void StopCapture()
    {
        if (m_Coroutine!=null)
        {
            StopCoroutine(m_Coroutine);
            m_Coroutine = null;
        }
    }

    #region private function

    private IEnumerator CaptureRoutine()
    {
        // 檢查是否有相機權限
        if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
        {
            // 如果沒有相機權限,等待用戶授權
            yield return RequestCameraPermission();
        }

        // 啟動相機
        StartCamera();

        // 等待用戶拍照
        yield return WaitForUserToTakePhoto();

        // 拍照
        Texture2D photo = TakePhoto();

        if (photo != null)
        {
            // 將Texture2D轉換為byte數(shù)組
            byte[] imageBytes = photo.EncodeToPNG();

            // 將byte數(shù)組轉換為base64字符串
            string base64String = Convert.ToBase64String(imageBytes);

            Debug.Log("Base64 Image: " + base64String);

            // 在這里執(zhí)行你的異步任務,例如上傳base64圖片到服務器
            OnGetBase64ImageSuccess?.Invoke(base64String);
        }
        else {
            OnGetBase64ImageFailed?.Invoke("capture image failed.");
        }

        // 停止相機
        StopCamera();
    }

    private IEnumerator RequestCameraPermission()
    {
        // 請求相機權限
        Permission.RequestUserPermission(Permission.Camera);

        // 等待用戶授權
        yield return new WaitUntil(() => Permission.HasUserAuthorizedPermission(Permission.Camera));
    }

    private void StartCamera()
    {
        // 獲取可用的相機設備
        WebCamDevice[] devices = WebCamTexture.devices;

        if (devices.Length > 0)
        {
            // 使用第一個相機設備
            webcamTexture = new WebCamTexture(devices[0].name);
            webcamTexture.Play();
        }
        else
        {
            Debug.LogError("No camera device available.");
            OnGetBase64ImageFailed?.Invoke("No camera device available.");
        }
    }

    private IEnumerator WaitForUserToTakePhoto()
    {
        // 可以其他按鍵操作拍照
        // 這里直接等到若干秒
        yield return new WaitForSecondsRealtime(0.1f);
    }

    private Texture2D TakePhoto()
    {
        if (webcamTexture != null && webcamTexture.isPlaying)
        {
            Texture2D photo = new Texture2D(webcamTexture.width, webcamTexture.height);
            photo.SetPixels(webcamTexture.GetPixels());
            photo.Apply();
            return photo;
        }
        return null;
    }

    private void StopCamera()
    {
        if (webcamTexture != null && webcamTexture.isPlaying)
        {
            webcamTexture.Stop();
        }
    }

    #endregion
}

4、ImageLoader文章來源地址http://www.zghlxwxcb.cn/news/detail-766504.html


using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class ImageLoader : Singleton<ImageLoader>
{
    [SerializeField] private string imageAddress = "車"; // 設置為你圖片在Addressables中的地址

    public async Task<string> LoadImageAndConvertToBase64()
    {
        string base64String = string.Empty;

        // 使用Addressables加載圖片
        AsyncOperationHandle<Texture2D> handle = Addressables.LoadAssetAsync<Texture2D>(imageAddress);

        // 等待加載完成
        await handle.Task;

        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            Texture2D texture = handle.Result;

            // 將Texture2D轉換為byte數(shù)組
            byte[] imageBytes = texture.EncodeToPNG();

            // 將byte數(shù)組轉換為base64字符串
            base64String = Convert.ToBase64String(imageBytes);

            Debug.Log("Base64 Image: " + base64String);
        }
        else
        {
            Debug.LogError("Failed to load image: " + handle.OperationException);
        }

        // 釋放資源
        Addressables.Release(handle);

        return base64String;
    }
}

到了這里,關于Unity 訊飛 之 訊飛星火大模型的簡單封裝和使用(補充訊飛大模型識圖功能)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯(lián)網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【訊飛星火認知大模型】大模型之星火手機助理

    【訊飛星火認知大模型】大模型之星火手機助理

    目錄 1.?訊飛星火認知大模型介紹 2. API 申請 3.?星火手機助理 4. 效果展示 訊飛星火認知大模型是科大訊飛自研的基于深度學習的自然語言處理模型,它可以理解和生成中文,執(zhí)行多種任務,如問答、翻譯、寫作、編程等。它的目標是實現(xiàn)“智能涌現(xiàn)”,覆蓋多維度多任務多

    2024年02月13日
    瀏覽(17)
  • 【訊飛星火大模型AI】SpringBoot項目快速接入訊飛星火API

    【訊飛星火大模型AI】SpringBoot項目快速接入訊飛星火API

    訊飛官網:訊飛星火認知大模型-AI大語言模型-星火大模型-科大訊飛 (xfyun.cn) 新用戶認證之后可以免費領取二百萬token,有效期一年,免費薅羊毛。 認證完成后,創(chuàng)建一個應用(很簡單),點點點就能完成。 2.1 配置 創(chuàng)建完成之后,去github上找到訊飛開放平臺的sdk,推薦下面這個

    2024年04月15日
    瀏覽(20)
  • Unity+訊飛語音+訊飛星火+Motionverse打造智能數(shù)字人

    不廢話,先來效果視頻 unity+訊飛語音識別+訊飛星火大模型+Motionver 然后說說原理 要實現(xiàn)這個,主要的實現(xiàn)三個模塊的接入: 語音識別。作用是吧麥克風的語音轉化為gpt大模型能夠識別的文字。然后發(fā)給gpt。 GPT大模型。作用當然是把第一步中生成的問題文字轉換為解答文本。

    2024年02月12日
    瀏覽(27)
  • 科大訊飛交卷,實測星火大模型

    科大訊飛交卷,實測星火大模型

    作者 |?辰紋 來源 |?洞見新研社 星星之火,可以燎原。 5月6日,訊飛星火認知大模型揭開神秘面紗。 發(fā)布會上,科大訊飛董事長劉慶峰、研究院院長劉聰現(xiàn)場實測了星火大模型七大核心能力,并發(fā)布基于該大模型的教育、辦公、汽車和數(shù)字員工等多個領域的相關產品。 與此

    2024年02月03日
    瀏覽(25)
  • springBoot整合訊飛星火認知大模型

    springBoot整合訊飛星火認知大模型

    訊飛星火大模型是科大訊飛最近開放的擁有跨領域的知識和語言理解能力的大模型,能夠完成問答對話和文學創(chuàng)作等。由于訊飛星火大模型最近可以免費試用,開發(fā)者都可以免費申請一個QPS不超過2的賬號,用來實現(xiàn)對平臺能力的驗證。本文將利用Springboot框架對星火大模型進

    2024年02月04日
    瀏覽(30)
  • 訊飛星火大模型將超越chatgpt?

    近日,科大訊飛召開了星火認知大模型成果發(fā)布會,會上表示訊飛星火大模型將突破開放式問答,對標ChatGPT,在中文能力上超過ChatGPT,在英文能力上與ChatGPT相當。對此,你怎么看? 這一突破意味著人工智能技術正在不斷進步,能夠更好地服務于廣大用戶。同時,對于中英文

    2024年02月03日
    瀏覽(27)
  • 【分享】科大訊飛星火認知大模型(初體驗)

    【分享】科大訊飛星火認知大模型(初體驗)

    前言: 哈嘍,大家好,我是木易巷~ 隨著人工智能技術的迅猛發(fā)展,自然語言處理(NLP)成為了熱門話題。在眾多NLP模型中,科大訊飛星火認知大模型成為了一個備受矚目的新秀,今天我們來了解一下這個由科大訊飛公司開發(fā)的人工智能模型~ (內測方法在文末) 5月6日,訊

    2024年02月07日
    瀏覽(25)
  • 科大訊飛一季度凈虧損同比擴大418%,訊飛星火大模型不靈了?

    科大訊飛一季度凈虧損同比擴大418%,訊飛星火大模型不靈了?

    近日,科大訊飛公布截至2024年3月31日的一季度業(yè)績報告及2023年年報。財報顯示,科大訊飛一季度總營收同比增長26.27%,為36.46億元;一季度凈虧損3億元,上年同期凈虧損5789.5萬元,同比擴大418.17%。 科大訊飛2023年總營收為196.5億元,歸母凈利潤6.57億元,同比增長17.12%。 營收

    2024年04月25日
    瀏覽(23)
  • 科大訊飛星火認知大模型是真能打

    5月6日,科大訊飛正式發(fā)布星火認知大模型。 先進的技術,出色的表現(xiàn),直擊產業(yè)痛點的商業(yè)應用,讓人們再次認識了科大訊飛的強大。當然,星火認知大模型也是真能打。 01 火爆的大模型 2022年11月,人工智能公司OpenAI推出的生成式機器人ChatGPT發(fā)布后短時間便火遍全球,成

    2024年02月05日
    瀏覽(19)
  • “訊飛星火”大模型計劃10月底趕超ChatGPT

    “訊飛星火”大模型計劃10月底趕超ChatGPT

    ?創(chuàng)作者:全棧弄潮兒 ?? 個人主頁: 全棧弄潮兒的個人主頁 ??? 個人社區(qū),歡迎你的加入:全棧弄潮兒的個人社區(qū) ?? 專欄地址:AI大模型 5月6日,訊飛星火認知大模型成果發(fā)布會在安徽合肥舉行。科大訊飛董事長劉慶峰、研究院院長劉聰發(fā)布訊飛星火認知大模型,現(xiàn)場

    2024年02月04日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包