人工智慧(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的功能,如影象處理和音訊互動。花點時間瀏覽一下文件,看看你可以如何擴充套件我們在這裡涉及的內容。
評論留言