From a0eb2345398b524d28f404bb14b505e11704fe02 Mon Sep 17 00:00:00 2001 From: chenchun Date: Tue, 22 Jul 2025 10:40:23 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=BC=E5=AE=B9=E4=BA=86=E7=94=A8?= =?UTF-8?q?=E9=87=8F=E4=BD=BF=E7=94=A8=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AzureDatabricksChatCompletionsService.cs | 54 ++++++++--------- .../Chats/DeepSeekChatCompletionsService.cs | 60 +++++++++---------- .../Entities/Chat/MessageAggregateRoot.cs | 12 +++- .../Entities/UsageStatisticsAggregateRoot.cs | 8 +-- .../ValueObjects/TokenUsageValueObject.cs | 4 +- .../Managers/AiGateWayManager.cs | 8 +-- .../Managers/UsageStatisticsManager.cs | 15 +++-- .../YiFrameworkAiHubDomainModule.cs | 11 ++++ 8 files changed, 97 insertions(+), 75 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorAzureDatabricks/Chats/AzureDatabricksChatCompletionsService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorAzureDatabricks/Chats/AzureDatabricksChatCompletionsService.cs index 0de17416..e9ed19c3 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorAzureDatabricks/Chats/AzureDatabricksChatCompletionsService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/AiGateWay/Impl/ThorAzureDatabricks/Chats/AzureDatabricksChatCompletionsService.cs @@ -108,33 +108,33 @@ public class AzureDatabricksChatCompletionsService(ILogger(line, ThorJsonSerializer.DefaultOptions); - var content = result?.Choices?.FirstOrDefault()?.Delta; - - if (first && string.IsNullOrWhiteSpace(content?.Content) && string.IsNullOrEmpty(content?.ReasoningContent)) - { - continue; - } - - if (first && content.Content == OpenAIConstant.ThinkStart) - { - isThink = true; - //continue; - // 需要将content的内容转换到其他字段 - } - - if (isThink && content.Content.Contains(OpenAIConstant.ThinkEnd)) - { - isThink = false; - // 需要将content的内容转换到其他字段 - //continue; - } - - if (isThink) - { - // 需要将content的内容转换到其他字段 - foreach (var choice in result.Choices) - { - //choice.Delta.ReasoningContent = choice.Delta.Content; - //choice.Delta.Content = string.Empty; - } - } + // var content = result?.Choices?.FirstOrDefault()?.Delta; + // + // // if (first && string.IsNullOrWhiteSpace(content?.Content) && string.IsNullOrEmpty(content?.ReasoningContent)) + // // { + // // continue; + // // } + // + // if (first && content.Content == OpenAIConstant.ThinkStart) + // { + // isThink = true; + // //continue; + // // 需要将content的内容转换到其他字段 + // } + // + // if (isThink && content.Content.Contains(OpenAIConstant.ThinkEnd)) + // { + // isThink = false; + // // 需要将content的内容转换到其他字段 + // //continue; + // } + // + // if (isThink) + // { + // // 需要将content的内容转换到其他字段 + // foreach (var choice in result.Choices) + // { + // //choice.Delta.ReasoningContent = choice.Delta.Content; + // //choice.Delta.Content = string.Empty; + // } + // } // first = false; diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/MessageAggregateRoot.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/MessageAggregateRoot.cs index 40d9575c..752621b4 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/MessageAggregateRoot.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/MessageAggregateRoot.cs @@ -29,10 +29,18 @@ public class MessageAggregateRoot : FullAuditedAggregateRoot ModelId = modelId; if (tokenUsage is not null) { + long inputTokenCount = tokenUsage.PromptTokens + ?? tokenUsage.InputTokens + ?? 0; + + long outputTokenCount = tokenUsage.CompletionTokens + ?? tokenUsage.OutputTokens + ?? 0; + this.TokenUsage = new TokenUsageValueObject { - OutputTokenCount = tokenUsage.OutputTokens ?? 0, - InputTokenCount = tokenUsage.InputTokens ?? 0, + OutputTokenCount = outputTokenCount, + InputTokenCount = inputTokenCount, TotalTokenCount = tokenUsage.TotalTokens ?? 0 }; } diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/UsageStatisticsAggregateRoot.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/UsageStatisticsAggregateRoot.cs index 62170a8a..ad0ad586 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/UsageStatisticsAggregateRoot.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/UsageStatisticsAggregateRoot.cs @@ -37,22 +37,22 @@ public class UsageStatisticsAggregateRoot : FullAuditedAggregateRoot /// /// 使用输出token总数 /// - public int UsageOutputTokenCount { get; set; } + public long UsageOutputTokenCount { get; set; } /// /// 使用输入总数 /// - public int UsageInputTokenCount { get; set; } + public long UsageInputTokenCount { get; set; } /// /// 总token使用数量 /// - public int TotalTokenCount { get; set; } + public long TotalTokenCount { get; set; } /// /// 新增一次聊天统计 /// - public void AddOnceChat(int inputTokenCount, int outputTokenCount) + public void AddOnceChat(long inputTokenCount, long outputTokenCount) { UsageTotalNumber += 1; UsageOutputTokenCount += outputTokenCount; diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/ValueObjects/TokenUsageValueObject.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/ValueObjects/TokenUsageValueObject.cs index 96b3718b..8b3a92ec 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/ValueObjects/TokenUsageValueObject.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/ValueObjects/TokenUsageValueObject.cs @@ -2,9 +2,9 @@ public class TokenUsageValueObject { - public int OutputTokenCount { get; set; } + public long OutputTokenCount { get; set; } - public int InputTokenCount { get; set; } + public long InputTokenCount { get; set; } public long TotalTokenCount { get; set; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs index 66523c1d..d1d28a83 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs @@ -132,8 +132,7 @@ public class AiGateWayManager : DomainService TokenUsage = data.Usage }); - await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, data.Usage.InputTokens ?? 0, - data.Usage.OutputTokens ?? 0); + await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, data.Usage); } await response.WriteAsJsonAsync(data, cancellationToken); @@ -200,7 +199,7 @@ public class AiGateWayManager : DomainService { await foreach (var data in completeChatResponse) { - if (data.Usage is not null && data.Usage.TotalTokens is not null) + if (data.Usage is not null) { tokenUsage = data.Usage; } @@ -261,8 +260,7 @@ public class AiGateWayManager : DomainService TokenUsage = tokenUsage }); - await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, tokenUsage.InputTokens ?? 0, - tokenUsage.OutputTokens ?? 0); + await _usageStatisticsManager.SetUsageAsync(userId.Value, request.Model, tokenUsage); } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/UsageStatisticsManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/UsageStatisticsManager.cs index a1782308..66ae6f65 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/UsageStatisticsManager.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/UsageStatisticsManager.cs @@ -1,5 +1,6 @@ using Medallion.Threading; using Volo.Abp.Domain.Services; +using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi; using Yi.Framework.AiHub.Domain.Entities; using Yi.Framework.SqlSugarCore.Abstractions; @@ -17,8 +18,16 @@ public class UsageStatisticsManager : DomainService private IDistributedLockProvider DistributedLock => LazyServiceProvider.LazyGetRequiredService(); - public async Task SetUsageAsync(Guid userId, string modelId, int inputTokenCount, int outputTokenCount) + public async Task SetUsageAsync(Guid userId, string modelId, ThorUsageResponse? tokenUsage) { + long inputTokenCount = tokenUsage?.PromptTokens + ?? tokenUsage.InputTokens + ?? 0; + + long outputTokenCount = tokenUsage?.CompletionTokens + ?? tokenUsage.OutputTokens + ?? 0; + await using (await DistributedLock.AcquireLockAsync($"UsageStatistics:{userId.ToString()}")) { var entity = await _repository._DbQueryable.FirstAsync(x => x.UserId == userId && x.ModelId == modelId); @@ -37,8 +46,4 @@ public class UsageStatisticsManager : DomainService } } } -} - -internal class LazyServiceProvider -{ } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/YiFrameworkAiHubDomainModule.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/YiFrameworkAiHubDomainModule.cs index 4798c43d..bd70b201 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/YiFrameworkAiHubDomainModule.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/YiFrameworkAiHubDomainModule.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Domain; +using Yi.Framework.AiHub.Application.Contracts.Dtos.OpenAi; using Yi.Framework.AiHub.Domain.AiGateWay; using Yi.Framework.AiHub.Domain.AiGateWay.Impl.ThorAzureDatabricks.Chats; using Yi.Framework.AiHub.Domain.AiGateWay.Impl.ThorAzureOpenAI.Chats; @@ -48,6 +49,16 @@ namespace Yi.Framework.AiHub.Domain request.Temperature = null; } }); + options.Handles.Add(request => + { + if (request.Stream == true) + { + request.StreamOptions = new ThorStreamOptions() + { + IncludeUsage = true + }; + } + }); }); }