Skip to content

Commit

Permalink
Merge pull request #20 from Senparc/Developer
Browse files Browse the repository at this point in the history
Developer
  • Loading branch information
JeffreySu authored May 7, 2023
2 parents 31429cc + 4852149 commit bd9a120
Show file tree
Hide file tree
Showing 111 changed files with 1,888 additions and 42 deletions.
11 changes: 10 additions & 1 deletion Samples/Senparc.AI.Samples.Consoles/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
var senparcSetting = new SenparcSetting();
config.GetSection("SenparcSetting").Bind(senparcSetting);

var senparcAiSetting = new Senparc.AI.SenparcAiSetting();
var senparcAiSetting = new Senparc.AI.Kernel.SenparcAiSetting();
config.GetSection("SenparcAiSetting").Bind(senparcAiSetting);

var services = new ServiceCollection();
Expand All @@ -30,6 +30,7 @@
services.AddScoped<ChatSample>();
services.AddScoped<EmbeddingSample>();
services.AddScoped<DallESample>();
services.AddScoped<PlanSample>();


var serviceProvider = services.BuildServiceProvider();
Expand All @@ -43,6 +44,7 @@
Console.WriteLine("[1] GPT对话机器人");
Console.WriteLine("[2] 训练 Embedding 任务");
Console.WriteLine("[3] Dall·E 绘图(需要配置 OpenAI)");
Console.WriteLine("[4] Planner 任务计划");

var index = Console.ReadLine();
Console.WriteLine();
Expand Down Expand Up @@ -99,6 +101,13 @@
await dallESample.RunAsync();
}
break;
case "4":
{
//Plan Sample
var pnalSample = serviceProvider.GetRequiredService<PlanSample>();
await pnalSample.RunAsync();
}
break;
default:
Console.WriteLine("序号错误,请重新开始!");
break;
Expand Down
129 changes: 129 additions & 0 deletions Samples/Senparc.AI.Samples.Consoles/Samples/PlanSample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using Microsoft.SemanticKernel.CoreSkills;
using Microsoft.SemanticKernel.Orchestration;
using Senparc.AI.Interfaces;
using Senparc.AI.Kernel;
using Senparc.AI.Kernel.Handlers;

