Skip to content

Commit

Permalink
Merge pull request #84 from AIDotNet/feature_llamasharp
Browse files Browse the repository at this point in the history
Feature llamasharp
  • Loading branch information
xuzeyu91 authored Apr 28, 2024
2 parents 1256956 + 0ea52ec commit 73b65f7
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 93 deletions.
2 changes: 1 addition & 1 deletion src/AntSK.Domain/AntSK.Domain.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/AntSK.Domain/Domain/Interface/IChatService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ namespace AntSK.Domain.Domain.Interface
{
public interface IChatService
{
IAsyncEnumerable<StreamingKernelContent> SendChatByAppAsync(Apps app, string questions, ChatHistory history);
IAsyncEnumerable<string> SendChatByAppAsync(Apps app, ChatHistory history);

IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List<RelevantSource> relevantSources = null);
Task<string> SendImgByAppAsync(Apps app, string questions);
Task<ChatHistory> GetChatHistory(List<Chats> MessageList);
Task<ChatHistory> GetChatHistory(List<Chats> MessageList, ChatHistory history);
}
}
73 changes: 41 additions & 32 deletions src/AntSK.Domain/Domain/Service/ChatService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Markdig;
using Microsoft.KernelMemory;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
using System.Diagnostics;
using System.Drawing;
Expand All @@ -35,45 +36,54 @@ IAIModels_Repositories _aIModels_Repositories
/// <param name="questions"></param>
/// <param name="history"></param>
/// <returns></returns>
public async IAsyncEnumerable<StreamingKernelContent> SendChatByAppAsync(Apps app, string questions, ChatHistory history)
public async IAsyncEnumerable<string> SendChatByAppAsync(Apps app, 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 chat = _kernel.GetRequiredService<IChatCompletionService>();
var temperature = app.Temperature / 100;//存的是0~100需要缩小
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
List<string> completionList = new List<string>();
if (!string.IsNullOrEmpty(app.ApiFunctionList) || !string.IsNullOrEmpty(app.NativeFunctionList))//这里还需要加上本地插件的
{
_kernelService.ImportFunctionsByApp(app, _kernel);
settings.ToolCallBehavior = ToolCallBehavior.AutoInvokeKernelFunctions;
settings.ToolCallBehavior = ToolCallBehavior.EnableKernelFunctions;
while (true)
{
ChatMessageContent result = await chat.GetChatMessageContentAsync(history, settings, _kernel);
if (result.Content is not null)
{
string chunkCompletion = result.Content.ConvertToString();
completionList.Add(chunkCompletion);
foreach (var content in completionList)
{
yield return content.ConvertToString();
}
break;
}

history.Add(result);

IEnumerable<FunctionCallContent> functionCalls = FunctionCallContent.GetFunctionCalls(result);
if (!functionCalls.Any())
{
break;
}

foreach (var functionCall in functionCalls)
{
FunctionResultContent resultContent = await functionCall.InvokeAsync(_kernel);

history.Add(resultContent.ToChatMessage());
}
}
}
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
var chatResult = _kernel.InvokeStreamingAsync(function: func,
arguments: args);
await foreach (var content in chatResult)
else
{
yield return content;
var chatResult = chat.GetStreamingChatMessageContentsAsync(history, settings, _kernel);
await foreach (var content in chatResult)
{
yield return content.ConvertToString();
}
}
}

Expand Down Expand Up @@ -318,9 +328,8 @@ public async Task<string> SendImgByAppAsync(Apps app, string questions)
}
}

