Learn.VideoAnalysis/VideoAnalysisCore/AICore/GPT/ChatGPT/ChatGPTClient.cs

138 lines
5.5 KiB
C#

using VideoAnalysisCore.Common;
using System.Net.Http.Headers;
using System.Text;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System.Net.Http;
using Newtonsoft.Json;
using System.Net.Http.Json;
using AntDesign;
using OneOf.Types;
using System.Net;
namespace VideoAnalysisCore.AICore.GPT.ChatGPT
{
public class ChatGPTClient
{
public static string Host = AppCommon.Config.ChatGpt.ChatGpt.Host;
public static string ApiKey = AppCommon.Config.ChatGpt.ChatGpt.ApiKey;
private readonly IHttpClientFactory _httpClientFactory;
public ChatGPTClient(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
/// <summary>
/// ChatSSE[流式传输 更稳定]
/// </summary>
/// <param name="chatReq"></param>
/// <returns>Return HttpResponseMessage for SSE</returns>
public async Task<(Usage u, string res)?> ChatSSE(ChatRequest chatReq)
{
throw new Exception($"未实现");
//chatReq.stream = true;
var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq);
var chatResp = await PostJsonStreamAsync("/v1/chat/completions", requestBody);
using var stream = await chatResp.Content.ReadAsStreamAsync();
using var reader = new StreamReader(stream, Encoding.UTF8);
string line;
StringBuilder messageBuilder = new StringBuilder();
ChatRes lastChat = new ChatRes();
//while ((line = await reader.ReadLineAsync()) != null)
//{
// if (line.EndsWith("[DONE]"))
// {
// // 表示一条消息结束
// string message = messageBuilder.ToString();
// messageBuilder.Clear();
// var u = lastChat?.choices?.FirstOrDefault()?.usage;
// if (u == null || string.IsNullOrEmpty(message))
// return null;
// return (u, message);
// }
// else if (line.StartsWith("data:"))
// {
// try
// {
// var data = System.Text.Json.JsonSerializer.Deserialize<ChatRes>(line.Substring("data:".Length).Trim());
// lastChat = data;
// var str = data?.choices.FirstOrDefault()?.delta.content;
// if (!string.IsNullOrEmpty(str))
// messageBuilder.Append(str);
// }
// catch (Exception e)
// {
// Console.WriteLine("异常 ChatSSE=>");
// Console.WriteLine(line);
// Console.WriteLine(e.Message);
// Console.WriteLine(e.StackTrace);
// }
// }
//}
return null;
}
/// <summary>
/// Chat
/// </summary>
/// <param name="chatReq"></param>
/// <returns>Return HttpResponseMessage for SSE</returns>
public async Task<(Usage u, string res)?> Chat(ChatRequest chatReq)
{
var requestBody = System.Text.Json.JsonSerializer.Serialize(chatReq);
var chatResp = await PostJsonStreamAsync("/v1/chat/completions", requestBody);
var res = await chatResp.Content.ReadFromJsonAsync<ChatRes>();
var chatResContent = res?.choices.FirstOrDefault()?.message.content.Trim();
if (res is null)
throw new Exception($" ChatGPT模型返回异常 返回参数: " +
$" {System.Text.Json.JsonSerializer.Serialize(res)}");
if (string.IsNullOrEmpty(chatResContent))
return null;
return (res.usage, chatResContent);
}
private async Task<HttpResponseMessage> PostJsonStreamAsync(string path, string json)
{
var uriBuilder = new UriBuilder(Host + path);
var maxRestart = 4;
var errorMSG = new Exception[maxRestart];
for (int i = 0; i < maxRestart; i++)
{
try
{
var client = _httpClientFactory.CreateClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", AppCommon.Config.ChatGpt.ChatGpt.ApiKey);
client.Timeout = TimeSpan.FromSeconds(Timeout.Infinite);//超时时间20分钟
client.DefaultRequestVersion = HttpVersion.Version20;
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionOrLower;
client.DefaultRequestHeaders.ConnectionClose = true;
var content = new StringContent(json, Encoding.UTF8, "application/json");
return await client.PostAsync(uriBuilder.Uri, content);
}
catch (Exception e)
{
errorMSG[i] = e;
Console.WriteLine("====================[请求异常,重试]====================");
Console.WriteLine(uriBuilder.Uri);
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
Console.WriteLine("==============================================");
}
Thread.Sleep(1000);
}
throw errorMSG.Last(s => s != null);
}
}
}