├── src ├── Xzy.SK.Api │ ├── plugins │ │ ├── Travel │ │ │ ├── Weather │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ ├── Traffic │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ ├── Attractions │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ └── Delicacy │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ ├── Translate │ │ │ ├── EN │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ ├── JP │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ └── KO │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ ├── Calculate │ │ │ ├── Addition │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ ├── Subtraction │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ └── Multiplication │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ ├── Multiplication │ │ │ ├── skprompt.txt │ │ │ └── config.json │ │ ├── Plan │ │ │ └── Eat │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ ├── MathPlugin │ │ │ ├── FindMaxMin │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ ├── MathSK.cs │ │ │ └── NativeNested.cs │ │ ├── BasePlugin │ │ │ ├── GetIntent │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ └── JSON │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ └── UtilsPlugin.cs │ ├── doc │ │ ├── file4-SK-Readme.pdf │ │ ├── file5-NASA-news.pdf │ │ ├── file3-lorem-ipsum.docx │ │ ├── file2-Wikipedia-Moon.txt │ │ └── file1-Wikipedia-Carbon.txt │ ├── appsettings.json │ ├── Controllers │ │ ├── SK │ │ │ ├── MsgContextController.cs │ │ │ ├── TemplateController.cs │ │ │ ├── TextChunkController.cs │ │ │ ├── FunCoreDemoController.cs │ │ │ ├── SKDemoController.cs │ │ │ └── MemoryStoreController.cs │ │ └── KM │ │ │ └── KMDemoController.cs │ ├── Program.cs │ ├── Xzy.SK.Api.csproj │ ├── Xzy.SK.Api.xml │ └── Startup.cs ├── Xzy.SK.Domain │ ├── Repositories │ │ └── Base │ │ │ ├── CreateEntity │ │ │ ├── IEntityService.cs │ │ │ └── EntityService.cs │ │ │ ├── SqlSugarHelper.cs │ │ │ ├── IRepository.cs │ │ │ └── Repository.cs │ ├── Common │ │ ├── Options │ │ │ ├── ConnectionOptions.cs │ │ │ └── OpenAIOptions.cs │ │ ├── RepoUtils │ │ │ ├── YourAppException.cs │ │ │ ├── ObjectExtensions.cs │ │ │ └── RepoFiles.cs │ │ ├── Map │ │ │ ├── AutoMapProfile.cs │ │ │ ├── MapperRegister.cs │ │ │ └── MapperExtend.cs │ │ ├── Model │ │ │ ├── PageList.cs │ │ │ └── ResponseResult.cs │ │ ├── Excel │ │ │ └── ExeclPropertyAttribute.cs │ │ ├── DependencyInjection │ │ │ ├── ServiceDescriptionAttribute.cs │ │ │ └── ServiceCollectionExtensions.cs │ │ ├── Utils │ │ │ ├── DateTimeConverter.cs │ │ │ ├── OpenAIHttpClientHandler.cs │ │ │ └── ConvertUtils.cs │ │ ├── SK │ │ │ └── KernelFunctionCombinators.cs │ │ └── Extensions │ │ │ └── SugarExtensions.cs │ ├── Domain │ │ └── DTO │ │ │ └── Chat │ │ │ └── ChatMessageInput.cs │ ├── Xzy.SK.Domain.csproj │ └── Xzy.SK.Domain.xml └── Xzy.SK.Test │ ├── TestXunit.cs │ ├── Xzy.SK.Test.csproj │ └── Startup.cs ├── README.md ├── Xzy.SK.sln ├── .gitattributes └── .gitignore /src/Xzy.SK.Api/plugins/Travel/Weather/skprompt.txt: -------------------------------------------------------------------------------- 1 | 为我查询所在地的天气: 2 | 我的请求是:{{$input}} -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Traffic/skprompt.txt: -------------------------------------------------------------------------------- 1 | 为我推荐本次旅行适合的交通方式: 2 | 我的请求是:{{$input}} -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Attractions/skprompt.txt: -------------------------------------------------------------------------------- 1 | 为我推荐当地旅游合适的景点: 2 | 我的要求是:{{$input}} -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Delicacy/skprompt.txt: -------------------------------------------------------------------------------- 1 | 为我推荐当地旅游的美食: 2 | 我的要求是:{{$input}} 3 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/EN/skprompt.txt: -------------------------------------------------------------------------------- 1 | Translate this into English: 2 | {{$input}} 3 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/JP/skprompt.txt: -------------------------------------------------------------------------------- 1 | Translate this into Japanese: 2 | {{$input}} 3 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/KO/skprompt.txt: -------------------------------------------------------------------------------- 1 | Translate this into Korean: 2 | {{$input}} 3 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Addition/skprompt.txt: -------------------------------------------------------------------------------- 1 | 把2个数相加: 2 | 第一个数是:{{$num1}} 3 | 第二个数是:{{$num2}} 4 | 返回中文大写,只返回中文大写 -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Multiplication/skprompt.txt: -------------------------------------------------------------------------------- 1 | 把2个数相乘: 2 | 第一个数是:{{MathPlugin.Negative $num1}} 3 | 第二个数是:{{$num2}} 4 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Subtraction/skprompt.txt: -------------------------------------------------------------------------------- 1 | 把2个数相减: 2 | 第一个数是:{{$num1}} 3 | 第二个数是:{{$num2}} 4 | 5 | 只返回结果,不要有多余文字内容 -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Plan/Eat/skprompt.txt: -------------------------------------------------------------------------------- 1 | 我会给你一批数,你需要从中找到最大和最小的两个数: 2 | {{$input}} 3 | 4 | 仅返回结果,除此之外不要有多余内容,按照如下格式: 5 | 最大的数-最小的数 6 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/doc/file4-SK-Readme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzeyu91/SemanticKernelDemo/HEAD/src/Xzy.SK.Api/doc/file4-SK-Readme.pdf -------------------------------------------------------------------------------- /src/Xzy.SK.Api/doc/file5-NASA-news.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzeyu91/SemanticKernelDemo/HEAD/src/Xzy.SK.Api/doc/file5-NASA-news.pdf -------------------------------------------------------------------------------- /src/Xzy.SK.Api/doc/file3-lorem-ipsum.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xuzeyu91/SemanticKernelDemo/HEAD/src/Xzy.SK.Api/doc/file3-lorem-ipsum.docx -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Multiplication/skprompt.txt: -------------------------------------------------------------------------------- 1 | 把2个数相乘: 2 | 第一个数是:{{MathPlugin.Negative $num1}} 3 | 第二个数是:{{$num2}} 4 | 5 | 只返回结果,不要有多余文字内容 -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/MathPlugin/FindMaxMin/skprompt.txt: -------------------------------------------------------------------------------- 1 | 我会给你一批数,你需要从中找到最大和最小的两个数: 2 | {{$input}} 3 | 4 | 仅返回结果,除此之外不要有多余内容,按照如下格式: 5 | 最大的数-最小的数 6 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/BasePlugin/GetIntent/skprompt.txt: -------------------------------------------------------------------------------- 1 | 用户: {{$input}} 2 | 3 | --------------------------------------------- 4 | 5 | 提供用户的意图。其意图应为以下内容之一: {{$options}} 6 | 7 | 意图: -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/BasePlugin/JSON/skprompt.txt: -------------------------------------------------------------------------------- 1 | 你作为一个json提取器 2 | 我要提取的内容是: 3 | {{$input}} 4 | 5 | --------------------------------------------- 6 | 参考如下json格式进行返回,仅返回json,除此之外不要有其他文字: 7 | {{$example}} -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Repositories/Base/CreateEntity/IEntityService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Xzy.SK.Domain.Repositories 6 | { 7 | public interface IEntityService 8 | { 9 | bool CreateEntity(string entityName, string filePath); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Options/ConnectionOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Xzy.SK.Domain 6 | { 7 | public class ConnectionOptions 8 | { 9 | public static string SqlServer { get; set; } 10 | 11 | public static string MySql { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*", 10 | "urls": "http://*:5000", 11 | "OpenAI": { 12 | "Key": "", 13 | "Endpoint": "", 14 | "Model": "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Options/OpenAIOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Xzy.SK.Domain.Common.Options 8 | { 9 | public class OpenAIOptions 10 | { 11 | public static string Model { get; set; } 12 | 13 | public static string Endpoint { get; set; } 14 | 15 | public static string Key { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Plan/Eat/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "推荐的美食", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "推荐的美食", 17 | "defaultValue": "" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/EN/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把一个语言翻译成英文", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "内容变成了英文", 17 | "defaultValue": "" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/JP/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把一个语言翻译成日语", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "内容变成了日语", 17 | "defaultValue": "" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Translate/KO/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把一个语言翻译成韩语", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "内容变成了韩语", 17 | "defaultValue": "" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/MathPlugin/FindMaxMin/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "找到最大和最小的数", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "找到最大和最小的数", 17 | "defaultValue": "" 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/RepoUtils/YourAppException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | 3 | using System; 4 | 5 | namespace RepoUtils; 6 | 7 | public class YourAppException : Exception 8 | { 9 | public YourAppException() : base() 10 | { 11 | } 12 | 13 | public YourAppException(string message) : base(message) 14 | { 15 | } 16 | 17 | public YourAppException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Xzy.SK.Test/TestXunit.cs: -------------------------------------------------------------------------------- 1 | 2 | using Xzy.SK.Domain.Repositories; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using Xunit; 7 | 8 | namespace Xzy.SK.Test 9 | { 10 | public class TestXunit 11 | { 12 | 13 | //可以依赖注入service 14 | public TestXunit() 15 | { 16 | 17 | } 18 | 19 | [Fact] 20 | public void Test() 21 | { 22 | 23 | //Assert.NotNull(result); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Map/AutoMapProfile.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Xzy.SK.Domain.Common.Map 7 | { 8 | public class AutoMapProfile : Profile 9 | { 10 | public AutoMapProfile() 11 | { 12 | 13 | //映射时忽略null值映射,适用于MapTo场景 14 | //CreateMap().ForAllMembers(opt => opt.Condition((src, dest, sourceMember) => sourceMember != null)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Addition/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把2个数相加", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.0, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "num1", 16 | "description": "数字1", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "num2", 21 | "description": "数字2", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Multiplication/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把2个数相乘", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.5, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "num1", 16 | "description": "数字1", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "num2", 21 | "description": "数字2", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Subtraction/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把2个数相减", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.0, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "num1", 16 | "description": "数字1", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "num2", 21 | "description": "数字2", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/RepoUtils/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json; 6 | using System.Threading.Tasks; 7 | 8 | namespace Xzy.SK.Domain.Common.RepoUtils 9 | { 10 | public static class ObjectExtensions 11 | { 12 | private static readonly JsonSerializerOptions s_jsonOptionsCache = new() { WriteIndented = true }; 13 | 14 | public static string AsJson(this object obj) 15 | { 16 | return JsonSerializer.Serialize(obj, s_jsonOptionsCache); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Calculate/Multiplication/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "把2个数相乘", 5 | "completion": { 6 | "max_tokens": 200, 7 | "temperature": 0.0, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "num1", 16 | "description": "数字1", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "num2", 21 | "description": "数字2", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/BasePlugin/JSON/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Json提取", 5 | "completion": { 6 | "max_tokens": 500, 7 | "temperature": 0.0, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "要提取的内容。", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "example", 21 | "description": "提取参考格式示例。", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Delicacy/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "推荐当地美食", 5 | "completion": { 6 | "max_tokens": 400, 7 | "temperature": 0.7, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "用户的问题。", 17 | "defaultValue": "" 18 | }, 19 | 20 | { 21 | "name": "history", 22 | "description": "对话的历史。", 23 | "defaultValue": "" 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Traffic/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "推荐旅游交通方式", 5 | "completion": { 6 | "max_tokens": 400, 7 | "temperature": 0.7, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "用户的问题。", 17 | "defaultValue": "" 18 | }, 19 | 20 | { 21 | "name": "history", 22 | "description": "对话的历史。", 23 | "defaultValue": "" 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Weather/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "查询当地的天气", 5 | "completion": { 6 | "max_tokens": 400, 7 | "temperature": 0.7, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "用户的问题。", 17 | "defaultValue": "" 18 | }, 19 | 20 | { 21 | "name": "history", 22 | "description": "对话的历史。", 23 | "defaultValue": "" 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/BasePlugin/GetIntent/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "获取用户的意图。", 5 | "completion": { 6 | "max_tokens": 500, 7 | "temperature": 0.0, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "用户的请求。", 17 | "defaultValue": "" 18 | }, 19 | { 20 | "name": "options", 21 | "description": "可供选择的选项。", 22 | "defaultValue": "" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/Travel/Attractions/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "推荐当地旅游景点", 5 | "completion": { 6 | "max_tokens": 400, 7 | "temperature": 0.7, 8 | "top_p": 0.0, 9 | "presence_penalty": 0.0, 10 | "frequency_penalty": 0.0 11 | }, 12 | "input": { 13 | "parameters": [ 14 | { 15 | "name": "input", 16 | "description": "用户的问题。", 17 | "defaultValue": "" 18 | }, 19 | 20 | { 21 | "name": "history", 22 | "description": "对话的历史。", 23 | "defaultValue": "" 24 | } 25 | ] 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/UtilsPlugin.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SemanticKernel; 2 | using System; 3 | using System.ComponentModel; 4 | 5 | namespace Xzy.SK.Api.plugins 6 | { 7 | public class UtilsPlugin 8 | { 9 | /// 10 | /// 11 | /// 12 | private readonly Kernel _kernel; 13 | public UtilsPlugin(Kernel kernel) 14 | { 15 | _kernel = kernel; 16 | } 17 | 18 | [KernelFunction, Description("发送邮件")] 19 | public string SendEmail(string input) 20 | { 21 | Console.WriteLine(input); 22 | return "发送成功"; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Model/PageList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Xzy.SK.Domain.Common.Model 6 | { 7 | /// 8 | /// 返回分页结果 9 | /// 10 | public class PageList 11 | { 12 | //查询结果 13 | public List List { get; set; } 14 | /// 15 | /// 当前页,从1开始 16 | /// 17 | public int PageIndex { get; set; } 18 | /// 19 | /// 每页数量 20 | /// 21 | public int PageSize { get; set; } 22 | /// 23 | /// 总数 24 | /// 25 | public int TotalCount { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Domain/DTO/Chat/ChatMessageInput.cs: -------------------------------------------------------------------------------- 1 | using Azure.AI.OpenAI; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Xzy.SK.Domain.Domain.DTO.Chat 10 | { 11 | public class ChatMessageInput 12 | { 13 | [Required] 14 | [MinLength(1)] 15 | public List Prompts { get; set; } = new List(); 16 | } 17 | 18 | public class ChatMessageItem 19 | { 20 | [Required] 21 | public ChatRole role { get; set; } 22 | [Required] 23 | public string Content { get; set; } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Excel/ExeclPropertyAttribute.cs: -------------------------------------------------------------------------------- 1 | using NPOI.SS.UserModel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Xzy.SK.Domain.Common.Excel 7 | { 8 | public class ExeclPropertyAttribute : Attribute 9 | { 10 | public ExeclPropertyAttribute() 11 | { 12 | 13 | } 14 | public ExeclPropertyAttribute(string displayName, int order, CellType cellType = CellType.String) 15 | { 16 | DisplayName = displayName; 17 | Order = order; 18 | CellType = cellType; 19 | } 20 | 21 | public string DisplayName { get; set; } 22 | 23 | public int Order { get; set; } 24 | 25 | public CellType CellType { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/DependencyInjection/ServiceDescriptionAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Xzy.SK.Domain 6 | { 7 | public class ServiceDescriptionAttribute : Attribute 8 | { 9 | public ServiceDescriptionAttribute(Type serviceType, ServiceLifetime lifetime) 10 | { 11 | ServiceType = serviceType; 12 | Lifetime = lifetime; 13 | } 14 | 15 | public Type ServiceType { get; set; } 16 | 17 | public ServiceLifetime Lifetime { get; set; } 18 | } 19 | 20 | public enum ServiceLifetime { 21 | /// 22 | /// 作用域 23 | /// 24 | Scoped, 25 | /// 26 | /// 单例 27 | /// 28 | Singleton, 29 | /// 30 | /// 瞬时 31 | /// 32 | Transient 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Map/MapperRegister.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Xzy.SK.Domain.Common.Map 8 | { 9 | public static class MapperRegister 10 | { 11 | public static void AddMapper(this IServiceCollection services) 12 | { 13 | var config = new MapperConfiguration(cfg => 14 | { 15 | cfg.CreateMissingTypeMaps = true; 16 | cfg.ValidateInlineMaps = false; 17 | cfg.AddProfile(); 18 | }); 19 | 20 | IMapper mapper = config.CreateMapper(); 21 | 22 | //启动实体映射 23 | Mapper.Initialize(cfg => 24 | { 25 | cfg.CreateMissingTypeMaps = true; 26 | cfg.ValidateInlineMaps = false; 27 | cfg.AddProfile(); 28 | }); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/MathPlugin/MathSK.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SemanticKernel; 2 | using System; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using Xzy.SK.Domain; 6 | 7 | namespace Xzy.SK.Api.plugins.MathPlugin 8 | { 9 | public class MathSK 10 | { 11 | /// 12 | /// 得到负数 13 | /// 14 | /// 15 | /// 16 | [KernelFunction, Description("得到负数")] 17 | public string Negative(string number) 18 | { 19 | return (number.ConvertToInt32() * -1).ToString(); 20 | } 21 | 22 | /// 23 | /// 两个数相减 24 | /// 25 | /// 26 | /// 27 | [KernelFunction, Description("两个数相减")] 28 | [return: Description("减完后的数")] 29 | public string Subtraction( 30 | [Description("The value to subtract")] int num1, 31 | [Description("Amount to subtract")] int num2) => 32 | (num1 - num2).ToString(); 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Xzy.SK.Test/Xzy.SK.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | all 16 | 17 | 18 | runtime; build; native; contentfiles; analyzers; buildtransitive 19 | all 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/Xzy.SK.Test/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using System; 5 | using Xunit; 6 | 7 | namespace Xzy.SK.Test 8 | { 9 | public class Startup 10 | { 11 | // 自定义 host 构建 12 | public void ConfigureHost(IHostBuilder hostBuilder) 13 | { 14 | hostBuilder 15 | .ConfigureAppConfiguration(builder => 16 | { 17 | // 注册配置 18 | builder.AddJsonFile("appsettings.Development.json"); 19 | }) 20 | .ConfigureServices((context, services) => 21 | { 22 | //// 注册自定义服务 23 | //services.AddServicesFromAssemblies("Xzy.Project.Domain"); 24 | 25 | }).ConfigureWebHostDefaults(webBuilder => 26 | { 27 | //启动Api中的依赖注入、初始化等操作 28 | webBuilder.UseStartup(); 29 | }); 30 | 31 | } 32 | 33 | // 可以添加要用到的方法参数,会自动从注册的服务中获取服务实例,类似于 asp.net core 里 Configure 方法 34 | public void Configure(IServiceProvider applicationServices) 35 | { 36 | // 有一些测试数据要初始化可以放在这里 37 | 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/plugins/MathPlugin/NativeNested.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SemanticKernel; 2 | using RepoUtils; 3 | using System.IO; 4 | using System.Threading.Tasks; 5 | 6 | namespace Xzy.SK.Api.plugins.MathPlugin 7 | { 8 | public class NativeNested 9 | { 10 | private readonly Kernel _kernel; 11 | public NativeNested(Kernel kernel) 12 | { 13 | _kernel = kernel; 14 | } 15 | 16 | //通过自然语义先找到最大和最小的2个值,然后用最大值减去最小值得到结果返回 17 | [KernelFunction] 18 | public async Task Test(string input) 19 | { 20 | var mathPlugin1 = _kernel.ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "MathPlugin")); 21 | var mathPlugin2 = _kernel.ImportPluginFromObject(new MathSK(), "MathPlugin1"); 22 | 23 | var maxmin = await _kernel.InvokeAsync( mathPlugin1["FindMaxMin"],new KernelArguments() { ["input"]=input } ); 24 | 25 | var nums = maxmin.GetValue().Split("-"); 26 | 27 | var variables = new KernelArguments 28 | { 29 | ["num1"] = nums[0], 30 | ["num2"] = nums[1] 31 | }; 32 | var result = await _kernel.InvokeAsync(mathPlugin2["Subtraction"], variables); 33 | return result.GetValue(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Repositories/Base/SqlSugarHelper.cs: -------------------------------------------------------------------------------- 1 | using SqlSugar; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Xzy.SK.Domain.Repositories.Base 9 | { 10 | public class SqlSugarHelper //不能是泛型类 11 | { 12 | /// 13 | /// sqlserver连接 14 | /// 15 | public static SqlSugarScope SqlServerDb = new SqlSugarScope(new ConnectionConfig() 16 | { 17 | ConnectionString = ConnectionOptions.SqlServer, 18 | DbType = DbType.SqlServer, 19 | InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息 20 | IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了 21 | MoreSettings = new ConnMoreSettings() 22 | { 23 | IsWithNoLockQuery = true//看这里 24 | } 25 | }, Db => 26 | { 27 | Db.Aop.OnLogExecuting = (sql, pars) => 28 | { 29 | if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").ConvertToString() == "Development") 30 | { 31 | Console.WriteLine(sql + "\r\n" + 32 | SqlServerDb.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); 33 | Console.WriteLine(); 34 | } 35 | }; 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Utils/DateTimeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.Json; 6 | using System.Text.Json.Serialization; 7 | using System.Threading.Tasks; 8 | 9 | namespace Xzy.SK.Domain.Common.Utils 10 | { 11 | public class DateTimeConverter : JsonConverter 12 | { 13 | public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 14 | { 15 | return DateTime.TryParse(reader.GetString(), out var dateTime) ? dateTime : default(DateTime); 16 | } 17 | 18 | public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) 19 | { 20 | writer.WriteStringValue(value.ToString("yyyy-MM-dd HH:mm:ss")); 21 | } 22 | } 23 | public class DateTimeNullableConvert : JsonConverter 24 | { 25 | public override DateTime? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) 26 | { 27 | return DateTime.TryParse(reader.GetString(), out var dateTime) ? dateTime : default(DateTime?); 28 | } 29 | 30 | public override void Write(Utf8JsonWriter writer, DateTime? value, JsonSerializerOptions options) 31 | { 32 | writer.WriteStringValue(value?.ToString("yyyy-MM-dd HH:mm:ss")); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/RepoUtils/RepoFiles.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Microsoft. All rights reserved. 2 | 3 | using System.IO; 4 | using System.Reflection; 5 | 6 | namespace RepoUtils; 7 | 8 | public static class RepoFiles 9 | { 10 | /// 11 | /// Scan the local folders from the repo, looking for "samples/plugins" folder. 12 | /// 13 | /// The full path to samples/plugins 14 | public static string SamplePluginsPath() 15 | { 16 | string Parent = System.IO.Directory.GetCurrentDirectory(); 17 | string Folder = "plugins"; 18 | 19 | bool SearchPath(string pathToFind, out string result, int maxAttempts = 10) 20 | { 21 | var currDir = Path.GetFullPath(Assembly.GetExecutingAssembly().Location); 22 | bool found; 23 | do 24 | { 25 | result = Path.Join(currDir, pathToFind); 26 | found = Directory.Exists(result); 27 | currDir = Path.GetFullPath(Path.Combine(currDir, "..")); 28 | } while (maxAttempts-- > 0 && !found); 29 | 30 | return found; 31 | } 32 | 33 | if (!SearchPath(Parent + Path.DirectorySeparatorChar + Folder, out string path) 34 | && !SearchPath(Folder, out path)) 35 | { 36 | throw new YourAppException("Plugins directory not found. The app needs the plugins from the repo to work."); 37 | } 38 | 39 | return path; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Repositories/Base/CreateEntity/EntityService.cs: -------------------------------------------------------------------------------- 1 | using Xzy.SK.Domain.Repositories; 2 | using SqlSugar; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Xzy.SK.Domain.Repositories 8 | { 9 | [ServiceDescription(typeof(IEntityService), ServiceLifetime.Scoped)] 10 | public class EntityService:IEntityService 11 | { 12 | public SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() 13 | { 14 | ConnectionString = ConnectionOptions.SqlServer, 15 | DbType = DbType.SqlServer, 16 | InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息 17 | IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了 18 | }); 19 | /// 20 | /// 生成实体类 21 | /// 22 | /// 23 | /// 24 | /// 25 | public bool CreateEntity(string entityName, string filePath) 26 | { 27 | try 28 | { 29 | db.DbFirst.IsCreateAttribute().Where(entityName).SettingClassTemplate(old => 30 | { 31 | return old.Replace("{Namespace}", "Xzy.SK.Domain.Repositories");//修改Namespace命名空间 32 | }).CreateClassFile(filePath); 33 | return true; 34 | } 35 | catch (Exception) 36 | { 37 | return false; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/doc/file2-Wikipedia-Moon.txt: -------------------------------------------------------------------------------- 1 | The Moon is Earth's only natural satellite. Its diameter is about one-quarter of Earth's (comparable to the width of Australia),[17] making it the fifth largest satellite in the Solar System and the largest and most massive relative to its parent planet. It is larger than all known dwarf planets in the Solar System.[18] The Moon is a planetary-mass object with a differentiated rocky body, making it a satellite planet under the geophysical definitions of the term. It lacks any significant atmosphere, hydrosphere, or magnetic field. Its surface gravity is about one-sixth of Earth's at 0.1654 g—Jupiter's moon Io is the only satellite in the Solar System known to have a higher surface gravity and density. 2 | 3 | The Moon orbits Earth at an average distance of 384,400 km (238,900 mi), or about 30 times Earth's diameter. Its gravitational influence is the main driver of Earth's tides and very slowly lengthens Earth's day. The Moon's orbit around Earth has a sidereal period of 27.3 days. During each synodic period of 29.5 days, the amount of the Moon's Earth-facing surface that is illuminated by the Sun varies from none up to nearly 100%, resulting in lunar phases that form the basis for the months of a lunar calendar.[19] The Moon is tidally locked to Earth, which means that the length of a full rotation of the Moon on its own axis causes its same side (the near side) to always face Earth, and the somewhat longer lunar day is the same as the synodic period. Due to cyclical shifts in perspective (libration), 59% of the lunar surface is visible from Earth. -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Map/MapperExtend.cs: -------------------------------------------------------------------------------- 1 | using AutoMapper; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Xzy.SK.Domain.Common.Map 7 | { 8 | public static class MapperExtend 9 | { 10 | /// 11 | /// Entity集合转DTO集合 12 | /// 13 | /// 14 | /// 15 | /// 16 | public static List ToDTOList(this object value) 17 | { 18 | if (value == null) 19 | return new List(); 20 | 21 | return Mapper.Map>(value); 22 | } 23 | /// 24 | /// Entity转DTO 25 | /// 26 | /// 27 | /// 28 | /// 29 | public static T ToDTO(this object value) 30 | { 31 | if (value == null) 32 | return default(T); 33 | 34 | return Mapper.Map(value); 35 | } 36 | 37 | /// 38 | /// 给已有对象map,适合update场景,如需过滤空值需要在AutoMapProfile 设置 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | public static T MapTo(this object self, T result) 45 | { 46 | if (self == null) 47 | return default(T); 48 | return (T)Mapper.Map(self, result, self.GetType(), typeof(T)); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/MsgContextController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.Connectors.OpenAI; 5 | using System.Threading.Tasks; 6 | 7 | 8 | namespace Xzy.SK.Api.Controllers 9 | { 10 | [Route("api/[controller]/[action]")] 11 | [ApiController] 12 | public class MsgContextController : ControllerBase 13 | { 14 | private readonly Kernel _kernel; 15 | 16 | public MsgContextController(Kernel kernel) 17 | { 18 | _kernel = kernel; 19 | } 20 | 21 | /// 22 | /// 聊天上下文 23 | /// 24 | /// 25 | [HttpPost] 26 | public async Task Test() 27 | { 28 | string history = @"User:你好\r\n ChatBot:你好!我是AI助手,有什么需要帮忙的吗?"; 29 | string input = "我刚才说了什么"; 30 | 31 | string FunctionDefinition = @$" 32 | {history} 33 | User: {input}"; 34 | 35 | var promptRenderer = new KernelPromptTemplateFactory(); 36 | var renderedPrompt = promptRenderer.Create(new PromptTemplateConfig(FunctionDefinition)); 37 | 38 | var test = _kernel.CreateFunctionFromPrompt(FunctionDefinition, new OpenAIPromptExecutionSettings() { MaxTokens = 100 }); 39 | KernelArguments KernelArguments = new () 40 | { 41 | ["$history"] = history, 42 | ["$input"] = input 43 | }; 44 | var result = await _kernel.InvokeAsync(test, KernelArguments); 45 | 46 | return Ok(result.GetValue()); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/TemplateController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.Connectors.OpenAI; 5 | using Microsoft.SemanticKernel.Plugins.Core; 6 | 7 | using System; 8 | using System.Threading.Tasks; 9 | 10 | namespace Xzy.SK.Api.Controllers 11 | { 12 | [Route("api/[controller]/[action]")] 13 | [ApiController] 14 | public class TemplateController : ControllerBase 15 | { 16 | private readonly Kernel _kernel; 17 | 18 | public TemplateController(Kernel kernel) 19 | { 20 | _kernel = kernel; 21 | } 22 | 23 | [HttpPost] 24 | public async Task CreateTemplate() 25 | { 26 | _kernel.ImportPluginFromObject(new TimePlugin(), "time"); 27 | 28 | const string FunctionDefinition = @" 29 | 今天是: {{time.Date}} 30 | 当前时间为:{{time.Time}} 31 | 32 | 使用JSON语法回答以下问题,包括使用的数据。 33 | 是上午、下午、晚上还是晚上(上午/下午/晚上/晚上)? 34 | 是周末时间吗(周末/不是周末)? 35 | "; 36 | 37 | var promptTemplateFactory = new KernelPromptTemplateFactory(); 38 | var promptTemplate = promptTemplateFactory.Create(new PromptTemplateConfig(FunctionDefinition)); 39 | var renderedPrompt = await promptTemplate.RenderAsync(_kernel); 40 | 41 | var kindOfDay = _kernel.CreateFunctionFromPrompt(FunctionDefinition, new OpenAIPromptExecutionSettings() { MaxTokens = 100 }); 42 | 43 | // Show the result 44 | Console.WriteLine("--- Prompt Function result"); 45 | var result = await _kernel.InvokeAsync(kindOfDay); 46 | return Ok(result.GetValue()); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/TextChunkController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.Plugins.Core; 5 | using Microsoft.SemanticKernel.Text; 6 | using System.Collections.Generic; 7 | using System; 8 | using System.Threading.Tasks; 9 | 10 | namespace Xzy.SK.Api.Controllers 11 | { 12 | [Route("api/[controller]/[action]")] 13 | [ApiController] 14 | public class TextChunkController : ControllerBase 15 | { 16 | private readonly Kernel _kernel; 17 | 18 | public TextChunkController(Kernel kernel) 19 | { 20 | _kernel = kernel; 21 | } 22 | 23 | /// 24 | /// 文本分块 25 | /// 26 | /// 27 | [HttpPost] 28 | public async Task Test() 29 | { 30 | string msg = System.IO.File.ReadAllText("诛仙.txt"); 31 | 32 | 33 | ///将纯文本拆分成行。 34 | ///要拆分的文本 35 | ///每行的最大令牌数 36 | ///对字符串中的令牌进行计数的函数。如果未提供,将使用默认计数器 37 | ///<return>行列表 38 | var lines = TextChunker.SplitPlainTextLines(msg, 40); 39 | 40 | ///将纯文本拆分为段落。 41 | ///文本行 42 | ///每个段落的最大令牌数 43 | ///段落之间重叠的令牌数 44 | ///要在每个单独的区块前加上前缀的文本 45 | ///对字符串中的令牌进行计数的函数。如果未提供,将使用默认计数器 46 | ///<return>段落列表 47 | var paragraphs = TextChunker.SplitPlainTextParagraphs(lines, 4000); 48 | 49 | return Ok(); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Model/ResponseResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Xzy.SK.Domain.Common.Model 6 | { 7 | public class Result 8 | { 9 | /// 10 | /// 错误码,0是正常返回,异常返回错误码 11 | /// 12 | public string Code { get; set; } = "0"; 13 | /// 14 | /// 返回数据 15 | /// 16 | public object Data { get; set; } 17 | /// 18 | /// 返回信息详情 19 | /// 20 | public string Message { get; set; } 21 | 22 | 23 | } 24 | 25 | public static class ResponseResult 26 | { 27 | /// 28 | /// 执行成功 29 | /// 30 | /// 31 | public static Result Success() 32 | { 33 | return new Result 34 | { 35 | Data = "", 36 | Code = "0", 37 | Message = "ok" 38 | }; 39 | } 40 | 41 | /// 42 | /// 执行成功 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | public static Result Success(this object data, string code = "0", string message = "ok") 49 | { 50 | return new Result 51 | { 52 | Data = data, 53 | Code = code, 54 | Message = message 55 | }; 56 | } 57 | /// 58 | /// 执行失败 59 | /// 60 | /// 61 | /// 62 | /// 63 | /// 64 | public static Result Error(this object data, string code, string message) 65 | { 66 | return new Result 67 | { 68 | Data = data, 69 | Code = code, 70 | Message = message 71 | }; 72 | } 73 | /// 74 | /// 执行失败 75 | /// 76 | /// 77 | /// 78 | /// 79 | public static Result Error(string code, string message) 80 | { 81 | return new Result 82 | { 83 | Data = "", 84 | Code = code, 85 | Message = message 86 | }; 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SKdemo示例 2 | > 官方github地址:https://github.com/microsoft/semantic-kernel 3 | 4 | 5 | ### 本项目主要介绍了SK的基本功能使用(以及配套视频教程) 6 | 1. SK插件Plugins及VSCode调试工具 7 | > https://www.bilibili.com/video/BV1sr4y1f7zb/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 8 | 2. 原生函数 9 | > https://www.bilibili.com/video/BV1Hw411Y71S/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 10 | 3. 嵌套函数 11 | > https://www.bilibili.com/video/BV1zF411m7YA/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 12 | 4. 原生嵌套函数 13 | > https://www.bilibili.com/video/BV1F841117Jc/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 14 | 5. Plan流程编排 15 | > https://www.bilibili.com/video/BV12j41187GX/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 16 | 6. 意图识别、json提取 17 | > https://www.bilibili.com/video/BV1nm4y1V7dz/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 18 | 7. 依赖注入、Pipeline 19 | > https://www.bilibili.com/video/BV1Qj41147i6/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 20 | 8. MemoryStore向量存储与检索 21 | > https://www.bilibili.com/video/BV1tu411M7k9/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 22 | 9. 1.0beta1版本有哪些更新 23 | > https://www.bilibili.com/video/BV1E34y1G7Pz/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 24 | 10. SK如何对接ChatGLM 通义 文心 星火等其他大模型 25 | > https://www.bilibili.com/video/BV1uw41117gf/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 26 | 11. ConversationPlugins 27 | > https://www.bilibili.com/video/BV1s34y1g7ux/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 28 | 12. TextMemory 29 | > https://www.bilibili.com/video/BV12w411c7yY/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 30 | 13. Template 31 | > https://www.bilibili.com/video/BV1T94y1j78H/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 32 | 14. 聊天上下文 33 | > https://www.bilibili.com/video/BV16N411T7uW/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 34 | 15. TextChunk 35 | > https://www.bilibili.com/video/BV1gw411p7LE/?share_source=copy_web&vd_source=a71998b5a5f44b203630a79e1a22c179 36 | -------------------------------------------------------------------------------- /Xzy.SK.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio Version 17 3 | VisualStudioVersion = 17.7.34031.279 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xzy.SK.Api", "src\Xzy.SK.Api\Xzy.SK.Api.csproj", "{B7138D00-A84E-4B56-821C-A71B836440E4}" 6 | EndProject 7 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xzy.SK.Domain", "src\Xzy.SK.Domain\Xzy.SK.Domain.csproj", "{7730A0E2-25B1-483F-8F7B-00DEBDB7135B}" 8 | EndProject 9 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xzy.SK.Test", "src\Xzy.SK.Test\Xzy.SK.Test.csproj", "{161E3478-8E2C-44FA-88C1-A3C0A010CEA2}" 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Any CPU = Debug|Any CPU 14 | Release|Any CPU = Release|Any CPU 15 | EndGlobalSection 16 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 17 | {B7138D00-A84E-4B56-821C-A71B836440E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {B7138D00-A84E-4B56-821C-A71B836440E4}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {B7138D00-A84E-4B56-821C-A71B836440E4}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {B7138D00-A84E-4B56-821C-A71B836440E4}.Release|Any CPU.Build.0 = Release|Any CPU 21 | {7730A0E2-25B1-483F-8F7B-00DEBDB7135B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {7730A0E2-25B1-483F-8F7B-00DEBDB7135B}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {7730A0E2-25B1-483F-8F7B-00DEBDB7135B}.Release|Any CPU.ActiveCfg = Release|Any CPU 24 | {7730A0E2-25B1-483F-8F7B-00DEBDB7135B}.Release|Any CPU.Build.0 = Release|Any CPU 25 | {161E3478-8E2C-44FA-88C1-A3C0A010CEA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 26 | {161E3478-8E2C-44FA-88C1-A3C0A010CEA2}.Debug|Any CPU.Build.0 = Debug|Any CPU 27 | {161E3478-8E2C-44FA-88C1-A3C0A010CEA2}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {161E3478-8E2C-44FA-88C1-A3C0A010CEA2}.Release|Any CPU.Build.0 = Release|Any CPU 29 | EndGlobalSection 30 | GlobalSection(SolutionProperties) = preSolution 31 | HideSolutionNode = FALSE 32 | EndGlobalSection 33 | GlobalSection(ExtensibilityGlobals) = postSolution 34 | SolutionGuid = {68D21C10-BBBC-4C5B-ADAA-E88C2B026776} 35 | EndGlobalSection 36 | EndGlobal 37 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/DependencyInjection/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | using System.Text; 6 | 7 | namespace Xzy.SK.Domain 8 | { 9 | /// 10 | /// 容器扩展 11 | /// 12 | public static class ServiceCollectionExtensions 13 | { 14 | /// 15 | /// 从程序集中加载类型并添加到容器中 16 | /// 17 | /// 容器 18 | /// 程序集集合 19 | /// 20 | public static IServiceCollection AddServicesFromAssemblies(this IServiceCollection services, params string[] assemblies) 21 | { 22 | Type attributeType = typeof(ServiceDescriptionAttribute); 23 | //var refAssembyNames = Assembly.GetExecutingAssembly().GetReferencedAssemblies(); 24 | foreach (var item in assemblies) 25 | { 26 | Assembly assembly = Assembly.Load(item); 27 | 28 | var types = assembly.GetTypes(); 29 | 30 | foreach (var classType in types) 31 | { 32 | if (!classType.IsAbstract && classType.IsClass && classType.IsDefined(attributeType, false)) 33 | { 34 | ServiceDescriptionAttribute serviceAttribute = (classType.GetCustomAttribute(attributeType) as ServiceDescriptionAttribute); 35 | switch (serviceAttribute.Lifetime) 36 | { 37 | case ServiceLifetime.Scoped: 38 | services.AddScoped(serviceAttribute.ServiceType, classType); 39 | break; 40 | 41 | case ServiceLifetime.Singleton: 42 | services.AddSingleton(serviceAttribute.ServiceType, classType); 43 | break; 44 | 45 | case ServiceLifetime.Transient: 46 | services.AddTransient(serviceAttribute.ServiceType, classType); 47 | break; 48 | } 49 | } 50 | } 51 | } 52 | 53 | return services; 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Xzy.SK.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | True 6 | 7 | 8 | false 9 | 10 | 11 | Xzy.SK.Domain.xml 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Always 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/KM/KMDemoController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.KernelMemory; 4 | using System; 5 | using System.IO; 6 | using System.Net.Http; 7 | using System.Threading.Tasks; 8 | using Xzy.SK.Domain.Common.Options; 9 | using Xzy.SK.Domain.Common.Utils; 10 | 11 | namespace Xzy.SK.Api.Controllers.KM 12 | { 13 | [Route("api/[controller]/[action]")] 14 | [ApiController] 15 | public class KMDemoController : ControllerBase 16 | { 17 | /// 18 | /// 测试KM 19 | //// 20 | /// 21 | [HttpPost] 22 | public async Task< IActionResult> Test(string question) 23 | { 24 | var handler = new OpenAIHttpClientHandler(); 25 | var memory = new KernelMemoryBuilder() 26 | .WithOpenAITextGeneration(new OpenAIConfig() 27 | { 28 | APIKey = OpenAIOptions.Key, 29 | TextModel = OpenAIOptions.Model, 30 | 31 | },null, new HttpClient(handler)) 32 | .WithOpenAITextEmbeddingGeneration(new OpenAIConfig() 33 | { 34 | APIKey = OpenAIOptions.Key, 35 | EmbeddingModel = "text-embedding-ada-002", 36 | 37 | },null,false, new HttpClient(handler)) 38 | .Build(); 39 | 40 | string filepath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "doc\\file4-SK-Readme.pdf"); 41 | await memory.ImportDocumentAsync(filepath); 42 | 43 | var answer = await memory.AskAsync(question); 44 | 45 | return Ok(answer.Result); 46 | } 47 | 48 | 49 | [HttpPost] 50 | public async Task TestFile(IFormFile file,string question) 51 | { 52 | var forms = await Request.ReadFormAsync(); 53 | using (var stream = forms.Files[0].OpenReadStream()) 54 | { 55 | var handler = new OpenAIHttpClientHandler(); 56 | var memory = new KernelMemoryBuilder() 57 | .WithOpenAITextGeneration(new OpenAIConfig() 58 | { 59 | APIKey = OpenAIOptions.Key, 60 | TextModel = OpenAIOptions.Model, 61 | 62 | }, null, new HttpClient(handler)) 63 | .WithOpenAITextEmbeddingGeneration(new OpenAIConfig() 64 | { 65 | APIKey = OpenAIOptions.Key, 66 | EmbeddingModel = "text-embedding-ada-002", 67 | 68 | }, null, false, new HttpClient(handler)) 69 | .Build(); 70 | 71 | await memory.ImportDocumentAsync(stream, forms.Files[0].FileName); 72 | 73 | var answer = await memory.AskAsync(question); 74 | 75 | return Ok(answer.Result); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Utils/OpenAIHttpClientHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Text.RegularExpressions; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Xzy.SK.Domain.Common.Options; 10 | 11 | namespace Xzy.SK.Domain.Common.Utils 12 | { 13 | public class OpenAIHttpClientHandler : HttpClientHandler 14 | { 15 | 16 | protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 17 | { 18 | UriBuilder uriBuilder; 19 | Regex regex = new Regex(@"(https?)://([^/:]+)(:\d+)?/(.*)"); 20 | Match match = regex.Match(OpenAIOptions.Endpoint); 21 | if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" && request.Content != null) 22 | { 23 | string requestBody = await request.Content.ReadAsStringAsync(); 24 | //便于调试查看请求prompt 25 | Console.WriteLine(requestBody); 26 | } 27 | if (match.Success) 28 | { 29 | string xieyi = match.Groups[1].Value; 30 | string host = match.Groups[2].Value; 31 | string port = match.Groups[3].Value; // 可选的端口号 32 | string route = match.Groups[4].Value; 33 | // 如果port不为空,它将包含冒号,所以你可能需要去除它 34 | port = string.IsNullOrEmpty(port) ? port : port.Substring(1); 35 | // 拼接host和端口号 36 | var hostnew = string.IsNullOrEmpty(port) ? host : $"{host}:{port}"; 37 | 38 | switch (request.RequestUri.LocalPath) 39 | { 40 | case "/v1/chat/completions": 41 | //替换代理 42 | uriBuilder = new UriBuilder(request.RequestUri) 43 | { 44 | // 这里是你要修改的 URL 45 | Scheme = $"{xieyi}://{hostnew}/", 46 | Host = host, 47 | Path = route + "v1/chat/completions", 48 | }; 49 | if (port.ConvertToInt32() != 0) 50 | { 51 | uriBuilder.Port = port.ConvertToInt32(); 52 | } 53 | 54 | request.RequestUri = uriBuilder.Uri; 55 | 56 | break; 57 | case "/v1/embeddings": 58 | uriBuilder = new UriBuilder(request.RequestUri) 59 | { 60 | // 这里是你要修改的 URL 61 | Scheme = $"{xieyi}://{host}/", 62 | Host = host, 63 | Path = route + "v1/embeddings", 64 | }; 65 | if (port.ConvertToInt32() != 0) 66 | { 67 | uriBuilder.Port = port.ConvertToInt32(); 68 | } 69 | request.RequestUri = uriBuilder.Uri; 70 | break; 71 | } 72 | } 73 | 74 | // 接着,调用基类的 SendAsync 方法将你的修改后的请求发出去 75 | HttpResponseMessage response = await base.SendAsync(request, cancellationToken); 76 | 77 | return response; 78 | } 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | using System.Collections; 11 | using Xzy.SK.Domain; 12 | 13 | namespace Xzy.SK 14 | { 15 | public class Program 16 | { 17 | public static void Main(string[] args) 18 | { 19 | CreateHostBuilder(args).Build().Run(); 20 | } 21 | 22 | public static IHostBuilder CreateHostBuilder(string[] args) 23 | { 24 | var appsettings = GetAppSettings(); 25 | var configuration = new ConfigurationBuilder().SetBasePath(Environment.CurrentDirectory) 26 | //.AddJsonFile("appsettings.json") 27 | .AddJsonStream(new MemoryStream(appsettings)) 28 | .Build(); 29 | var url = configuration["urls"]; 30 | return Host.CreateDefaultBuilder(args) 31 | .ConfigureAppConfiguration(config => 32 | { 33 | config.AddJsonStream(new MemoryStream(appsettings)); 34 | }) 35 | .ConfigureWebHostDefaults(webBuilder => 36 | { 37 | webBuilder.UseUrls(url); 38 | webBuilder.UseStartup(); 39 | }); 40 | } 41 | 42 | /// 43 | /// 初始化配置文件 44 | /// 45 | /// 46 | private static byte[] GetAppSettings() 47 | { 48 | string envName = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT").ConvertToString(); 49 | //读取configmap。写入到配置文件 50 | var builderEnv = new ConfigurationBuilder().AddEnvironmentVariables(); 51 | IConfiguration Configuration = builderEnv.Build(); 52 | //获取configmap 53 | string appsettings = Configuration.GetValue("appsettings.json"); 54 | //获取 55 | if (appsettings.ConvertToString() == "") 56 | { 57 | if (envName == "Production") 58 | { 59 | appsettings = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, "appsettings.json")); 60 | } 61 | else 62 | { 63 | appsettings = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, $"appsettings.{envName}.json")); 64 | } 65 | } 66 | appsettings = InitSecrect(appsettings); 67 | return System.Text.Encoding.UTF8.GetBytes(appsettings); 68 | } 69 | 70 | //通过环境变量Secret替换appsetting 71 | private static string InitSecrect(string appsettings) 72 | { 73 | var envList = Environment.GetEnvironmentVariables(); 74 | foreach (DictionaryEntry env in envList) 75 | { 76 | if (env.Key.ConvertToString().Contains("._")) 77 | { 78 | appsettings = appsettings.Replace(env.Key.ConvertToString(), env.Value.ConvertToString()); 79 | Console.WriteLine($"替换Screct:{env.Key.ConvertToString()}"); 80 | } 81 | } 82 | return appsettings; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Repositories/Base/IRepository.cs: -------------------------------------------------------------------------------- 1 | using Xzy.SK.Domain.Common.Model; 2 | using SqlSugar; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq.Expressions; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Xzy.SK.Domain.Repositories 10 | { 11 | //基础仓储 12 | public interface IRepository 13 | { 14 | SqlSugarScope GetDB(); 15 | List GetList(); 16 | Task> GetListAsync(); 17 | List GetList(Expression> whereExpression); 18 | Task> GetListAsync(Expression> whereExpression); 19 | int Count(Expression> whereExpression); 20 | Task CountAsync(Expression> whereExpression); 21 | PageList GetPageList(Expression> whereExpression, PageModel page); 22 | PageList

GetPageList

(Expression> whereExpression, PageModel page); 23 | Task> GetPageListAsync(Expression> whereExpression, PageModel page); 24 | Task> GetPageListAsync

(Expression> whereExpression, PageModel page); 25 | PageList GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 26 | Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 27 | PageList

GetPageList

(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 28 | Task> GetPageListAsync

(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 29 | PageList GetPageList(List conditionalList, PageModel page); 30 | Task> GetPageListAsync(List conditionalList, PageModel page); 31 | PageList GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 32 | Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc); 33 | T GetById(dynamic id); 34 | Task GetByIdAsync(dynamic id); 35 | T GetSingle(Expression> whereExpression); 36 | Task GetSingleAsync(Expression> whereExpression); 37 | T GetFirst(Expression> whereExpression); 38 | Task GetFirstAsync(Expression> whereExpression); 39 | bool Insert(T obj); 40 | Task InsertAsync(T obj); 41 | bool InsertRange(List objs); 42 | Task InsertRangeAsync(List objs); 43 | int InsertReturnIdentity(T obj); 44 | Task InsertReturnIdentityAsync(T obj); 45 | long InsertReturnBigIdentity(T obj); 46 | Task InsertReturnBigIdentityAsync(T obj); 47 | bool DeleteByIds(dynamic[] ids); 48 | Task DeleteByIdsAsync(dynamic[] ids); 49 | bool Delete(dynamic id); 50 | Task DeleteAsync(dynamic id); 51 | bool Delete(T obj); 52 | Task DeleteAsync(T obj); 53 | bool Delete(Expression> whereExpression); 54 | Task DeleteAsync(Expression> whereExpression); 55 | bool Update(T obj); 56 | Task UpdateAsync(T obj); 57 | bool UpdateRange(List objs); 58 | Task UpdateRangeAsync(List objs); 59 | bool IsAny(Expression> whereExpression); 60 | Task IsAnyAsync(Expression> whereExpression); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/FunCoreDemoController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.Plugins.Core; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Threading.Tasks; 8 | 9 | namespace Xzy.SK.Api.Controllers 10 | { 11 | [Route("api/[controller]/[action]")] 12 | [ApiController] 13 | public class FunCoreDemoController : ControllerBase 14 | { 15 | private readonly Kernel _kernel; 16 | 17 | public FunCoreDemoController(Kernel kernel) 18 | { 19 | _kernel = kernel; 20 | } 21 | 22 | private const string ChatTranscript = @"约翰:你好,你好吗? 23 | 简:我很好,谢谢。你好吗 24 | 约翰:我做得很好,写了一些示例代码。 25 | 简:太棒了!我也在写一些示例代码。 26 | 约翰:你在写什么? 27 | 简:我正在写一个聊天机器人。 28 | 约翰:太酷了。我也在写一个聊天机器人。 29 | 简:你是用什么语言写的? 30 | 约翰:我是用C#写的。 31 | 简:我是用Python写的。 32 | 约翰:太酷了。我需要学习Python。 33 | 简:我需要学习C#。 34 | 约翰:我可以试试你的聊天机器人吗? 35 | 简:当然,这是链接。 36 | 约翰:谢谢! 37 | 简:不客气。 38 | 简:看看我的聊天机器人写的这首诗: 39 | 简:玫瑰是红色的 40 | 简:小提琴是蓝色的 41 | 简:我正在写一个聊天机器人 42 | 简:你呢? 43 | 约翰:太酷了。让我看看我的是否也会写诗。 44 | 约翰:这是我的聊天机器人写的一首诗: 45 | 约翰:宇宙的奇异性是个谜。 46 | 约翰:宇宙是个谜。 47 | 约翰:宇宙是个谜。 48 | 约翰:宇宙是个谜。 49 | 约翰:看来我需要改进我的,哦,好吧。 50 | 简:你可能想试着用另一种型号。 51 | 简:我用的是GPT-3型号。 52 | 约翰:我用的是GPT-2型号。这是有道理的。 53 | 约翰:这是模型更新后的一首新诗。 54 | 约翰:宇宙是个谜。 55 | 约翰:宇宙是个谜。 56 | 约翰:宇宙是个谜。 57 | 约翰:哎呀,它真的卡住了,不是吗?你能帮我调试代码吗? 58 | 简:当然,出什么问题了? 59 | 约翰:我不确定。我认为这是代码中的一个错误。 60 | 简:我去看看。 61 | 简:我想我发现问题了。 62 | 简:看起来你没有给模型传递正确的参数。 63 | 约翰:谢谢你的帮助! 64 | 简:我现在正在写一个机器人来总结对话。我想确保它在谈话时间长的时候起作用。 65 | 约翰:所以你需要一直和我说话才能产生长时间的对话? 66 | 简:是的,没错。 67 | 约翰:好的,我继续说。我们应该谈什么? 68 | 简:我不知道,你想谈什么? 69 | 约翰:我不知道,CoPilot为我们做了大部分谈话,这很好。但有时肯定会卡住。 70 | 简:我同意,很高兴CoPilot为我们做了大部分的谈话。 71 | 简:但有时候肯定会卡住。 72 | 约翰:你知道需要多长时间吗? 73 | 简:我想最大长度是1024个代币。大约为1024*4=4096个字符。 74 | 约翰:角色太多了。 75 | 简:是的。 76 | 约翰:我不知道还能说多久。 77 | 简:我想我们快到了。让我检查一下。 78 | 简:我有个坏消息,我们只走了一半。 79 | 约翰:哦,不,我不确定我能不能坚持下去。我累了。 80 | 简:我也累了。 81 | 约翰:也许有一大块文本可以用来进行长时间的对话。 82 | 简:这是个好主意。让我看看能不能找到一个。也许是Lorem Ipsum? 83 | 约翰:是的,这是个好主意。 84 | 简:我找到了一个Lorem Ipsum生成器。 85 | Jane:这是一个4096个字符的Lorem Ipsum文本: 86 | 简:Lorem ipsum悲哀坐amet,con 87 | 简:Lorem ipsum悲哀坐amet,consectetur adipiscing elit。Sed euismod,nunc sit amet aliquam 88 | 简:Lorem ipsum悲哀坐amet,consectetur adipiscing elit。Sed euismod,nunc sit amet aliquam 89 | 简:亲爱的,这只是在重复stuf。 90 | 约翰:我想我们完了。 91 | 简:但我们不是!我们还需要1500个字符。 92 | 约翰:哦,卡南达,我们的家乡。 93 | 简:你所有的儿子都有真正的爱国者之爱。 94 | 约翰:我们看到你的心在发光。 95 | 简:真正的北方坚强而自由。 96 | 约翰:加拿大啊,我们从四面八方为你站岗。 97 | 简:上帝保佑我们的土地光荣自由。 98 | 约翰:加拿大啊,我们为你站岗。 99 | 简:哦,加拿大,我们为你站岗。 100 | 简:很有趣,谢谢。让我现在检查一下。 101 | 简:我想我们还需要600个字。 102 | 约翰:哦,你能看见吗? 103 | 简:黎明前。 104 | 约翰:我们多么自豪地欢呼啊。 105 | 简:在黄昏的最后一刻。 106 | 约翰:宽阔的条纹和明亮的星星。 107 | 简:通过危险的战斗。 108 | 约翰:哦,我们看的城墙。 109 | 简:我们真是太殷勤了。 110 | 约翰:还有火箭的红光。 111 | 简:炸弹在空中爆炸。 112 | 约翰:彻夜提供证据。 113 | 简:我们的国旗还在那儿。 114 | 约翰:哦,说那条星条旗还没有飘扬。 115 | 简:哦,自由之地。 116 | 约翰:还有勇敢者的家。 117 | 简:你是西雅图海怪队的球迷吗? 118 | 约翰:是的,我喜欢。我喜欢去看比赛。 119 | 简:我也是西雅图海怪队的球迷。谁是你最喜欢的球员? 120 | 约翰:我喜欢看所有的球员,但我想我最喜欢的是马蒂·贝尼尔斯。 121 | 简:是的,他是个伟大的球员。我也喜欢看他。我也喜欢看贾登·施瓦茨。 122 | 约翰:亚当·拉尔森是另一个好的。那只大猫! 123 | 简:我们成功了!它足够长了。非常感谢。 124 | 约翰:不客气。我很高兴我们能帮忙。再见 125 | 简:再见!"; 126 | 127 | ///

128 | /// 会话总结,标签提取 129 | /// 130 | /// 131 | [HttpPost] 132 | public async Task ConversationSummary() 133 | { 134 | KernelPlugin conversationSummaryPlugin = _kernel.ImportPluginFromType(); 135 | 136 | FunctionResult summary = await _kernel.InvokeAsync( 137 | conversationSummaryPlugin["SummarizeConversation"],new KernelArguments() { ["input"]= ChatTranscript }); 138 | 139 | Console.WriteLine("SummarizeConversation:"); 140 | Console.WriteLine(summary.GetValue()); 141 | 142 | summary = await _kernel.InvokeAsync( 143 | conversationSummaryPlugin["SummarizeConversation"], new KernelArguments() { ["input"] = ChatTranscript }); 144 | 145 | Console.WriteLine("GetConversationActionItems:"); 146 | Console.WriteLine(summary.GetValue()); 147 | 148 | summary = await _kernel.InvokeAsync( 149 | conversationSummaryPlugin["SummarizeConversation"], new KernelArguments() { ["input"] = ChatTranscript }); 150 | 151 | Console.WriteLine("GetConversationTopics:"); 152 | Console.WriteLine(summary.GetValue()); 153 | return Ok(); 154 | } 155 | } 156 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Xzy.SK.Api.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | 6 | 7 | false 8 | 9 | 10 | Xzy.SK.Api.xml 11 | 12 | CA1050,CA1707,CA2007,VSTHRD111,CS1591,RCS1110,CA5394,SKEXP0001,SKEXP0002,SKEXP0003,SKEXP0004,SKEXP0010,SKEXP0011,,SKEXP0012,SKEXP0020,SKEXP0021,SKEXP0022,SKEXP0023,SKEXP0024,SKEXP0025,SKEXP0026,SKEXP0027,SKEXP0028,SKEXP0029,SKEXP0030,SKEXP0031,SKEXP0032,SKEXP0040,SKEXP0041,SKEXP0042,SKEXP0050,SKEXP0051,SKEXP0052,SKEXP0053,SKEXP0054,SKEXP0055,SKEXP0060,SKEXP0061,SKEXP0101,SKEXP0102 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Always 31 | 32 | 33 | Always 34 | 35 | 36 | Always 37 | 38 | 39 | Always 40 | 41 | 42 | Always 43 | 44 | 45 | Always 46 | 47 | 48 | Always 49 | 50 | 51 | Always 52 | 53 | 54 | Always 55 | 56 | 57 | Always 58 | 59 | 60 | Always 61 | 62 | 63 | Always 64 | 65 | 66 | PreserveNewest 67 | 68 | 69 | PreserveNewest 70 | 71 | 72 | PreserveNewest 73 | 74 | 75 | Always 76 | 77 | 78 | Always 79 | 80 | 81 | Always 82 | 83 | 84 | Always 85 | 86 | 87 | Always 88 | 89 | 90 | Always 91 | 92 | 93 | 94 | 95 | 96 | PreserveNewest 97 | 98 | 99 | PreserveNewest 100 | 101 | 102 | PreserveNewest 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/SK/KernelFunctionCombinators.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.SemanticKernel; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Xzy.SK.Domain.Common.SK 10 | { 11 | public static class KernelFunctionCombinators 12 | { 13 | /// 14 | /// Invokes a pipeline of functions, running each in order and passing the output from one as the first argument to the next. 15 | /// 16 | /// The pipeline of functions to invoke. 17 | /// The kernel to use for the operations. 18 | /// The arguments. 19 | /// The cancellation token to monitor for a cancellation request. 20 | /// 21 | public static Task InvokePipelineAsync( 22 | IEnumerable functions, Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken) => 23 | Pipe(functions).InvokeAsync(kernel, arguments, cancellationToken); 24 | 25 | /// 26 | /// Invokes a pipeline of functions, running each in order and passing the output from one as the named argument to the next. 27 | /// 28 | /// The sequence of functions to invoke, along with the name of the argument to assign to the result of the function's invocation. 29 | /// The kernel to use for the operations. 30 | /// The arguments. 31 | /// The cancellation token to monitor for a cancellation request. 32 | /// 33 | public static Task InvokePipelineAsync( 34 | IEnumerable<(KernelFunction Function, string OutputVariable)> functions, Kernel kernel, KernelArguments arguments, CancellationToken cancellationToken) => 35 | Pipe(functions).InvokeAsync(kernel, arguments, cancellationToken); 36 | 37 | /// 38 | /// Creates a function whose invocation will invoke each of the supplied functions in sequence. 39 | /// 40 | /// The pipeline of functions to invoke. 41 | /// The name of the combined operation. 42 | /// The description of the combined operation. 43 | /// The result of the final function. 44 | /// 45 | /// The result from one function will be fed into the first argument of the next function. 46 | /// 47 | public static KernelFunction Pipe( 48 | IEnumerable functions, 49 | string? functionName = null, 50 | string? description = null) 51 | { 52 | ArgumentNullException.ThrowIfNull(functions); 53 | 54 | KernelFunction[] funcs = functions.ToArray(); 55 | Array.ForEach(funcs, f => ArgumentNullException.ThrowIfNull(f)); 56 | 57 | var funcsAndVars = new (KernelFunction Function, string OutputVariable)[funcs.Length]; 58 | for (int i = 0; i < funcs.Length; i++) 59 | { 60 | string p = ""; 61 | if (i < funcs.Length - 1) 62 | { 63 | var parameters = funcs[i + 1].Metadata.Parameters; 64 | if (parameters.Count > 0) 65 | { 66 | p = parameters[0].Name; 67 | } 68 | } 69 | 70 | funcsAndVars[i] = (funcs[i], p); 71 | } 72 | 73 | return Pipe(funcsAndVars, functionName, description); 74 | } 75 | 76 | /// 77 | /// Creates a function whose invocation will invoke each of the supplied functions in sequence. 78 | /// 79 | /// The pipeline of functions to invoke, along with the name of the argument to assign to the result of the function's invocation. 80 | /// The name of the combined operation. 81 | /// The description of the combined operation. 82 | /// The result of the final function. 83 | /// 84 | /// The result from one function will be fed into the first argument of the next function. 85 | /// 86 | public static KernelFunction Pipe( 87 | IEnumerable<(KernelFunction Function, string OutputVariable)> functions, 88 | string? functionName = null, 89 | string? description = null) 90 | { 91 | ArgumentNullException.ThrowIfNull(functions); 92 | 93 | (KernelFunction Function, string OutputVariable)[] arr = functions.ToArray(); 94 | Array.ForEach(arr, f => 95 | { 96 | ArgumentNullException.ThrowIfNull(f.Function); 97 | ArgumentNullException.ThrowIfNull(f.OutputVariable); 98 | }); 99 | 100 | return KernelFunctionFactory.CreateFromMethod(async (Kernel kernel, KernelArguments arguments) => 101 | { 102 | FunctionResult? result = null; 103 | for (int i = 0; i < arr.Length; i++) 104 | { 105 | result = await arr[i].Function.InvokeAsync(kernel, arguments).ConfigureAwait(false); 106 | if (i < arr.Length - 1) 107 | { 108 | arguments[arr[i].OutputVariable] = result.GetValue(); 109 | } 110 | } 111 | 112 | return result; 113 | }, functionName, description); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/doc/file1-Wikipedia-Carbon.txt: -------------------------------------------------------------------------------- 1 | Carbon (from Latin carbo 'coal') is a chemical element with the symbol C and atomic number 6. It is nonmetallic and tetravalent—its atom making four electrons available to form covalent chemical bonds. It belongs to group 14 of the periodic table.[14] Carbon makes up about 0.025 percent of Earth's crust.[15] Three isotopes occur naturally, 12C and 13C being stable, while 14C is a radionuclide, decaying with a half-life of about 5,730 years.[16] Carbon is one of the few elements known since antiquity.[17] 2 | 3 | Carbon is the 15th most abundant element in the Earth's crust, and the fourth most abundant element in the universe by mass after hydrogen, helium, and oxygen. Carbon's abundance, its unique diversity of organic compounds, and its unusual ability to form polymers at the temperatures commonly encountered on Earth, enables this element to serve as a common element of all known life. It is the second most abundant element in the human body by mass (about 18.5%) after oxygen.[18] 4 | 5 | The atoms of carbon can bond together in diverse ways, resulting in various allotropes of carbon. Well-known allotropes include graphite, diamond, amorphous carbon, and fullerenes. The physical properties of carbon vary widely with the allotropic form. For example, graphite is opaque and black, while diamond is highly transparent. Graphite is soft enough to form a streak on paper (hence its name, from the Greek verb "γράφειν" which means "to write"), while diamond is the hardest naturally occurring material known. Graphite is a good electrical conductor while diamond has a low electrical conductivity. Under normal conditions, diamond, carbon nanotubes, and graphene have the highest thermal conductivities of all known materials. All carbon allotropes are solids under normal conditions, with graphite being the most thermodynamically stable form at standard temperature and pressure. They are chemically resistant and require high temperature to react even with oxygen. 6 | 7 | The most common oxidation state of carbon in inorganic compounds is +4, while +2 is found in carbon monoxide and transition metal carbonyl complexes. The largest sources of inorganic carbon are limestones, dolomites and carbon dioxide, but significant quantities occur in organic deposits of coal, peat, oil, and methane clathrates. Carbon forms a vast number of compounds, with about two hundred million having been described and indexed;[19] and yet that number is but a fraction of the number of theoretically possible compounds under standard conditions. 8 | 9 | The allotropes of carbon include graphite, one of the softest known substances, and diamond, the hardest naturally occurring substance. It bonds readily with other small atoms, including other carbon atoms, and is capable of forming multiple stable covalent bonds with suitable multivalent atoms. Carbon is a component element in the large majority of all chemical compounds, with about two hundred million examples having been described in the published chemical literature.[19] Carbon also has the highest sublimation point of all elements. At atmospheric pressure it has no melting point, as its triple point is at 10.8 ± 0.2 megapascals (106.6 ± 2.0 atm; 1,566 ± 29 psi) and 4,600 ± 300 K (4,330 ± 300 °C; 7,820 ± 540 °F),[3][4] so it sublimes at about 3,900 K (3,630 °C; 6,560 °F).[21][22] Graphite is much more reactive than diamond at standard conditions, despite being more thermodynamically stable, as its delocalised pi system is much more vulnerable to attack. For example, graphite can be oxidised by hot concentrated nitric acid at standard conditions to mellitic acid, C6(CO2H)6, which preserves the hexagonal units of graphite while breaking up the larger structure.[23] 10 | 11 | Carbon sublimes in a carbon arc, which has a temperature of about 5800 K (5,530 °C or 9,980 °F). Thus, irrespective of its allotropic form, carbon remains solid at higher temperatures than the highest-melting-point metals such as tungsten or rhenium. Although thermodynamically prone to oxidation, carbon resists oxidation more effectively than elements such as iron and copper, which are weaker reducing agents at room temperature. 12 | 13 | Carbon is the sixth element, with a ground-state electron configuration of 1s22s22p2, of which the four outer electrons are valence electrons. Its first four ionisation energies, 1086.5, 2352.6, 4620.5 and 6222.7 kJ/mol, are much higher than those of the heavier group-14 elements. The electronegativity of carbon is 2.5, significantly higher than the heavier group-14 elements (1.8–1.9), but close to most of the nearby nonmetals, as well as some of the second- and third-row transition metals. Carbon's covalent radii are normally taken as 77.2 pm (C−C), 66.7 pm (C=C) and 60.3 pm (C≡C), although these may vary depending on coordination number and what the carbon is bonded to. In general, covalent radius decreases with lower coordination number and higher bond order.[24] 14 | 15 | Carbon-based compounds form the basis of all known life on Earth, and the carbon-nitrogen-oxygen cycle provides a small portion of the energy produced by the Sun, and most of the energy in larger stars (e.g. Sirius). Although it forms an extraordinary variety of compounds, most forms of carbon are comparatively unreactive under normal conditions. At standard temperature and pressure, it resists all but the strongest oxidizers. It does not react with sulfuric acid, hydrochloric acid, chlorine or any alkalis. At elevated temperatures, carbon reacts with oxygen to form carbon oxides and will rob oxygen from metal oxides to leave the elemental metal. This exothermic reaction is used in the iron and steel industry to smelt iron and to control the carbon content of steel: 16 | 17 | Fe 18 | 3O 19 | 4 + 4 C(s) + 2 O 20 | 2 → 3 Fe(s) + 4 CO 21 | 2(g). 22 | 23 | Carbon reacts with sulfur to form carbon disulfide, and it reacts with steam in the coal-gas reaction used in coal gasification: 24 | 25 | C(s) + H2O(g) → CO(g) + H2(g). 26 | 27 | Carbon combines with some metals at high temperatures to form metallic carbides, such as the iron carbide cementite in steel and tungsten carbide, widely used as an abrasive and for making hard tips for cutting tools. 28 | 29 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Xzy.SK.Api.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Xzy.SK.Api 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 会话总结,标签提取 13 | 14 | 15 | 16 | 17 | 18 | 查询向量 19 | 20 | 21 | 22 | 23 | 24 | 25 | 第1部分:使用ISemanticTextMemory(textMemory)对象存储和检索内存。 26 | 这是一种从代码角度存储内存的简单方法,无需使用内核。 27 | 28 | 29 | 30 | 31 | 32 | 第2部分:创建TextMemoryPlugin,通过内核存储和检索内存。 33 | 这使得语义功能和人工智能(通过规划者)能够访问记忆 34 | 35 | 36 | 37 | 38 | 39 | 第三部分:用语义搜索回忆相似的想法 40 | 使用AI嵌入基于意图而非特定密钥对内存进行模糊查找。 41 | 42 | 43 | 44 | 45 | 46 | TextMemoryPugin在语义函数中的回忆 47 | 渲染提示模板时查找相关内存,然后将渲染的提示发送到 48 | 用于回答自然语言查询的文本完成模型。 49 | 50 | 51 | 52 | 53 | 54 | 聊天上下文 55 | 56 | 57 | 58 | 59 | 60 | SKDemo示例 61 | 62 | 63 | 64 | 65 | 测试Plugins翻译 66 | 67 | 68 | 69 | 70 | 71 | 72 | 测试Plugins计算 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 原生函数测试 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 嵌套函数 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 原生嵌套,通过自然语义先找到最大和最小的2个值,然后用最大值减去最小值得到结果返回 97 | 98 | 99 | 100 | 101 | 102 | 103 | 计划 104 | 105 | 小明有7个冰淇淋,我有2个冰淇淋,他比我多几个冰淇淋? 106 | 小明有7个冰淇淋,我有2个冰淇淋,我们一共有几个冰淇淋? 107 | 108 | 109 | 110 | 111 | 意图识别 112 | 113 | 114 | 115 | 116 | 117 | 118 | 管道 119 | https://learn.microsoft.com/en-us/semantic-kernel/ai-orchestration/plugins/out-of-the-box-plugins?tabs=Csharp#whats-the-ms-graph-connector-kit 120 | 121 | 122 | 123 | 124 | 125 | 文本分块 126 | 127 | 128 | 129 | 130 | 131 | 得到负数 132 | 133 | 134 | 135 | 136 | 137 | 138 | 两个数相减 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 初始化配置文件 151 | 152 | 153 | 154 | 155 | 156 | 初始化模型验证 157 | 158 | 159 | 160 | 161 | 162 | 初始化swagger 163 | 164 | 165 | 166 | 167 | 168 | 注入配置文件 169 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Utils/ConvertUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Xzy.SK.Domain 9 | { 10 | /// 11 | /// 转换工具类 12 | /// 13 | public static class ConvertUtils 14 | { 15 | /// 16 | /// 判断是否为空,为空返回true 17 | /// 18 | /// 19 | /// 20 | public static bool IsNull(this object data) 21 | { 22 | //如果为null 23 | if (data == null) 24 | { 25 | return true; 26 | } 27 | 28 | //如果为"" 29 | if (data.GetType() == typeof(String)) 30 | { 31 | if (string.IsNullOrEmpty(data.ToString().Trim())) 32 | { 33 | return true; 34 | } 35 | } 36 | return false; 37 | } 38 | 39 | /// 40 | /// 判断是否为空,为空返回true 41 | /// 42 | /// 43 | /// 44 | public static bool IsNotNull(this object data) 45 | { 46 | //如果为null 47 | if (data == null) 48 | { 49 | return false; 50 | } 51 | 52 | //如果为"" 53 | if (data.GetType() == typeof(String)) 54 | { 55 | if (string.IsNullOrEmpty(data.ToString().Trim())) 56 | { 57 | return false; 58 | } 59 | } 60 | return true; 61 | } 62 | 63 | /// 64 | /// 判断是否为空,为空返回true 65 | /// 66 | /// 67 | /// 68 | public static bool IsNull(string data) 69 | { 70 | //如果为null 71 | if (data == null) 72 | { 73 | return true; 74 | } 75 | 76 | //如果为"" 77 | if (data.GetType() == typeof(String)) 78 | { 79 | if (string.IsNullOrEmpty(data.ToString().Trim())) 80 | { 81 | return true; 82 | } 83 | } 84 | return false; 85 | } 86 | 87 | /// 88 | /// 将obj类型转换为string 89 | /// 90 | /// 91 | /// 92 | public static string ConvertToString(this object s) 93 | { 94 | if (s == null) 95 | { 96 | return ""; 97 | } 98 | else 99 | { 100 | return Convert.ToString(s); 101 | } 102 | } 103 | 104 | /// 105 | /// object 转int32 106 | /// 107 | /// 108 | /// 109 | public static Int32 ConvertToInt32(this object s) 110 | { 111 | int i = 0; 112 | if (s == null) 113 | { 114 | return 0; 115 | } 116 | else 117 | { 118 | int.TryParse(s.ToString(), out i); 119 | } 120 | return i; 121 | } 122 | 123 | /// 124 | /// object 转int32 125 | /// 126 | /// 127 | /// 128 | public static Int64 ConvertToInt64(this object s) 129 | { 130 | long i = 0; 131 | if (s == null) 132 | { 133 | return 0; 134 | } 135 | else 136 | { 137 | long.TryParse(s.ToString(), out i); 138 | } 139 | return i; 140 | } 141 | 142 | /// 143 | /// 将字符串转double 144 | /// 145 | /// 146 | /// 147 | public static double ConvertToDouble(this object s) 148 | { 149 | double i = 0; 150 | if (s == null) 151 | { 152 | return 0; 153 | } 154 | else 155 | { 156 | double.TryParse(s.ToString(), out i); 157 | } 158 | return i; 159 | } 160 | 161 | /// 162 | /// 转换为datetime类型 163 | /// 164 | /// 165 | /// 166 | public static DateTime ConvertToDateTime(this string s) 167 | { 168 | DateTime dt = new DateTime(); 169 | if (s == null || s == "") 170 | { 171 | return DateTime.Now; 172 | } 173 | DateTime.TryParse(s, out dt); 174 | return dt; 175 | } 176 | 177 | /// 178 | /// 转换为datetime类型的格式字符串 179 | /// 180 | /// 要转换的对象 181 | /// 格式化字符串 182 | /// 183 | public static string ConvertToDateTime(this string s, string y) 184 | { 185 | DateTime dt = new DateTime(); 186 | DateTime.TryParse(s, out dt); 187 | return dt.ToString(y); 188 | } 189 | 190 | 191 | /// 192 | /// 将字符串转换成decimal 193 | /// 194 | /// 195 | /// 196 | public static decimal ConvertToDecimal(this object s) 197 | { 198 | decimal d = 0; 199 | if (s == null || s == "") 200 | { 201 | return 0; 202 | } 203 | 204 | Decimal.TryParse(s.ToString(), out d); 205 | 206 | return d; 207 | 208 | } 209 | /// 210 | /// decimal保留2位小数 211 | /// 212 | public static decimal DecimalFraction(this decimal num) 213 | { 214 | return Convert.ToDecimal(num.ToString("f2")); 215 | } 216 | 217 | 218 | /// 219 | /// 替换html种的特殊字符 220 | /// 221 | /// 222 | /// 223 | public static string ReplaceHtml(this string s) 224 | { 225 | return s.Replace("<", "<").Replace(">", ">").Replace("&", "&").Replace(""", "\""); 226 | } 227 | 228 | /// 229 | /// 流转byte 230 | /// 231 | /// 232 | /// 233 | public static byte[] StreamToByte(this Stream stream) 234 | { 235 | byte[] bytes = new byte[stream.Length]; 236 | stream.Read(bytes, 0, bytes.Length); 237 | // 设置当前流的位置为流的开始 238 | stream.Seek(0, SeekOrigin.Begin); 239 | return bytes; 240 | } 241 | } 242 | } 243 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | 244 | # SQL Server files 245 | *.mdf 246 | *.ldf 247 | *.ndf 248 | 249 | # Business Intelligence projects 250 | *.rdl.data 251 | *.bim.layout 252 | *.bim_*.settings 253 | *.rptproj.rsuser 254 | 255 | # Microsoft Fakes 256 | FakesAssemblies/ 257 | 258 | # GhostDoc plugin setting file 259 | *.GhostDoc.xml 260 | 261 | # Node.js Tools for Visual Studio 262 | .ntvs_analysis.dat 263 | node_modules/ 264 | 265 | # Visual Studio 6 build log 266 | *.plg 267 | 268 | # Visual Studio 6 workspace options file 269 | *.opt 270 | 271 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 272 | *.vbw 273 | 274 | # Visual Studio LightSwitch build output 275 | **/*.HTMLClient/GeneratedArtifacts 276 | **/*.DesktopClient/GeneratedArtifacts 277 | **/*.DesktopClient/ModelManifest.xml 278 | **/*.Server/GeneratedArtifacts 279 | **/*.Server/ModelManifest.xml 280 | _Pvt_Extensions 281 | 282 | # Paket dependency manager 283 | .paket/paket.exe 284 | paket-files/ 285 | 286 | # FAKE - F# Make 287 | .fake/ 288 | 289 | # JetBrains Rider 290 | .idea/ 291 | *.sln.iml 292 | 293 | # CodeRush 294 | .cr/ 295 | 296 | # Python Tools for Visual Studio (PTVS) 297 | __pycache__/ 298 | *.pyc 299 | 300 | # Cake - Uncomment if you are using it 301 | # tools/** 302 | # !tools/packages.config 303 | 304 | # Tabs Studio 305 | *.tss 306 | 307 | # Telerik's JustMock configuration file 308 | *.jmconfig 309 | 310 | # BizTalk build output 311 | *.btp.cs 312 | *.btm.cs 313 | *.odx.cs 314 | *.xsd.cs 315 | 316 | # OpenCover UI analysis results 317 | OpenCover/ 318 | 319 | # Azure Stream Analytics local run output 320 | ASALocalRun/ 321 | 322 | # MSBuild Binary and Structured Log 323 | *.binlog 324 | 325 | # NVidia Nsight GPU debugger configuration file 326 | *.nvuser 327 | 328 | # MFractors (Xamarin productivity tool) working folder 329 | .mfractor/ 330 | /src/Xzy.SK.Api/appsettings.Development.json 331 | .vs 332 | /.semantic-kernel/results/src/Xzy.SK.Api/plugins/Translate 333 | /.semantic-kernel/results/src/Xzy.SK.Api/plugins 334 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Common/Extensions/SugarExtensions.cs: -------------------------------------------------------------------------------- 1 | using NPOI.Util; 2 | using SqlSugar; 3 | using System; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.ComponentModel; 7 | using System.Linq; 8 | using System.Linq.Expressions; 9 | using System.Reflection; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | 13 | namespace Xzy.SK.Domain 14 | { 15 | public static class SugarExtensions 16 | { 17 | 18 | /// 19 | /// 兼容旧的查询参数(尽量使用新的语法,参照下面的Url地址) 20 | /// 新语法地址:https://www.donet5.com/Home/Doc?typeId=2314 21 | /// 22 | /// 23 | /// 24 | /// 查询条件 25 | /// 26 | public static ISugarQueryable Where(this ISugarQueryable queryable, List conditions) 27 | { 28 | if (conditions == null || conditions.Count == 0) 29 | { 30 | return queryable; 31 | } 32 | IEnumerable source2 = conditions.OrderBy(g => g.Prefix); 33 | IEnumerable> enumerable = source2.GroupBy(g => g.Prefix); 34 | foreach (var condition in enumerable) 35 | { 36 | queryable = queryable.WhereUsingConditions(condition); 37 | } 38 | return queryable; 39 | } 40 | 41 | 42 | #region 辅助方法 43 | private static ISugarQueryable WhereUsingConditions(this ISugarQueryable queryable, IGrouping conditions) 44 | { 45 | Expression expression = null; 46 | ParameterExpression parameterExpression = Expression.Parameter(typeof(T), "TEntity"); 47 | foreach (Condition condition in conditions) 48 | { 49 | if (!string.IsNullOrEmpty(Convert.ToString(condition.Value))) 50 | { 51 | if (expression != null) 52 | { 53 | expression = ((condition.Relation == Relation.And) ? Expression.AndAlso(expression, ConditonToExpression(condition, parameterExpression)) : Expression.OrElse(expression, ConditonToExpression(condition, parameterExpression))); 54 | } 55 | else 56 | { 57 | expression = ConditonToExpression(condition, parameterExpression); 58 | } 59 | } 60 | } 61 | if (expression == null) 62 | { 63 | return queryable; 64 | } 65 | 66 | 67 | return queryable.Where(Expression.Lambda>(expression, new ParameterExpression[] 68 | { 69 | parameterExpression 70 | })); 71 | 72 | 73 | } 74 | private static Expression ConditonToExpression(Condition condition, Expression parameter) 75 | { 76 | Expression result = null; 77 | Type typeFromHandle = typeof(T); 78 | PropertyInfo property = typeFromHandle.GetProperty(condition.Field); 79 | Expression expression = Expression.Property(parameter, property); 80 | ICollection collection = condition.Value as ICollection; 81 | Expression expression2; 82 | if (collection == null) 83 | { 84 | expression2 = Expression.ConvertChecked(Expression.Constant(ChangeType(condition.Value, property.PropertyType)), property.PropertyType); 85 | if (property.PropertyType == typeof(string)) 86 | { 87 | expression2 = Expression.Constant(condition.Value, property.PropertyType); 88 | } 89 | } 90 | else 91 | { 92 | IList list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(new Type[] 93 | { 94 | property.PropertyType 95 | })); 96 | foreach (object value in collection) 97 | { 98 | list.Add(Convert.ChangeType(value, property.PropertyType)); 99 | } 100 | expression2 = Expression.Constant(list, list.GetType()); 101 | } 102 | switch (condition.Operator) 103 | { 104 | case Operator.Equal: 105 | result = Expression.Equal(expression, expression2); 106 | break; 107 | case Operator.NotEqual: 108 | result = Expression.NotEqual(expression, expression2); 109 | break; 110 | case Operator.LessThan: 111 | result = Expression.LessThan(expression, expression2); 112 | break; 113 | case Operator.LessThanOrEqual: 114 | result = Expression.LessThanOrEqual(expression, expression2); 115 | break; 116 | case Operator.GreaterThan: 117 | result = Expression.GreaterThan(expression, expression2); 118 | break; 119 | case Operator.GreaterThanOrEqual: 120 | result = Expression.GreaterThanOrEqual(expression, expression2); 121 | break; 122 | case Operator.Like: 123 | result = GenerateLike(expression, expression2); 124 | break; 125 | case Operator.IN: 126 | result = GenerateIn(expression2, expression); 127 | break; 128 | case Operator.NotIN: 129 | result = GenerateNotIn(expression2, expression); 130 | break; 131 | } 132 | return result; 133 | } 134 | 135 | private static Expression GenerateIn(Expression left, Expression right) 136 | { 137 | MethodInfo method = left.Type.GetMethod("Contains"); 138 | return Expression.Call(left, method, new Expression[] 139 | { 140 | right 141 | }); 142 | } 143 | 144 | private static Expression GenerateNotIn(Expression left, Expression right) 145 | { 146 | MethodInfo method = left.Type.GetMethod("Contains"); 147 | return Expression.Not(Expression.Call(left, method, new Expression[] 148 | { 149 | right 150 | })); 151 | } 152 | 153 | 154 | private static Expression GenerateLike(Expression left, Expression right) 155 | { 156 | MethodInfo method = left.Type.GetMethod("Contains"); 157 | return Expression.Call(left, method, new Expression[] 158 | { 159 | right 160 | }); 161 | } 162 | 163 | 164 | private static object ChangeType(object value, Type conversionType) 165 | { 166 | if (value.ToString().Trim() == string.Empty && (typeof(int) == conversionType || typeof(short) == conversionType || typeof(long) == conversionType)) 167 | { 168 | return null; 169 | } 170 | if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 171 | { 172 | if (value.IsNull()) 173 | { 174 | return null; 175 | } 176 | NullableConverter nullableConverter = new NullableConverter(conversionType); 177 | conversionType = nullableConverter.UnderlyingType; 178 | } 179 | else if (conversionType == typeof(Guid)) 180 | { 181 | TypeConverter converter = TypeDescriptor.GetConverter(typeof(Guid)); 182 | return (Guid)converter.ConvertFrom(value); 183 | } 184 | return Convert.ChangeType(value, conversionType); 185 | } 186 | 187 | 188 | 189 | #endregion 190 | 191 | 192 | } 193 | 194 | #region 查询条件 195 | 196 | public class SearchCondition 197 | { 198 | public SearchCondition() 199 | { } 200 | 201 | public List Conditions { get; set; } 202 | public string SortExpression { get; set; } 203 | } 204 | 205 | public class Condition 206 | { 207 | public Condition() 208 | { 209 | 210 | } 211 | 212 | public string Field { get; set; } 213 | public Operator Operator { get; set; } 214 | public int Prefix { get; set; } 215 | public Relation Relation { get; set; } 216 | public object Value { get; set; } 217 | } 218 | 219 | public enum Relation 220 | { 221 | And = 0, 222 | Or = 1, 223 | } 224 | 225 | public enum Operator 226 | { 227 | Equal = 0, 228 | NotEqual = 1, 229 | LessThan = 2, 230 | LessThanOrEqual = 3, 231 | GreaterThan = 4, 232 | GreaterThanOrEqual = 5, 233 | Like = 6, 234 | IN = 7, 235 | NotIN = 8, 236 | } 237 | #endregion 238 | } 239 | -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Startup.cs: -------------------------------------------------------------------------------- 1 | using Xzy.SK.Domain; 2 | using Microsoft.AspNetCore.Builder; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Hosting; 8 | using Microsoft.Extensions.Logging; 9 | using Microsoft.OpenApi.Models; 10 | using Swashbuckle.AspNetCore.SwaggerGen; 11 | using System; 12 | using System.Collections.Generic; 13 | using System.IO; 14 | using System.Linq; 15 | using System.Reflection; 16 | using Xzy.SK.Domain.Common.Map; 17 | using Xzy.SK.Domain.Common.Options; 18 | using FluentValidation.AspNetCore; 19 | using System.Text.Encodings.Web; 20 | using System.Text.Unicode; 21 | using Xzy.SK.Domain.Common.Utils; 22 | using Microsoft.SemanticKernel; 23 | using Microsoft.SemanticKernel.Plugins.Memory; 24 | using System.Net.Http; 25 | 26 | namespace Xzy.SK 27 | { 28 | public class Startup 29 | { 30 | public IHostEnvironment Env { get; set; } 31 | private readonly string Any = "Any"; 32 | 33 | public Startup(IConfiguration configuration, IHostEnvironment env) 34 | { 35 | Configuration = configuration; 36 | Env = env; 37 | } 38 | 39 | public IConfiguration Configuration { get; } 40 | 41 | // This method gets called by the runtime. Use this method to add services to the container. 42 | public void ConfigureServices(IServiceCollection services) 43 | { 44 | services.AddControllers().AddJsonOptions(config => 45 | { 46 | //此设定解决JsonResult中文被编码的问题 47 | config.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All); 48 | 49 | config.JsonSerializerOptions.Converters.Add(new DateTimeConverter()); 50 | config.JsonSerializerOptions.Converters.Add(new DateTimeNullableConvert()); 51 | }); 52 | 53 | //注入配置文件 54 | InitConfig(); 55 | 56 | //反射根据特性依赖注入 57 | services.AddServicesFromAssemblies("Xzy.SK.Domain"); 58 | 59 | //swagger 60 | InitSwagger(services); 61 | //Mapper 62 | services.AddMapper(); 63 | 64 | //允许跨域 65 | services.AddCors(options => options.AddPolicy(Any, 66 | builder => 67 | { 68 | builder.AllowAnyMethod() 69 | .AllowAnyHeader() 70 | .SetIsOriginAllowed(_ => true) 71 | .AllowCredentials(); 72 | })); 73 | //用户service中获取httpcontext 74 | services.AddHttpContextAccessor(); 75 | //初始化模型验证 76 | InitValidation(services); 77 | 78 | InitSK(services); 79 | } 80 | 81 | private static void InitSK(IServiceCollection services) 82 | { 83 | var handler = new OpenAIHttpClientHandler(); 84 | services.AddTransient((serviceProvider) => 85 | { 86 | return Kernel.CreateBuilder() 87 | .AddOpenAIChatCompletion( 88 | modelId: OpenAIOptions.Model, 89 | apiKey: OpenAIOptions.Key, 90 | httpClient: new HttpClient(handler) 91 | ) 92 | .Build(); 93 | }); 94 | } 95 | 96 | /// 97 | /// 初始化模型验证 98 | /// 99 | /// 100 | private static void InitValidation(IServiceCollection services) 101 | { 102 | //模型验证 103 | services.AddControllersWithViews() 104 | .AddFluentValidation(config =>//添加FluentValidation验证 105 | { 106 | //程序集方式添加验证 107 | // config.RegisterValidatorsFromAssemblyContaining(typeof(TMTotalCostGenerateDetailValidation)); 108 | //注入程序集 109 | config.RegisterValidatorsFromAssembly(Assembly.Load(Assembly.GetExecutingAssembly().GetName().Name)); 110 | config.RegisterValidatorsFromAssembly(Assembly.Load(Assembly.GetExecutingAssembly().GetName().Name.Replace("Api", "Domain"))); 111 | //是否与MvcValidation共存,设置为false后将不再执行特性方式的验证 112 | //config.RunDefaultMvcValidationAfterFluentValidationExecutes = false; 113 | }); 114 | //重写模型验证错误 115 | services.Configure(options => 116 | { 117 | options.InvalidModelStateResponseFactory = (context) => 118 | { 119 | var errors = context.ModelState 120 | .Values 121 | .SelectMany(x => x.Errors 122 | .Select(p => p.ErrorMessage)) 123 | .ToList(); 124 | 125 | var result = new 126 | { 127 | code = "400", 128 | message = "Validation errors", 129 | data = errors 130 | }; 131 | 132 | return new BadRequestObjectResult(result); 133 | }; 134 | }); 135 | } 136 | 137 | /// 138 | /// 初始化swagger 139 | /// 140 | /// 141 | private static void InitSwagger(IServiceCollection services) 142 | { 143 | services.AddSwaggerGen(c => 144 | { 145 | c.SwaggerDoc("v1", new OpenApiInfo { Title = "SK API", Version = "v1" }); 146 | //添加Api层注释(true表示显示控制器注释) 147 | var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; 148 | var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); 149 | c.IncludeXmlComments(xmlPath, true); 150 | //添加Domain层注释(true表示显示控制器注释) 151 | var xmlFile1 = $"{Assembly.GetExecutingAssembly().GetName().Name.Replace("Api", "Domain")}.xml"; 152 | var xmlPath1 = Path.Combine(AppContext.BaseDirectory, xmlFile1); 153 | c.IncludeXmlComments(xmlPath1, true); 154 | c.DocInclusionPredicate((docName, apiDes) => 155 | { 156 | if (!apiDes.TryGetMethodInfo(out MethodInfo method)) 157 | return false; 158 | var version = method.DeclaringType.GetCustomAttributes(true).OfType().Select(m => m.GroupName); 159 | if (docName == "v1" && !version.Any()) 160 | return true; 161 | var actionVersion = method.GetCustomAttributes(true).OfType().Select(m => m.GroupName); 162 | if (actionVersion.Any()) 163 | return actionVersion.Any(v => v == docName); 164 | return version.Any(v => v == docName); 165 | }); 166 | c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() 167 | { 168 | Description = "Directly enter bearer {token} in the box below (note that there is a space between bearer and token)", 169 | Name = "Authorization", 170 | In = ParameterLocation.Header, 171 | Type = SecuritySchemeType.ApiKey, 172 | }); 173 | c.AddSecurityRequirement(new OpenApiSecurityRequirement 174 | { 175 | { 176 | new OpenApiSecurityScheme 177 | { 178 | Reference = new OpenApiReference() 179 | { 180 | Id = "Bearer", 181 | Type = ReferenceType.SecurityScheme 182 | } 183 | }, Array.Empty() 184 | } 185 | }); 186 | }); 187 | } 188 | 189 | /// 190 | /// 注入配置文件 191 | /// 192 | private void InitConfig() 193 | { 194 | Configuration.GetSection("OpenAI").Get(); 195 | } 196 | 197 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 198 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider) 199 | { 200 | if (env.IsDevelopment()) 201 | { 202 | app.UseDeveloperExceptionPage(); 203 | } 204 | 205 | //app.UseHttpsRedirection(); 206 | 207 | app.UseRouting(); 208 | 209 | //跨域 210 | app.UseCors(Any); 211 | 212 | app.UseAuthorization(); 213 | 214 | if (!env.IsProduction()) 215 | { 216 | //启用Swagger 217 | app.UseSwagger(); 218 | //配置Swagger UI 219 | app.UseSwaggerUI(c => 220 | { 221 | c.SwaggerEndpoint("/swagger/v1/swagger.json", "SK API"); //注意中间段v1要和上面SwaggerDoc定义的名字保持一致 222 | }); 223 | } 224 | app.UseEndpoints(endpoints => 225 | { 226 | endpoints.MapControllers(); 227 | }); 228 | } 229 | } 230 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/SKDemoController.cs: -------------------------------------------------------------------------------- 1 | using Humanizer; 2 | using Microsoft.AspNetCore.Http; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Microsoft.SemanticKernel; 5 | using Microsoft.SemanticKernel.Planning.Handlebars; 6 | using Microsoft.SemanticKernel.Plugins.Core; 7 | using Newtonsoft.Json; 8 | using RepoUtils; 9 | using System; 10 | using System.IO; 11 | using System.Threading.Tasks; 12 | using Xzy.SK.Api.plugins; 13 | using Xzy.SK.Api.plugins.MathPlugin; 14 | using Xzy.SK.Domain.Common.SK; 15 | 16 | namespace Xzy.SK.Api.Controllers 17 | { 18 | /// 19 | /// SKDemo示例 20 | /// 21 | [Route("api/[controller]/[action]")] 22 | [ApiController] 23 | public class SKDemoController : ControllerBase 24 | { 25 | private readonly Kernel _kernel; 26 | 27 | public SKDemoController(Kernel kernel) 28 | { 29 | _kernel = kernel; 30 | } 31 | 32 | /// 33 | /// 测试Plugins翻译 34 | /// 35 | /// 36 | /// 37 | [HttpPost] 38 | public async Task Translate(string input, string language) 39 | { 40 | //导入本地技能 41 | var writerPlugin = _kernel 42 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "Translate")); 43 | 44 | var result = await _kernel.InvokeAsync( writerPlugin[language],new () { ["input"]= input } ); 45 | 46 | return Ok(result.GetValue()); 47 | } 48 | 49 | /// 50 | /// 测试Plugins计算 51 | /// 52 | /// 53 | /// 54 | /// 55 | [HttpPost] 56 | public async Task Calculate(string num1, string num2) 57 | { 58 | //导入本地技能,多参数 59 | var calculatePlugin = _kernel 60 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "Calculate")); 61 | 62 | var variables = new KernelArguments 63 | { 64 | ["num1"] = num1, 65 | ["num2"] = num2 66 | }; 67 | var result = await _kernel.InvokeAsync(calculatePlugin["Addition"], variables); 68 | 69 | return Ok(result.GetValue()); 70 | } 71 | 72 | /// 73 | /// 原生函数测试 74 | /// 75 | /// 76 | /// 77 | /// 78 | [HttpPost] 79 | public async Task Native(string num1, string num2) 80 | { 81 | //导入原生函数 82 | 83 | var mathPlugin = _kernel.ImportPluginFromObject(new MathSK(), "MathPlugin"); 84 | 85 | var variables = new KernelArguments 86 | { 87 | ["num1"] = num1, 88 | ["num2"] = num2 89 | }; 90 | var result = await _kernel.InvokeAsync( mathPlugin["Subtraction"], variables); 91 | 92 | return Ok(result.GetValue()); 93 | } 94 | 95 | /// 96 | /// 嵌套函数 97 | /// 98 | /// 99 | /// 100 | /// 101 | [HttpPost] 102 | public async Task Nested(string num1, string num2) 103 | { 104 | //嵌套函数使用,在prompty中使用 {{Plugin.Fun}} 可以嵌套调用 105 | 106 | var calculatePlugin = _kernel 107 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "Calculate")); 108 | //MathPlugin Multiplication 中可以嵌套其他函数 109 | var mathPlugin = _kernel.ImportPluginFromObject(new MathSK(), "MathPlugin"); 110 | 111 | var variables = new KernelArguments 112 | { 113 | ["num1"] = num1, 114 | ["num2"] = num2 115 | }; 116 | var result = await _kernel.InvokeAsync( calculatePlugin["Multiplication"], variables); 117 | 118 | return Ok(result.GetValue()); 119 | } 120 | 121 | /// 122 | /// 原生嵌套,通过自然语义先找到最大和最小的2个值,然后用最大值减去最小值得到结果返回 123 | /// 124 | /// 125 | /// 126 | 127 | [HttpPost] 128 | public async Task NativeNested(string msg) 129 | { 130 | var NativeNested = _kernel.ImportPluginFromObject(new NativeNested(_kernel), "NativeNested"); 131 | 132 | var result = await _kernel.InvokeAsync(NativeNested["Test"], new () { ["input"] = msg }); 133 | 134 | return Ok(result.GetValue()); 135 | } 136 | 137 | /// 138 | /// 计划 139 | /// 140 | /// 小明有7个冰淇淋,我有2个冰淇淋,他比我多几个冰淇淋? 141 | /// 小明有7个冰淇淋,我有2个冰淇淋,我们一共有几个冰淇淋? 142 | /// 143 | [HttpPost] 144 | public async Task Plan(string msg) 145 | { 146 | var planner = new HandlebarsPlanner( 147 | new HandlebarsPlannerOptions() 148 | { 149 | // Change this if you want to test with loops regardless of model selection. 150 | AllowLoops = true 151 | }); 152 | var calculatePlugin = _kernel 153 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "Calculate")); 154 | 155 | var plan = await planner.CreatePlanAsync(_kernel,msg); 156 | Console.WriteLine("Plan:\n"); 157 | Console.WriteLine(JsonConvert.SerializeObject(plan)); 158 | 159 | var result = await plan.InvokeAsync(_kernel); 160 | return Ok(result); 161 | } 162 | 163 | /// 164 | /// 意图识别 165 | /// 166 | /// 167 | /// 168 | [HttpPost] 169 | public async Task Intent(string msg) 170 | { 171 | //对话摘要 SK.Skills.Core 核心技能 172 | _kernel.ImportPluginFromObject(new ConversationSummaryPlugin(), "ConversationSummarySkill"); 173 | var intentPlugin = _kernel 174 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "BasePlugin")); 175 | var travelPlugin = _kernel 176 | .ImportPluginFromPromptDirectory(Path.Combine(RepoFiles.SamplePluginsPath(), "Travel")); 177 | 178 | var NativeNested = _kernel.ImportPluginFromObject(new UtilsPlugin(_kernel), "UtilsPlugin"); 179 | var getIntentVariables = new KernelArguments 180 | { 181 | ["input"] = msg, 182 | ["options"] = "Attractions, Delicacy,Traffic,Weather,SendEmail" //给GPT的意图,通过Prompt限定选用这些里面的 183 | }; 184 | string intent = (await _kernel.InvokeAsync( intentPlugin["GetIntent"], getIntentVariables)).GetValue().Trim(); 185 | KernelFunction MathFunction; 186 | //获取意图后动态调用Fun 187 | switch (intent) 188 | { 189 | case "Attractions": 190 | MathFunction = _kernel.Plugins.GetFunction("Travel", "Attractions"); 191 | break; 192 | 193 | case "Delicacy": 194 | MathFunction = _kernel.Plugins.GetFunction("Travel", "Delicacy"); 195 | break; 196 | 197 | case "Traffic": 198 | MathFunction = _kernel.Plugins.GetFunction("Travel", "Traffic"); 199 | break; 200 | 201 | case "Weather": 202 | MathFunction = _kernel.Plugins.GetFunction("Travel", "Weather"); 203 | break; 204 | 205 | case "SendEmail": 206 | KernelArguments sendEmailVariables = new () 207 | { 208 | ["input"] = msg, 209 | ["example"] = JsonConvert.SerializeObject(new { send_user = "xzy", receiver_user = "xzy", body = "hello" }) 210 | }; 211 | msg = (await _kernel.InvokeAsync( intentPlugin["JSON"], sendEmailVariables)).GetValue(); 212 | MathFunction = _kernel.Plugins.GetFunction("UtilsPlugin", "SendEmail"); 213 | break; 214 | 215 | default: 216 | return Ok("对不起我不知道"); 217 | } 218 | var result = await _kernel.InvokeAsync( MathFunction,new KernelArguments() { ["input"]= msg } ); 219 | 220 | return Ok(result.GetValue()); 221 | } 222 | 223 | /// 224 | /// 管道 225 | /// https://learn.microsoft.com/en-us/semantic-kernel/ai-orchestration/plugins/out-of-the-box-plugins?tabs=Csharp#whats-the-ms-graph-connector-kit 226 | /// 227 | /// 228 | [HttpPost] 229 | public async Task Pipeline() 230 | { 231 | var myText = _kernel.ImportPluginFromObject(new TextPlugin()); 232 | KernelFunction pipeline = KernelFunctionCombinators.Pipe(new[] 233 | { 234 | myText["TrimStart"],//清除左边空格 235 | myText["TrimEnd"],//清除右边空格 236 | myText["Uppercase"] 237 | }, "pipeline"); 238 | //管道模式的顺序调用 239 | var myOutput = await pipeline.InvokeAsync( 240 | _kernel,new KernelArguments() { ["input"]= " i n f i n i t e s p a c e " });//转大写 241 | 242 | return Ok(myOutput.GetValue()); 243 | } 244 | } 245 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Api/Controllers/SK/MemoryStoreController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.SemanticKernel; 4 | using Microsoft.SemanticKernel.Connectors.OpenAI; 5 | using Microsoft.SemanticKernel.Memory; 6 | using Microsoft.SemanticKernel.Plugins.Memory; 7 | using NPOI.POIFS.FileSystem; 8 | using System; 9 | using System.Collections; 10 | using System.Collections.Generic; 11 | using System.IO; 12 | using System.Net.Http; 13 | using System.Threading; 14 | using System.Threading.Tasks; 15 | using Xzy.SK.Domain.Common.Model; 16 | using Xzy.SK.Domain.Common.Options; 17 | using Xzy.SK.Domain.Common.Utils; 18 | 19 | namespace Xzy.SK.Api.Controllers 20 | { 21 | [Route("api/[controller]/[action]")] 22 | [ApiController] 23 | public class MemoryStoreController : ControllerBase 24 | { 25 | private readonly Kernel _kernel; 26 | 27 | public MemoryStoreController(Kernel kernel) 28 | { 29 | _kernel = kernel; 30 | } 31 | 32 | /// 33 | /// 查询向量 34 | /// 35 | /// 36 | /// 37 | [HttpPost] 38 | public async Task MemoryStore(string text) 39 | { 40 | var handler = new OpenAIHttpClientHandler(); 41 | //创建embedding实例 42 | var memoryWithCustomDb = new MemoryBuilder() 43 | .WithOpenAITextEmbeddingGeneration("text-embedding-ada-002", OpenAIOptions.Key, httpClient: new HttpClient(handler)) 44 | .WithMemoryStore(new VolatileMemoryStore()) 45 | .Build(); 46 | 47 | //支持的vector-db 48 | //https://learn.microsoft.com/en-us/semantic-kernel/memories/vector-db 49 | 50 | var bilibiliFiles = BiliBiliData(); 51 | var i = 0; 52 | foreach (var entry in bilibiliFiles) 53 | { 54 | await memoryWithCustomDb.SaveReferenceAsync( 55 | collection: "BiliBili", 56 | externalSourceName: "BiliBili", 57 | externalId: entry.Key, 58 | description: entry.Value, 59 | text: entry.Value); 60 | 61 | Console.Write($" #{++i} 保存成功."); 62 | } 63 | 64 | var memories = memoryWithCustomDb.SearchAsync("BiliBili", text, limit: 2, minRelevanceScore: 0.5); 65 | 66 | string result = ""; 67 | await foreach (MemoryQueryResult memory in memories) 68 | { 69 | result += $"Id:{memory.Metadata.Id},Description:{memory.Metadata.Description},Relevance:{memory.Relevance}\n"; 70 | } 71 | 72 | return Ok(result); 73 | } 74 | 75 | private Dictionary BiliBiliData() 76 | { 77 | return new Dictionary 78 | { 79 | ["https://www.bilibili.com/video/BV1sr4y1f7zb/"] 80 | = "SK 插件Plugins及VSCode调试工具", 81 | ["https://www.bilibili.com/video/BV1Hw411Y71S"] 82 | = "SK 原生函数使用方法", 83 | ["https://www.bilibili.com/video/BV1zF411m7YA/"] 84 | = "SK 嵌套函数使用方法", 85 | ["https://www.bilibili.com/video/BV1F841117Jc/"] 86 | = "SK 原生函数及嵌套函数串联使用方法", 87 | ["https://www.bilibili.com/video/BV12j41187GX/"] 88 | = "SK Plan流程编排", 89 | ["https://www.bilibili.com/video/BV1nm4y1V7dz/"] 90 | = "SK 意图识别、json提取", 91 | ["https://www.bilibili.com/video/BV1Qj41147i6/"] 92 | = "SK 依赖注入、Pipeline" 93 | }; 94 | } 95 | 96 | /// 97 | /// 第1部分:使用ISemanticTextMemory(textMemory)对象存储和检索内存。 98 | ///这是一种从代码角度存储内存的简单方法,无需使用内核。 99 | /// 100 | /// 101 | [HttpPost] 102 | public async Task TextMemory1() 103 | { 104 | IMemoryStore memoryStore = new VolatileMemoryStore(); 105 | var handler = new OpenAIHttpClientHandler(); 106 | var embeddingGenerator = new OpenAITextEmbeddingGenerationService("text-embedding-ada-002", OpenAIOptions.Key, httpClient: new HttpClient(handler)); 107 | 108 | SemanticTextMemory textMemory = new(memoryStore, embeddingGenerator); 109 | 110 | await textMemory.SaveInformationAsync("Xzy", id: "info1", text: "我的名字是许泽宇", cancellationToken: default); 111 | await textMemory.SaveInformationAsync("Xzy", id: "info2", text: "我的职位是架构师", cancellationToken: default); 112 | await textMemory.SaveInformationAsync("Xzy", id: "info3", text: "我有13年工作经验", cancellationToken: default); 113 | await textMemory.SaveInformationAsync("Xzy", id: "info4", text: "我擅长.Net Core、微服务、云原生、AI", cancellationToken: default); 114 | 115 | var memoryPlugin = new TextMemoryPlugin(textMemory); 116 | var memoryFunctions = _kernel.ImportPluginFromObject(memoryPlugin); 117 | MemoryQueryResult? lookup = await textMemory.GetAsync("Xzy", "info1", cancellationToken: default); 118 | Console.WriteLine(" 'info1':" + lookup?.Metadata.Text ?? "ERROR: memory 没找到"); 119 | 120 | return Ok(); 121 | } 122 | 123 | /// 124 | ///第2部分:创建TextMemoryPlugin,通过内核存储和检索内存。 125 | ///这使得语义功能和人工智能(通过规划者)能够访问记忆 126 | /// 127 | /// 128 | [HttpPost] 129 | public async Task TextMemory2() 130 | { 131 | IMemoryStore memoryStore = new VolatileMemoryStore(); 132 | //AzureOpenAITextEmbeddingGenerationService 133 | var handler = new OpenAIHttpClientHandler(); 134 | var embeddingGenerator = new OpenAITextEmbeddingGenerationService("text-embedding-ada-002", OpenAIOptions.Key, httpClient: new HttpClient(handler)); 135 | 136 | SemanticTextMemory textMemory = new(memoryStore, embeddingGenerator); 137 | var memoryPlugin = new TextMemoryPlugin(textMemory); 138 | var memoryFunctions = _kernel.ImportPluginFromObject(memoryPlugin); 139 | await _kernel.InvokeAsync(memoryFunctions["Save"], new() 140 | { 141 | [TextMemoryPlugin.CollectionParam] = "Xzy", 142 | [TextMemoryPlugin.KeyParam] = "info1", 143 | ["input"] = "我的名字是许泽宇" 144 | }, cancellationToken: default); 145 | var result = await _kernel.InvokeAsync(memoryFunctions["Retrieve"], new() 146 | { 147 | [TextMemoryPlugin.CollectionParam] = "Xzy", 148 | [TextMemoryPlugin.KeyParam] = "info1" 149 | }, cancellationToken: default); 150 | return Ok(result.GetValue()); 151 | } 152 | 153 | /// 154 | ///第三部分:用语义搜索回忆相似的想法 155 | ///使用AI嵌入基于意图而非特定密钥对内存进行模糊查找。 156 | /// 157 | /// 158 | [HttpPost] 159 | public async Task TextMemory3() 160 | { 161 | IMemoryStore memoryStore = new VolatileMemoryStore(); 162 | var handler = new OpenAIHttpClientHandler(); 163 | var embeddingGenerator = new OpenAITextEmbeddingGenerationService("text-embedding-ada-002", OpenAIOptions.Key, httpClient: new HttpClient(handler)); 164 | 165 | SemanticTextMemory textMemory = new(memoryStore, embeddingGenerator); 166 | await textMemory.SaveInformationAsync("Xzy", id: "info1", text: "我的名字是许泽宇", cancellationToken: default); 167 | await textMemory.SaveInformationAsync("Xzy", id: "info2", text: "我的职位是架构师", cancellationToken: default); 168 | await textMemory.SaveInformationAsync("Xzy", id: "info3", text: "我有13年工作经验", cancellationToken: default); 169 | await textMemory.SaveInformationAsync("Xzy", id: "info4", text: "我擅长.Net Core、微服务、云原生、AI", cancellationToken: default); 170 | 171 | await foreach (var answer in textMemory.SearchAsync( 172 | collection: "Xzy", 173 | query: "我叫什么名字?", 174 | limit: 2, 175 | minRelevanceScore: 0.79, 176 | withEmbeddings: true, 177 | cancellationToken: default)) 178 | { 179 | Console.WriteLine($"Answer: {answer.Metadata.Text} "); 180 | } 181 | return Ok(); 182 | } 183 | 184 | private const string RecallFunctionDefinition = @" 185 | 回答问题时只考虑以下事实: 186 | 开始事实 187 | 关于我: {{Recall '我在哪里长大的?'}} 188 | 关于我: {{Recall '我现在住在哪里?'}} 189 | 结束事实 190 | 191 | 问题: {{$input}} 192 | 193 | 答案: 194 | "; 195 | 196 | /// 197 | ///TextMemoryPugin在语义函数中的回忆 198 | ///渲染提示模板时查找相关内存,然后将渲染的提示发送到 199 | ///用于回答自然语言查询的文本完成模型。 200 | /// 201 | /// 202 | [HttpPost] 203 | public async Task TextMemory4() 204 | { 205 | IMemoryStore memoryStore = new VolatileMemoryStore(); 206 | var handler = new OpenAIHttpClientHandler(); 207 | var embeddingGenerator = new OpenAITextEmbeddingGenerationService("text-embedding-ada-002", OpenAIOptions.Key, httpClient: new HttpClient(handler)); 208 | 209 | SemanticTextMemory textMemory = new(memoryStore, embeddingGenerator); 210 | 211 | await textMemory.SaveInformationAsync("Xzy", id: "info1", text: "我的名字是许泽宇", cancellationToken: default); 212 | await textMemory.SaveInformationAsync("Xzy", id: "info2", text: "我的职位是架构师", cancellationToken: default); 213 | await textMemory.SaveInformationAsync("Xzy", id: "info3", text: "我有13年工作经验", cancellationToken: default); 214 | await textMemory.SaveInformationAsync("Xzy", id: "info4", text: "我擅长.Net Core、微服务、云原生、AI", cancellationToken: default); 215 | await textMemory.SaveInformationAsync("Xzy", id: "info5", text: "我住在武汉", cancellationToken: default); 216 | var memoryPlugin = new TextMemoryPlugin(textMemory); 217 | var memoryFunctions = _kernel.ImportPluginFromObject(memoryPlugin); 218 | var aboutMeOracle = _kernel.CreateFunctionFromPrompt(RecallFunctionDefinition, new OpenAIPromptExecutionSettings() { MaxTokens = 100 }); 219 | 220 | var result = await _kernel.InvokeAsync(aboutMeOracle, new KernelArguments() 221 | { 222 | [TextMemoryPlugin.CollectionParam] = "Xzy", 223 | [TextMemoryPlugin.RelevanceParam] = "0.79", 224 | [TextMemoryPlugin.LimitParam] = "2", 225 | [TextMemoryPlugin.InputParam] = "我住在哪里?" 226 | }, cancellationToken: default); 227 | return Ok(result.GetValue()); 228 | } 229 | } 230 | } -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Repositories/Base/Repository.cs: -------------------------------------------------------------------------------- 1 | using Xzy.SK.Domain.Common.Model; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Options; 4 | using SqlSugar; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Configuration; 8 | using System.Linq; 9 | using System.Linq.Expressions; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Xzy.SK.Domain.Repositories.Base; 13 | using Xzy.SK.Domain.Common.Map; 14 | 15 | 16 | namespace Xzy.SK.Domain.Repositories 17 | { 18 | public class Repository : SimpleClient where T : class, new() 19 | { 20 | public Repository(ISqlSugarClient context = null) : base(context)//注意这里要有默认值等于null 21 | { 22 | if (context == null) 23 | { 24 | 25 | } 26 | } 27 | 28 | //注意:如果使用Client不能写成静态的,Scope并发更高 29 | public static SqlSugarScope SqlServerDb = SqlSugarHelper.SqlServerDb; 30 | 31 | public SimpleClient CurrentDb { get { return new SimpleClient(SqlServerDb); } }//用来处理T表的常用操作 32 | 33 | 34 | 35 | #region 通用方法 36 | 37 | public virtual SqlSugarScope GetDB() 38 | { 39 | return SqlServerDb; 40 | } 41 | /// 42 | /// 获取所有list 43 | /// 44 | /// 45 | public virtual List GetList() 46 | { 47 | return CurrentDb.GetList(); 48 | } 49 | /// 50 | /// 获取所有list-异步 51 | /// 52 | /// 53 | public virtual async Task> GetListAsync() 54 | { 55 | return await CurrentDb.GetListAsync(); 56 | } 57 | 58 | /// 59 | /// 根据lambda查询 60 | /// 61 | /// 62 | /// 63 | public virtual List GetList(Expression> whereExpression) 64 | { 65 | return CurrentDb.GetList(whereExpression); 66 | } 67 | /// 68 | /// 根据lambda查询-异步 69 | /// 70 | /// 71 | /// 72 | public virtual async Task> GetListAsync(Expression> whereExpression) 73 | { 74 | 75 | return await CurrentDb.GetListAsync(whereExpression); 76 | } 77 | /// 78 | /// 根据lambda表达式获取数量 79 | /// 80 | /// 81 | /// 82 | public virtual int Count(Expression> whereExpression) 83 | { 84 | return CurrentDb.Count(whereExpression); 85 | } 86 | /// 87 | /// 根据lambda表达式获取数量-异步 88 | /// 89 | /// 90 | /// 91 | public virtual async Task CountAsync(Expression> whereExpression) 92 | { 93 | return await CurrentDb.CountAsync(whereExpression); 94 | } 95 | /// 96 | /// 获取分页 97 | /// 98 | /// 99 | /// 100 | /// 101 | public virtual PageList GetPageList(Expression> whereExpression, PageModel page) 102 | { 103 | PageList list = new PageList(); 104 | list.List= CurrentDb.GetPageList(whereExpression, page); 105 | list.PageIndex = page.PageIndex; 106 | list.PageSize = page.PageSize; 107 | list.TotalCount = page.TotalCount; 108 | return list; 109 | } 110 | public virtual PageList

GetPageList

(Expression> whereExpression, PageModel page) 111 | { 112 | var result = CurrentDb.GetPageList(whereExpression, page); 113 | var pageData = new PageList

114 | { 115 | TotalCount = page.TotalCount, 116 | PageIndex = page.PageIndex, 117 | PageSize = page.PageSize, 118 | List = result.ToDTOList

() 119 | }; 120 | return pageData; 121 | } 122 | 123 | ///

124 | /// 获取分页-异步 125 | /// 126 | /// 127 | /// 128 | /// 129 | public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page) 130 | { 131 | PageList list = new PageList(); 132 | list.List = await CurrentDb.GetPageListAsync(whereExpression, page); 133 | list.PageIndex = page.PageIndex; 134 | list.PageSize = page.PageSize; 135 | list.TotalCount = page.TotalCount; 136 | return list; 137 | } 138 | 139 | public virtual async Task> GetPageListAsync

(Expression> whereExpression, PageModel page) 140 | { 141 | var result = await CurrentDb.GetPageListAsync(whereExpression, page); 142 | var pageData = new PageList

143 | { 144 | TotalCount = page.TotalCount, 145 | PageIndex = page.PageIndex, 146 | PageSize = page.PageSize, 147 | List = result.ToDTOList

() 148 | }; 149 | return pageData; 150 | } 151 | 152 | 153 | public virtual PageList GetPageList(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 154 | { 155 | PageList list = new PageList(); 156 | list.List = CurrentDb.GetPageList(whereExpression, page, orderByExpression, orderByType); 157 | list.PageIndex = page.PageIndex; 158 | list.PageSize = page.PageSize; 159 | list.TotalCount = page.TotalCount; 160 | return list; 161 | } 162 | public virtual async Task> GetPageListAsync(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 163 | { 164 | PageList list = new PageList(); 165 | list.List = await CurrentDb.GetPageListAsync(whereExpression, page, orderByExpression, orderByType); 166 | list.PageIndex = page.PageIndex; 167 | list.PageSize = page.PageSize; 168 | list.TotalCount = page.TotalCount; 169 | return list; 170 | } 171 | public virtual PageList

GetPageList

(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 172 | { 173 | var result = CurrentDb.GetPageList(whereExpression, page, orderByExpression, orderByType); 174 | var pageData = new PageList

175 | { 176 | TotalCount = page.TotalCount, 177 | PageIndex = page.PageIndex, 178 | PageSize = page.PageSize, 179 | List = result.ToDTOList

() 180 | }; 181 | return pageData; 182 | } 183 | 184 | public virtual async Task> GetPageListAsync

(Expression> whereExpression, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 185 | { 186 | var result = await CurrentDb.GetPageListAsync(whereExpression, page, orderByExpression, orderByType); 187 | var pageData = new PageList

188 | { 189 | TotalCount = page.TotalCount, 190 | PageIndex = page.PageIndex, 191 | PageSize = page.PageSize, 192 | List = result.ToDTOList

() 193 | }; 194 | return pageData; 195 | } 196 | 197 | public virtual PageList GetPageList(List conditionalList, PageModel page) 198 | { 199 | PageList list = new PageList(); 200 | list.List = CurrentDb.GetPageList(conditionalList, page); 201 | list.PageIndex = page.PageIndex; 202 | list.PageSize = page.PageSize; 203 | list.TotalCount = page.TotalCount; 204 | return list; 205 | } 206 | public virtual async Task> GetPageListAsync(List conditionalList, PageModel page) 207 | { 208 | PageList list = new PageList(); 209 | list.List = await CurrentDb.GetPageListAsync(conditionalList, page); 210 | list.PageIndex = page.PageIndex; 211 | list.PageSize = page.PageSize; 212 | list.TotalCount = page.TotalCount; 213 | return list; 214 | } 215 | 216 | public virtual PageList GetPageList(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 217 | { 218 | PageList list = new PageList(); 219 | list.List = CurrentDb.GetPageList(conditionalList, page, orderByExpression, orderByType); 220 | list.PageIndex = page.PageIndex; 221 | list.PageSize = page.PageSize; 222 | list.TotalCount = page.TotalCount; 223 | return list; 224 | } 225 | public virtual async Task> GetPageListAsync(List conditionalList, PageModel page, Expression> orderByExpression = null, OrderByType orderByType = OrderByType.Asc) 226 | { 227 | PageList list = new PageList(); 228 | list.List = await CurrentDb.GetPageListAsync(conditionalList, page, orderByExpression,orderByType); 229 | list.PageIndex = page.PageIndex; 230 | list.PageSize = page.PageSize; 231 | list.TotalCount = page.TotalCount; 232 | return list; 233 | } 234 | 235 | ///

236 | /// 根据id获取实体 237 | /// 238 | /// 239 | /// 240 | public virtual T GetById(dynamic id) 241 | { 242 | return CurrentDb.GetById(id); 243 | } 244 | /// 245 | /// 根据id获取实体-异步 246 | /// 247 | /// 248 | /// 249 | public virtual async Task GetByIdAsync(dynamic id) 250 | { 251 | return await CurrentDb.GetByIdAsync(id); 252 | } 253 | /// 254 | /// 根据lambda获取单个对象 (注意,需要确保唯一,如果获取到2个会报错,这种场景需要使用GetFirst) 255 | /// 256 | /// 257 | /// 258 | public virtual T GetSingle(Expression> whereExpression) 259 | { 260 | return CurrentDb.GetSingle(whereExpression); //Db.Queryable().First(whereExpression); 261 | } 262 | 263 | /// 264 | /// 根据lambda获取单个对象-异步 (注意,需要确保唯一,如果获取到2个会报错,这种场景需要使用GetFirst) 265 | /// 266 | /// 267 | /// 268 | public virtual async Task GetSingleAsync(Expression> whereExpression) 269 | { 270 | return await CurrentDb.GetSingleAsync(whereExpression); //await Db.Queryable().FirstAsync(whereExpression); 271 | } 272 | 273 | /// 274 | /// 根据lambda获取单个对象 275 | /// 276 | /// 277 | /// 278 | public virtual T GetFirst(Expression> whereExpression) 279 | { 280 | return GetDB().Queryable().First(whereExpression); 281 | } 282 | 283 | /// 284 | /// 根据lambda获取单个对象 --异步 285 | /// 286 | /// 287 | /// 288 | public virtual async Task GetFirstAsync(Expression> whereExpression) 289 | { 290 | return await GetDB().Queryable().FirstAsync(whereExpression); 291 | } 292 | 293 | /// 294 | /// 实体插入 295 | /// 296 | /// 297 | /// 298 | public virtual bool Insert(T obj) 299 | { 300 | return CurrentDb.Insert(obj); 301 | } 302 | 303 | /// 304 | /// 实体插入-异步 305 | /// 306 | /// 307 | /// 308 | public virtual async Task InsertAsync(T obj) 309 | { 310 | return await CurrentDb.InsertAsync(obj); 311 | } 312 | 313 | /// 314 | /// 批量插入 315 | /// 316 | /// 317 | /// 318 | public virtual bool InsertRange(List objs) 319 | { 320 | return CurrentDb.InsertRange(objs); 321 | } 322 | /// 323 | /// 批量插入-异步 324 | /// 325 | /// 326 | /// 327 | public virtual async Task InsertRangeAsync(List objs) 328 | { 329 | return await CurrentDb.InsertRangeAsync(objs); 330 | } 331 | 332 | /// 333 | /// 插入返回自增列 334 | /// 335 | /// 336 | /// 337 | public virtual int InsertReturnIdentity(T obj) 338 | { 339 | return CurrentDb.InsertReturnIdentity(obj); 340 | } 341 | /// 342 | /// 插入返回自增列-异步 343 | /// 344 | /// 345 | /// 346 | public virtual async Task InsertReturnIdentityAsync(T obj) 347 | { 348 | return await CurrentDb.InsertReturnIdentityAsync(obj); 349 | } 350 | 351 | /// 352 | /// 插入返回longid 353 | /// 354 | /// 355 | /// 356 | public virtual long InsertReturnBigIdentity(T obj) 357 | { 358 | return CurrentDb.InsertReturnBigIdentity(obj); 359 | } 360 | /// 361 | /// 插入返回longid-异步 362 | /// 363 | /// 364 | /// 365 | public virtual async Task InsertReturnBigIdentityAsync(T obj) 366 | { 367 | return await CurrentDb.InsertReturnBigIdentityAsync(obj); 368 | } 369 | 370 | /// 371 | /// 批量删除 372 | /// 373 | /// 374 | /// 375 | public virtual bool DeleteByIds(dynamic[] ids) 376 | { 377 | return CurrentDb.DeleteByIds(ids); 378 | } 379 | 380 | /// 381 | /// 批量删除-异步 382 | /// 383 | /// 384 | /// 385 | public virtual async Task DeleteByIdsAsync(dynamic[] ids) 386 | { 387 | return await CurrentDb.DeleteByIdsAsync(ids); 388 | } 389 | 390 | /// 391 | /// 根据主键删除 392 | /// 393 | /// 394 | /// 395 | public virtual bool Delete(dynamic id) 396 | { 397 | return CurrentDb.DeleteById(id); 398 | } 399 | 400 | /// 401 | /// 根据主键删除-异步 402 | /// 403 | /// 404 | /// 405 | public virtual async Task DeleteAsync(dynamic id) 406 | { 407 | return await CurrentDb.DeleteByIdAsync(id); 408 | } 409 | 410 | /// 411 | /// 根据实体删除 412 | /// 413 | /// 414 | /// 415 | public virtual bool Delete(T obj) 416 | { 417 | return CurrentDb.Delete(obj); 418 | } 419 | 420 | /// 421 | /// 根据实体删除-异步 422 | /// 423 | /// 424 | /// 425 | public virtual async Task DeleteAsync(T obj) 426 | { 427 | return await CurrentDb.DeleteAsync(obj); 428 | } 429 | 430 | /// 431 | /// 根据表达式删除 432 | /// 433 | /// 434 | /// 435 | public virtual bool Delete(Expression> whereExpression) 436 | { 437 | return CurrentDb.Delete(whereExpression); 438 | } 439 | 440 | /// 441 | /// 根据表达式删除-异步 442 | /// 443 | /// 444 | /// 445 | public virtual async Task DeleteAsync(Expression> whereExpression) 446 | { 447 | return await CurrentDb.DeleteAsync(whereExpression); 448 | } 449 | 450 | 451 | /// 452 | /// 更新 453 | /// 454 | /// 455 | /// 456 | public virtual bool Update(T obj) 457 | { 458 | return CurrentDb.Update(obj); 459 | } 460 | /// 461 | /// 更新-异步 462 | /// 463 | /// 464 | /// 465 | public virtual async Task UpdateAsync(T obj) 466 | { 467 | return await CurrentDb.UpdateAsync(obj); 468 | } 469 | 470 | /// 471 | /// 批量更新 472 | /// 473 | /// 474 | /// 475 | public virtual bool UpdateRange(List objs) 476 | { 477 | return CurrentDb.UpdateRange(objs); 478 | } 479 | 480 | /// 481 | /// 批量更新-异步 482 | /// 483 | /// 484 | /// 485 | public virtual async Task UpdateRangeAsync(List objs) 486 | { 487 | return await CurrentDb.UpdateRangeAsync(objs); 488 | } 489 | 490 | /// 491 | /// 是否包含元素 492 | /// 493 | /// 494 | /// 495 | public virtual bool IsAny(Expression> whereExpression) 496 | { 497 | return CurrentDb.IsAny(whereExpression); 498 | } 499 | /// 500 | /// 是否包含元素-异步 501 | /// 502 | /// 503 | /// 504 | public virtual async Task IsAnyAsync(Expression> whereExpression) 505 | { 506 | return await CurrentDb.IsAnyAsync(whereExpression); 507 | } 508 | #endregion 509 | } 510 | } 511 | -------------------------------------------------------------------------------- /src/Xzy.SK.Domain/Xzy.SK.Domain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Xzy.SK.Domain 5 | 6 | 7 | 8 | 9 | 容器扩展 10 | 11 | 12 | 13 | 14 | 从程序集中加载类型并添加到容器中 15 | 16 | 容器 17 | 程序集集合 18 | 19 | 20 | 21 | 22 | 作用域 23 | 24 | 25 | 26 | 27 | 单例 28 | 29 | 30 | 31 | 32 | 瞬时 33 | 34 | 35 | 36 | 37 | 将excel导入到datatable 38 | 39 | excel路径 40 | 第一行是否是列名 41 | 返回datatable 42 | 43 | 44 | 45 | 将excel导入到datatable 46 | 47 | 流 48 | 第一行是否是列名 49 | 50 | 51 | 52 | 53 | excel转list 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | excel转list-根据sheetName得到List 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | List导出excel 二进制流 71 | 72 | 实体 73 | List 74 | sheetname 可不填,默认Sheet0 75 | 76 | 77 | 78 | 79 | Dt导出excel 二进制流 80 | 81 | datatable 82 | strFile 83 | 84 | 85 | 86 | 87 | List写入excel 88 | 89 | 90 | 91 | 路径 92 | 93 | 94 | 95 | 96 | 97 | dt写入excel 98 | 99 | datatable 100 | 路径 101 | 102 | 103 | 104 | 105 | Entity集合转DTO集合 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | Entity转DTO 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 给已有对象map,适合update场景,如需过滤空值需要在AutoMapProfile 设置 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 返回分页结果 131 | 132 | 133 | 134 | 135 | 当前页,从1开始 136 | 137 | 138 | 139 | 140 | 每页数量 141 | 142 | 143 | 144 | 145 | 总数 146 | 147 | 148 | 149 | 150 | 错误码,0是正常返回,异常返回错误码 151 | 152 | 153 | 154 | 155 | 返回数据 156 | 157 | 158 | 159 | 160 | 返回信息详情 161 | 162 | 163 | 164 | 165 | 执行成功 166 | 167 | 168 | 169 | 170 | 171 | 执行成功 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 执行失败 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 执行失败 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | Invokes a pipeline of functions, running each in order and passing the output from one as the first argument to the next. 198 | 199 | The pipeline of functions to invoke. 200 | The kernel to use for the operations. 201 | The arguments. 202 | The cancellation token to monitor for a cancellation request. 203 | 204 | 205 | 206 | 207 | Invokes a pipeline of functions, running each in order and passing the output from one as the named argument to the next. 208 | 209 | The sequence of functions to invoke, along with the name of the argument to assign to the result of the function's invocation. 210 | The kernel to use for the operations. 211 | The arguments. 212 | The cancellation token to monitor for a cancellation request. 213 | 214 | 215 | 216 | 217 | Creates a function whose invocation will invoke each of the supplied functions in sequence. 218 | 219 | The pipeline of functions to invoke. 220 | The name of the combined operation. 221 | The description of the combined operation. 222 | The result of the final function. 223 | 224 | The result from one function will be fed into the first argument of the next function. 225 | 226 | 227 | 228 | 229 | Creates a function whose invocation will invoke each of the supplied functions in sequence. 230 | 231 | The pipeline of functions to invoke, along with the name of the argument to assign to the result of the function's invocation. 232 | The name of the combined operation. 233 | The description of the combined operation. 234 | The result of the final function. 235 | 236 | The result from one function will be fed into the first argument of the next function. 237 | 238 | 239 | 240 | 241 | 兼容旧的查询参数(尽量使用新的语法,参照下面的Url地址) 242 | 新语法地址:https://www.donet5.com/Home/Doc?typeId=2314 243 | 244 | 245 | 246 | 查询条件 247 | 248 | 249 | 250 | 251 | 转换工具类 252 | 253 | 254 | 255 | 256 | 判断是否为空,为空返回true 257 | 258 | 259 | 260 | 261 | 262 | 263 | 判断是否为空,为空返回true 264 | 265 | 266 | 267 | 268 | 269 | 270 | 判断是否为空,为空返回true 271 | 272 | 273 | 274 | 275 | 276 | 277 | 将obj类型转换为string 278 | 279 | 280 | 281 | 282 | 283 | 284 | object 转int32 285 | 286 | 287 | 288 | 289 | 290 | 291 | object 转int32 292 | 293 | 294 | 295 | 296 | 297 | 298 | 将字符串转double 299 | 300 | 301 | 302 | 303 | 304 | 305 | 转换为datetime类型 306 | 307 | 308 | 309 | 310 | 311 | 312 | 转换为datetime类型的格式字符串 313 | 314 | 要转换的对象 315 | 格式化字符串 316 | 317 | 318 | 319 | 320 | 将字符串转换成decimal 321 | 322 | 323 | 324 | 325 | 326 | 327 | decimal保留2位小数 328 | 329 | 330 | 331 | 332 | 替换html种的特殊字符 333 | 334 | 335 | 336 | 337 | 338 | 339 | 流转byte 340 | 341 | 342 | 343 | 344 | 345 | 346 | 生成实体类 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 获取所有list 355 | 356 | 357 | 358 | 359 | 360 | 获取所有list-异步 361 | 362 | 363 | 364 | 365 | 366 | 根据lambda查询 367 | 368 | 369 | 370 | 371 | 372 | 373 | 根据lambda查询-异步 374 | 375 | 376 | 377 | 378 | 379 | 380 | 根据lambda表达式获取数量 381 | 382 | 383 | 384 | 385 | 386 | 387 | 根据lambda表达式获取数量-异步 388 | 389 | 390 | 391 | 392 | 393 | 394 | 获取分页 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 获取分页-异步 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 根据id获取实体 411 | 412 | 413 | 414 | 415 | 416 | 417 | 根据id获取实体-异步 418 | 419 | 420 | 421 | 422 | 423 | 424 | 根据lambda获取单个对象 (注意,需要确保唯一,如果获取到2个会报错,这种场景需要使用GetFirst) 425 | 426 | 427 | 428 | 429 | 430 | 431 | 根据lambda获取单个对象-异步 (注意,需要确保唯一,如果获取到2个会报错,这种场景需要使用GetFirst) 432 | 433 | 434 | 435 | 436 | 437 | 438 | 根据lambda获取单个对象 439 | 440 | 441 | 442 | 443 | 444 | 445 | 根据lambda获取单个对象 --异步 446 | 447 | 448 | 449 | 450 | 451 | 452 | 实体插入 453 | 454 | 455 | 456 | 457 | 458 | 459 | 实体插入-异步 460 | 461 | 462 | 463 | 464 | 465 | 466 | 批量插入 467 | 468 | 469 | 470 | 471 | 472 | 473 | 批量插入-异步 474 | 475 | 476 | 477 | 478 | 479 | 480 | 插入返回自增列 481 | 482 | 483 | 484 | 485 | 486 | 487 | 插入返回自增列-异步 488 | 489 | 490 | 491 | 492 | 493 | 494 | 插入返回longid 495 | 496 | 497 | 498 | 499 | 500 | 501 | 插入返回longid-异步 502 | 503 | 504 | 505 | 506 | 507 | 508 | 批量删除 509 | 510 | 511 | 512 | 513 | 514 | 515 | 批量删除-异步 516 | 517 | 518 | 519 | 520 | 521 | 522 | 根据主键删除 523 | 524 | 525 | 526 | 527 | 528 | 529 | 根据主键删除-异步 530 | 531 | 532 | 533 | 534 | 535 | 536 | 根据实体删除 537 | 538 | 539 | 540 | 541 | 542 | 543 | 根据实体删除-异步 544 | 545 | 546 | 547 | 548 | 549 | 550 | 根据表达式删除 551 | 552 | 553 | 554 | 555 | 556 | 557 | 根据表达式删除-异步 558 | 559 | 560 | 561 | 562 | 563 | 564 | 更新 565 | 566 | 567 | 568 | 569 | 570 | 571 | 更新-异步 572 | 573 | 574 | 575 | 576 | 577 | 578 | 批量更新 579 | 580 | 581 | 582 | 583 | 584 | 585 | 批量更新-异步 586 | 587 | 588 | 589 | 590 | 591 | 592 | 是否包含元素 593 | 594 | 595 | 596 | 597 | 598 | 599 | 是否包含元素-异步 600 | 601 | 602 | 603 | 604 | 605 | 606 | sqlserver连接 607 | 608 | 609 | 610 | 611 | Scan the local folders from the repo, looking for "samples/plugins" folder. 612 | 613 | The full path to samples/plugins 614 | 615 | 616 | 617 | --------------------------------------------------------------------------------