
人工智慧(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聊天
很好! 這是一個互動式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的情況下按預期工作
這看起來很酷!但新增一些造型會讓它看起來像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工作
用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的輸出
程式碼的後端部分就這樣結束了。下一部分將使用剛剛建立的端點( 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
如果你在 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工作
恭喜你完成了這個專案!全棧聊天機器人的工作更多,但它幫助我們分離了關注點,建立了一個更安全和有吸引力的應用程式,併為使用者提供了更好的體驗。所以,這些努力是值得的。你可以在GitHub上找到這一部分的程式碼。
小結
本教學希望向你展示,任何具有基本程式設計知識的人都可以構建人工智慧驅動的軟體。你學會了如何使用React和Nodejs構建一個聊天機器人,我們還討論了每種技術的利弊。最後,我們建立了一個既實用、安全又有視覺吸引力的解決方案。讀完本教學後,你現在可以探索AI的功能,如影象處理和音訊互動。花點時間瀏覽一下文件,看看你可以如何擴充套件我們在這裡涉及的內容。

評論留言