如何使用 React 和 OpenAI API 構建和部署 ChatGPT 克隆應用程序
已發表: 2023-03-13隨著聊天機器人和虛擬助手的使用不斷增長,許多企業和開發人員正在尋找創建自己的人工智能聊天機器人的方法。 ChatGPT 就是這樣一種由 OpenAI 創建的聊天機器人,它能夠進行類似人類的對話並回答範圍廣泛的問題。
你要建造什麼
在本教程中,您將學習如何使用 React 和 OpenAI API 構建 ChatGPT 克隆應用程序。 如果您想在周末嘗試一個有趣且引人入勝的項目,這是深入研究 React 和 OpenAI 的絕佳機會。
您還將了解如何直接從 GitHub 存儲庫部署到 Kinsta 的應用程序託管平台,該平台提供免費的.kinsta.app域,讓您的項目快速上線。 借助 Kinsta 的免費試用版和 Hobby Tier,您無需任何費用即可輕鬆上手。
這是 ChatGPT 克隆應用程序的現場演示。
如果你想更仔細地檢查這個項目,你可以訪問它的 GitHub 存儲庫。
或者,您也可以克隆 React 應用程序啟動項目,其中包含樣式、Font Awesome CDN 鏈接、OpenAI 包和基本結構等基本元素,以幫助您入門。
要求/先決條件
本教程旨在提供“跟進”體驗。 因此,建議您使用以下工具輕鬆編寫代碼:
- 對 HTML、CSS 和 JavaScript 的基本理解
- 對 React 有一定的了解
- 在您的計算機上安裝 Node.js 和 npm(節點包管理器)或紗線
什麼是 OpenAI API?
OpenAI API 是一個基於雲的平台,允許開發人員通過 API 訪問 OpenAI 的語言模型,例如 GPT-3。 它允許開發人員在他們的應用程序中添加自然語言處理功能,如文本完成、情感分析、摘要和翻譯,而無需開發和訓練他們的模型。
要使用 OpenAI API,開發人員必須在 OpenAI 網站上創建一個帳戶並獲取 API 密鑰。 API 密鑰用於驗證 API 請求和跟踪使用情況。
獲得 API 密鑰後,開發人員可以使用 API 向語言模型提交文本並接收響應。
為什麼反應?
React 是一個流行的 JavaScript 庫,用於構建用戶界面。 根據 2022 Stack Overflow 開發者調查,它是第二大最常用的 Web 技術,市場份額為 42.62%。
React 允許開發人員創建表示用戶界面不同部分的聲明式組件。 這些組件是使用稱為 JSX 的語法定義的,它是 JavaScript 和 HTML 的組合。
由於其龐大的組件庫和工具包生態系統,開發人員可以輕鬆地使用和集成 OpenAI API 等 API,以構建複雜的聊天界面,這使其成為構建 ChatGPT 克隆應用程序的絕佳選擇。
如何設置你的 React 開發環境
安裝 React 或創建 React 項目的最佳方式是使用 create-react-app 安裝它。 一個先決條件是在您的計算機上安裝 Node.js。 要確認您已安裝 Node,請在終端中運行以下命令。
node -v
如果它提出一個版本,那麼它就存在。 使用npx需要確保你的Node版本不低於v14.0.0,你的NPM版本不低於v5.6; 否則,您可能需要通過運行npm update -g
來更新它。 了解 npm 後,您現在可以通過運行以下命令來設置 React 項目:
npx create-react-app chatgpt-clone
注意: “chatgpt-clone”是我們正在創建的應用程序名稱,但您可以將其更改為您選擇的任何名稱。
安裝過程可能需要幾分鐘。 成功後,您可以導航到該目錄並安裝 Node.js OpenAI 包,使用以下命令可以方便地從 Node.js 訪問 OpenAI API:
npm install openai
您現在可以運行npm start
以在localhost:3000上查看您的應用程序。
當使用create-react-app
命令創建 React 項目時,它會自動搭建一個文件夾結構。 與您相關的主要文件夾是src
文件夾,這是進行開發的地方。 默認情況下,此文件夾包含許多文件,但您應該只關心App.js 、 index.js和index.css文件。
- App.js : App.js文件是 React 應用程序中的主要組件。 它通常表示呈現應用程序中所有其他組件的頂級組件。
- index.js :此文件是 React 應用程序的入口點。 它是打開應用程序時加載的第一個文件,負責將App.js組件呈現給瀏覽器。
- index.css :此文件負責定義 React 應用程序的整體樣式和佈局。
如何使用 React 和 OpenAI API 構建 ChatGPT 克隆
ChatGPT 克隆應用程序將由兩個組件組成,以使應用程序更易於理解和維護。 這兩個組件是:
- 表單部分:此組件包括一個文本區域字段和一個供用戶與聊天機器人交互的按鈕。
- Answer Section :問題和相應的答案將存儲在一個數組中並顯示在該部分中。 您將按時間順序遍歷數組,首先顯示最新的。
設置 ChatGPT 克隆應用程序
在本教程中,讓我們首先構建應用程序界面,然後您可以實現功能,以便您的應用程序與 OpenAI API 交互。 首先創建您將在本教程中使用的兩個組件。 為了進行適當的組織,您將在存儲所有組件的src文件夾中創建一個組件文件夾。
表單部分組件
這是一個簡單的表單,由一個textarea
和一個提交button
組成。
// components/FormSection.jsx const FormSection = () => { return ( <div className="form-section"> <textarea rows="5" className="form-control" placeholder="Ask me anything..." ></textarea> <button className="btn"> Generate Response </button> </div> ) } export default FormSection;
這是將表單導入App.js文件時預期的樣子:
答案部分組件
此部分將顯示所有問題和答案。 當您將此部分也導入App.js文件時,這就是該部分的樣子。
您將從數組和循環中獲取這些問題和答案,使您的代碼更易於閱讀和維護。
// components/AnswerSection.jsx const AnswerSection = () => { return ( <> <hr className="hr-line" /> <div className="answer-container"> <div className="answer-section"> <p className="question">Who is the founder of OpenAi?</p> <p className="answer">OpenAI was founded in December 2015 by Elon Musk, Sam Altman, Greg Brockman, Ilya Sutskever, Wojciech Zaremba, and John Schulman.</p> <div className="copy-icon"> <i className="fa-solid fa-copy"></i> </div> </div> </div> </> ) } export default AnswerSection;
主頁
您現在已經創建了兩個組件,但是當您運行您的應用程序時不會出現任何內容,因為您需要將它們導入您的App.js文件中。 對於此應用程序,您將不會實現任何形式的路由,這意味著App.js文件將用作您的應用程序的主組件/頁面。
在導入組件之前,您可以添加一些內容,例如應用程序的標題和描述。
// App.js import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; const App = () => { return ( <div> <div className="header-section"> <h1>ChatGPT CLONE </h1> <p> I am an automated question and answer system, designed to assist you in finding relevant information. You are welcome to ask me any queries you may have, and I will do my utmost to offer you a reliable response. Kindly keep in mind that I am a machine and operate solely based on programmed algorithms. </p> </div> <FormSection /> <AnswerSection /> </div> ); }; export default App;
在上面的代碼中,這兩個組件被導入並添加到應用程序中。 當您運行您的應用程序時,您的應用程序將如下所示:
添加功能並集成 OpenAI API
您現在擁有應用程序的用戶界面。 下一步是使應用程序正常運行,以便它可以與 OpenAI API 交互並獲得響應。 首先,您需要在提交時從表單中獲取值,因為它將用於查詢 OpenAI API。
從表單中獲取數據
在 React 中,存儲和更新數據的最佳方式是使用狀態。 在功能組件中, useState()
鉤子用於處理狀態。 您可以創建一個狀態,將表單中的值分配給該狀態,並在其值發生變化時更新它。 讓我們首先將useState()
掛鉤導入FormSection.jsx組件,然後創建一個狀態來存儲和更新newQuestions
。
// components/FormSection.jsx import { useState } from 'react'; const FormSection = ({ generateResponse }) => { const [newQuestion, setNewQuestion] = useState(''); return ( // Form to submit a new question ) } export default FormSection;
接下來,您可以將textarea
字段的值分配給狀態,並創建一個onChange()
事件以在輸入值更改時更新狀態:
<textarea rows="5" className="form-control" placeholder="Ask me anything..." value={newQuestion} onChange={(e) => setNewQuestion(e.target.value)} ></textarea>
最後,您可以創建一個onClick()
事件,以便在單擊提交按鈕時加載一個函數。 該方法將在App.js文件中創建,並以newQuestion
和setNewQuestion
值作為參數作為 props 傳遞到FormSection.jsx組件中。
<button className="btn" onClick={() => generateResponse(newQuestion, setNewQuestion)}> Generate Response </button>
您現在已經創建了一個狀態來存儲和更新表單值,添加了一個作為道具從App.js文件傳遞並處理點擊事件的方法。 這是最終代碼的樣子:
// components/FormSection.jsx import { useState } from 'react'; const FormSection = ({ generateResponse }) => { const [newQuestion, setNewQuestion] = useState(''); return ( <div className="form-section"> <textarea rows="5" className="form-control" placeholder="Ask me anything..." value={newQuestion} onChange={(e) => setNewQuestion(e.target.value)} ></textarea> <button className="btn" onClick={() => generateResponse(newQuestion, setNewQuestion)}> Generate Response </button> </div> ) } export default FormSection;
下一步將是在App.js文件中創建一個方法來處理與 OpenAI API 交互的整個過程。
與 OpenAI API 交互
要在 React 應用程序中與 OpenAI API 交互並獲取 API 密鑰,您必須創建一個 OpenAI API 帳戶。 您可以使用您的谷歌帳戶或電子郵件在 OpenAI 網站上註冊一個帳戶。 要生成 API 密鑰,請單擊網站右上角的個人; 會出現一些選項; 單擊查看 API 密鑰。
單擊“創建新密鑰”按鈕,將密鑰複製到某處,就像您在此應用程序中使用它與 OpenAI 交互一樣。 您現在可以通過導入 openai 包(您已經安裝)以及配置方法來繼續初始化 OpenAI。 然後使用生成的密鑰創建一個配置,並使用它來初始化 OpenAI。
// src/App.js import { Configuration, OpenAIApi } from 'openai'; import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; const App = () => { const configuration = new Configuration({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); return ( // Render FormSection and AnswerSection ); }; export default App;
在上面的代碼中,OpenAI API 密鑰作為環境變量存儲在.env文件中。 您可以在應用程序的根文件夾中創建一個.env文件,並將密鑰存儲到變量REACT_APP_OPENAI_API_KEY
中。
// .env REACT_APP_OPENAI_API_KEY = sk-xxxxxxxxxx…
您現在可以繼續在App.js文件中創建generateResponse
方法,並傳入您已創建的表單中預期的兩個參數,以處理請求並從 API 獲取響應。
// src/App.js import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; const App = () => { const generateResponse = (newQuestion, setNewQuestion) => { // Set up OpenAI API and handle response }; return ( // Render FormSection and AnswerSection ); }; export default App;
您現在可以向 OpenAI API 發送請求。 OpenAI API 可以執行許多操作,例如問答 (Q&A)、語法糾正、翻譯等等。 對於這些操作中的每一個,選項都是不同的。 例如,Q&A 的引擎值為text-davinci-00
,而 SQL 翻譯的引擎值為code-davinci-002
。 請隨時查看 OpenAI 示例文檔以了解各種示例及其選項。
對於本教程,我們只使用問答,這是該選項的樣子:
{ model: "text-davinci-003", prompt: "Who is Obama?", temperature: 0, max_tokens: 100, top_p: 1, frequency_penalty: 0.0, presence_penalty: 0.0, stop: ["\"], }
注意:我更改了提示值。
提示是從表單發送的問題。 這意味著您需要從作為參數傳遞給generateResponse
方法的表單輸入中接收它。 為此,您將定義選項,然後使用擴展運算符創建一個包含提示的完整選項:
// src/App.js import { Configuration, OpenAIApi } from 'openai'; import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; const App = () => { const configuration = new Configuration({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); const generateResponse = async (newQuestion, setNewQuestion) => { let options = { model: 'text-davinci-003', temperature: 0, max_tokens: 100, top_p: 1, frequency_penalty: 0.0, presence_penalty: 0.0, stop: ['/'], }; let completeOptions = { ...options, prompt: newQuestion, }; }; return ( // Render FormSection and AnswerSection ); }; export default App;
至此,剩下的就是通過createCompletion
方法向 OpenAI 發送請求以獲得響應。
// src/App.js import { Configuration, OpenAIApi } from 'openai'; import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; import { useState } from 'react'; const App = () => { const configuration = new Configuration({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); const [storedValues, setStoredValues] = useState([]); const generateResponse = async (newQuestion, setNewQuestion) => { let options = { model: 'text-davinci-003', temperature: 0, max_tokens: 100, top_p: 1, frequency_penalty: 0.0, presence_penalty: 0.0, stop: ['/'], }; let completeOptions = { ...options, prompt: newQuestion, }; const response = await openai.createCompletion(completeOptions); console.log(response.data.choices[0].text); }; return ( // Render FormSection and AnswerSection ); }; export default App;
在上面的代碼中,答案的文本將顯示在您的控制台上。 隨時通過提出任何問題來測試您的應用程序。 最後一步是創建一個狀態來保存問題和答案數組,然後將此數組作為道具發送到AnswerSection組件中。 這就是App.js最終代碼的樣子:
// src/App.js import { Configuration, OpenAIApi } from 'openai'; import FormSection from './components/FormSection'; import AnswerSection from './components/AnswerSection'; import { useState } from 'react'; const App = () => { const configuration = new Configuration({ apiKey: process.env.REACT_APP_OPENAI_API_KEY, }); const openai = new OpenAIApi(configuration); const [storedValues, setStoredValues] = useState([]); const generateResponse = async (newQuestion, setNewQuestion) => { let options = { model: 'text-davinci-003', temperature: 0, max_tokens: 100, top_p: 1, frequency_penalty: 0.0, presence_penalty: 0.0, stop: ['/'], }; let completeOptions = { ...options, prompt: newQuestion, }; const response = await openai.createCompletion(completeOptions); if (response.data.choices) { setStoredValues([ { question: newQuestion, answer: response.data.choices[0].text, }, ...storedValues, ]); setNewQuestion(''); } }; return ( <div> <div className="header-section"> <h1>ChatGPT CLONE </h1> <p> I am an automated question and answer system, designed to assist you in finding relevant information. You are welcome to ask me any queries you may have, and I will do my utmost to offer you a reliable response. Kindly keep in mind that I am a machine and operate solely based on programmed algorithms. </p> </div> <FormSection generateResponse={generateResponse} /> <AnswerSection storedValues={storedValues} /> </div> ); }; export default App;
您現在可以編輯AnswerSection組件,使其從App.js接收 props 值並使用 JavaScript Map()
方法查看storedValues
數組:
// components/AnswerSection.jsx const AnswerSection = ({ storedValues }) => { return ( <> <hr className="hr-line" /> <div className="answer-container"> {storedValues.map((value, index) => { return ( <div className="answer-section" key={index}> <p className="question">{value.question}</p> <p className="answer">{value.answer}</p> <div className="copy-icon"> <i className="fa-solid fa-copy"></i> </div> </div> ); })} </div> </> ) } export default AnswerSection;
當您運行您的應用程序並通過提問對其進行測試時,答案將顯示在下方。 但是您會注意到復制按鈕不起作用。 您需要向按鈕添加一個onClick()
事件,以便它觸發一個方法來處理該功能。 您可以使用navigator.clipboard.writeText()
方法來處理該功能。 這就是AnswerSection組件現在的樣子:
// components/AnswerSection.jsx const AnswerSection = ({ storedValues }) => { const copyText = (text) => { navigator.clipboard.writeText(text); }; return ( <> <hr className="hr-line" /> <div className="answer-container"> {storedValues.map((value, index) => { return ( <div className="answer-section" key={index}> <p className="question">{value.question}</p> <p className="answer">{value.answer}</p> <div className="copy-icon" onClick={() => copyText(value.answer)} > <i className="fa-solid fa-copy"></i> </div> </div> ); })} </div> </> ) } export default AnswerSection;
當您運行您的應用程序時,您的 ChatGPT 克隆應用程序將完美運行。 您現在可以部署您的應用程序以在線訪問它並與朋友分享。
如何將 React 應用程序部署到 Kinsta
構建此應用程序並將其留在本地計算機上是不夠的。 您需要在線共享它,以便其他人可以訪問它。 讓我們看看如何使用 GitHub 和 Kinsta 來做到這一點。
將代碼推送到 GitHub
要將代碼推送到 GitHub,您可以使用 Git 命令,這是管理代碼更改、項目協作和維護版本歷史記錄的可靠且高效的方法。
推送代碼的第一步是創建一個新的存儲庫,方法是登錄您的 GitHub 帳戶,單擊屏幕右上角的+按鈕,然後從下拉菜單中選擇新建存儲庫。
為您的存儲庫命名,添加描述(可選),然後選擇您希望它是公開的還是私有的。 單擊創建存儲庫以創建它。
創建存儲庫後,請確保從存儲庫的主頁獲取存儲庫 URL,您需要使用該 URL 將代碼推送到 GitHub。
打開您的終端或命令提示符並導航到包含您的項目的目錄。 一條一條運行以下命令,將您的代碼推送到您的 GitHub 存儲庫:
git init git add . git commit -m "my first commit" git remote add origin [repository URL] git push -u origin master
git init
初始化本地 Git 存儲庫git add .
將當前目錄及其子目錄中的所有文件添加到新的 Git 存儲庫中。 git commit -m "my first commit"
將更改提交到存儲庫並帶有一條簡短消息。 git remote add origin [repository URL]
將repository URL設置為遠程倉庫, git push -u origin master
將代碼推送到master分支中的遠程倉庫(origin)。
將您的 ChatGPT Clone React 應用程序部署到 Kinsta
要將您的存儲庫部署到 Kinsta,請執行以下步驟:
- 在 My Kinsta 儀表板上登錄或創建您的 Kinsta 帳戶。
- 單擊左側邊欄上的應用程序,然後單擊添加服務。
- 從下拉菜單中選擇應用程序以將 React 應用程序部署到 Kinsta。
- 從出現的模式中選擇您希望部署的存儲庫。 如果您有多個分支,您可以選擇要部署的分支並為應用程序指定一個名稱。 在 25 個可用數據中心位置中選擇一個,Kinsta 將自動檢測啟動命令。
- 最後,將 API 密鑰推送到 GitHub 等公共主機是不安全的,它是在本地作為環境變量添加的。 託管時,您還可以使用相同的變量名稱和鍵作為其值將其添加為環境變量。
您的應用程序將開始部署,幾分鐘後,將提供一個鏈接以訪問您的應用程序的已部署版本。 在這種情況下,這是https://chatgpt-clone-g9q10.kinsta.app/注意:您可以啟用自動部署,因此每當您更改代碼庫並將其推送到 GitHub 時,Kinsta 都會重新部署您的應用程序。
概括
OpenAI API 可用於構建廣泛的潛在應用程序,從客戶支持和個人助理到語言翻譯和內容創建。
在本教程中,您學習瞭如何使用 React 和 OpenAI 構建 ChatGPT 克隆應用程序。 您可以將此應用程序/功能集成到其他應用程序中,為用戶提供類似人類的對話體驗。
關於 OpenAI API 可以做什麼以及如何改進這個克隆應用程序,還有更多內容。 例如,您可以實現本地存儲,這樣即使您刷新瀏覽器,以前的問題和答案也不會消失。
通過 Kinsta 的免費試用和 Hobby Tier,您可以輕鬆開始使用我們的應用程序託管而無需支付任何費用。 那麼為什麼不嘗試一下,看看你能創造出什麼?
在下面的評論中分享您的項目和經驗。