【OpenAI&SK】:实现自己的问答机器人
前ChatGPT让人惊叹的是,它好像有了真人的思维逻辑,能记住上下文,还能很融洽地和你聊天,并且回答问题让你满意。但如果你问他一些自己身边事,或者公司最新产品的事,ChatGPT的回复就天马行空了。怎么才能让他成为自己的问答机器人呢?下面给出了一个简单的事例,一起看一下吧。
后端代码:
using Microsoft.SemanticKernel; using Microsoft.SemanticKernel.Connectors.Memory.Sqlite; using Microsoft.SemanticKernel.Orchestration; using Microsoft.SemanticKernel.SkillDefinition; var builder = WebApplication.CreateBuilder(args); await builder.AddEmband(); var app = builder.Build(); app.UseStaticFiles(); app.MapGet("/bot", async (IKernel kernel, SKContext context, ISKFunction semanticFunction, string ask,CancellationToken token) => { var facts = kernel.Memory.SearchAsync("gsw", ask, limit: 10, withEmbeddings: true,cancellationToken:token); var fact = await facts.FirstOrDefaultAsync(cancellationToken: token); context["fact"] = fact?.Metadata?.Text!; context["ask"] = ask; var resultContext = await semanticFunction.InvokeAsync(context); return resultContext.Result; }); app.Run(); public static class BuilderExt { public static async Task AddEmband(this WebApplicationBuilder builder) { var key = File.ReadAllText(@"C:\\GPT\key.txt"); var store = Directory.GetCurrentDirectory() + "/db.sqlite"; var kernel = Kernel.Builder .WithOpenAITextCompletionService("text-davinci-003", key, serviceId: "gsw") .WithOpenAITextEmbeddingGenerationService("text-embedding-ada-002", key, serviceId: "gsw") .WithMemoryStorage(await SqliteMemoryStore.ConnectAsync(store)) .Build(); const string MemoryCollectionName = "gsw"; await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info0", text: "名字叫桂素伟"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info1", text: "性别男,身高171cm,\r\n体重75千克"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info2", text: "职业是农民,他擅长种茄子"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info3", text: "有20年的种地经验"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info4", text: "现在住在五十亩村"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info5", text: "祖籍山西长治市省黎城县西井镇五十亩村"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info6", text: "老家山西长治市省黎城县西井镇五十亩村"); await kernel.Memory.SaveInformationAsync(MemoryCollectionName, id: "info7", text: "来自山西长治市省黎城县西井镇五十亩村"); var prompt = """ 给出答案或者不知道答案时说“非常抱歉,我没有找到你要的问题!” 对话中的关于桂素伟的信息: {{ $fact }} 用户: {{ $ask }} 机器人: """; var semanticFunction = kernel.CreateSemanticFunction(prompt, temperature: 0.7, topP: 0.5); var context = kernel.CreateNewContext(); builder.Services.AddSingleton(kernel); builder.Services.AddSingleton(semanticFunction); builder.Services.AddSingleton(context); } }
本例用到OpenAITextCompletion和OpenAITextEmbeddingGeneration两个服务,前者是用来补全词语,后者是用来本地存储自己的问题,本例是用sqlite的方式来持久化。基本原理是,当你提问一个问题,首先会从本地存储的问题向量中找到得分最高的答案,然后一起提交给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="bot">开始</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 () { $("#bot").click(function () { var askDiv = $("<div class='alert alert-primary'>"); askDiv.text("【您】" + $("#ask").val()); var answerDiv = $("<div class='alert alert-warning'>"); answerDiv.text("……"); $("#messagesdiv").append(askDiv); $("#messagesdiv").append(answerDiv); $.ajax({ url: '/bot', type: 'GET', dataType: 'text', data: { ask: $("#ask").val() }, success: function (data) { answerDiv.removeClass("alert-warning") answerDiv.addClass("alert-success") answerDiv.text(data) $("#ask").val("") }, error: function (xhr, status, error) { answerDiv.text(error) } }); }) }); </script> </body> </html>
前端代码相对简单,把问题提交后端,等结果就ok
运行效果:
文章来源微信公众号
想要更快更方便的了解相关知识,可以关注微信公众号
****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!