0


如何利用OpenAI自主搭建一个AI聊天机器人

人工智能(AI)最近一直在掀起波澜,ChatGPT的Chat completions彻底改变了互联网。

你可以用它做很多事情:起草电子邮件或其他文章,回答关于一组文件的问题,创建对话代理,给你的软件一个自然语言界面,辅导各种科目,翻译语言,等等。本教程使用Chat completions功能建立一个AI聊天应用程序的基本知识,使每个程序员都能轻松上手。它并不像看起来那样艰难。在你跟随本教程时,你会看到这一点。

您将学到以下内容:

  • 如何只用Node.js创建一个CLI聊天应用程序。
  • 如何只用React建立一个聊天应用。
  • 如何结合React和Node.js来创建更好的聊天AI软件。

本教程将以 gpt-3.5-turbo 模型为基础。

前提条件

本教程需要JavaScript、CSS、React和Node.js的基本知识。你还需要一个OpenAI平台的账户,chatGPT就在这个平台上。它是免费的,所以你可以在这里创建一个。

如何用Node.js创建一个CLI聊天AI应用程序

本节将重点介绍创建一个只在终端使用Node.js运行的聊天应用程序。

首先,为该项目创建一个目录:

mkdir nodejs-chatgpt-tutorial

导航到该文件夹:

cd nodejs-chatgpt-tutorial

初始化该项目:

npm init -y

这将创建一个

package.json

文件来跟踪项目的细节

在该文件中添加以下一行代码:

"type": "module"

这将使你能够使用ES6模块的导入语句。用以下命令安装OpenAI:

npm i openai

创建一个文件,所有的代码都在其中。命名为

index.js

touch index.js

从OpenAI模块导入

Configuration

OpenAIApi

,从

readline

模块导入readline:

import { Configuration, OpenAIApi } from "openai";

import readline from "readline";

像这样建立OpenAI的配置:

const configuration = new Configuration({

organization: "org-0nmrFWw6wSm6xIJXSbx4FpTw",

apiKey: "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",

});

这段代码创建了一个

Configuration

对象的新实例。在它里面,你将输入你的

organization

apiKey

的值。你可以在设置中找到你的组织的详细信息,在API密钥中找到你的apiKey信息。如果你没有现有的API Key,你可以创建它。在配置后输入以下代码,创建一个新的OpenAI API实例:

const openai = new OpenAIApi(configuration);

你将在整个项目中使用它。

输入下面的代码来测试

createChatCompletion

函数:

openai

.createChatCompletion({

model: "gpt-3.5-turbo",

messages: [{ role: "user", content: "Hello" }],

})

.then((res) => {

console.log(res.data.choices[0].message.content);

})

.catch((e) => {

console.log(e);

});

这段代码调用

createChatCompletion

函数,触发一个端点(

https://api.openai.com/v1/chat/completions

)。该函数接受一个参数对象(使用中的chatGPT

model

和用户与AI之间的

messages

数组。我们将在下一节中研究如何使用

messages

数组来保存聊天历史并改进应用程序)。每个消息都是一个对象,包含

role

(即谁发送了该消息。如果是来自人工智能,该值可以是助理,如果是来自人类的消息,该值可以是用户)和

content

(发送的信息)。最后,代码打印了来自人工智能的响应(

res.data.choice[0].message.content

)。用这个命令在终端运行该文件:

node index

这将在几秒钟后返回人工智能的响应。这就是创建聊天机器人的全部内容!但通过请求用户输入信息而不是将信息内容硬编码到代码中,使应用程序更具互动性将是很有帮助的。readline模块将在这方面帮助我们。要使其具有互动性,请删除你最后输入的代码,并添加以下内容:

const userInterface = readline.createInterface({

input: process.stdin,

output: process.stdout,

});

这段代码在终端创建了一个用户界面,允许用户输入他们的问题。

接下来,用下面的代码提示用户输入一个信息:

userInterface.prompt();

最后,输入以下代码:

userInterface.on("line", async (input) => {

await openai

.createChatCompletion({

model: "gpt-3.5-turbo",

messages: [{ role: "user", content: input }],

})

.then((res) => {

console.log(res.data.choices[0].message.content);

userInterface.prompt();

})

.catch((e) => {

console.log(e);

});

});

