mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-22 17:49:37 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d450efcffe | ||
|
|
2a6c84c200 | ||
|
|
138a952ace | ||
|
|
eb6528ecd2 | ||
|
|
2c30bbfa09 | ||
|
|
c5a78c2135 | ||
|
|
f03362ee41 | ||
|
|
fad3167d97 | ||
|
|
ad949681dd | ||
|
|
27999d76b0 | ||
|
|
83278352d6 | ||
|
|
fcc56f5fef | ||
|
|
4ebe2ecc32 | ||
|
|
e684cba527 | ||
|
|
888dc19ee0 | ||
|
|
731aea702f | ||
|
|
09e22bc76a |
@@ -10,6 +10,8 @@
|
||||
|
||||
- **知识库**:通过文档(Word、PDF、Excel、Txt、Markdown、Json、PPT)等形式导入知识库,可以进行知识库问答。
|
||||
|
||||
- **文生图**:集成**StableDiffusion** 本地模型,可以进行文生图。
|
||||
|
||||
- **GPTs 生成**:此平台支持创建个性化的GPT模型,尝试构建您自己的GPT模型。
|
||||
|
||||
- **API接口发布**:将内部功能以API的形式对外提供,便于开发者将AntSK 集成进其他应用,增强应用智慧。
|
||||
|
||||
@@ -292,6 +292,26 @@
|
||||
API调用秘钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.Relevance">
|
||||
<summary>
|
||||
相似度
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.MaxAskPromptSize">
|
||||
<summary>
|
||||
提问最大token数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.MaxMatchesCount">
|
||||
<summary>
|
||||
向量匹配数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Apps.AnswerTokens">
|
||||
<summary>
|
||||
回答最大token数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Funs.Path">
|
||||
<summary>
|
||||
接口描述
|
||||
|
||||
@@ -7,13 +7,13 @@ namespace AntSK.Domain.Domain.Interface
|
||||
{
|
||||
public interface IKMService
|
||||
{
|
||||
MemoryServerless GetMemory(Apps app);
|
||||
MemoryServerless GetMemoryByApp(Apps app);
|
||||
|
||||
MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null);
|
||||
MemoryServerless GetMemoryByKMS(string kmsID);
|
||||
|
||||
Task<List<KMFile>> GetDocumentByFileID(string kmsId, string fileId);
|
||||
|
||||
Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg);
|
||||
Task<List<RelevantSource>> GetRelevantSourceList(Apps app, string msg);
|
||||
|
||||
List<UploadFileItem> FileList { get; }
|
||||
|
||||
|
||||
@@ -11,5 +11,22 @@ namespace AntSK.Domain.Domain.Model.Constant
|
||||
public const string KmsIdTag = "kmsid";
|
||||
public const string KmsIndex = "kms";
|
||||
public const string KmsSearchNull="知识库未搜索到相关内容";
|
||||
|
||||
public const string KmsPrompt = @"使用<data></data>标记的内容作为你的知识:
|
||||
<data>
|
||||
{{$doc}}
|
||||
</data>
|
||||
--------------------------
|
||||
回答要求:
|
||||
- 如果你不清楚答案,你需要澄清
|
||||
- 避免提及你是从<data></data>获取的知识
|
||||
- 保持答案与<data></data>众描述一致
|
||||
- 使用Markdown语法优化回答格式。
|
||||
- 如果Markdown有图片则正常显示
|
||||
--------------------------
|
||||
|
||||
历史聊天记录:{{ConversationSummaryPlugin.SummarizeConversation $history}}
|
||||
--------------------------
|
||||
用户问题: {{$input}}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
{
|
||||
public string ID { get; set; } = "";
|
||||
public string Context { get; set; } = "";
|
||||
public string HtmlAnswers { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 发送是true 接收是false
|
||||
@@ -13,8 +12,6 @@
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
public string? FilePath { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using Python.Runtime;
|
||||
using Microsoft.KernelMemory.AI.OpenAI.GPT3;
|
||||
using Python.Runtime;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -37,7 +38,7 @@ namespace AntSK.Domain.Domain.Other
|
||||
dynamic modelscope = Py.Import("modelscope");
|
||||
//dynamic model_dir = modelscope.snapshot_download("AI-ModelScope/bge-large-zh-v1.5", revision: "master");
|
||||
dynamic model_dir = modelscope.snapshot_download(modelName, revision: "master");
|
||||
dynamic HuggingFaceBgeEmbeddingstemp = Py.Import("langchain.embeddings");
|
||||
dynamic HuggingFaceBgeEmbeddingstemp = Py.Import("langchain_community.embeddings.huggingface");
|
||||
dynamic HuggingFaceBgeEmbeddings = HuggingFaceBgeEmbeddingstemp.HuggingFaceBgeEmbeddings;
|
||||
string model_name = model_dir;
|
||||
dynamic model_kwargs = new PyDict();
|
||||
@@ -72,12 +73,18 @@ namespace AntSK.Domain.Domain.Other
|
||||
|
||||
public static int TokenCount(string queryStr)
|
||||
{
|
||||
using (Py.GIL())
|
||||
{
|
||||
PyObject queryResult = model.client.tokenize(queryStr);
|
||||
int len = (int)(queryResult.Length());
|
||||
return len;
|
||||
}
|
||||
//using (Py.GIL())
|
||||
//{
|
||||
// PyObject queryResult = model.client.tokenize(queryStr);
|
||||
// // 使用Python的内置len()函数获取长度
|
||||
// PyObject lenFunc = Py.Import("builtins").GetAttr("len");
|
||||
// PyObject length = lenFunc.Invoke(queryResult["input_ids"]);
|
||||
// int len = length.As<int>(); // 将PyObject转换为C#中的整数
|
||||
// return len;
|
||||
|
||||
//}
|
||||
var tokenCount1 = GPT3Tokenizer.Encode(queryStr).Count;
|
||||
return tokenCount1;
|
||||
}
|
||||
|
||||
public static void Dispose()
|
||||
|
||||
@@ -80,11 +80,12 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
public async IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List<RelevantSource> relevantSources = null)
|
||||
{
|
||||
var relevantSourceList = await _kMService.GetRelevantSourceList(app.KmsIdList, questions);
|
||||
relevantSources?.Clear();
|
||||
var relevantSourceList = await _kMService.GetRelevantSourceList(app, questions);
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
if (!string.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
var memory = _kMService.GetMemory(app);
|
||||
var memory = _kMService.GetMemoryByApp(app);
|
||||
var fileId = Guid.NewGuid().ToString();
|
||||
var result = await memory.ImportDocumentAsync(new Microsoft.KernelMemory.Document(fileId).AddFile(filePath)
|
||||
.AddTag(KmsConstantcs.KmsIdTag, app.Id)
|
||||
@@ -104,20 +105,43 @@ namespace AntSK.Domain.Domain.Service
|
||||
var dataMsg = new StringBuilder();
|
||||
if (relevantSourceList.Any())
|
||||
{
|
||||
bool isSearch=false;
|
||||
foreach (var item in relevantSourceList)
|
||||
{
|
||||
//匹配相似度
|
||||
if (item.Relevance >= app.Relevance/100)
|
||||
{
|
||||
dataMsg.AppendLine(item.ToString());
|
||||
isSearch=true;
|
||||
}
|
||||
}
|
||||
|
||||
//处理markdown显示
|
||||
relevantSources?.AddRange(relevantSourceList);
|
||||
foreach (var item in relevantSourceList)
|
||||
{
|
||||
dataMsg.AppendLine(item.ToString());
|
||||
item.Text = Markdown.ToHtml(item.Text);
|
||||
}
|
||||
|
||||
KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1");
|
||||
var chatResult = _kernel.InvokeStreamingAsync(function: jsonFun,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["questions"] = questions });
|
||||
|
||||
await foreach (var content in chatResult)
|
||||
if (isSearch)
|
||||
{
|
||||
yield return content;
|
||||
//KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1");
|
||||
var temperature = app.Temperature / 100;//存的是0~100需要缩小
|
||||
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
|
||||
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
|
||||
|
||||
var chatResult = _kernel.InvokeStreamingAsync(function: func,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg.ToString(), ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["input"] = questions });
|
||||
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
yield return content;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new StreamingTextContent(KmsConstantcs.KmsSearchNull);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -135,7 +159,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
var temperature = app.Temperature / 100; //存的是0~100需要缩小
|
||||
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
|
||||
var func = _kernel.CreateFunctionFromPrompt("你是一个StableDiffusion提示词助手,需要将用户问题转化为StableDiffusion的英文提示词并返回,请注意只返回提示词不要有其他多余内容,用户的问题是:{{$input}}", settings);
|
||||
var func = _kernel.CreateFunctionFromPrompt("Translate this into English:{{$input}}", settings);
|
||||
var chatResult = await _kernel.InvokeAsync(function: func, arguments: args);
|
||||
if (chatResult.IsNotNull())
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
public List<UploadFileItem> FileList => _fileList;
|
||||
|
||||
public MemoryServerless GetMemory(Apps app)
|
||||
public MemoryServerless GetMemoryByApp(Apps app)
|
||||
{
|
||||
var chatModel = _aIModels_Repositories.GetFirst(p => p.Id == app.ChatModelID);
|
||||
var embedModel = _aIModels_Repositories.GetFirst(p => p.Id == app.EmbeddingModelID);
|
||||
@@ -45,9 +45,9 @@ namespace AntSK.Domain.Domain.Service
|
||||
|
||||
var searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
MaxAskPromptSize = app.MaxAskPromptSize,
|
||||
MaxMatchesCount = app.MaxMatchesCount,
|
||||
AnswerTokens = app.AnswerTokens,
|
||||
EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
};
|
||||
|
||||
@@ -71,7 +71,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
return _memory;
|
||||
}
|
||||
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID, SearchClientConfig searchClientConfig = null)
|
||||
public MemoryServerless GetMemoryByKMS(string kmsID)
|
||||
{
|
||||
//if (_memory.IsNull())
|
||||
{
|
||||
@@ -85,19 +85,19 @@ namespace AntSK.Domain.Domain.Service
|
||||
var embeddingHttpClient = OpenAIHttpClientHandlerUtil.GetHttpClient(embedModel.EndPoint);
|
||||
|
||||
//搜索配置
|
||||
if (searchClientConfig.IsNull())
|
||||
{
|
||||
searchClientConfig = new SearchClientConfig
|
||||
{
|
||||
MaxAskPromptSize = 2048,
|
||||
MaxMatchesCount = 3,
|
||||
AnswerTokens = 1000,
|
||||
EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
};
|
||||
}
|
||||
//if (searchClientConfig.IsNull())
|
||||
//{
|
||||
// searchClientConfig = new SearchClientConfig
|
||||
// {
|
||||
// MaxAskPromptSize = 2048,
|
||||
// MaxMatchesCount = 3,
|
||||
// AnswerTokens = 1000,
|
||||
// EmptyAnswer = KmsConstantcs.KmsSearchNull
|
||||
// };
|
||||
//}
|
||||
|
||||
var memoryBuild = new KernelMemoryBuilder()
|
||||
.WithSearchClientConfig(searchClientConfig)
|
||||
//.WithSearchClientConfig(searchClientConfig)
|
||||
.WithCustomTextPartitioningOptions(new TextPartitioningOptions
|
||||
{
|
||||
MaxTokensPerLine = kms.MaxTokensPerLine,
|
||||
@@ -277,15 +277,15 @@ namespace AntSK.Domain.Domain.Service
|
||||
return docTextList;
|
||||
}
|
||||
|
||||
public async Task<List<RelevantSource>> GetRelevantSourceList(string kmsIdListStr, string msg)
|
||||
public async Task<List<RelevantSource>> GetRelevantSourceList(Apps app ,string msg)
|
||||
{
|
||||
var result = new List<RelevantSource>();
|
||||
if (string.IsNullOrWhiteSpace(kmsIdListStr))
|
||||
if (string.IsNullOrWhiteSpace(app.KmsIdList))
|
||||
return result;
|
||||
var kmsIdList = kmsIdListStr.Split(",");
|
||||
var kmsIdList = app.KmsIdList.Split(",");
|
||||
if (!kmsIdList.Any()) return result;
|
||||
|
||||
var memory = GetMemoryByKMS(kmsIdList.FirstOrDefault()!);
|
||||
var memory = GetMemoryByApp(app);
|
||||
|
||||
var filters = kmsIdList.Select(kmsId => new MemoryFilter().ByTag(KmsConstantcs.KmsIdTag, kmsId)).ToList();
|
||||
|
||||
@@ -297,7 +297,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
result.AddRange(item.Partitions.Select(part => new RelevantSource()
|
||||
{
|
||||
SourceName = item.SourceName,
|
||||
Text = Markdown.ToHtml(part.Text),
|
||||
Text = part.Text,
|
||||
Relevance = part.Relevance
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.Tracing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
@@ -67,7 +68,9 @@ namespace AntSK.Domain.Domain.Service
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit();
|
||||
OnLogMessageReceived("--------------------完成--------------------");
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
await cmdTask;
|
||||
}
|
||||
|
||||
public async Task StartLLamaFactory(string modelName, string templateName)
|
||||
@@ -106,7 +109,10 @@ namespace AntSK.Domain.Domain.Service
|
||||
process.BeginOutputReadLine();
|
||||
process.BeginErrorReadLine();
|
||||
process.WaitForExit();
|
||||
|
||||
OnLogMessageReceived("--------------------完成--------------------");
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
await cmdTask;
|
||||
}
|
||||
|
||||
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace AntSK.Domain.Repositories
|
||||
/// <summary>
|
||||
/// 提示词
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDataType = "varchar(2000)")]
|
||||
public string? Prompt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -77,5 +78,28 @@ namespace AntSK.Domain.Repositories
|
||||
/// API调用秘钥
|
||||
/// </summary>
|
||||
public string? SecretKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 相似度
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "70")]
|
||||
public double Relevance { get; set; } = 70;
|
||||
|
||||
/// <summary>
|
||||
/// 提问最大token数
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "2048")]
|
||||
public int MaxAskPromptSize { get; set; } = 2048;
|
||||
/// <summary>
|
||||
/// 向量匹配数
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "3")]
|
||||
public int MaxMatchesCount { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 回答最大token数
|
||||
/// </summary>
|
||||
[SugarColumn(DefaultValue = "2048")]
|
||||
public int AnswerTokens { get; set; } = 2048;
|
||||
}
|
||||
}
|
||||
@@ -15,4 +15,6 @@ fastapi
|
||||
sse-starlette
|
||||
matplotlib
|
||||
fire
|
||||
modelscope
|
||||
modelscope
|
||||
langchain-community
|
||||
sentence_transformers
|
||||
@@ -24,7 +24,7 @@
|
||||
<IconPicker @bind-Value="@context.Icon"></IconPicker>
|
||||
</FormItem>
|
||||
<FormItem Label="类型" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<RadioGroup @bind-Value="context.Type">
|
||||
<RadioGroup @bind-Value="context.Type" OnChange="OnAppTypeChange" TValue="string">
|
||||
<Radio RadioButton Value="@AppType.chat.ToString()">会话应用</Radio>
|
||||
<Radio RadioButton Value="@AppType.kms.ToString()">知识库</Radio>
|
||||
<Radio RadioButton Value="@AppType.img.ToString()">做图应用</Radio>
|
||||
@@ -52,6 +52,14 @@
|
||||
</Select>
|
||||
<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" />
|
||||
</FormItem>
|
||||
<FormItem Label="温度系数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<span>更确定</span>
|
||||
<Slider TValue="double" Style="display: inline-block;width: 300px; " Min="0" Max="100" DefaultValue="70" @bind-Value="@context.Temperature" />
|
||||
<span>更发散</span>
|
||||
</FormItem>
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -66,17 +74,6 @@
|
||||
}
|
||||
@if (@context.Type == AppType.chat.ToString())
|
||||
{
|
||||
|
||||
<FormItem Label="提示词" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<TextArea MinRows="4" Placeholder="请输入提示词,用户输入使用{{$input}} 来做占位符" @bind-Value="@context.Prompt" />
|
||||
</FormItem>
|
||||
|
||||
<FormItem Label="温度系数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<span>更确定</span>
|
||||
<Slider TValue="double" Style="display: inline-block;width: 300px; " Min="0" Max="100" DefaultValue="70" @bind-Value="@context.Temperature" />
|
||||
<span>更发散</span>
|
||||
</FormItem>
|
||||
|
||||
<FormItem Label="API插件列表" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Select Mode="multiple"
|
||||
@bind-Values="apiIds"
|
||||
@@ -125,6 +122,19 @@
|
||||
}
|
||||
</SelectOptions>
|
||||
</Select>
|
||||
<Button Type="@ButtonType.Link" OnClick="NavigateKmsList">去创建</Button>
|
||||
</FormItem>
|
||||
<FormItem Label="提问最大token数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<AntDesign.InputNumber @bind-Value="context.MaxAskPromptSize" PlaceHolder="提问最大token数"></AntDesign.InputNumber>
|
||||
</FormItem>
|
||||
<FormItem Label="回答最大token数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<AntDesign.InputNumber @bind-Value="context.AnswerTokens" PlaceHolder="回答最大token数"></AntDesign.InputNumber>
|
||||
</FormItem>
|
||||
<FormItem Label="向量匹配数" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<AntDesign.InputNumber @bind-Value="context.MaxMatchesCount" PlaceHolder="向量匹配数"></AntDesign.InputNumber>
|
||||
</FormItem>
|
||||
<FormItem Label="最低相似度(%)" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Slider TValue="double" Style="display: inline-block;width: 300px; " Min="0" Max="100" DefaultValue="70" @bind-Value="@context.Relevance" />
|
||||
</FormItem>
|
||||
}
|
||||
<FormItem Label=" " Style="margin-top:32px" WrapperCol="LayoutModel._submitFormLayout.WrapperCol">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using AntDesign;
|
||||
using AntSK.Domain.Domain.Model.Constant;
|
||||
using AntSK.Domain.Domain.Model.Enum;
|
||||
using AntSK.Domain.Domain.Service;
|
||||
using AntSK.Domain.Repositories;
|
||||
@@ -89,7 +90,14 @@ namespace AntSK.Pages.AppPage
|
||||
}
|
||||
_appModel.KmsIdList = string.Join(",", kmsIds);
|
||||
}
|
||||
|
||||
if (_appModel.Type == AppType.kms.ToString())
|
||||
{
|
||||
if (string.IsNullOrEmpty(_appModel.Prompt)|| !_appModel.Prompt.Contains("{{$doc}}") || !_appModel.Prompt.Contains("{{$input}}"))
|
||||
{
|
||||
_ = Message.Error("知识库提示词必须包含 {{$doc}} 和 {{$input}}", 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (apiIds.IsNotNull())
|
||||
{
|
||||
_appModel.ApiFunctionList = string.Join(",", apiIds);
|
||||
@@ -99,7 +107,7 @@ namespace AntSK.Pages.AppPage
|
||||
|
||||
_appModel.NativeFunctionList = string.Join(",", funIds);
|
||||
}
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(AppId))
|
||||
{
|
||||
//新增
|
||||
@@ -135,6 +143,25 @@ namespace AntSK.Pages.AppPage
|
||||
{
|
||||
NavigationManager.NavigateTo("/setting/modellist");
|
||||
}
|
||||
|
||||
private void NavigateKmsList()
|
||||
{
|
||||
NavigationManager.NavigateTo("/KmsList");
|
||||
}
|
||||
|
||||
|
||||
private void OnAppTypeChange(string value)
|
||||
{
|
||||
if (value == AppType.kms.ToString() && string.IsNullOrEmpty( _appModel.Prompt))
|
||||
{
|
||||
_appModel.Prompt = KmsConstantcs.KmsPrompt;
|
||||
}
|
||||
|
||||
if (value == AppType.chat.ToString())
|
||||
{
|
||||
_appModel.Prompt = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
}
|
||||
else if (context.Type == AppType.img.ToString())
|
||||
{
|
||||
<Tag Color="@PresetColor.Lime.ToString()">做图应用</Tag>
|
||||
<Tag Color="@PresetColor.Red.ToString()">做图应用</Tag>
|
||||
}
|
||||
</DescriptionTemplate>
|
||||
</CardMeta>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
</GridCol>
|
||||
<GridCol Span="23">
|
||||
<div class="chat-bubble received">
|
||||
@((MarkupString)(item.HtmlAnswers))
|
||||
@((MarkupString)(item.Context))
|
||||
</div>
|
||||
|
||||
</GridCol>
|
||||
|
||||
@@ -181,11 +181,11 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
var base64= await _chatService.SendImgByAppAsync(app, questions);
|
||||
if (string.IsNullOrEmpty(base64))
|
||||
{
|
||||
info.HtmlAnswers = "生成失败";
|
||||
info.Context = "生成失败";
|
||||
}
|
||||
else
|
||||
{
|
||||
info.HtmlAnswers = $"<img src=\"data:image/jpeg;base64,{base64}\" alt=\"Base64 Image\" />";
|
||||
info.Context = $"<img src=\"data:image/jpeg;base64,{base64}\" alt=\"Base64 Image\" />";
|
||||
}
|
||||
MessageList.Add(info);
|
||||
}
|
||||
@@ -208,14 +208,13 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
info.Context = content.ConvertToString();
|
||||
info.HtmlAnswers = content.ConvertToString();
|
||||
info.CreateTime = DateTime.Now;
|
||||
|
||||
MessageList.Add(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.HtmlAnswers += content.ConvertToString();
|
||||
info.Context += content.ConvertToString();
|
||||
await Task.Delay(50);
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
@@ -243,14 +242,13 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
info.Context = content.ConvertToString();
|
||||
info.HtmlAnswers = content.ConvertToString();
|
||||
info.CreateTime = DateTime.Now;
|
||||
|
||||
MessageList.Add(info);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.HtmlAnswers += content.ConvertToString();
|
||||
info.Context += content.ConvertToString();
|
||||
await Task.Delay(50);
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
@@ -264,7 +262,7 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
if (info.IsNotNull())
|
||||
{
|
||||
// info!.HtmlAnswers = markdown.Transform(info.HtmlAnswers);
|
||||
info!.HtmlAnswers = Markdown.ToHtml(info.HtmlAnswers);
|
||||
info!.Context = Markdown.ToHtml(info.Context);
|
||||
|
||||
}
|
||||
await InvokeAsync(StateHasChanged);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<Extra>
|
||||
<Button Type="@ButtonType.Primary" Style="position: absolute; right:360px; margin-bottom: 8px;" OnClick="Refresh">刷新 </Button>
|
||||
<Dropdown Style="position: absolute; right: 20px; margin-bottom: 8px;">
|
||||
<Dropdown Style="position: absolute; right: 20px; margin-bottom: 8px;" Trigger="@(new Trigger[] { Trigger.Click })">
|
||||
<Overlay>
|
||||
<Menu>
|
||||
@(_fileUpload(() => FileShowModal()))
|
||||
|
||||
@@ -24,11 +24,10 @@
|
||||
</FormItem>
|
||||
|
||||
<FormItem Label="AI类型" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<EnumRadioGroup @bind-Value="context.AIType" ButtonStyle="RadioButtonStyle.Solid"> </EnumRadioGroup>
|
||||
<EnumRadioGroup @bind-Value="context.AIType" ButtonStyle="RadioButtonStyle.Solid" OnChange="AITypeChange" TEnum="AIType"> </EnumRadioGroup>
|
||||
</FormItem>
|
||||
<FormItem Label="模型类型" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<RadioGroup @bind-Value="context.AIModelType">
|
||||
|
||||
<RadioGroup @bind-Value="context.AIModelType">
|
||||
@if (context.AIType == AIType.StableDiffusion)
|
||||
{
|
||||
<Radio RadioButton Value="@(AIModelType.Image)">图片模型</Radio>
|
||||
@@ -39,7 +38,7 @@
|
||||
{
|
||||
<Radio RadioButton Value="@(AIModelType.Chat)">会话模型</Radio>
|
||||
}
|
||||
@if (context.AIType != AIType.LLamaFactory && context.AIType != AIType.Mock)
|
||||
@if (context.AIType != AIType.LLamaFactory && context.AIType != AIType.Mock && context.AIType != AIType.SparkDesk)
|
||||
{
|
||||
<Radio RadioButton Value="@(AIModelType.Embedding)">向量模型</Radio>
|
||||
}
|
||||
@@ -127,6 +126,9 @@
|
||||
<FormItem Label="请求地址" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Input Placeholder="http://localhost:8080/" @bind-Value="@context.EndPoint" />
|
||||
</FormItem>
|
||||
<FormItem Label="环境安装" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Button Type="primary" OnClick="PipInstall">环境安装</Button>
|
||||
</FormItem>
|
||||
<FormItem Label="llama factory服务" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<InputGroup>
|
||||
@if (!llamaFactoryIsStart)
|
||||
@@ -138,10 +140,7 @@
|
||||
<Button OnClick="StopLFService" Disabled="@(!llamaFactoryIsStart)">停止</Button>
|
||||
}
|
||||
</InputGroup>
|
||||
</FormItem>
|
||||
<FormItem Label="环境安装" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Button Type="primary" OnClick="PipInstall">初始化</Button>
|
||||
</FormItem>
|
||||
</FormItem>
|
||||
}
|
||||
|
||||
@if (context.AIType == AIType.BgeEmbedding)
|
||||
@@ -156,6 +155,9 @@
|
||||
<FormItem Label="PythonDll路径" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Input Placeholder="D:\Programs\Python\Python311\python311.dll" @bind-Value="@context.EndPoint" />
|
||||
</FormItem>
|
||||
<FormItem Label="环境安装" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Button Type="primary" OnClick="PipInstall">环境安装</Button>
|
||||
</FormItem>
|
||||
<FormItem Label="下载并初始化" LabelCol="LayoutModel._formItemLayout.LabelCol" WrapperCol="LayoutModel._formItemLayout.WrapperCol">
|
||||
<Spin Tip="请等待..." Spinning="@(BgeIsStart)" >
|
||||
<Button Type="primary" Disabled="@(BgeIsStart)" OnClick="BgeDownload">@BgeBtnText</Button>
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace AntSK.Pages.Setting.AIModel
|
||||
/// <summary>
|
||||
/// 启动服务
|
||||
/// </summary>
|
||||
private void StartLFService()
|
||||
private async Task StartLFService()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_aiModel.ModelName))
|
||||
{
|
||||
@@ -264,7 +264,7 @@ namespace AntSK.Pages.Setting.AIModel
|
||||
{
|
||||
_logModalVisible = true;
|
||||
_ILLamaFactoryService.LogMessageReceived += CmdLogHandler;
|
||||
await _ILLamaFactoryService.PipInstall();
|
||||
_ILLamaFactoryService.PipInstall();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,9 +314,27 @@ namespace AntSK.Pages.Setting.AIModel
|
||||
_logModalVisible = false;
|
||||
}
|
||||
|
||||
private void AITypeModelChange()
|
||||
{
|
||||
|
||||
private void AITypeChange(AIType aiType)
|
||||
{
|
||||
switch (aiType)
|
||||
{
|
||||
case AIType.LLamaFactory:
|
||||
_aiModel.EndPoint = "http://localhost:8080/";
|
||||
_aiModel.AIModelType=AIModelType.Chat;
|
||||
break;
|
||||
case AIType.StableDiffusion:
|
||||
_aiModel.AIModelType = AIModelType.Image;
|
||||
break;
|
||||
case AIType.Mock:
|
||||
_aiModel.AIModelType = AIModelType.Chat;
|
||||
break ;
|
||||
case AIType.BgeEmbedding:
|
||||
_aiModel.AIModelType = AIModelType.Embedding;
|
||||
break;
|
||||
default:
|
||||
_aiModel.AIModelType = AIModelType.Chat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<PageContainer Title="模型列表">
|
||||
<Content>
|
||||
<RadioGroup @bind-Value="@_modelType">
|
||||
<RadioGroup @bind-Value="@_modelType" OnChange="OnModelTypeChange" TValue="string">
|
||||
<Radio Value="@("gguf")" DefaultChecked=true>LLama本地模型(gguf)</Radio>
|
||||
<Radio Value="@("safetensors")">StableDiffusion(safetensors)</Radio>
|
||||
<Radio Value="@("ckpt")">StableDiffusion2(ckpt)</Radio>
|
||||
|
||||
@@ -48,5 +48,10 @@ namespace AntSK.Pages.Setting.AIModel
|
||||
{
|
||||
NavigationManager.NavigateTo($"/setting/modeldown/detail/{modelPath}");
|
||||
}
|
||||
|
||||
private void OnModelTypeChange(string value)
|
||||
{
|
||||
InitData("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace AntSK.Services.OpenApi
|
||||
string result = "";
|
||||
var _kernel = _kernelService.GetKernelByApp(app);
|
||||
|
||||
var relevantSource = await _kMService.GetRelevantSourceList(app.KmsIdList, questions);
|
||||
var relevantSource = await _kMService.GetRelevantSourceList(app, questions);
|
||||
var dataMsg = new StringBuilder();
|
||||
if (relevantSource.Any())
|
||||
{
|
||||
@@ -210,9 +210,12 @@ namespace AntSK.Services.OpenApi
|
||||
dataMsg.AppendLine(item.ToString());
|
||||
}
|
||||
|
||||
KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1");
|
||||
var chatResult = await _kernel.InvokeAsync(function: jsonFun,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["questions"] = questions });
|
||||
//KernelFunction jsonFun = _kernel.Plugins.GetFunction("KMSPlugin", "Ask1");
|
||||
var temperature = app.Temperature / 100;//存的是0~100需要缩小
|
||||
OpenAIPromptExecutionSettings settings = new() { Temperature = temperature };
|
||||
var func = _kernel.CreateFunctionFromPrompt(app.Prompt, settings);
|
||||
var chatResult = await _kernel.InvokeAsync(function: func,
|
||||
arguments: new KernelArguments() { ["doc"] = dataMsg, ["history"] = string.Join("\n", history.Select(x => x.Role + ": " + x.Content)), ["input"] = questions });
|
||||
if (chatResult.IsNotNull())
|
||||
{
|
||||
string answers = chatResult.GetValue<string>();
|
||||
|
||||
@@ -3,7 +3,7 @@ Facts:
|
||||
--------------------------
|
||||
History:{{ConversationSummaryPlugin.SummarizeConversation $history}}
|
||||
--------------------------
|
||||
Question: {{$questions}}
|
||||
Question: {{$input}}
|
||||
--------------------------
|
||||
Given only the facts above, provide a comprehensive/detailed answer.
|
||||
You don't know where the knowledge comes from, just answer.
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
|
||||
历史聊天记录:{{ConversationSummaryPlugin.SummarizeConversation $history}}
|
||||
--------------------------
|
||||
用户问题: {{$questions}}
|
||||
用户问题: {{$input}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user