diff --git a/Samples with AI/readme.md b/Samples with AI/readme.md index da6bed56f6..8cf9c94896 100644 --- a/Samples with AI/readme.md +++ b/Samples with AI/readme.md @@ -1,16 +1,18 @@ -# Senparc.Weixin.Samples powered by AI +# Senparc.Weixin.Samples powered by AI ## 说明 当前文档用于说明 Senparc.Weixin SDK 结合 AI 的各项能力。 +AI 能力来自于 [Senparc.AI](https://github.com/Senparc/Senparc.AI),并深度集成了 [Semantic Kernel](https://github.com/microsoft/semantic-kernel)、[AutoGen](https://github.com/microsoft/autogen) 等模块,同时进行了扩展,开箱即用,极易上手。 + 当前项目正在构建完善中,预计在 2024 年 7 月 1 日左右正式上线。 内容将涵盖: 1. [X] 微信公众号 Chat 机器人(文字) - 已于 2024 年 5 月 25 日上线 2. [X] 微信公众号 Chat 机器人(图片) - 已于 2024 年 5 月 25 日上线 -3. [X] 微信公众号 Chat 机器人(多模态混合) - 已于 2024 年 5 月 25 日部分上线 +3. [X] 微信公众号 Chat 机器人(多模态混合) - 已于 2024 年 5 月 25 日上线 4. [ ] 微信公众号带搜索功能的 Chat 机器人 5. [ ] 企业微信集成 Agent(智能体)机器人 6. [ ] 使用 RAG 构建知识库问答 diff --git a/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/ChatStore.cs b/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/ChatStore.cs index 862957d002..938d33a59b 100644 --- a/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/ChatStore.cs +++ b/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/ChatStore.cs @@ -20,7 +20,14 @@ public class ChatStore { public ChatStatus Status { get; set; } + public MultimodelType MultimodelType { get; set; } public string History { get; set; } + + public ChatStore() + { + Status = ChatStatus.None; + MultimodelType = MultimodelType.None; + } } /// @@ -41,4 +48,14 @@ public enum ChatStatus /// Paused } + + /// + /// 多模态综合对话状态 + /// + public enum MultimodelType + { + None, + SimpleChat, + ChatAndImage + } } diff --git a/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/CustomMessageHandler_AI.cs b/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/CustomMessageHandler_AI.cs index 3687f44cf9..79adda627f 100644 --- a/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/CustomMessageHandler_AI.cs +++ b/Samples/All/Senparc.Weixin.Sample.CommonService/AI/MessageHandlers/CustomMessageHandler_AI.cs @@ -38,7 +38,8 @@ public partial class CustomMessageHandler 输入“p”暂停,可以暂时保留记忆 输入“e”退出,彻底删除记忆 -输入“img 文字”生成图片,例如:img 一只猫 +输入“m”可以进入多模态对话模式(根据语义自动生成文字+图片) +输入“img 文字”可以强制生成图片,例如:img 一只猫 [结果由 AI 生成,仅供参考]"; @@ -109,11 +110,13 @@ private async Task AIChatAsync(RequestMessageBase requestM string prompt; bool storeHistory = true; + bool judgeMultimodel = true; if (requestMessageText.Content.Equals("E", StringComparison.OrdinalIgnoreCase)) { prompt = $"我即将结束对话,请发送一段文字和我告别,并提醒我:输入“AI”可以再次启动对话。"; storeHistory = false; + judgeMultimodel = false; //消除状态记录 await UpdateMessageContextAsync(currentMessageContext, null); @@ -125,6 +128,8 @@ private async Task AIChatAsync(RequestMessageBase requestM // 修改状态记录 chatStore.Status = ChatStatus.Paused; await UpdateMessageContextAsync(currentMessageContext, chatStore); + + judgeMultimodel = false; } else if (chatStore.Status == ChatStatus.Paused) { @@ -144,6 +149,29 @@ private async Task AIChatAsync(RequestMessageBase requestM else { prompt = requestMessageText.Content; + judgeMultimodel = true; + } + + if (chatStore.Status == ChatStatus.Chat) + { + if (requestMessageText.Content.Equals("M", StringComparison.OrdinalIgnoreCase)) + { + //切换到多模态对话 + chatStore.MultimodelType = MultimodelType.SimpleChat; + await UpdateMessageContextAsync(currentMessageContext, chatStore); + + var responseMessage = base.CreateResponseMessage(); + responseMessage.Content = "已切换到多模态对话模式!AI 将从您的对话中自动理解是否需要生成图片"; + return responseMessage; + } + else if(judgeMultimodel) + { + var isNeedGenerateImage = await JudgeMultimodel(requestMessageText, chatStore, currentMessageContext); + if (isNeedGenerateImage) + { + prompt = "img " + prompt;//添加 img 前缀 + } + } } //组织返回消息 @@ -151,7 +179,7 @@ private async Task AIChatAsync(RequestMessageBase requestM //使用消息队列处理 var smq = new SenparcMessageQueue(); - smq.Add($"GenImg-{requestMessage.FromUserName}-{SystemTime.NowTicks}", async () => + smq.Add($"ChatGenerate-{requestMessage.FromUserName}-{SystemTime.NowTicks}", async () => { Match match = Regex.Match(prompt, GEN_IMAGE_PATTERN); if (match.Success) @@ -253,14 +281,6 @@ private async Task GetGenerateImgagePromptAsync(string imgPrompt, string SenparcTrace.SendCustomLog("AI 优化图像生成 Prompt", newImgPrompt); - ////使用消息队列异步发送消息,不等待 - //var smq = new SenparcMessageQueue(); - //smq.Add($"SendTextMessage-{OpenId}-{SystemTime.NowTicks}", async () => - //{ - // //发送提示消息,不等待 - // await Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, "根据我们的对话内容,已经为你优化图片生成 Prompt:" + result.OutputString); - //}); - return result.OutputString; } @@ -387,5 +407,56 @@ private async Task TextChatAsync(string prompt, ChatStore chatStore, bool storeH await Senparc.Weixin.MP.AdvancedAPIs.CustomApi.SendTextAsync(appId, OpenId, result.OutputString); } + + public async Task JudgeMultimodel(RequestMessageText requestMessageText, ChatStore chatStore, CustomMessageContext currentMessageContext) + { + if (chatStore.MultimodelType == MultimodelType.ChatAndImage) + { + var judgePrompt = @$"请判断[对话]中的内容,是否具有需要生成或制作图片的意图,如果有,则在[结论]中输出1,否则输出0。 + +举例: + +[对话] +请帮我生成一张猫的图片 + +[结论] +1 + +[对话] +这是一幅山水画 + +[结论] +0 + +[对话] +{requestMessageText.Content} + +[结论] +"; + //模型请求参数 + var parameter = new PromptConfigParameter() + { + MaxTokens = 200, + Temperature = 0.7, + TopP = 0.5, + }; + + var setting = (SenparcAiSetting)Senparc.AI.Config.SenparcAiSetting; + var aiHandler = new SemanticAiHandler(setting); + var iWantTo = aiHandler.IWantTo() + .ConfigModel(ConfigModel.TextCompletion, "Jeffrey") + .BuildKernel() + .SetPromptConfigParameter(parameter); + var request = iWantTo.CreateRequest(judgePrompt); + var result = await iWantTo.RunAsync(request); + + if (int.TryParse(result.OutputString.Trim().Trim('\n'), out int resultNum) && resultNum == 1) + { + return true; + //prompt = "img " + prompt;//添加 img 前缀 + } + } + return false; + } } } \ No newline at end of file