原:基于C#+WPF编写的调用讯飞星火大模型工具_c#xf$xccx-CSDN博客
记录一下以防以后用到。
using Newtonsoft.Json;
using System.Collections.Generic;
public class JsonResponse
{
[JsonProperty("header")]
public ResponseHeader Header { get; set; }
[JsonProperty("payload")]
public ResponsePayload Payload { get; set; }
}
public class ResponseHeader
{
/// <summary>
/// 错误码,0表示正常,非0表示出错;详细释义可在接口说明文档最后的错误码说明了解
/// </summary>
[JsonProperty("code")]
public int Code { get; set; }
/// <summary>
/// 会话是否成功的描述信息
/// </summary>
[JsonProperty("message")]
public string Message { get; set; }
/// <summary>
/// 会话的唯一id,用于讯飞技术人员查询服务端会话日志使用,出现调用错误时建议留存该字段
/// </summary>
[JsonProperty("sid")]
public string Sid { get; set; }
/// <summary>
/// 会话状态,取值为[0,1,2];0代表首次结果;1代表中间结果;2代表最后一个结果
/// </summary>
[JsonProperty("status")]
public int Status { get; set; }
}
public class ResponsePayload
{
[JsonProperty("choices")]
public ResponseChoices Choices { get; set; }
[JsonProperty("useage")]
public ResponseUsage Usage { get; set; }
}
public class ResponseChoices
{
/// <summary>
/// 文本响应状态,取值为[0,1,2]; 0代表首个文本结果;1代表中间文本结果;2代表最后一个文本结果
/// </summary>
[JsonProperty("status")]
public int Status { get; set; }
/// <summary>
/// 返回的数据序号,取值为[0,9999999]
/// </summary>
[JsonProperty("seq")]
public int Seq { get; set; }
[JsonProperty("text")]
public List<ReponseContent> Text { get; set; }
}
public class ReponseContent
{
/// <summary>
/// AI的回答内容
/// </summary>
[JsonProperty("content")]
public string Content { get; set; }
/// <summary>
/// 角色标识,固定为assistant,标识角色为AI
/// </summary>
[JsonProperty("role")]
public string Role { get; set; }
/// <summary>
/// 结果序号,取值为[0,10]; 当前为保留字段,开发者可忽略
/// </summary>
[JsonProperty("index")]
public int Index { get; set; }
}
public class ResponseUsage
{
[JsonProperty("text")]
public ResponseUsageDetails Text { get; set; }
}
public class ResponseUsageDetails
{
/// <summary>
/// 保留字段,可忽略
/// </summary>
[JsonProperty("question_tokens")]
public int QuestionTokens { get; set; }
/// <summary>
/// 包含历史问题的总tokens大小
/// </summary>
[JsonProperty("prompt_tokens")]
public int PromptTokens { get; set; }
/// <summary>
/// 回答的tokens大小
/// </summary>
[JsonProperty("completion_tokens")]
public int CompletionTokens { get; set; }
/// <summary>
/// prompt_tokens和completion_tokens的和,也是本次交互计费的tokens大小
/// </summary>
[JsonProperty("total_tokens")]
public int TotalTokens { get; set; }
}
文章来源:https://www.toymoban.com/news/detail-836863.html
//构造请求体
using Newtonsoft.Json;
using System.Collections.Generic;
public class JsonRequest
{
[JsonProperty("header")]
public RequestHeader Header { get; set; }
[JsonProperty("parameter")]
public RequestParameter Parameter { get; set; }
[JsonProperty("payload")]
public RequestPayload Payload { get; set; }
}
public class RequestHeader
{
/// <summary>
/// 应用appid,从开放平台控制台创建的应用中获取
/// </summary>
[JsonProperty("app_id")]
public string app_id { get; set; }
/// <summary>
/// 每个用户的id,用于区分不同用户
/// </summary>
[JsonProperty("uid")]
public string uid { get; set; }
}
public class RequestParameter
{
[JsonProperty("chat")]
public RequestChat Chat { get; set; }
}
public class RequestChat
{
/// <summary>
/// 指定访问的领域,general指向V1.5版本,generalv2指向V2版本,generalv3指向V3版本 。注意:不同的取值对应的url也不一样!
/// </summary>
[JsonProperty("domain")]
public string domain { get; set; }
/// <summary>
/// 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高
/// </summary>
[JsonProperty("temperature")]
public double temperature { get; set; }
/// <summary>
/// 模型回答的tokens的最大长度
/// </summary>
[JsonProperty("max_tokens")]
public int max_tokens { get; set; }
}
public class RequestPayload
{
[JsonProperty("message")]
public RequestMessage Message { get; set; }
}
public class RequestMessage
{
[JsonProperty("text")]
public List<ReuqestContent> Text { get; set; }
}
public class ReuqestContent
{
/// <summary>
/// user表示是用户的问题,assistant表示AI的回复
/// </summary>
[JsonProperty("role")]
public string role { get; set; }
/// <summary>
/// 用户和AI的对话内容
/// </summary>
[JsonProperty("content")]
public string content { get; set; }
}
文章来源地址https://www.toymoban.com/news/detail-836863.html
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System;
using System.Linq;
namespace XFYun.SparkChat.SDK
{
public class SparkWebSDK
{
private string _appId;
private string _apiSecret;
private string _apiKey;
private SparkVersions _version;
private ClientWebSocket _webSocketClient;
public SparkWebSDK()
{
}
public void Setup(string appId, string apiSecret, string apiKey, SparkVersions version = SparkVersions.V3_5)
{
this._apiKey = apiKey;
this._apiSecret = apiSecret;
this._appId = appId;
this._version = version;
}
private string GetAuthUrl(string baseUrl, string apiSecret, string apiKey)
{
string date = DateTime.UtcNow.ToString("r");
Uri uri = new Uri(baseUrl);
var str = $"host: {uri.Host}\ndate: {date}\nGET {uri.LocalPath} HTTP/1.1";
//使用apisecret,HMACSHA256算法加密str
var sha256Bytes = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret)).ComputeHash(Encoding.UTF8.GetBytes(str));
var sha256Str = Convert.ToBase64String(sha256Bytes);
var authorization = $"api_key=\"{apiKey}\",algorithm=\"hmac-sha256\",headers=\"host date request-line\",signature=\"{sha256Str}\"";
//date要做url处理
date = Uri.EscapeDataString(date);
string newUrl = $"ws://{uri.Host}{uri.LocalPath}?authorization={Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization))}&date={date}&host={uri.Host}";
return newUrl;
}
/// <summary>
/// 询问问题,流式调用response
/// 返回结果表示调用成功还是失败,如果调用失败,则返回失败原因
/// </summary>
/// <param name="question"></param>
/// <param name="response"></param>
/// <returns></returns>
public async Task<(bool, string)> Ask(List<string> questions, CancellationToken token, Action<List<string>> responseHandler)
{
try
{
string url = "";
string domain = "";
switch (this._version)
{
case SparkVersions.V1_5:
url = "ws://spark-api.xf-yun.com/v1.1/chat";
domain = "general";
break;
case SparkVersions.V2_0:
url = "ws://spark-api.xf-yun.com/v2.1/chat";
domain = "generalv2";
break;
case SparkVersions.V3_0:
url = "ws://spark-api.xf-yun.com/v3.1/chat";
domain = "generalv3";
break;
case SparkVersions.V3_5:
url = "ws://spark-api.xf-yun.com/v3.5/chat";
domain = "generalv3.5";
break;
}
var newUrl = GetAuthUrl(url, this._apiSecret, this._apiKey);
this._webSocketClient = new ClientWebSocket();
await this._webSocketClient.ConnectAsync(new Uri(newUrl), token);
var request = new JsonRequest()
{
Header = new RequestHeader()
{
app_id = this._appId,
uid = "123"
},
Parameter = new RequestParameter()
{
Chat = new RequestChat()
{
domain = domain,
temperature = 0.5,
max_tokens = 1024,
}
},
Payload = new RequestPayload()
{
Message = new RequestMessage()
{
Text = questions.Select(x => new ReuqestContent()
{
role = "user",
content = x
}).ToList()
}
}
};
var jsonStr = Newtonsoft.Json.JsonConvert.SerializeObject(request);
await this._webSocketClient.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(jsonStr)), WebSocketMessageType.Text, true, token);
var recvBuffer = new byte[1024];
while (true)
{
WebSocketReceiveResult result = await this._webSocketClient.ReceiveAsync(new ArraySegment<byte>(recvBuffer), token);
if (result.CloseStatus.HasValue) return (true, "");
if (result.MessageType == WebSocketMessageType.Text)
{
string recvMsg = Encoding.UTF8.GetString(recvBuffer, 0, result.Count);
var response = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonResponse>(recvMsg);
if (response.Header.Code != 0)
{
return (false, response.Header.Message);
}
if (response.Payload.Choices.Status == 2)//最后一个消息
{
responseHandler?.Invoke(response.Payload.Choices.Text.Select(x => x.Content).ToList());
return (true, "调用成功!");
}
responseHandler?.Invoke(response.Payload.Choices.Text.Select(x => x.Content).ToList());
}
else if (result.MessageType == WebSocketMessageType.Close)
{
return (false, result.CloseStatusDescription);
}
}
}
catch (Exception e)
{
return (false, e.Message);
}
finally
{
await this._webSocketClient?.CloseAsync(WebSocketCloseStatus.NormalClosure, "client raise close request", token);
}
}
public async void Close()
{
if (_webSocketClient != null)
{
await _webSocketClient.CloseAsync(WebSocketCloseStatus.NormalClosure, "正常关闭", new CancellationToken());
}
}
}
public enum SparkVersions
{
V1_5,
V2_0,
V3_0,
V3_5
}
}
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using XFYun.SparkChat.SDK;
public class XFTest : MonoBehaviour
{
private SparkWebSDK sdk;
public string app_id;
public string api_secret;
public string api_key;
public SparkVersions api_version;
public InputField request;
public Text response;
public Button send;
// Start is called before the first frame update
void Start()
{
sdk = new SparkWebSDK();
sdk.Setup(app_id, api_secret, api_key, api_version);
send.onClick.RemoveAllListeners();
send.onClick.AddListener(async delegate
{
response.text = "";
var (ok, errMsg) = await sdk.Ask(new List<string>() { request.text }, new System.Threading.CancellationToken(), strs =>
{
foreach (var str in strs)
{
response.text += str;
}
});
response.text += "\n我的回答结束!";
if (!ok)
{
Debug.LogError($"error msg = {errMsg}");
}
});
}
}
到了这里,关于Unity接入讯飞的大数据模型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!