From 337088c9085ded540aec2a0215b0b4c09a10043a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A9=99=E5=AD=90?= <454313500@qq.com> Date: Fri, 7 Mar 2025 00:35:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=85=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Entities/StockNewsAggregateRoot.cs | 9 ++++-- .../Managers/NewsManager.cs | 28 ++++++++++++++++--- .../SemanticKernel/Plugins/NewsPlugins.cs | 26 ++++++++++++++--- .../SemanticKernel/SemanticKernelClient.cs | 11 ++++---- .../SemanticKernel/SemanticKernelOptions.cs | 23 +++++++++++++++ .../YiFrameworkStockDomainModule.cs | 12 +++++++- 6 files changed, 93 insertions(+), 16 deletions(-) diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Entities/StockNewsAggregateRoot.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Entities/StockNewsAggregateRoot.cs index f1062336..1a047d77 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Entities/StockNewsAggregateRoot.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Entities/StockNewsAggregateRoot.cs @@ -22,7 +22,7 @@ namespace Yi.Framework.Stock.Domain.Entities /// /// 创建时间 /// - public DateTime CreationTime { get; set; } = DateTime.Now; + public DateTime CreationTime { get; set; } /// /// 创建者ID @@ -57,13 +57,18 @@ namespace Yi.Framework.Stock.Domain.Entities /// /// 发布时间 /// - public DateTime PublishTime { get; set; } = DateTime.Now; + public DateTime PublishTime { get; set; } /// /// 新闻来源 /// public string Source { get; set; } = string.Empty; + /// + /// 新闻摘要 + /// + public string Summary { get; set; } = string.Empty; + public StockNewsAggregateRoot() { } public StockNewsAggregateRoot( diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs index 7d845d5f..d170c220 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/NewsManager.cs @@ -1,14 +1,17 @@ using Yi.Framework.Stock.Domain.Managers.Plugins; - +using Volo.Abp.Domain.Services; +using Yi.Framework.SqlSugarCore.Abstractions; +using Yi.Framework.Stock.Domain.Entities; namespace Yi.Framework.Stock.Domain.Managers; -public class NewsManager +public class NewsManager:DomainService { private SemanticKernelClient _skClient; - - public NewsManager(SemanticKernelClient skClient) + private ISqlSugarRepository _newsRepository; + public NewsManager(SemanticKernelClient skClient,ISqlSugarRepository newsRepository) { _skClient = skClient; + _newsRepository = newsRepository; } /// @@ -20,4 +23,21 @@ public class NewsManager _skClient.RegisterPlugins("news"); await _skClient.ChatCompletionAsync("帮我生成一个新闻"); } + + public async Task SaveNewsAsync(NewsModel news) + { + var newsEntity = new StockNewsAggregateRoot( + title: news.Title, + content: news.Content, + source: news.Source + ) + { + Summary = news.Summary, + CreationTime = DateTime.Now, + IsDeleted = false, + OrderNum = 0 + }; + + await _newsRepository.InsertAsync(newsEntity); + } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/Plugins/NewsPlugins.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/Plugins/NewsPlugins.cs index fa02ad6c..42df958d 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/Plugins/NewsPlugins.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/Plugins/NewsPlugins.cs @@ -1,19 +1,27 @@ using System.ComponentModel; using System.Text.Json.Serialization; using Microsoft.SemanticKernel; +using Yi.Framework.Stock.Domain.Managers; namespace Yi.Framework.Stock.Domain.Managers.Plugins; public class NewsPlugins { - [KernelFunction("save_news"), Description("生成并且保存一个新闻")] - public async Task SaveAsync(NewModel news) + private readonly NewsManager _newsManager; + + public NewsPlugins(NewsManager newsManager) { - return "成功"; + _newsManager = newsManager; + } + + [KernelFunction("save_news"), Description("生成并且保存一个新闻")] + public async Task SaveAsync(NewsModel news) + { + await _newsManager.SaveNewsAsync(news); } } -public class NewModel +public class NewsModel { [JsonPropertyName("title")] [DisplayName("新闻标题")] @@ -22,4 +30,14 @@ public class NewModel [JsonPropertyName("content")] [DisplayName("新闻内容")] public string? Content { get; set; } + + //新闻简介 + [JsonPropertyName("summary")] + [DisplayName("新闻简介")] + public string? Summary { get; set; } + + //新闻来源 + [JsonPropertyName("source")] + [DisplayName("新闻来源")] + public string? Source { get; set; } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelClient.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelClient.cs index a9f7eb34..62783d67 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelClient.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelClient.cs @@ -2,10 +2,11 @@ using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.OpenAI; +using Volo.Abp.DependencyInjection; namespace Yi.Framework.Stock.Domain.Managers; -public class SemanticKernelClient +public class SemanticKernelClient:ITransientDependency { private Kernel Kernel { get; } private readonly IKernelBuilder _kernelBuilder; @@ -26,9 +27,9 @@ public class SemanticKernelClient private void RegisterChatCompletion() { _kernelBuilder.AddOpenAIChatCompletion( - modelId: "", - apiKey: "", - httpClient: new HttpClient() { BaseAddress = new Uri("") }); + modelId: Options.ModelId, + apiKey: Options.ApiKey, + httpClient: new HttpClient() { BaseAddress = new Uri(Options.Endpoint) }); } /// @@ -74,7 +75,7 @@ public class SemanticKernelClient OpenAIPromptExecutionSettings openAIPromptExecutionSettings = new() { FunctionChoiceBehavior = FunctionChoiceBehavior.Auto(), - MaxTokens = 1000 + MaxTokens = Options.MaxTokens }; var chatCompletionService = this.Kernel.GetRequiredService(); diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs index 95edd997..16565ace 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/Managers/SemanticKernel/SemanticKernelOptions.cs @@ -2,5 +2,28 @@ public class SemanticKernelOptions { + /// + /// OpenAI 模型 ID + /// + public string ModelId { get; set; } = string.Empty; + /// + /// OpenAI API 密钥 + /// + public string ApiKey { get; set; } = string.Empty; + + /// + /// API 端点地址 + /// + public string Endpoint { get; set; } = string.Empty; + + /// + /// 最大生成令牌数 + /// + public int MaxTokens { get; set; } = 1000; + + /// + /// 插件目录路径 + /// + public string PluginsDirectoryPath { get; set; } = string.Empty; } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs index 106120d3..fff803e3 100644 --- a/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs +++ b/Yi.Abp.Net8/module/ai-stock/Yi.Framework.Stock.Domain/YiFrameworkStockDomainModule.cs @@ -2,6 +2,7 @@ using Volo.Abp.Caching; using Volo.Abp.Domain; using Yi.Framework.Stock.Domain.Shared; using Yi.Framework.Mapster; +using Yi.Framework.Stock.Domain.Managers; namespace Yi.Framework.Stock.Domain { @@ -14,6 +15,15 @@ namespace Yi.Framework.Stock.Domain )] public class YiFrameworkStockDomainModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure((options)=>{ + options.Endpoint = "https://api.token-ai.cn/v1"; + options.ApiKey = "sk-V6OqmrloXDAiTM2FWoisGgaop72Ngr0fXAnXL8"; + options.ModelId = "gpt-4o-mini"; + options.MaxTokens = 1000; + options.PluginsDirectoryPath = "plugins"; + }); + } } } \ No newline at end of file