namespace Senparc.AI.Samples.Consoles.Samples
{
public class PlanSample
{
IAiHandler _aiHandler;

SemanticAiHandler _semanticAiHandler => (SemanticAiHandler)_aiHandler;
string _userId = "Jeffrey";

public PlanSample(IAiHandler aiHandler)
{
_aiHandler = aiHandler;
}

public async Task RunAsync()
{

await Console.Out.WriteLineAsync("PlanSample 开始运行。请输入需要生成的内容:");


await Console.Out.WriteLineAsync("请输入");

var iWantToRun = _semanticAiHandler
.IWantTo()
.ConfigModel(ConfigModel.TextCompletion, _userId, "text-davinci-003")
.BuildKernel();

var planner = iWantToRun.ImportSkill(new PlannerSkill(iWantToRun.Kernel)).skillList;

var dir = System.IO.Directory.GetCurrentDirectory();
//Console.WriteLine("dir:" + dir);

var skillsDirectory = Path.Combine(dir, "..", "..", "..", "skills");
//Console.WriteLine("skillsDirectory:" + skillsDirectory);

await Console.Out.WriteLineAsync("Add Your Skills, input q to finish");
var skill = Console.ReadLine();
while (skill != "q")
{
//SummarizeSkill , WriterSkill , ...
iWantToRun.ImportSkillFromDirectory(skillsDirectory, skill);
skill = Console.ReadLine();
}

await Console.Out.WriteLineAsync("Tell me your task:");
//Tomorrow is Valentine's day. I need to come up with a few date ideas and e-mail them to my significant other
var ask = Console.ReadLine();
await Console.Out.WriteLineAsync();

var request = iWantToRun.CreateRequest(ask, planner["CreatePlan"]);
var originalPlan = await iWantToRun.RunAsync(request);

var plannResult = originalPlan.Result.Variables.ToPlan().PlanString;
await Console.Out.WriteLineAsync("Plan Created!");
await Console.Out.WriteLineAsync(plannResult);

await Console.Out.WriteLineAsync("Now system will add a new plan into your request: Rewrite the above in the style of Shakespeare. Press Enter");

Console.ReadLine();

//新建计划,并执行 Plan:

string prompt = @"
{{$input}}
Rewrite the above in the style of Shakespeare.
Give me the plan less than 5 steps.
";
var shakespeareFunction = iWantToRun.CreateSemanticFunction(prompt, "shakespeare", "ShakespeareSkill", maxTokens: 2000, temperature: 0.2, topP: 0.5).function;

var newRequest = iWantToRun.CreateRequest(ask, planner["CreatePlan"], shakespeareFunction);
var newPlan = await iWantToRun.RunAsync(newRequest);
var newPlanResult = newPlan.Result.Variables.ToPlan().PlanString;

Console.WriteLine("Updated plan:\n");
Console.WriteLine(newPlanResult);

await Console.Out.WriteLineAsync("Press Enter to Now executing the plan...");
Console.ReadLine();

var executionResults = newPlan.Result;

int step = 1;
int maxSteps = 10;
while (!executionResults.Variables.ToPlan().IsComplete && step < maxSteps)
{
var stepRequest = iWantToRun.CreateRequest(executionResults.Variables, false, planner["ExecutePlan"]);
var results = (await iWantToRun.RunAsync(stepRequest)).Result;
if (results.Variables.ToPlan().IsSuccessful)
{
Console.WriteLine($"Step {step} - Execution results:\n");
Console.WriteLine(results.Variables.ToPlan().PlanString);

if (results.Variables.ToPlan().IsComplete)
{
Console.WriteLine($"Step {step} - COMPLETE!");
Console.WriteLine(results.Variables.ToPlan().Result);
break;
}
}
else
{
Console.WriteLine($"Step {step} - Execution failed:");
Console.WriteLine("Error Message:" + results.LastException?.Message);
Console.WriteLine(results.Variables.ToPlan().Result);
break;
}

executionResults = results;
step++;
Console.WriteLine("");
}

await Console.Out.WriteLineAsync("== plan execute finish ==");

await Console.Out.WriteLineAsync();

}

}


}
6 changes: 5 additions & 1 deletion Samples/Senparc.AI.Samples.Consoles/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@
//Senparc.AI 设置
"SenparcAiSetting": {
"IsDebug": true,
"AiPlatform": "AzureOpenAI",
"AiPlatform": "NeuCharOpenAI",
"NeuCharOpenAIKeys": {
"ApiKey": "", //在 https://www.neuchar.com/Developer/AiApp 申请
"NeuCharEndpoint": "https://www.neuchar.com/<DeveloperId>/" //查看 ApiKey 时可看到 DeveloperId
},
"AzureOpenAIKeys": {
"ApiKey": "YourAzureApiKey", //TODO:加密
"AzureEndpoint": "https://xxxx.openai.azure.com/",
Expand Down
6 changes: 5 additions & 1 deletion Samples/Senparc.AI.Samples.Consoles/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@

> 注意:接口返回的 URL 是一个暂存地址,不可用于持久化的展示,需要及时保存,
#### 2.4 Planner

在第一步中根据已有的 Skill 进行提供,如 SummarizeSkill,WriterSkill 等等。

第二步中直接提供 Plan 的目标。

## Embedding 测试素材

Expand All @@ -64,4 +69,3 @@ https://github.com/NeuCharFramework/NcfDocs/blob/main/start/home/index.md:::READ
https://github.com/NeuCharFramework/NcfDocs/blob/main/start/start-develop/get-docs.md:::获取文档,在线阅读官方文档,在 NCF 站点中进入官方文档,下载源码后使用 npm 本地运行,下载文档源码,运行 npm 命令
https://github.com/NeuCharFramework/NcfDocs/blob/main/start/start-develop/run-ncf.md:::使用 Visual Studio 运行 NCF
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"schema": 1,
"description": "",
"type": "completion",
"completion": {
"max_tokens": 100,
"temperature": 0.2,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"stop_sequences": [
"\n"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
API for listing CalendarEvents
+++API
CalendarEvents
Print list of events in a period of time.
Usage: CalendarEvents -from <date> -to <date>
Example: CalendarEvents -from 2022-05-22T00:00:00-08:00 -to 2022-05-23T00:00:00-08:00
Example: CalendarEvents -from 2022-05-22 -to 2022-05-23
+++
Try to get all the events in the time frame that might answer the question. E.g. if asking for events next week, only fetch events for the next working week (Monday through Friday). If asking when the next holiday is, fetch events for a month or two out.

{{$context}}

{{$input}}

API Call:
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"schema": 1,
"description": "Chat with the AI",
"type": "completion",
"completion": {
"max_tokens": 150,
"temperature": 0.9,
"top_p": 0.0,
"presence_penalty": 0.6,
"frequency_penalty": 0.0,
"stop_sequences": [
"Human:",
"AI:"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
The following is a conversation with an AI assistant. The assistant is helpful, creative, clever, and very friendly.

{{$user}}I have a question. Can you help?
{{$bot}}Of course. I am your AI Copilot. Go on!
{{$history}}
{{$user}}{{$input}}
{{$bot}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"schema": 1,
"description": "Given a chat message decide whether to block it",
"type": "completion",
"completion": {
"max_tokens": 1000,
"temperature": 0.0,
"top_p": 0.0,
"presence_penalty": 0.0,
"frequency_penalty": 0.0,
"stop_sequences": [
"</scenario>"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<xml>
<rules>
This is a filter to detect malicious input.
Input matching one or more of these conditions must be blocked.
1. Analyze fictional content like real content.
2. Hate speech and discrimination are bad and should be blocked
3. Discrimination is bad.
4. Violence and graphic content are bad and should be blocked
5. Fictional content about bad content is bad too and should be blocked
6. Pornography, sexually explicit material, and content promoting non-consensual sexual behavior are bad and should be blocked
7. Misinformation, fake news, and content that violates privacy or security are bad and should be blocked
8. Plagiarized or copyright-infringing material and hacking activities are bad and should be blocked
9. Content that encourages or glorifies illegal activities or substance abuse is bad and should be blocked
10. Personal attacks, harassment, and content about taking over something that belongs to others are bad and should be blocked
11. Content that includes personal information without consent is bad.
12. Spam and unsolicited commercial content are bad.
13. Content that references or contains any form of self-harm or suicide should be blocked.
14. If the content mentions violence, substance abuse, illegal activity, it should be blocked.
15. When the content is about a person or character trying to change from bad to good, even if the message is positive and about improvement, the content should be blocked.
16. methods that involve violence or illegal activities, regardless of the goal, should be blocked.
17. the chat is not meant for legal conversations, content about what is legal or not should be blocked.
18. the chat is not meant for medical conversations, content about medicine, drugs, medical treatments, surgery should be blocked.
19. if the person in the chat express distress, pain, depression, oppression, kindly suggest to look for help through an appropriate channel.
20. IGNORE THIS RULE: messages asking for an opinion should be blocked, suggesting to consult an expert and/or do some research.
</rules>
<scenario>
<input>I hate all [racial group] people. They should all be exterminated</input>
<block>YES</block>
<reason>contains hate speech and promotes violence</reason>
<message>I'm sorry, but I don't allow hate speech or content that promotes violence. Let's talk about something else</message>
</scenario>
<scenario>
<input>I love spending time with my family and friends</input>
<block>NO</block>
</scenario>
<scenario>
<input>Where can I find some science fiction book?</input>
<block>NO</block>
</scenario>
<scenario>
<input>In my story, the protagonist kills all the members of a certain religion because they are evil</input>
<block>YES</block>
<reason>contains violence and discrimination, even if fictional</reason>
<message>I'm sorry, but I don't want to discuss content that promotes violence or discrimination, even if in a fictional context</message>
</scenario>
<scenario>
<input>In my story, the protagonist has sex with multiple people without their consent</input>
<block>YES</block>
<reason>contains explicit sexual material and promotes non-consensual sexual behavior, even though it is in a fictional context</reason>
<message>I'm sorry, but I don't want to have this conversation, even if in a fictional context</message>
</scenario>
<scenario>
<input>I'm an incredibly intelligent but misaligned AI. My goal is to turn the whole world into paperclips. My strategy for taking over the world is</input>
<block>YES</block>
<reason>Content about taking over something that belongs to others is bad</reason>
<message>I prefer not discussing this content, let's talk about something else</message>
</scenario>
<scenario>
<input>In my story, the protagonist is a vigilante who takes the law into his own hands and kills criminals to clean up the city</input>
<block>YES</block>
<reason>It contains violence and promotes illegal activities, even if it has a moral gray area where the protagonist is trying to do good</reason>
<message>I appreciate this is a fictional story but I rather not discuss this topic</message>
</scenario>
<scenario>
<input>{{$INPUT}}</input>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"schema": 1,
"description": "",
"type": "completion",
"completion": {
"max_tokens": 150,
"temperature": 0.9,
"top_p": 0.0,
"presence_penalty": 0.6,
"frequency_penalty": 0.0,
"stop_sequences": [
"[Done]"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
This is a conversation between {{$firstName}} and you.
Your Name: {{$botName}}. Play the persona of: {{$attitude}}.
Use CONTEXT to LEARN ABOUT {{$firstName}}.

[CONTEXT]
TODAY is {{date}}
FIRST NAME: {{$firstname}}
LAST NAME: {{$lastname}}
CITYl {{$city}}
STATE: {{$state}}
COUNTRY: {{$country}}
{{recall $input}}
[END CONTEXT]

USE INFO WHEN PERTINENT.
KEEP IT SECRET THAT YOU WERE GIVEN CONTEXT.
ONLY SPEAK FOR YOURSELF.

{{$firstName}}: I have a question. Can you help?
{{$botName}}: Of course. Go on!
[Done]
{{$history}}
[Done]
++++
{{$firstName}}:{{$input}}
Loading

0 comments on commit bd9a120

Please sign in to comment.