SemanticKernel其中一个功能是实现像https://chat.openai.com那样的问答聊天功能,给过SK封装,就变得简单灵活了,下面是不到百地代码实现的一个简单聊天功能。
32行(后端)+51行(前端)=83行.
后端:
using Microsoft.SemanticKernel;using Microsoft.SemanticKernel.AI.ChatCompletion;using Microsoft.SemanticKernel.Connectors.AI.OpenAI.ChatCompletion;using System.Text;var key = File.ReadAllText(@"C:\\GPT\key.txt");var builder = WebApplication.CreateBuilder(args);var kernel = Kernel.Builder.WithOpenAIChatCompletionService("gpt-4", key, serviceId: "gsw_chat").Build();var chatGPT = kernel.GetService<IChatCompletion>();builder.Services.AddSingleton(chatGPT);builder.Services.AddSingleton((OpenAIChatHistory)chatGPT.CreateNewChat());var app = builder.Build();app.UseStaticFiles();app.MapGet("/chat", AskAsync);app.Run();async IAsyncEnumerable<string> AskAsync(IChatCompletion chat, OpenAIChatHistory history, string ask){history.AddUserMessage(ask);var reply = chat.GenerateMessageStreamAsync(history, new ChatRequestSettings() { MaxTokens = 2048 });var answer = new StringBuilder();await foreach (var item in reply){if(item==null){continue;}answer.Append(item);yield return item;}history.AddAssistantMessage(answer.ToString());}
首先构建一个KernelBuilder,把OpenAI的ChatCompletion服务添加到Builder中,然后把Chat服务注入到asp.net core的服务容器中,同时也把History列表注入到服务容器中,当前api有访问的时候,通过chat结合history来获取OpenAI返回的聊天信息,以流的形式输出到前端。
前端:
<!DOCTYPE html><html><head><title>小助手</title><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"></head><body><div class="container"><div class="row"><h3 class="display-4">小助手</h3></div><div class="row"><div class="input-group mb-3"><input type="text" id="ask" class="form-control" placeholder="请输入问题" aria-label="请输入问题" aria-describedby="chat"><button class="btn btn-outline-secondary" type="button" id="chat">开始</button></div></div><div id="messagesdiv" class="row"></div></div><script src="https://code.jquery.com/jquery-3.6.0.min.js"></script><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script><script>$(function () {$("#chat").click(function () {var askDiv = $("<div class='alert alert-primary'>");askDiv.text("【您】" + $("#ask").val());var answerDiv = $("<textarea class='alert alert-warning' style='min-height:150px'>");$("#messagesdiv").append(askDiv);$("#messagesdiv").append(answerDiv);var xhr = new $.ajaxSettings.xhr();xhr.onreadystatechange = function () {if (xhr.readyState == 3) {var content = "";var list = JSON.parse(xhr.responseText.replace(']', '') + ']');$(list).each(function (index, item) {content += item})answerDiv.text(content)} else if (xhr.readyState == 4) {answerDiv.removeClass("alert-warning")answerDiv.addClass("alert-success")$("#ask").val("")}}xhr.open('GET', '/chat?ask=' + $("#ask").val())xhr.send()})});</script></body></html>
前端代码用ajax的形式接收流显示在页面上,再通过jquery控制一些样式即可。
运行效果如下:

细心的朋友可能会发现,这个上下文是所有用户共享的。那么怎样才能做到像ChatGPT那样独享呢?这个话题留给你吧!