Files
Yi.Framework/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiChat/Impl/AzureRestChatService.cs
2025-06-25 00:05:00 +08:00

118 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Runtime.CompilerServices;
using System.Text;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OpenAI.Chat;
using Yi.Framework.AiHub.Application.Contracts.Options;
using Yi.Framework.AiHub.Domain.Extensions;
namespace Yi.Framework.AiHub.Domain.AiChat.Impl;
public class AzureRestChatService : IChatService
{
private readonly AiChatModelOptions _options;
public AzureRestChatService(IOptions<AiGateWayOptions> options)
{
this._options = options.Value.Chats[nameof(AzureRestChatService)];
}
public async IAsyncEnumerable<string> CompleteChatAsync(string modelId, List<ChatMessage> messages,
[EnumeratorCancellation] CancellationToken cancellationToken)
{
// 设置API URL
var apiUrl = $"{_options.Endpoint}models/chat/completions";
var ss = messages.Select(x => new
{
role = x.GetRoleAsString(),
content = x.Content.FirstOrDefault()?.Text
}).ToList();
// 准备请求内容
var requestBody = new
{
messages = messages.Select(x => new
{
role = x.GetRoleAsString(),
content = x.Content.FirstOrDefault()?.Text
}).ToList(),
stream = true,
max_tokens = 2048,
temperature = 0.8,
top_p = 0.1,
presence_penalty = 0,
frequency_penalty = 0,
model = modelId
};
// 序列化请求内容为JSON
string jsonBody = JsonConvert.SerializeObject(requestBody);
using var httpClient = new HttpClient();
// 设置请求头
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_options.ApiKey}");
// 其他头信息如Content-Type在StringContent中设置
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
// 发送POST请求
HttpResponseMessage response = await httpClient.PostAsync(apiUrl, content, cancellationToken);
// 确认响应成功
response.EnsureSuccessStatusCode();
// 读取响应内容
var responseStream = await response.Content.ReadAsStreamAsync(cancellationToken);
// 从流中读取数据并输出到控制台
using var streamReader = new System.IO.StreamReader(responseStream);
string line;
while ((line = await streamReader.ReadLineAsync(cancellationToken)) != null)
{
var result = GetContent(line);
if (result is not null)
{
yield return result;
}
}
}
private string? GetContent(string line)
{
if (string.IsNullOrWhiteSpace(line))
return null;
string prefix = "data: ";
line = line.Substring(prefix.Length);
try
{
// 解析为JObject
var jsonObj = JObject.Parse(line);
var content = jsonObj["choices"][0]["delta"]["content"].ToString();
return content;
// // 判断choices是否存在且是数组并且有元素
// if (jsonObj.TryGetValue("choices", out var choicesToken) && choicesToken is JArray choicesArray &&
// choicesArray.Count > 0)
// {
// var firstChoice = choicesArray[0] as JObject;
// // 判断delta字段是否存在
// if (firstChoice.TryGetValue("delta", out var deltaToken))
// {
// // 获取content字段
// if (deltaToken.Type == JTokenType.Object && ((JObject)deltaToken).TryGetValue("content", out var contentToken))
// {
// return contentToken.ToString();
// }
// }
// }
}
catch (Exception)
{
// 解析失败
return null;
}
return null;
}
}