在上面的代码中

  • 当用户输入东西并点击 Enter 时,上面的代码会触发一个回调函数。
  • 它将用户输入的任何内容作为 input
  • input 的内容现在被用作 content
  • 在显示人工智能的响应后,在 then 块中提示用户输入另一条信息。

查看GitHub上的所有代码。运行该文件并与人工智能进行对话。它将看起来像下面的图片:

与AI的CLI聊天

与AI的CLI聊天

很好! 这是一个交互式CLI聊天。这对少数人(如工程师)很有用,但它有很好的安全性,因为它是在服务器端。但其他可能不了解如何使用CLI应用程序的人呢?他们将需要一些更容易使用的、具有更好的用户界面(UI)和用户体验(UX)的东西。下一节将重点介绍使用React构建这种应用程序。

如何使用React创建一个聊天应用程序

本节旨在帮助前端开发者快速掌握ChatGPT API,以创建一个聊天应用程序,并构建一个更好的用户界面,给用户带来更好的体验。你可以把在这里获得的知识应用于其他前端框架或库。

首先要做的是设置一个基本的React模板。我将使用Vite来实现这一目的。你可以用Vite来搭建任何现代JavaScript前端项目的脚手架。使用下面的命令:

npm create vite@latest

该命令将提示你为你的项目创建一个名称和文件夹,并选择一个框架或库(本教程使用React)。之后,你将导航到该文件夹,并运行以下命令:

npm install

npm run dev

这些命令将安装必要的依赖性,并在

5173

端口启动本地服务器,接下来,用以下命令安装OpenAI:

npm i openai

这个模块提供了我们创建聊天应用程序所需的所有权限。现在我们准备开始写代码了!导航到

src/App.jsx

文件,删除其所有内容。然后添加以下导入语句:

import { useState } from "react";

import { Configuration, OpenAIApi } from "openai";

上面的代码导入了用于设置配置值的

Configuration

和用于让我们访问Chat completions的

OpenAIApi

。之后,像这样建立配置:

const configuration = new Configuration({

organization: "org-0nmrFWw6wSm6xIJXSbx4FpTw",

apiKey: "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",

});

这段代码创建了一个

Configuration

对象的新实例。在它里面,你输入你的

organization

apiKey

的值。你可以在设置中找到你的组织的详细信息,你的apiKey信息在API密钥中。如果你没有现有的API密钥,你可以创建它。在配置后输入以下代码,创建一个新的OpenAI API实例:

const openai = new OpenAIApi(configuration);

我们将在整个项目中使用它。创建并导出一个默认函数:

function App() {

return (

<main>

<h1>Chat AI Tutorial</h1>

<main/>

);

}

export default App;

这个函数将容纳其余的代码。在

return

语句之前设置以下状态:

const [message, setMessage] = useState("");

const [chats, setChats] = useState([]);

const [isTyping, setIsTyping] = useState(false);
  • message 将保存从应用程序发送至人工智能的信息。
  • chats 数组将记录双方(用户和人工智能)发送的所有信息。
  • isTyping 变量将通知用户,机器人是否正在打字。

在h1标签下输入以下几行代码

<div className={isTyping ? "" : "hide"}>

<p>

<i>{isTyping ? "Typing" : ""}</i>

</p>

</div>

上面的代码将显示

Typing

,只要用户在等待AI的响应。创建一个表单,用户可以在其中输入信息,将下面的代码添加到

main

元素中:

<form action="" onSubmit={(e) => chat(e, message)}>

<input

type="text"

name="message"

value={message}

placeholder="Type a message here and hit Enter..."

onChange={(e) => setMessage(e.target.value)}

/>

</form>

这段代码创建了一个有一个输入的表单。每当点击

Enter

键提交表单时,就会触发

chat

函数。聊天函数将接受两(2)个参数(

e

message

),像这样:

const chat = async (e, message) => {

}

在该函数中输入以下几行:

e.preventDefault();

if (!message) return;

setIsTyping(true);

上面的代码防止

form

重新加载网页,检查提交前是否输入了信息,并将

isTyping

设置为

true

,以表明应用程序已经开始处理所提供的输入。ChatGPT有一个信息的格式。它采取以下模式:

