using HuanMeng.MiaoYu.Code.Chat.Contract; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http.Headers; using System.Net.Http; using System.Net.Http.Json; using System.Text; using System.Threading.Tasks; using Newtonsoft.Json.Serialization; using HuanMeng.MiaoYu.Code.Chat.Claude.Model; namespace HuanMeng.MiaoYu.Code.Chat.Claude { /// /// Claude3 https://docs.anthropic.com/en/api/messages ClaudeChatInfo /// public class ClaudeChat(ClaudeChatConfig claudeChatConfig, IHttpClientFactory factory) : IChat { /// /// /// /// /// /// /// public async Task MessagesAsync(BaseChatParams chatParams) { var claudeChatChatParams = chatParams as ClaudeChatChatParams; if (claudeChatChatParams == null) { throw new ArgumentException("参数异常"); } //添加默认值 if (claudeChatChatParams.MaxTokens == 0) { claudeChatChatParams.MaxTokens = claudeChatConfig.MaxTokens; } //添加默认值 if (string.IsNullOrEmpty(claudeChatChatParams.Model)) { claudeChatChatParams.Model = claudeChatConfig.Model; } //去线程池里拿http线程 using (var httpClient = factory.CreateClient()) { // 设置请求头 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Add("x-api-key", claudeChatConfig.ApiKey); httpClient.DefaultRequestHeaders.Add("anthropic-version", claudeChatConfig.AnthropicVersion); var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; string json = JsonConvert.SerializeObject(chatParams, settings); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content); if (response.IsSuccessStatusCode) { //var chatInfo1 = await response.Content.ReadFromJsonAsync(); string responseBody = await response.Content.ReadAsStringAsync(); var chatInfo = JsonConvert.DeserializeObject(responseBody); return chatInfo; } else { // 读取并打印返回消息 string responseBody = await response.Content.ReadAsStringAsync(); Console.WriteLine($"返回消息: {responseBody}"); } } return null; } public async IAsyncEnumerable MessagesStreamAsync(BaseChatParams chatParams) { var claudeChatChatParams = chatParams as ClaudeChatChatStreamParams; if (claudeChatChatParams == null) { throw new ArgumentException("参数异常"); } //添加默认值 if (claudeChatChatParams.MaxTokens == 0) { claudeChatChatParams.MaxTokens = claudeChatConfig.MaxTokens; } claudeChatChatParams.Stream = true; //添加默认值 if (!string.IsNullOrEmpty(claudeChatChatParams.Model)) { claudeChatChatParams.Model = claudeChatChatParams.Model; } //去线程池里拿http线程 using (var httpClient = factory.CreateClient()) { // 设置请求头 httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Add("x-api-key", claudeChatConfig.ApiKey); httpClient.DefaultRequestHeaders.Add("anthropic-version", claudeChatConfig.AnthropicVersion); var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; string json = JsonConvert.SerializeObject(chatParams, settings); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content); if (response.IsSuccessStatusCode) { var chatInfo = await response.Content.ReadFromJsonAsync(); if (chatInfo?.Type == "message_delta") { claudeChatChatParams.OutCharResponse.Usage.OutputTokens = chatInfo.Usage?.OutputTokens ?? 0; } else if (chatInfo?.Type == "content_block_start") { claudeChatChatParams.OutCharResponse = chatInfo?.Message ?? new ClaudeChatResponse(); } else if (chatInfo?.Type == "content_block_delta") { var text = chatInfo?.Delta?.Text ?? ""; if (!string.IsNullOrEmpty(text)) { yield return text; } } claudeChatChatParams.OutObj.Add(chatInfo); } } } } }