前言
当下ChatGPT可谓是炙手可热的人工智能产品,它不仅可以与人类进行智能对话,还能够理解人类的想法和需求。涵盖了内容创作、营销、智能客服、教育、投资等诸多领域和场景,有很大的商业价值。上周末有空闲,我花了点时间研究了ChatGPT聊天机器人。虽然之前也体验过,但没深入了解过。网上有很多一键搭建ChatGPT聊天机器人的教程,我也部署了几个相关的开源项目,感觉都很不错,功能也很完善。但作为一个程序员,我更想知道它的实现原理,所以我决定尝试开发自己的ChatGPT聊天机器人。
上网找了有关.Net与 ChatGPT开发的文章,发现很少,因此打算把我开发过程中的一些关键问题和解决方法分享出来,和大家一起学习。
开发准备
开发工具:Visual Studio 2022
开发技术:.Net core 7.0 、C# 8.0
开发框架:ASP.NET Core Web应用(模型-视图-控制器)
开始之前,你需要先申请一个ChatGPT API KEY(SK),也就是与ChatGPT通信的Authorization Token。网上有很如何申请的教程,很简单,自行百度即可。
API Key查看地址:
https://platform.openai.com/account/api-keys

涉及文档:
//ASP.NET Core Web应用开发文档:
https://learn.microsoft.com/zh-cn/aspnet/core/tutorials/choose-web-ui?view=aspnetcore-7.0
//ChatGPT API文档:
https://platform.openai.com/docs/introduction/overview
//ChatGPT SDK文档
https://github.com/betalgo/openai/wiki
开始开发
一、 新建一个ASP.NET Core Web应用应用
为了方便大家查看,我会为每一个章节新建一个项目,第一章节项目命名为:ChatGPT.Demo1

目录结构:
二、安装ChatGPT SDK
ChatGPT SDK官方只提供了Python库,其它语言的SDK为社区版本,.Net SDK官方推荐了三个:

这里我选择第一个 Betalgo.OpenAI,然后进行安装
Install-Package Betalgo.OpenAI
三、开始编码
1、项目中找到Program.cs文件并打开,然后配置Betalgo.OpenAI服务,和设置Api Key。
using OpenAI.Extensions;
builder.Services.AddOpenAIService(settings =>
{
settings.ApiKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
});

2、鼠标右键Controllers文件夹,添加一个名为ChatController的控制器,控制器的类型我们使用Api控制器。

3、打开ChatController,引入命名空间:
using OpenAI.Interfaces;
using OpenAI.ObjectModels.RequestModels;
注入Service服务:
private readonly IOpenAIService _openAiService;
public ChatController(IOpenAIService openAiService)
{
_openAiService = openAiService;
}
添加一个Action,然后调用ChatGT的/v1/chat/completions接口,并指定模型gpt-3.5-turbo来与我们对话:
[HttpGet]
public async Task<string> Input()
{
//访方法实现了ChatGT的/v1/chat/completions接口
var completionResult = await _openAiService.ChatCompletion.CreateCompletion(
new ChatCompletionCreateRequest
{
//堆代码 duidaima.com
//聊天信息
Messages = new List<ChatMessage>
{
ChatMessage.FromUser("你好!")
},
//指定模型
Model = OpenAI.ObjectModels.Models.ChatGpt3_5Turbo,
//设置Tokens数量限制
MaxTokens = 50
});
if (!completionResult.Successful)
return "请求失败";
return $"ChatGPT:{completionResult.Choices.First().Message.Content}";
}
下面为大家附上ChatGPT提供的API和模型文档,大家可以先了解一下,后续章节我将进行详细讲解。
//ChatGTP API文档
https://platform.openai.com/docs/api-reference
//ChatGPT模型介绍
https://platform.openai.com/docs/models/overview
完整代码如下:

在Input方法中,我们向ChatGPT发送一句问候,然后输出ChatGPT的回复内容。F5启动项目,在地址栏后追加api/chat路径访问Input方法,来看一下ChatGPT给我们的回复:

这样,我们就完成了与ChatGPT的第一次对话。
4、设计一个简单的web聊天界面
为了方便,我选择Mvc自带的bootstrap V5.1前端框架来实现。项目中找到Views/Home/Index.cshtml文件并打开,然后把页面中的Html标签替换为下面的内容:
<div class="text-center">
<h3>AI对话</h3>
</div>
<div class="container">
<div id="messagesList" style="min-height:300px;" class="border border-1 p-2"> </div>
<div class="input-group mt-3">
<textarea type="text" class="form-control" id="messageInput" rows="3" placeholder="请输入聊天内容"></textarea>
</div>
<div class="input-group mt-3">
<input type="button" id="sendButton" value="发送" class="btn btn-primary" />
</div>
</div>
div>
页面中我们加入了标题、内容显示框、消息输入框及发送按钮,效果如下:

接下来,在页面的底部加入以下js代码:
<script type="text/javascript">
//内容显示框
var messagesList = document.getElementById("messagesList")
//消息输入框
var messageInput = document.getElementById("messageInput");
//发送按钮
var sendButton = document.getElementById("sendButton");
// 定义一个XMLHttpRequest对象,用于发送请求和接收响应
var httpRequest = new XMLHttpRequest();
//发送按钮绑定click事件
sendButton.addEventListener("click", function (event) {
var message = messageInput.value;
if (message.length == 0) {
alert('请输入聊天内容');
return;
}
send(message);
event.preventDefault();
});
function send(message) {
//向内容显示框中追加发送的内容
var div = document.createElement("div");
div.className = "alert alert-secondary";
div.textContent = `Me:${message}`;
messageInput.value = '';
messagesList.appendChild(div);
//向内容显示框中追加ChatGpt返回的内容
div = document.createElement("div");
div.className = "alert alert-primary";
messagesList.appendChild(div);
div.textContent = "……";
//创建FormData格式消息
var formData = new FormData();
formData.set('message', message);
//添加事件监听器
httpRequest.onload = function () {
//处理响应数据
div.textContent = httpRequest.response;
};
httpRequest.onerror = function () {
//请求失败时处理错误
console.log("请求失败");
};
//打开请求,设置请求方法和地址,并设置异步为true
httpRequest.open("POST", "api/chat", true);
httpRequest.send(formData);//发送请求
}
</script>
我们对发送按钮绑定了一个点击事件,用于提交对话内容,通过定义一个XMLHttpRequest对象,来实现异步发送请求和接收响应,并采用POST方式提交,因此服务端需要做稍微调整,把ChatController中的Input方法由HttpGet改为HttpPost,并增加了一个从form表单中接收消息的message参数,传递给ChatGPT,如下图所示:

我们运行项目看一下效果:

此时还有一点小瑕疵,与ChatGPT的对话是有限制的,在发出消息至收到ChatGPT的回复期间内,我们是不可以再发起请求的,因此在消息发出后是需要锁定发送按钮的,太晚啦,就先到这吧,还有很多要改进的地方,一点点来,在这里先做个预告,接下来我将使用ChatGPT的流式响应及C#8.0中的异步流输出来提高服务端性能,采用SSE通信并实现打字机效果,请大家多多关注。