{role: user | assistant, content: message to be sent

每条信息(

content

)都必须显示谁发送的。当聊天是来自人工智能时,角色是

assistant

,但如果是来自人类,则是

user

。因此,在发送消息之前,一定要正确地格式化它,并像这样把它添加到数组(

chats

)中:

let msgs = chats;

msgs.push({ role: "user", content: message });

setChats(msgs);

setMessage("");

上面的最后一行清除了输入,以便用户输入另一个音符。现在我们将通过使用下面的代码触发

createChatCompletion

函数来调用

createChatCompletion

端点:

await openai

.createChatCompletion({

model: "gpt-3.5-turbo",

messages: [

{

role: "system",

content:

"You are a EbereGPT. You can help with graphic design tasks",

},

...chats,

],

})
createChatCompletion

函数至少需要两(2)个参数(

model

messages

):

  • 模型指定了正在使用的chatGPT的版本。
  • 消息是迄今为止用户和人工智能之间的所有消息的列表,以及一个系统消息,让人工智能了解它能提供什么样的帮助。
{

role: "system",

content:

"You are a EbereGPT. You can help with graphic design tasks",

}

你可以把内容改成任何适合你的东西。

messages

不一定要在数组中包含一个以上的对象。它可以只是一条消息。但是当它是一个数组时,它提供了一个消息历史,人工智能可以依靠它在未来给出更好的回复,而且它使用户打字更少,因为可能没有必要一直过度描述。

createChatCompletion

函数返回一个承诺。所以使用

then...catch...

块来获取响应。

.then((res) => {

msgs.push(res.data.choices[0].message);

setChats(msgs);

setIsTyping(false);

})

.catch((error) => {

console.log(error);

});

这段代码将从人工智能返回的消息添加到聊天数组中,并将

isTyping

设置为

false

,表示人工智能已经完成了回复。你现在应该在每次发送消息时收到反馈(Typing):

聊天应用程序在人工智能即将作出反应时给予反馈

聊天应用程序在人工智能即将作出反应时给予反馈

现在是显示聊天历史给用户看的时候了。在

h1

标签下面输入以下代码:

<section>

{chats && chats.length

? chats.map((chat, index) => (

<p key={index} className={chat.role === "user" ? "user_msg" : ""}>

<span>

<b>{chat.role.toUpperCase()}</b>

</span>

<span>:</span>

<span>{chat.content}</span>

</p>

))

: ""}

</section>

上面的代码循环浏览

chats

,并将它们一个接一个地显示给用户。它把

role

的大写字母和消息的

content

并排输出。以下是输出结果的样子:

聊天机器人在没有CSS的情况下按预期工作

聊天机器人在没有CSS的情况下按预期工作

这看起来很酷!但添加一些造型会让它看起来像WhatsApp或Messenger一样吸引人。用以下内容替换

src/index.css

文件的内容:

:root {

font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;

line-height: 1.5;

font-weight: 400;

color-scheme: light dark;

color: rgba(255, 255, 255, 0.87);

background-color: #242424;

font-synthesis: none;

text-rendering: optimizeLegibility;

-webkit-font-smoothing: antialiased;

-moz-osx-font-smoothing: grayscale;

-webkit-text-size-adjust: 100%;

}

h1 {

font-size: 3.2em;

line-height: 1.1;

text-align: center;

position: sticky;

top: 0;

background-color: #242424;

}

main{

max-width: 500px;

margin: auto;

}

p{

background-color: darkslategray;

max-width: 70%;

padding: 15px;

border-radius: 50px;

}

p span{

margin: 5px;

}

p span:first-child{

margin-right: 0;

}

.user_msg{

text-align: right;

margin-left: 30%;

display: flex;

flex-direction: row-reverse;

}

.hide {

visibility: hidden;

display: none;

}

form{

text-align: center;

position: sticky;

bottom: 0;

}

input{

width: 100%;

height: 40px;

border: none;

padding: 10px;

font-size: 1.2rem;

}

input:focus{

outline: none;

}

并删除

src/App.css

文件中的所有样式。

你可以在GitHub上找到完整的代码。现在应用程序应该有一个新的外观:

聊天机器人如期使用CSS工作

聊天机器人如期使用CSS工作

用React和ChatGPT创建一个聊天机器人的工作就这样结束了。它并不像听起来那么困难。但像这样的前端应用最好是用于演示,而不是生产。这样创建应用程序的问题是,前端将API密钥暴露给网络攻击。

要解决这个问题,明智的做法可能是将API Key和Organisation Id保存在云端某个安全的地方并引用它,或者为你的应用程序建立一个具有更好安全性的后端。下面的部分将致力于解决这个问题。

如何结合React和Node.js来创建一个全栈式的聊天AI软件

本节现在将加入前几节的力量,建立一个更安全的应用程序,同时表现出更好的用户界面和用户体验。

我们将改进Node部分,使用服务器来暴露一个端点供前端使用,并简化前端与后台的交互,而不是直接联系OpenAI。

如何设置项目

这一部分将创建项目所需的文件夹和文件。创建项目目录:

mkdir react-node-chatgpt-tutorial

导航到该文件夹:

cd react-node-chatgpt-tutorial

使用Vite安装React,并将文件夹命名为

frontend

。使用这个命令:

npm create vite@latest

之后,你将浏览到该文件夹并运行以下命令:

npm install

npm run dev

这些命令将安装必要的依赖,并在

5173

端口启动本地服务器。创建后台文件夹:

mkdir backend

现在导航到后端文件夹,用这个命令初始化项目:

npm init -y

这将创建一个

package.json

文件来跟踪项目的细节。在该文件中添加以下一行代码:

"type": "module"

这将使ES6模块导入语句的使用成为可能。用下面的命令安装OpenAI和其他依赖项:

npm i openai body-parser cors express

创建一个文件,所有的代码都在其中。命名为

index.js

touch index.js

这就完成了项目的设置。现在有两个文件夹(

frontend

backend

)。

如何搭建服务器

这一部分将着重于创建一个本地服务器,以监听

8000

端口。

首先要做的是像这样导入必要的模块:

import { Configuration, OpenAIApi } from "openai";

import express from "express";

import bodyParser from "body-parser";

import cors from "cors";

接下来,设置

express

、监听

port

、用于接收输入的

body-parser

以及允许前端和后端自由通信的

cors

。使用下面的代码:

const app = express();

const port = 8000;

app.use(bodyParser.json());

app.use(cors());

最后,输入以下代码:

app.listen(port, () => {

console.log(`listening on port ${port}`);

});

这就完成了服务器的设置。当你运行

index.js

时,你应该得到以下输出:

listening on port 8000
如何创建端点

在这一部分,我们将建立一个端点,该端点将使用请求体接收来自前端的消息,并向调用者返回一个响应。开始时,我们要像前几节那样建立配置参数:

const configuration = new Configuration({

organization: "org-0nmrFWw6wSm6xIJXSbx4FpTw",

apiKey: "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",

});

const openai = new OpenAIApi(configuration);

接下来,使用下面的代码创建一个异步POST路由:

app.post("/", async (request, response) => {

});

这个端点将使用

http://localhost:8000/

,在回调函数中,输入以下代码,从请求体(

request.body

)接收

chats

的输入:

const { chats } = request.body;

现在像我们在React部分做的那样,调用

createChatCompletion

端点:

const result = await openai.createChatCompletion({

model: "gpt-3.5-turbo",

messages: [

{

role: "system",

content: "You are a EbereGPT. You can help with graphic design tasks",

},

...chats,

],

});

这里的区别是,我们没有使用

then...catch...

块,而是将其分配给一个变量(

result

),并使用

response.json()

返回响应,如以下代码:

response.json({

output: result.data.choices[0].message,

});

在GitHub上找到这部分的代码。以下是在Postman上测试时的输出:

来自Postman的输出

来自Postman的输出

代码的后端部分就这样结束了。下一部分将使用刚刚创建的端点(

http://localhost:8000/

)连接前端和后端。

如何从前端连接到后端

这一部分把我们带到前台,在那里我们将创建一个表单。该表单将通过API端点向后端发送消息,并通过相同的媒介接收响应。导航到

frontend/src/App.jsx

文件并输入以下代码:

import { useState } from "react";

function App() {

const [message, setMessage] = useState("");

const [chats, setChats] = useState([]);

const [isTyping, setIsTyping] = useState(false);

const chat = async (e, message) => {

e.preventDefault();

if (!message) return;

setIsTyping(true);

let msgs = chats;

msgs.push({ role: "user", content: message });

setChats(msgs);

setMessage("");

alert(message);

};

return (

<main>

<h1>FullStack Chat AI Tutorial</h1>

<section>

{chats && chats.length

? chats.map((chat, index) => (

<p key={index} className={chat.role === "user" ? "user_msg" : ""}>

<span>

<b>{chat.role.toUpperCase()}</b>

</span>

<span>:</span>

<span>{chat.content}</span>

</p>

))

: ""}

</section>

<div className={isTyping ? "" : "hide"}>

<p>

<i>{isTyping ? "Typing" : ""}</i>

</p>

</div>

<form action="" onSubmit={(e) => chat(e, message)}>

<input

type="text"

name="message"

value={message}

placeholder="Type a message here and hit Enter..."

onChange={(e) => setMessage(e.target.value)}

/>

</form>

</main>

);

}

export default App;

这段代码与上一节的代码相似。但我们删除了OpenAI的配置,因为我们在本节中不再需要它们。

在这一点上,每当表单被提交时,就会弹出一个警报。这一点一会儿就会改变。在聊天函数中,去掉

alert

信息,然后输入以下内容:

fetch("http://localhost:8000/", {

method: "POST",

headers: {

"Content-Type": "application/json",

},

body: JSON.stringify({

chats,

}),

})

.then((response) => response.json())

.then((data) => {

msgs.push(data.output);

setChats(msgs);

setIsTyping(false);

})

.catch((error) => {

console.log(error);

});

上面的代码调用了我们创建的端点,并传入

chats

数组供其处理。然后它返回一个响应,该响应被添加到

chats

中并显示在用户界面上:

样式设计前的全栈聊天UI

样式设计前的全栈聊天UI

如果你在

frontend/src/index.css

文件中添加以下样式,UI会看起来更好:

:root {

font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;

line-height: 1.5;

font-weight: 400;

color-scheme: light dark;

color: rgba(255, 255, 255, 0.87);

background-color: #242424;

font-synthesis: 无;

text-rendering: optimizeLegibility;

-webkit-font-smoothing: antialiased;

-moz-osx-font-smoothing: grayscale;

-webkit-text-size-adjust: 100%;

}

html, body{

scroll-behavior: smooth;

}

h1 {

font-size: 3.2em;

line-height: 1.1;

text-align: center;

position: sticky;

top: 0;

background-color: #242424;

}

main{

max-width: 800px;

margin: auto;

}

p{

background-color: darkslategray;

max-width: 70%;

padding: 15px;

border-radius: 50px;

}

p span{

margin: 5px;

}

p span:first-child{

margin-right: 0;

}

.user_msg{

text-align: right;

margin-left: 30%;

display: flex;

flex-direction: row-reverse;

}

.hide {

visibility: hidden;

display: none;

}

form{

text-align: center;

position: sticky;

bottom: 0;

}

input{

width: 100%;

height: 40px;

border: none;

padding: 10px;

font-size: 1.2rem;

background-color: rgb(28, 23, 23);

}

input:focus{

outline: none;

}

并删除

frontend/src/App.css

文件中的所有样式。

这一部分的代码在GitHub上。现在,这里是最终的输出:

全栈式聊天机器人如期使用CSS工作

全栈式聊天机器人如期使用CSS工作

恭喜你完成了这个项目!全栈聊天机器人的工作更多,但它帮助我们分离了关注点,建立了一个更安全和有吸引力的应用程序,并为用户提供了更好的体验。所以,这些努力是值得的。你可以在GitHub上找到这一部分的代码。

小结

本教程希望向你展示,任何具有基本编程知识的人都可以构建人工智能驱动的软件。你学会了如何使用React和Nodejs构建一个聊天机器人,我们还讨论了每种技术的利弊。最后,我们建立了一个既实用、安全又有视觉吸引力的解决方案。读完本教程后,你现在可以探索AI的功能,如图像处理和音频互动。花点时间浏览一下文档,看看你可以如何扩展我们在这里涉及的内容。


本文转载自: https://blog.csdn.net/weixin_44026962/article/details/135704590
版权归原作者 WPHunter 所有, 如有侵权,请联系我们删除。

“如何利用OpenAI自主搭建一个AI聊天机器人”的评论:

还没有评论