【OpenAI&SK】:百行行代码实现GPT的chat

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控制一些样式即可。

运行效果如下:

【OpenAI&SK】:百行行代码实现GPT的chat

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