diff --git a/src/AntSK.Domain/AntSK.Domain.xml b/src/AntSK.Domain/AntSK.Domain.xml index e179a96..3467025 100644 --- a/src/AntSK.Domain/AntSK.Domain.xml +++ b/src/AntSK.Domain/AntSK.Domain.xml @@ -104,7 +104,7 @@ 避免模型重复加载,本地缓存 - + 发送消息 diff --git a/src/AntSK.Domain/Domain/Interface/IChatService.cs b/src/AntSK.Domain/Domain/Interface/IChatService.cs index 06df4a1..08a14b3 100644 --- a/src/AntSK.Domain/Domain/Interface/IChatService.cs +++ b/src/AntSK.Domain/Domain/Interface/IChatService.cs @@ -1,6 +1,8 @@ -using AntSK.Domain.Domain.Model.Dto; +using AntSK.Domain.Domain.Model; +using AntSK.Domain.Domain.Model.Dto; using AntSK.Domain.Repositories; using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; using System; using System.Collections.Generic; using System.Linq; @@ -11,8 +13,10 @@ namespace AntSK.Domain.Domain.Interface { public interface IChatService { - IAsyncEnumerable SendChatByAppAsync(Apps app, string questions, string history); + IAsyncEnumerable SendChatByAppAsync(Apps app, string questions, ChatHistory history); - IAsyncEnumerable SendKmsByAppAsync(Apps app, string questions, string history, string filePath, List relevantSources = null); + IAsyncEnumerable SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List relevantSources = null); + + Task GetChatHistory(List MessageList); } } \ No newline at end of file diff --git a/src/AntSK.Domain/Domain/Service/ChatService.cs b/src/AntSK.Domain/Domain/Service/ChatService.cs index b14061e..0fa5222 100644 --- a/src/AntSK.Domain/Domain/Service/ChatService.cs +++ b/src/AntSK.Domain/Domain/Service/ChatService.cs @@ -12,6 +12,10 @@ using System.Reflection.Metadata; using Microsoft.KernelMemory; using System.Collections.Generic; using Markdig; +using ChatHistory = Microsoft.SemanticKernel.ChatCompletion.ChatHistory; +using Microsoft.SemanticKernel.Plugins.Core; +using Azure.Core; +using AntSK.Domain.Domain.Model; namespace AntSK.Domain.Domain.Service { @@ -29,13 +33,31 @@ namespace AntSK.Domain.Domain.Service /// /// /// - public async IAsyncEnumerable SendChatByAppAsync(Apps app, string questions, string history) + public async IAsyncEnumerable SendChatByAppAsync(Apps app, string questions, ChatHistory history) { + if (string.IsNullOrEmpty(app.Prompt) || !app.Prompt.Contains("{{$input}}")) { //如果模板为空,给默认提示词 app.Prompt = app.Prompt.ConvertToString() + "{{$input}}"; } + KernelArguments args =new KernelArguments(); + if (history.Count > 10) + { + app.Prompt = @"${{ConversationSummaryPlugin.SummarizeConversation $history}}" + app.Prompt; + args = new() { + { "history", string.Join("\n", history.Select(x => x.Role + ": " + x.Content)) }, + { "input", questions } + }; + } + else + { + args=new() + { + { "input", $"{string.Join("\n", history.Select(x => x.Role + ": " + x.Content))}{Environment.NewLine} user:{questions}" } + }; + } + var _kernel = _kernelService.GetKernelByApp(app); var temperature = app.Temperature / 100;//存的是0~100需要缩小 OpenAIPromptExecutionSettings settings = new() { Temperature = temperature }; @@ -45,14 +67,15 @@ namespace AntSK.Domain.Domain.Service settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions; } var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings); - var chatResult = _kernel.InvokeStreamingAsync(function: func, arguments: new KernelArguments() { ["input"] = $"{history}{Environment.NewLine} user:{questions}" }); + var chatResult = _kernel.InvokeStreamingAsync(function: func, + arguments: args); await foreach (var content in chatResult) { yield return content; } } - public async IAsyncEnumerable SendKmsByAppAsync(Apps app, string questions, string history, string filePath, List relevantSources = null) + public async IAsyncEnumerable SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List relevantSources = null) { var relevantSourceList = await _kMService.GetRelevantSourceList(app.KmsIdList, questions); var _kernel = _kernelService.GetKernelByApp(app); @@ -84,9 +107,9 @@ namespace AntSK.Domain.Domain.Service dataMsg.AppendLine(item.ToString()); } - KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask"); + KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1"); var chatResult = _kernel.InvokeStreamingAsync(function: jsonFun, - arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = history, ["questions"] = questions }); + arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["questions"] = questions }); await foreach (var content in chatResult) { @@ -98,5 +121,26 @@ namespace AntSK.Domain.Domain.Service yield return new StreamingTextContent(KmsConstantcs.KmsSearchNull); } } + + public async Task GetChatHistory(List MessageList) + { + ChatHistory history = new ChatHistory(); + if (MessageList.Count > 1) + { + + foreach (var item in MessageList) + { + if (item.IsSend) + { + history.AddUserMessage(item.Context); + } + else + { + history.AddAssistantMessage(item.Context); + } + } + } + return history; + } } } \ No newline at end of file diff --git a/src/AntSK/Pages/ChatPage/Chat.razor.cs b/src/AntSK/Pages/ChatPage/Chat.razor.cs index 9275919..19b7305 100644 --- a/src/AntSK/Pages/ChatPage/Chat.razor.cs +++ b/src/AntSK/Pages/ChatPage/Chat.razor.cs @@ -8,6 +8,7 @@ using System.Text; using Markdig; using AntSK.Domain.Domain.Model; using AntSK.Domain.Domain.Model.Dto; +using Microsoft.SemanticKernel.ChatCompletion; namespace AntSK.Pages.ChatPage { @@ -121,24 +122,24 @@ namespace AntSK.Pages.ChatPage protected async Task SendAsync(string questions, string? filePath) { - string msg = ""; + ChatHistory history = new ChatHistory() ; //处理多轮会话 Apps app = _apps_Repositories.GetFirst(p => p.Id == AppId); if (MessageList.Count > 0) { - msg = await HistorySummarize(app, questions); + history = await _chatService.GetChatHistory(MessageList); } switch (app.Type) { case "chat" when filePath == null: //普通会话 - await SendChat(questions, msg, app); + await SendChat(questions, history, app); break; default: //知识库问答 - await SendKms(questions, msg, filePath, app); + await SendKms(questions, history, filePath, app); break; } @@ -149,14 +150,14 @@ namespace AntSK.Pages.ChatPage /// 发送知识库问答 /// /// - /// + /// /// /// /// - private async Task SendKms(string questions, string msg, string filePath, Apps app) + private async Task SendKms(string questions, ChatHistory history, string filePath, Apps app) { MessageInfo info = null; - var chatResult = _chatService.SendKmsByAppAsync(app, questions, msg, filePath, _relevantSources); + var chatResult = _chatService.SendKmsByAppAsync(app, questions, history, filePath, _relevantSources); await foreach (var content in chatResult) { if (info == null) @@ -189,7 +190,7 @@ namespace AntSK.Pages.ChatPage /// /// /// - private async Task SendChat(string questions, string history, Apps app) + private async Task SendChat(string questions, ChatHistory history, Apps app) { MessageInfo info = null; var chatResult = _chatService.SendChatByAppAsync(app, questions, history); @@ -222,6 +223,7 @@ namespace AntSK.Pages.ChatPage { if (info.IsNotNull()) { + info!.Context = info!.HtmlAnswers; // info!.HtmlAnswers = markdown.Transform(info.HtmlAnswers); info!.HtmlAnswers = Markdown.ToHtml(info.HtmlAnswers); } @@ -231,48 +233,6 @@ namespace AntSK.Pages.ChatPage await _JSRuntime.ScrollToBottomAsync("scrollDiv"); } - /// - /// 历史会话的会话总结 - /// - /// - /// - private async Task HistorySummarize(Apps app, string questions) - { - var _kernel = _kernelService.GetKernelByApp(app); - if (MessageList.Count > 1) - { - StringBuilder history = new StringBuilder(); - foreach (var item in MessageList) - { - if (item.IsSend) - { - history.Append($"user:{item.Context}{Environment.NewLine}"); - } - else - { - history.Append($"assistant:{item.Context}{Environment.NewLine}"); - } - } - - if (MessageList.Count > 10) - { - //历史会话大于10条,进行总结 - var msg = await _kernelService.HistorySummarize(_kernel, questions, history.ToString()); - return msg; - } - else - { - var msg = - $"history:{Environment.NewLine}{history.ToString()}{Environment.NewLine}{Environment.NewLine}"; - return msg; - } - } - else - { - return ""; - } - } - private void OnSingleCompleted(UploadInfo fileInfo) { fileList.Add(new() diff --git a/src/AntSK/Pages/ChatPage/OpenChat.razor.cs b/src/AntSK/Pages/ChatPage/OpenChat.razor.cs index 3ce3a62..a54e93c 100644 --- a/src/AntSK/Pages/ChatPage/OpenChat.razor.cs +++ b/src/AntSK/Pages/ChatPage/OpenChat.razor.cs @@ -12,6 +12,7 @@ using AntSK.Domain.Utils; using Microsoft.JSInterop; using Markdig; using AntSK.Domain.Domain.Model; +using Microsoft.SemanticKernel.ChatCompletion; namespace AntSK.Pages.ChatPage { @@ -120,22 +121,22 @@ namespace AntSK.Pages.ChatPage protected async Task SendAsync(string questions) { - string msg = ""; + ChatHistory history=new ChatHistory(); //处理多轮会话 Apps app = _apps_Repositories.GetFirst(p => p.Id == AppId); if (MessageList.Count > 0) { - msg = await HistorySummarize(app, questions); + history = await _chatService.GetChatHistory(MessageList); } switch (app.Type) { case "chat": //普通会话 - await SendChat(questions, msg, app); + await SendChat(questions, history, app); break; case "kms": //知识库问答 - await SendKms(questions, msg, app); + await SendKms(questions, history, app); break; } @@ -149,10 +150,10 @@ namespace AntSK.Pages.ChatPage /// /// /// - private async Task SendKms(string questions, string msg, Apps app) + private async Task SendKms(string questions, ChatHistory history, Apps app) { MessageInfo info = null; - var chatResult=_chatService.SendKmsByAppAsync(app, questions, "" ,msg); + var chatResult=_chatService.SendKmsByAppAsync(app, questions, history, "" ); await foreach (var content in chatResult) { if (info == null) @@ -183,7 +184,7 @@ namespace AntSK.Pages.ChatPage /// /// /// - private async Task SendChat(string questions, string history, Apps app) + private async Task SendChat(string questions, ChatHistory history, Apps app) { MessageInfo info = null; var chatResult = _chatService.SendChatByAppAsync(app, questions, history); @@ -221,45 +222,6 @@ namespace AntSK.Pages.ChatPage await InvokeAsync(StateHasChanged); await _JSRuntime.InvokeVoidAsync("Prism.highlightAll"); await _JSRuntime.ScrollToBottomAsync("scrollDiv"); - } - /// - /// 历史会话的会话总结 - /// - /// - /// - private async Task HistorySummarize(Apps app, string questions) - { - var _kernel = _kernelService.GetKernelByApp(app); - if (MessageList.Count > 1) - { - StringBuilder history = new StringBuilder(); - foreach (var item in MessageList) - { - if (item.IsSend) - { - history.Append($"user:{item.Context}{Environment.NewLine}"); - } - else - { - history.Append($"assistant:{item.Context}{Environment.NewLine}"); - } - } - if (MessageList.Count > 10) - { - //历史会话大于10条,进行总结 - var msg = await _kernelService.HistorySummarize(_kernel, questions, history.ToString()); - return msg; - } - else - { - var msg = $"history:{history.ToString()}{Environment.NewLine} user:{questions}"; ; - return msg; - } - } - else - { - return ""; - } - } + } } } diff --git a/src/AntSK/Services/OpenApi/OpenApiService.cs b/src/AntSK/Services/OpenApi/OpenApiService.cs index 2ece71e..b0ca4b6 100644 --- a/src/AntSK/Services/OpenApi/OpenApiService.cs +++ b/src/AntSK/Services/OpenApi/OpenApiService.cs @@ -5,6 +5,7 @@ using AntSK.Domain.Repositories; using AntSK.Domain.Utils; using Microsoft.KernelMemory; using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.ChatCompletion; using Microsoft.SemanticKernel.Connectors.OpenAI; using Newtonsoft.Json; using System.Text; @@ -99,7 +100,7 @@ namespace AntSK.Services.OpenApi private async Task SendChatStream(HttpContext HttpContext, OpenAIStreamResult result, Apps app, string msg) { HttpContext.Response.Headers.Add("Content-Type", "text/event-stream"); - var chatResult = _chatService.SendChatByAppAsync(app, msg, ""); + var chatResult = _chatService.SendChatByAppAsync(app, msg, new ChatHistory()); await foreach (var content in chatResult) { result.choices[0].delta.content = content.ConvertToString(); @@ -154,7 +155,7 @@ namespace AntSK.Services.OpenApi private async Task SendKmsStream(HttpContext HttpContext, OpenAIStreamResult result, Apps app, string msg) { HttpContext.Response.Headers.Add("Content-Type", "text/event-stream"); - var chatResult = _chatService.SendKmsByAppAsync(app, msg,"", ""); + var chatResult = _chatService.SendKmsByAppAsync(app, msg,new ChatHistory(), ""); int i = 0; await foreach (var content in chatResult) { diff --git a/src/AntSK/plugins/KMSPlugin/Ask/skprompt.txt b/src/AntSK/plugins/KMSPlugin/Ask/skprompt.txt index 9a9a92f..c21d08b 100644 --- a/src/AntSK/plugins/KMSPlugin/Ask/skprompt.txt +++ b/src/AntSK/plugins/KMSPlugin/Ask/skprompt.txt @@ -1,7 +1,7 @@ Facts: {{$doc}} -------------------------- -History:{{$history}} +History:{{ConversationSummaryPlugin.SummarizeConversation $history}} -------------------------- Question: {{$questions}} -------------------------- diff --git a/src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt b/src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt index eb6130f..4a8718a 100644 --- a/src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt +++ b/src/AntSK/plugins/KMSPlugin/Ask1/skprompt.txt @@ -11,7 +11,7 @@ - 如果Markdown有图片则正常显示 -------------------------- -历史聊天记录:{{$history}} +历史聊天记录:{{ConversationSummaryPlugin.SummarizeConversation $history}} -------------------------- 用户问题: {{$questions}}