public async Task<ChatHistory> GetChatHistory(List<Chats> MessageList)
public async Task<ChatHistory> GetChatHistory(List<Chats> MessageList, ChatHistory history)
{
ChatHistory history = new ChatHistory();
if (MessageList.Count > 1)
{

Expand Down
5 changes: 5 additions & 0 deletions src/AntSK.Domain/Domain/Service/KernelService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
using DocumentFormat.OpenXml.Drawing;
using Microsoft.KernelMemory;
using OpenCvSharp.ML;
using LLamaSharp.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.ChatCompletion;

namespace AntSK.Domain.Domain.Service
{
Expand Down Expand Up @@ -105,11 +107,13 @@ private void WithTextGenerationByAIType(IKernelBuilder builder,AIModels chatMode
var (weights, parameters) = LLamaConfig.GetLLamaConfig(chatModel.ModelName);
var ex = new StatelessExecutor(weights, parameters);
builder.Services.AddKeyedSingleton<ITextGenerationService>("local-llama", new LLamaSharpTextCompletion(ex));
builder.Services.AddKeyedSingleton<IChatCompletionService>("local-llama-chat", new LLamaSharpChatCompletion(ex));
break;

case Model.Enum.AIType.SparkDesk:
var options = new SparkDeskOptions { AppId = chatModel.EndPoint, ApiSecret = chatModel.ModelKey, ApiKey = chatModel.ModelName, ModelVersion = Sdcb.SparkDesk.ModelVersion.V3_5 };
builder.Services.AddKeyedSingleton<ITextGenerationService>("spark-desk", new SparkDeskTextCompletion(options, chatModel.Id));
builder.Services.AddKeyedSingleton<IChatCompletionService>("spark-desk-chat", new SparkDeskChatCompletion(options, chatModel.Id));
break;

case Model.Enum.AIType.DashScope:
Expand All @@ -118,6 +122,7 @@ private void WithTextGenerationByAIType(IKernelBuilder builder,AIModels chatMode

case Model.Enum.AIType.Mock:
builder.Services.AddKeyedSingleton<ITextGenerationService>("mock", new MockTextCompletion());
builder.Services.AddKeyedSingleton<IChatCompletionService>("mock-chat", new MockChatCompletion());
break;
case Model.Enum.AIType.LLamaFactory:
builder.AddOpenAIChatCompletion(
Expand Down
2 changes: 1 addition & 1 deletion src/AntSK/Pages/AppPage/AddApp.razor
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
<Button Type="@ButtonType.Link" OnClick="NavigateModelList">去创建</Button>
</FormItem>
<FormItem Label="提示词" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<TextArea MinRows="4" Placeholder="请输入提示词,用户输入使用{{$input}} 来做占位符" @bind-Value="@context.Prompt" />
<TextArea MinRows="4" Placeholder="请输入角色信息" @bind-Value="@context.Prompt" />
</FormItem>
<FormItem Label="温度系数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<span>更确定</span>
Expand Down
37 changes: 25 additions & 12 deletions src/AntSK/Pages/ChatPage/Components/ChatView.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,26 +224,40 @@ await Task.Run(() =>
/// <returns></returns>
protected async Task<bool> SendAsync(string questions, string? filePath)
{
ChatHistory history = new ChatHistory();

//处理多轮会话
Apps app = _apps_Repositories.GetFirst(p => p.Id == AppId);
if (MessageList.Count > 0)
{
history = await _chatService.GetChatHistory(MessageList);
}
ChatHistory history;

if (app.Type == AppType.chat.ToString() && (filePath == null || app.EmbeddingModelID.IsNull()))
{
await SendChat(questions, history, app);
if (string.IsNullOrEmpty(app.Prompt))
{
app.Prompt = "你叫AntSK,是一个人工智能助手";
}
//聊天应用增加系统角色
history = new ChatHistory(app.Prompt.ConvertToString());

if (MessageList.Count > 0)
{
history = await _chatService.GetChatHistory(MessageList, history);
}
await SendChat(history, app);
}
else if (app.Type == AppType.kms.ToString() || filePath != null || app.EmbeddingModelID.IsNotNull())
{
history = new ChatHistory();

if (MessageList.Count > 0)
{
history = await _chatService.GetChatHistory(MessageList, history);
}
await SendKms(questions, history, app, filePath);

}
else if (app.Type == AppType.img.ToString())
{
await SendImg(questions,app);
await SendImg(questions, app);
}

//缓存消息记录
Expand All @@ -253,7 +267,7 @@ protected async Task<bool> SendAsync(string questions, string? filePath)
if (OnRelevantSources.IsNotNull())
{
await OnRelevantSources.InvokeAsync(_relevantSources);
}
}
}


Expand Down Expand Up @@ -318,14 +332,13 @@ private async Task SendKms(string questions, ChatHistory history, Apps app, stri
/// <summary>
/// 发送普通对话
/// </summary>
/// <param name="questions"></param>
/// <param name="history"></param>
/// <param name="app"></param>
/// <returns></returns>
private async Task SendChat(string questions, ChatHistory history, Apps app)
private async Task SendChat(ChatHistory history, Apps app)
{
Chats info = null;
var chatResult = _chatService.SendChatByAppAsync(app, questions, history);
var chatResult = _chatService.SendChatByAppAsync(app, history);
await foreach (var content in chatResult)
{
if (info == null)
Expand Down
7 changes: 4 additions & 3 deletions src/AntSK/Pages/Setting/AIModel/AddModel.razor
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,13 @@
<FormItem Label="APPID" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入APPID" @bind-Value="@context.EndPoint" />
</FormItem>
<FormItem Label="APIKey" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入请输入APIKey" @bind-Value="@context.ModelName" />
</FormItem>
<FormItem Label="APISecret" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<InputPassword @bind-Value="@context.ModelKey" Placeholder="APISecret" Size="@InputSize.Large" />
</FormItem>
<FormItem Label="APIKey" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
<Input Placeholder="请输入请输入APIKey" @bind-Value="@context.ModelName" />
</FormItem>

}
@if (context.AIType == AIType.DashScope)
{
Expand Down
Loading

0 comments on commit 73b65f7

Please sign in to comment.