using Newtonsoft.Json; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Security.Cryptography; using System.Text; using UnityEngine; using UnityEngine.Networking; public class ChatGLM_Turbo : LLM { #region 参数 /// /// 选择的模型 /// [SerializeField] private ModelType m_Type= ModelType.chatglm_turbo; /// /// 调用方式 invoke/async-invoke/sse-invoke 先实现同步模式 /// [SerializeField] private string m_InvokeMethod = "invoke"; /// /// 智普AI的apikey /// [Header("填写智普AI的apikey")] [SerializeField] private string m_Key = string.Empty; //api key [SerializeField] private string m_ApiKey = string.Empty; //secret key [SerializeField] private string m_SecretKey = string.Empty; #endregion private void Awake() { OnInit(); } /// /// 发送消息 /// /// public override void PostMsg(string _msg, Action _callback) { base.PostMsg(_msg, _callback); } /// /// 发送数据 /// /// /// /// public override IEnumerator Request(string _postWord, System.Action _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(_msg); if (response.data.choices.Count > 0) { string _msgBack = response.data.choices[0].content; //添加记录 m_DataList.Add(new SendData("assistant", _msgBack)); //回调 _callback(_msgBack); } else { Debug.Log(_msg); } } } stopwatch.Stop(); Debug.Log("chatGLM Turbo耗时:" + stopwatch.Elapsed.TotalSeconds); } /// /// 初始化 /// private void OnInit() { SplitKey(); GetEndPointUrl(); } /// /// 获取资源路径 /// private void GetEndPointUrl() { url = String.Format("https://open.bigmodel.cn/api/paas/v3/model-api/{0}/{1}", m_Type, m_InvokeMethod); } /// /// 处理key /// private void SplitKey() { try { if (m_Key == "") return; string[] _split = m_Key.Split('.'); m_ApiKey = _split[0]; m_SecretKey = _split[1]; } catch { } } #region 生成api鉴权token /// /// 生成api鉴权 token /// /// 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) { // 构建Header string _headerJson = "{\"alg\":\"HS256\",\"sign_type\":\"SIGN\"}"; string encodedHeader = Base64UrlEncode(_headerJson); // 构建Payload string _playLoadJson = string.Format("{{\"api_key\":\"{0}\",\"exp\":{1}, \"timestamp\":{2}}}", apiKeyId, expirationMilliseconds, timestampMilliseconds); string encodedPayload = Base64UrlEncode(_playLoadJson); // 构建签名 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 #region 数据定义 /// /// 模型类型 /// public enum ModelType { chatglm_turbo, characterglm } [Serializable] private class RequestData { [SerializeField] public string model; [SerializeField] public List 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 choices=new List(); } #endregion }