人工智能 (AI) 最近掀起了波瀾,ChatGPT 通過 chat completion 功能徹底改變了互聯網。
你可以用它做很多事情:起草電子郵件或其他文章、回答文檔相關的問題、創建會話代理、為你的軟件提供自然語言界面、輔導各種科目、翻譯語言等等。
本文將教會你使用 chat completion 功能構建聊天應用程序的基礎知識,讓每個程序員都能輕鬆上手。 它並不像看起來那麼難。
你將學到以下內容:
- 如何僅使用 Node.js 創建 CLI 聊天應用程序
- 如何僅使用 React 構建聊天應用程序
- 如何結合 React 和 Node.js 來創建更好的聊天 AI 軟件
本文的內容將基於 gpt-3.5-turbo 模型
所需知識
本教程需要 JavaScript、CSS、React 和 Node.js 的基本知識。
你還需要在 chatGPT 的 OpenAI 平台上擁有一個帳户。 你可以在這裏創建一個
如何使用 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 keys 中找到你的 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);
});
此代碼調用觸發接口 https://api.openai.com/v1/chat/completions 的 createChatCompletion 函數。 該函數接受一個參數對象(正在使用的 chatGPT 模型 和用户與 AI 之間的 messages 數組。我們將在下一章中瞭解如何使用 messages 數組來保存聊天記錄並改進應用程序)。
每條消息都是一個對象,包含 role(即誰發送了消息。當消息來自人時,這個值為 user ;如果它來自 AI,則該值可以是 assistant)和 content(發送的信息)
最後,代碼打印來自 AI 的響應內容(res.data.choices[0].message.content),使用以下命令在終端中運行文件:
node index
這將在幾秒鐘後返回 AI 的響應
這就是創建聊天機器人所需的一切!
但是,為了使應用程序更具交互性,我們需要讓程序可以接收用户輸入消息而不是將消息內容硬編碼到代碼中。 readline 模塊將在這方面幫助我們。
要使其具有交互性,請刪除輸入的最後一個代碼並添加以下內容:
const userInterface = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
此代碼在終端中創建一個 UI,允許用户輸入他們的問題。
接下來,使用以下代碼提示用户輸入消息:
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- 顯示 AI 的響應後,將提示用户在
then中輸入另一條消息
添加 dotenv
npm i dotenv
根目錄創建 .env 文件,在文件中編寫以下環境變量(你自己的賬號的 Configuration 信息)
ORG = "org-xxx"
API_KEY = "sk-xxx"
修改 index.js 文件
...
...
import * as dotenv from 'dotenv'
dotenv.config()
const configuration = new Configuration({
organization: process.env.ORG,
apiKey: process.env.API_KEY,
})
最後記得創建項目的 .gitignore 文件,添加下面的內容
node_modules
.DS_Store
.env
你可以在這裏看到所有的代碼
https://github.com/zidanDirk/nodejs-chatgpt-tutorial-cn/
運行文件並與 AI 對話。 它將如下圖所示:
非常好! 這是一個交互式 CLI 聊天工具。
這對少數人(如工程師)有用,但它具有良好的安全性,因為它可以運行在服務器端
但是其他可能不瞭解如何使用 CLI 應用程序的人呢? 他們將需要更易於使用、具有更友好的用户界面 (UI) 和用户體驗 (UX) 的東西。 下一節將重點介紹如何使用 React 構建此類應用程序。
如何使用 React 創建一個聊天程序
本節旨在幫助前端開發人員加快使用 ChatGPT API 的速度,以創建聊天應用程序並構建更好的用户界面,從而為用户提供更好的體驗。 你可以將在這裏獲得的知識應用到其他前端框架或庫中。
首先要做的是設置一個基本的 React 模版。 為此,我將使用 Vite。 你可以使用 Vite 作為搭建任何現代 JavaScript 前端項目的腳手架。 使用以下命令:
npm create vite@latest
✔ Project name: react-chatgpt-tutorial-cn
✔ Select a framework: › React
✔ Select a variant: › JavaScript
此命令將提示你為項目創建名稱和文件夾,並選擇框架或庫(本教程使用 React)。 之後,你將進入到該文件夾並運行以下命令:
npm install
npm run dev
這些命令將安裝必要的依賴項並在端口 5173 上啓動本地服務器
接下來,使用以下命令安裝 OpenAI:
npm i openai
這個模塊可以訪問我們創建聊天應用程序所需的一切。
現在我們準備開始編寫代碼了!
定位到 src/App.jsx 文件並刪除它所有的內容。添加下面的導入語句
import { useState } from "react";
import { Configuration, OpenAIApi } from "openai";
上面的代碼導入了用於設置配置值的 Configuration 和 OpenAIApi,使我們能夠訪問 chat completion 功能。
之後,像這樣構建配置:
const configuration = new Configuration({
organization: "org-xxxx",
apiKey: "sk-xxxx",
});
此代碼創建 Configuration 對象的新實例。 在其中,你將為 organization 和 apiKey 輸入值。你可以在設置中找到你的組織的詳細信息,在 API keys 中找到你的 apiKey 信息。 如果你沒有現有的 API Key,您可以創建它。
配置後輸入以下代碼,創建一個新的OpenAI API實例:
const openai = new OpenAIApi(configuration);
我們將在整個項目中使用它。
創建並導出默認函數:
function App() {
return <main>
<h1>對話 AI 教程</h1>
</main>
}
在 return 之前設置下面的 state
const [message, setMessage] = useState("");
const [chats, setChats] = useState([]);
const [isTyping, setIsTyping] = useState(false);
message將保存從應用程序發送到 AI 的信息。chats數組將跟蹤雙方(用户和 AI)發送的所有消息。isTyping變量將通知用户當前機器人是否正在輸入。
在 h1 標籤下鍵入以下代碼行
<div className={isTyping ? "" : "hide"}>
<p>
<i>{isTyping ? "正在輸入..." : ""}</i>
</p>
</div>
每當用户等待 AI 的響應時,上面的代碼將顯示 正在輸入...
通過將以下代碼添加到 main 元素中,創建一個用户可以在其中鍵入消息的表單:
<form action="" onSubmit={(e) => chat(e, message)}>
<input
type="text"
name="message"
value={message}
placeholder="在這裏輸入消息並按下回車鍵..."
onChange={(e) => setMessage(e.target.value)}
/>
</form>
此代碼創建一個具有一個輸入項的表單。 每當通過按 回車 鍵提交表單時,它都會觸發 chat 回調函數。
chat 回調函數將會接受兩個參數(e 和 message),像這樣:
const chat = async (e, message) => {
}
函數的內容是這樣的:
const chat = async (e, message) => {
e.preventDefault();
if (!message) return;
setIsTyping(true);
}
上面的代碼阻止表單重新刷新網頁,檢查在提交之前是否鍵入了消息,並將 isTyping 設置為 true 來告知應用程序已開始處理用户的輸入。
ChatGPT 響應的消息的格式採用以下模式:
{role: user | assistant, content: message to be sent }
每條消息(content)都必須顯示發送者。 當聊天來自 AI 時,role 是 assitant,但如果是來自人類,則 role 是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:
"你現在是 EbereGPT。 你可以幫助完成圖形設計任務",
},
...chats,
],
})
createChatCompletion 函數至少需要 2 個參數(model 和 messages):
model指定了正在使用的 chatGPT 版本messages是到目前為止用户和 AI 之間的所有消息的列表,以及讓 AI 瞭解它可以提供什麼樣的幫助的系統消息。
{
role: "system",
content: "你現在是 EbereGPT。 你可以幫助完成圖形設計任務",
}
你可以將 content 更改為適合你的任何內容
messages 不必是數組並且包含多個對象。 它可以只是一條消息。 但是當它是一個數組時,它提供了 AI 可以依賴的消息歷史記錄,以便在未來提供更好的回覆,並且它可以減少用户的輸入,因為可以不需要一直進行過度描述。
createChatCompletion 函數返回的是一個 promise 對象,所以需要使用 then 和 catch 來獲取響應
.then((res) => {
msgs.push(res.data.choices[0].message);
setChats(msgs);
setIsTyping(false);
})
.catch((error) => {
console.log(error);
});
此代碼將 AI 返回的消息添加到 chats 數組並將 isTyping 設置為 false,表示 AI 已完成回覆。
現在應該在每次發送消息時收到反饋(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
輸出應該如下所示:
這簡直泰褲辣
如果你是一步一步按照我上述的教程編碼,那你還需要在這個時候添加你的樣式,讓你的應用更加美觀。用下面的代碼替換 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;
}
.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;
}
使用 React 和 ChatGPT 創建聊天機器人的過程到此結束。 它並不像聽起來那麼難。
但是像這樣的前端應用程序最適合演示,而不是生產。 以這種方式創建應用程序的問題是前端將 API 密鑰暴露給網絡攻擊。
要解決這個問題,明智的做法是將 API Key 和 Organisation Id 保存在雲中安全的某個地方並引用它,或者為您的應用程序構建一個安全性更高的後端。
本章的代碼你可以在 這裏 獲得
下一節將解決這個問題。
如何結合 React 和 Node.js 製作全棧聊天 AI 軟件
本部分現在將結合前面部分的功能來構建更安全的應用程序,同時展示更好的 UI 和 UX
我們將通過使用服務器來改進 Node 部分,為前端的調用暴露一個接口,並簡化前端與後端的交互,而不是直接調用 OpenAI
如何搭建項目
這部分將創建項目所需的文件夾和文件。
創建項目目錄:
mkdir react-nodejs-chatgpt-tutorial-cn
進入目錄
cd react-nodejs-chatgpt-tutorial-cn
使用 Vite 創建 React 項目,命名為 frontend ,使用以下命令
npm create vite@latest
接着我們進入目錄進行安裝和運行
npm install
npm run dev
這些命令將安裝必要的依賴項並在端口 5173 上啓動本地服務器
創建後端目錄:
mkdir backend
現在進入到後端文件夾並使用以下命令初始化項目:
cd backend
npm init -y
這將創建一個 package.json 文件來跟蹤項目詳細信息
將以下代碼行添加到文件中:
"type": "module"
這將使你能夠使用 ES6 模塊導入語句
使用下面的命令來安裝 OpenAI 和其他依賴項
npm i openai body-parser cors express dotenv
創建一個包含所有代碼的文件。 將其命名為 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";
import * as dotenv from 'dotenv'
dotenv.config()
接下來,設置 express、要監聽的端口、用於接收輸入的 body-parser 以及允許前端和後端之間跨域通信的 cors ,設置環境變量的 dotenv ,使用以下代碼:
const app = express();
const port = 8000;
app.use(bodyParser.json());
app.use(cors());
最後輸入下面的代碼
app.listen(port, () => {
console.log(`正在監聽端口 ${port} ...`);
});
這樣就完成了服務器設置。
當你運行 index.js 時,應該得到以下輸出:
正在監聽端口 8000 ...
如何創建一個接口
在這一部分中,我們將構建一個接口,該接口將從前端接收消息並將響應返回給調用者。
像我們在前幾節中所做的那樣,首先建立配置參數:
const configuration = new Configuration({
organization: process.env.organization,
apiKey: process.env.apiKey,
});
const openai = new OpenAIApi(configuration);
創建 backend/.env 文件,在 .env 文件中配置 organization 和 apiKey
organization = "xxxx"
apiKey="xxx"
接下來,使用以下代碼創建異步 POST 路由:
app.post("/", async (request, response) => {
});
將使用 http://localhost:8000/ 調用此接口
在回調函數中,輸入以下代碼以接收從請求體(request.body)輸入的聊天信息:
const { chats } = request.body;
現在像我們在 React 部分中所做的那樣調用 createChatCompletion 方法:
const result = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content: "你現在是 EbereGPT。 你可以幫助完成圖形設計任務",
},
...chats,
],
});
這裏的區別在於,我們沒有使用 then...catch... 塊,而是將其分配給一個變量(result)並使用 response.json() 返回響應,如以下代碼所示:
response.json({
output: result.data.choices[0].message,
});
你可以在這裏查詢到相關的代碼
如何在前端連接後端服務
這部分將我們帶到前端,我們將在其中創建一個表單。 表單將通過 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>全棧 AI 聊天程序</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 ? "正在輸入..." : ""}</i>
</p>
</div>
<form action="" onSubmit={(e) => chat(e, message)}>
<input
type="text"
name="message"
value={message}
placeholder="在這裏輸入消息並按下回車鍵..."
onChange={(e) => setMessage(e.target.value)}
/>
</form>
</main>
);
}
export default App;
此代碼類似於上一節中的代碼。 但是我們刪除了 OpenAI 配置,因為在本節中我們將不再需要它們。
此時,每當提交表單時都會彈出警報。 這將在一瞬間改變。
在聊天功能中,去掉警告消息並輸入以下內容:
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 中
如果將以下樣式添加到 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: none;
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;
}
.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);
color: white;
}
input:focus{
outline: none;
}
以下就是目前的 UI
恭喜你完成了這個項目!
全棧聊天機器人的工作量更大,但它幫助我們分離關注點,構建更安全、更有吸引力的應用程序,併為用户提供更好的體驗。 所以這些努力是值得的。
你可以在這裏找到這個章節的代碼
總結
本教程希望向你展示任何具有基本編程知識的人都可以構建 AI 驅動的軟件。 學習瞭如何使用 React 和 Nodejs 構建聊天機器人,我們討論了每種技術的優缺點。 最後,我們構建了一個既實用、安全又美觀的解決方案。
閲讀本教程後,你現在可以探索 AI 的更多功能,例如圖像處理和音頻交互。 花點時間閲讀文檔,看看如何擴展我們在這裏介紹的內容。最後感謝大家對本文的支持~歡迎點贊收藏,在評論區留下你的高見 🌹🌹🌹
其他
- 本文是翻譯文,原文地址
-
代碼倉庫
- https://github.com/zidanDirk/react-nodejs-chatgpt-tutorial-cn
- https://github.com/zidanDirk/react-chatgpt-tutorial-cn
- https://github.com/zidanDirk/nodejs-chatgpt-tutorial-cn