Skip to content

Commit

Permalink
Merge pull request #3 from Senparc/Developer
Browse files Browse the repository at this point in the history
Developer
  • Loading branch information
JeffreySu authored Apr 5, 2023
2 parents ba34c28 + 2efdd23 commit c109ce6
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 18 deletions.
73 changes: 72 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,73 @@
# Senaprc.AI
Senparc 全家桶的 AI 扩展包
Senparc 全家桶的 AI 扩展包,目前主要集中于 LLM(大语言模型)的交互。


## 项目介绍

`Senparc.AI` 为所有标准接口和基础功能的基础模块
`Senparc.AI.Kernel` 为基于 Senparc.AI 标准,使用 [SemanticKernel](https://github.com/microsoft/semantic-kernel) 实现的接口调用,可以实现即插即用。

## 开发过程

### 第一步:配置账号
在 appsettings.json 中配置 OpenAI 或 Azure OpenAI 的接口信息,如:
```
//CO2NET 设置
"SenparcSetting": {
"IsDebug": true,
"DefaultCacheNamespace": "SenparcAiCache"
},
"SenparcAiSetting": {
"IsDebug": true,
"AiPlatform": "AzureOpenAI",
"ApiKey": "YourKey",
"OrgaizationId": "YourOrgId",
//当设置 AiPlatform 为 AzureOpenAI 时需要设置以下参数:
"AzureEndpoint": "https://xxx.openai.azure.com",
"AzureOpenAIApiVersion": "2022-12-01"
},
```
其中:`AiPlatform` 目前可选值为 `OpenAI``AzureOpenAI`,分别对应 OpenAI.com 官方接口,以及基于微软 Azure 的 Azure OpenAI 接口,系统会根据配置自动实现切换,无需在逻辑代码中进行判断。

仅当 `AiPlatform` 设置为 `OpenAI` 时,才需要设置 `OrgaizationId` 参数。

仅当 `AiPlatform` 设置为 `AzureOpenAI` 时,才需要设置 `AzureEndpoint``AzureOpenAIApiVersion` 参数。

### 第二步:开发

Senparc.AI 使用了创新的对话式编程体验,您无需了解过多不同平台、SDK 的详细用法,只需要按照自己的想法进行定义和编程,最后接收结果,以目前最火的聊天场景(Chat)为例:

```C#
//创建 AI Handler 处理器(也可以通过工厂依赖注入)
var handler = new SemanticAiHandler();
var userId = "JeffreySu";//区分用户
var modelName = "text-davinci-003";//默认使用模型
//定义 AI 接口调用参数和 Token 限制等
var promptParameter = new PromptConfigParameter()
{
MaxTokens = 2000,
Temperature = 0.7,
TopP = 0.5,
};

//准备运行
var iWantToRun = await handler.IWantTo()
.Config(userId, modelName)
.RegisterSemanticFunctionAsync(promptParameter);

var prompt = "请问中国有多少人口?";
var aiRequest = iWantToRun.GetRequest(prompt);

//获取结果
var aiResult = await iWantToRun.RunAsync(aiRequest);

//aiResult.Result 结果:中国的人口约为13.8亿。
await Console.Out.WriteLineAsync(aiResult.ToJson(true));
```

## TODO:
1. 实现更多模型和模式的匹配。
2. 实现全自动的工厂模块自动配置。
3. 集成到 [Senaprc.Weixin SDK](https://github.com/JeffreySu/WeiXinMPSDK),0 逻辑代码实现 AI 能力接入(聊天场景为主)。
4. 集成到 [NeuCharFramework](https://github.com/NeuCharFramework/NCF),0 逻辑代码实现 AI 能力接入(开发和云运营场景为主)。
32 changes: 32 additions & 0 deletions src/Senparc.AI.Kernel.Tests/Handlers/SemanticAiHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Senparc.AI.Kernel.Handlers;

namespace Senparc.AI.Kernel.Tests.Handlers
{
Expand Down Expand Up @@ -69,5 +70,36 @@ public async Task ChatAsyncTest()
await Console.Out.WriteLineAsync("Q: " + result.Input);
await Console.Out.WriteLineAsync("A: " + result.Output);
}

[TestMethod]
public async Task ReadMeDemoTest()
{
//创建 AI Handler 处理器(也可以通过工厂依赖注入)
var handler = new SemanticAiHandler();
var userId = "JeffreySu";//区分用户
var modelName = "text-davinci-003";//默认使用模型

//定义 AI 接口调用参数和 Token 限制等
var promptParameter = new PromptConfigParameter()
{
MaxTokens = 2000,
Temperature = 0.7,
TopP = 0.5,
};

//准备运行
var iWantToRun = await handler.IWantTo()
.Config(userId, modelName)
.RegisterSemanticFunctionAsync(promptParameter);

var prompt = "请问中国有多少人口?";
var aiRequest = iWantToRun.GetRequest(prompt);

//获取结果
var aiResult = await iWantToRun.RunAsync(aiRequest);

//aiResult.Result 结果:中国的人口约为13.8亿。
await Console.Out.WriteLineAsync(aiResult.ToJson(true));
}
}
}
8 changes: 6 additions & 2 deletions src/Senparc.AI.Kernel/Handlers/IWanToExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Senparc.AI.Entities;

namespace Senparc.AI.Kernel.Handlers
{
Expand All @@ -14,6 +15,7 @@ public class IWantTo
public IKernel Kernel { get; set; }
public KernelConfig KernelConfig { get; set; }
public SemanticKernelHelper SemanticKernelHelper { get; set; }
public SemanticAiHandler SemanticAiHandler { get; set; }

public string UserId { get; set; }
public string ModelName { get; set; }
Expand All @@ -25,9 +27,10 @@ public IWantTo(KernelConfig kernelConfig)
KernelConfig = kernelConfig;
}

public IWantTo(SemanticKernelHelper semanticKernelHelper)
public IWantTo(SemanticAiHandler handler)
{
SemanticKernelHelper = semanticKernelHelper;
SemanticAiHandler = handler;
SemanticKernelHelper = handler.SemanticKernelHelper;
}


Expand Down Expand Up @@ -56,6 +59,7 @@ public class IWantToRun
public IWantTo IWantTo { get; set; }
public ISKFunction ISKFunction { get; set; }
public SenparcAiContext AiContext { get; set; }
public PromptConfigParameter PromptConfigParameter { get; set; }
public IWantToRun(IWantTo iWantTo)
{
IWantTo = iWantTo;
Expand Down
26 changes: 21 additions & 5 deletions src/Senparc.AI.Kernel/Handlers/KernelConfigExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,25 @@ namespace Senparc.AI.Kernel.Handlers
{
public static class KernelConfigExtension
{
public static IWantTo IWantTo(this SemanticKernelHelper sKHelper)
//public static IWantTo IWantTo(this SemanticKernelHelper sKHelper)
//{
// var iWantTo = new IWantTo(sKHelper);
// return iWantTo;
//}

public static IWantTo IWantTo(this SemanticAiHandler handler)
{
var iWantTo = new IWantTo(sKHelper);
var iWantTo = new IWantTo(handler);
return iWantTo;
}

public static SenparcAiRequest GetRequest(this IWantToRun iWantToRun, string requestContent)
{
var iWantTo = iWantToRun.IWantTo;
var request = new SenparcAiRequest(iWantTo.UserId, iWantTo.ModelName, requestContent, iWantToRun.PromptConfigParameter);
return request;
}

public static IWantToConfig Config(this IWantTo iWantTo, string userId, string modelName)
{
var kernel = iWantTo.SemanticKernelHelper.Config(userId, modelName);
Expand Down Expand Up @@ -84,6 +97,7 @@ ChatBot can have a conversation with you about any topic.

var iWantTo = iWantToConfig.IWantTo;
var helper = iWantTo.SemanticKernelHelper;
var handler = iWantTo.SemanticAiHandler;
var kernel = helper.GetKernel();
var promptTemplate = new PromptTemplate(skPrompt, promptConfig, kernel);
var functionConfig = new SemanticFunctionConfig(promptConfig, promptTemplate);
Expand All @@ -96,20 +110,22 @@ ChatBot can have a conversation with you about any topic.
var history = "";
aiContext.SubContext.Set(serviceId, history);

return new IWantToRun(new IWantTo(helper))
return new IWantToRun(new IWantTo(handler))
{
ISKFunction = chatFunction,
AiContext = aiContext
AiContext = aiContext,
PromptConfigParameter = promptConfigPara
};
}

public static async Task<SenparcAiResult> RunAsync(this IWantToRun iWanToRun, string prompt)
public static async Task<SenparcAiResult> RunAsync(this IWantToRun iWanToRun, SenparcAiRequest request)
{
var helper = iWanToRun.IWantTo.SemanticKernelHelper;
var kernel = helper.Kernel;
var function = iWanToRun.ISKFunction;
var context = iWanToRun.AiContext.SubContext;
var iWantTo = iWanToRun.IWantTo;
var prompt = request.RequestContent;

//设置最新的人类对话
context.Set("human_input", prompt);
Expand Down
18 changes: 8 additions & 10 deletions src/Senparc.AI.Kernel/Handlers/SemanticAiHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ namespace Senparc.AI.Kernel
public class SemanticAiHandler :
IAiHandler<SenparcAiRequest, SenparcAiResult, SenparcAiContext, ContextVariables>
{
private readonly SemanticKernelHelper _skHandler;
public SemanticKernelHelper SemanticKernelHelper { get; set; }
private readonly IKernel _kernel;

public SemanticAiHandler(SemanticKernelHelper semanticAiHandler = null)
public SemanticAiHandler(SemanticKernelHelper semanticAiHelper = null)
{
_skHandler = semanticAiHandler ?? new SemanticKernelHelper();
_kernel = _skHandler.GetKernel();
SemanticKernelHelper = semanticAiHelper ?? new SemanticKernelHelper();
_kernel = SemanticKernelHelper.GetKernel();
}

/// <summary>
Expand All @@ -34,7 +34,7 @@ public SemanticAiHandler(SemanticKernelHelper semanticAiHandler = null)
public SenparcAiResult Run(SenparcAiRequest request)
{
//TODO:此方法暂时还不能用
_skHandler.Config(request.UserId, request.ModelName, _kernel);
SemanticKernelHelper.Config(request.UserId, request.ModelName, _kernel);

var senparcAiResult = new SenparcAiResult();
return senparcAiResult;
Expand All @@ -43,9 +43,8 @@ public SenparcAiResult Run(SenparcAiRequest request)

public async Task<IWantToRun> ChatConfigAsync(PromptConfigParameter promptConfigParameter, string userId, string modelName = "text-davinci-003")
{
var iWantToRun = await _skHandler
.IWantTo()
.Config("Jeffrey", "text-davinci-003")
var iWantToRun = await this.IWantTo()
.Config(userId, modelName)
.RegisterSemanticFunctionAsync(promptConfigParameter);
return iWantToRun;
}
Expand All @@ -59,8 +58,7 @@ public async Task<SenparcAiResult> ChatAsync(IWantToRun iWantToRun, SenparcAiReq
// TopP = 0.5,
//};

var aiResult = await iWantToRun
.RunAsync(request.RequestContent);
var aiResult = await iWantToRun.RunAsync(request);

return aiResult;
}
Expand Down

0 comments on commit c109ce6

Please sign in to comment.