
掌握ChatGPT插件與自定義GPT
你興奮嗎?讓我們從頭開始構建它!
在開始構建聊天機器人之前,你需要了解一些基礎知識:
首先,如果您沒有 OpenAI 帳戶,則需要注冊一個 OpenAI 帳戶。登錄后,您將被帶到主頁。
在右上角,單擊 “Dashboard” 菜單。在側邊欄上,單擊“API Keys”,然后單擊“Create new secret key”按鈕以生成您的密鑰:
復制密鑰并將其保存在安全的地方,因為您稍后需要它來將您的應用程序連接到 OpenAI API。
您可以瀏覽 OpenAI API 參考指南,了解更多關于如何調用API、它接受哪些請求以及它給出的響應的更多信息。
讓我們轉到 spring initializer 以生成樣板代碼:
您可以提供您選擇的組、構件、名稱、描述和包。我們使用 Maven 作為構建工具,使用 Spring Boot 版本 3.3.3,使用 Jar 作為打包選項,并使用 Java 版本 17。
點擊生成按鈕,將下載 zip。解壓縮文件并將它們作為 Maven 項目導入到您最喜歡的 IDE 中(我的是 Intellij)。
你可以使用現有的application.properties文件或創建一個application.yaml文件。我喜歡使用 Yaml,所以我創建了一個application.yaml文件,我可以在其中放置我所有的 Spring Boot 配置。
將OpenAIKey、Model和Temperature添加到你的application.yaml文件中:
spring:
ai:
openai:
chat:
options:
model: "gpt-3.5-turbo"
temperature: "0.7"
key: "PUT YOUR OPEN_API_KEY HERE"
在application.properties中的類似配置可能如下所示:
spring.ai.openai.chat.options.model=gpt-3.5-turbo
spring.ai.openai.chat.options.temperature=0.7
spring.ai.openai.key="PUT YOUR OPEN_API_KEY HERE"
讓我們創建一個帶有URL /ai/chat/string的GET API和一個處理邏輯的方法:
@RestController
public class ChatController {
@Autowired
private final OpenAiChatModel chatModel;
@GetMapping("/ai/chat/string")
public Flux<String> generateString(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return chatModel.stream(message);
}
}
使用 maven 命令構建并運行 Spring Boot 應用程序:
./mvnw clean install spring-boot:run
理想情況下,它會在8080端口上運行,除非你已自定義端口。確保該端口空閑以便成功運行應用程序。
你可以使用Postman或Curl命令來測試你的REST API:
curl --location 'http://localhost:8080/ai/chat/string?message=How%20are%20you%3F'
為了本教程,我們將使它非常簡單和容易,所以請原諒我沒有遵循任何React的最佳實踐。
我們將使用useState來管理狀態:
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
messages
:它將存儲聊天中的所有消息。每條消息都有文本內容和發送者(要么是’user’(用戶),要么是’ai’(人工智能))。input
:用于存儲用戶在文本框中輸入的內容。loading
:當聊天機器人正在等待AI的響應時,此狀態設置為true,收到響應后設置為false。創建handleSend函數:當用戶點擊按鈕或按下Enter鍵發送消息時調用此函數。
const handleSend = async () => {
if (input.trim() === '') return;
const newMessage = { text: input, sender: 'user' };
setMessages([...messages, newMessage]);
setInput('');
setLoading(true);
try {
const response = await axios.get('http://localhost:8080/ai/chat/string?message=' + input);
const aiMessage = { text: response.data, sender: 'ai' };
setMessages([...messages, newMessage, aiMessage]);
} catch (error) {
console.error("Error fetching AI response", error);
} finally {
setLoading(false);
}
};
以下是逐步發生的事情:
現在,我們來編寫一個函數,以便用戶在輸入字段中輸入內容時更新輸入狀態:
const handleInputChange = (e) => {
setInput(e.target.value);
};
這個函數會監聽輸入字段的變化,并將新的輸入值存儲到狀態中,以便后續使用。每當用戶在輸入框中輸入或刪除字符時,這個函數都會被調用。
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
handleSend();
}
};
現在讓我們創建 UI 元素來呈現聊天消息:
{messages.map((message, index) => (
<div key={index} className={message-container ${message.sender}
}>
<img
src={message.sender === 'user' ? 'user-icon.png' : 'ai-assistant.png'}
alt={${message.sender} avatar
}
className="avatar"
/>
<div className={message ${message.sender}
}>
{message.text}
</div>
</div>
))}
此區塊呈現聊天中的所有消息:
.map()
方法遍歷消息數組,將每條消息以div
的形式顯示出來。接下來,讓我們創建一些邏輯,根據一個標志(flag)來顯示加載器:
{loading && (
<div className="message-container ai">
<img src="ai-assistant.png" alt="AI avatar" className="avatar" />
<div className="message ai">...</div>
</div>
)}
當AI正在思考(即加載狀態為true時),我們顯示一個加載消息(例如“…”),以便用戶知道響應很快就會到來。...
最后,創建一個按鈕來觸發發送消息的操作:
<button onClick={handleSend}>
<FaPaperPlane />
</button>
這個按鈕在被點擊時會觸發handleSend()
函數。這里使用的圖標是一張紙飛機,它是“發送”按鈕的常見圖標。
完整的Chatbot.js
文件如下所示:
import React, { useState } from 'react';
import axios from 'axios';
import { FaPaperPlane } from 'react-icons/fa';
import './Chatbot.css';
const Chatbot = () => {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
const handleSend = async () => {
if (input.trim() === '') return;
const newMessage = { text: input, sender: 'user' };
setMessages([...messages, newMessage]);
setInput('');
setLoading(true);
try {
const response = await axios.get('http://localhost:8080/ai/chat/string?message=' + input);
const aiMessage = { text: response.data, sender: 'ai' };
setMessages([...messages, newMessage, aiMessage]);
} catch (error) {
console.error("Error fetching AI response", error);
} finally {
setLoading(false);
}
};
const handleInputChange = (e) => {
setInput(e.target.value);
};
const handleKeyPress = (e) => {
if (e.key === 'Enter') {
handleSend();
}
};
return (
<div className="chatbot-container">
<div className="chat-header">
<img src="ChatBot.png" alt="Chatbot Logo" className="chat-logo" />
<div className="breadcrumb">Home > Chat</div>
</div>
<div className="chatbox">
{messages.map((message, index) => (
<div key={index} className={message-container ${message.sender}
}>
<img
src={message.sender === 'user' ? 'user-icon.png' : 'ai-assistant.png'}
alt={${message.sender} avatar
}
className="avatar"
/>
<div className={message ${message.sender}
}>
{message.text}
</div>
</div>
))}
{loading && (
<div className="message-container ai">
<img src="ai-assistant.png" alt="AI avatar" className="avatar" />
<div className="message ai">...</div>
</div>
)}
</div>
<div className="input-container">
<input
type="text"
value={input}
onChange={handleInputChange}
onKeyPress={handleKeyPress}
placeholder="Type your message..."
/>
<button onClick={handleSend}>
<FaPaperPlane />
</button>
</div>
</div>
);
};
export default Chatbot;
在App.js
中使用<Chatbot/>
來加載聊天機器人用戶界面:
function App() {
return (
<div className="App">
<Chatbot />
</div>
);
}
除此之外,我們還使用CSS來讓我們的聊天機器人看起來更美觀一些。您可以參考App.css
和Chatbot.css
文件。
使用npm命令來運行應用程序:
npm start
這應該在http://localhost:3000
上運行前端。現在,應用程序已經準備好進行測試了。
但是分別運行后端和前端有點麻煩。所以,讓我們使用Docker來讓整個構建過程變得更簡單。
讓我們將整個應用程序Docker化,以便能夠輕松地將其打包并部署到任何地方。您可以從Docker官方網站安裝和配置Docker。
我們的聊天機器人的后端是用Spring Boot構建的,因此我們將創建一個Dockerfile,它將Spring Boot應用程序構建成一個可執行的JAR文件,并在容器中運行它。
讓我們來編寫它的Dockerfile:
# Start with an official image that has Java installed
FROM openjdk:17-jdk-alpine
# Set the working directory inside the container
WORKDIR /app
# Copy the Maven/Gradle build file and source code into the container
COPY target/chatbot-backend.jar /app/chatbot-backend.jar
# Expose the application’s port
EXPOSE 8080
# Command to run the Spring Boot app
CMD ["java", "-jar", "chatbot-backend.jar"]
FROM openjdk:17-jdk-alpine
:這指定容器應基于包含 JDK 17 的輕量級 Alpine Linux 映像,這是運行 Spring Boot 所必需的。WORKDIR /app
:這行設置了容器內部的工作目錄為/app
,我們的應用程序文件將存放在這里。COPY target/chatbot-backend.jar /app/chatbot-backend.jar
:這行將構建好的JAR文件從本地機器(通常在使用Maven或Gradle構建項目后的target
文件夾中)復制到容器中。EXPOSE 8080
:這行告訴Docker應用程序將在8080端口監聽請求。CMD ["java", "-jar", "chatbot-backend.jar"]
:這行指定了容器啟動時將運行的命令。它運行啟動Spring Boot應用程序的JAR文件。我們的聊天機器人的前端是使用React構建的,我們可以通過創建一個Dockerfile來將其Docker化,這個Dockerfile將安裝必要的依賴項,構建應用程序,并使用像NGINX這樣的輕量級Web服務器來提供服務。
讓我們來編寫React前端的Dockerfile:
# Use a Node image to build the React app
FROM node:16-alpine AS build
# Set the working directory inside the container
WORKDIR /app
# Copy the package.json and install the dependencies
COPY package.json package-lock.json ./
RUN npm install
# Copy the rest of the application code and build it
COPY . .
RUN npm run build
# Use a lightweight NGINX server to serve the built app
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
# Expose port 80 for the web traffic
EXPOSE 80
# Start NGINX
CMD ["nginx", "-g", "daemon off;"]
FROM node:16-alpine AS build
:這行指定了使用輕量級的Node.js鏡像(版本16,基于Alpine Linux)來構建React應用。在這個容器中,我們將安裝所有依賴并構建應用。WORKDIR /app
:這行設置了容器內部的工作目錄為/app
。COPY package.json package-lock.json ./
:這行將package.json
和package-lock.json
文件復制到容器中,以便安裝依賴。RUN npm install
:這行在容器中運行npm install
命令,安裝package.json
中列出的依賴。COPY . .
:這行將前端源代碼的所有文件復制到容器中。RUN npm run build
:這行在容器中運行npm run build
命令,構建React應用。構建后的文件將位于build
文件夾中。FROM nginx:alpine
:在應用構建完成后,這行指定了基于nginx Web服務器的輕量級Alpine Linux鏡像來啟動一個新的容器。COPY --from=build /app/build /usr/share/nginx/html
:這行將第一個容器中構建的React應用復制到nginx容器中,并將其放置在nginx默認的服務文件夾中。EXPOSE 80
:這行將公開端口 80,NGINX 使用它來提供 Web 流量。CMD ["nginx", "-g", "daemon off;"]
:這行以前臺模式啟動nginx服務器,以提供React應用的服務。現在我們已經分別為前端和后端創建了Dockerfile,接下來我們將使用docker-compose來協調同時運行這兩個容器。
讓我們在項目根目錄下編寫docker-compose.yml
文件:
version: '3'
services:
backend:
build: ./backend
ports:
- "8080:8080"
networks:
- chatbot-network
frontend:
build: ./frontend
ports:
- "3000:80"
depends_on:
- backend
networks:
- chatbot-network
networks:
chatbot-network:
driver: bridge
version: '3'
:這行定義了所使用的Docker Compose的版本。services:
:這行開始定義了想要運行的服務。
backend
:這個服務使用位于./backend
目錄的Dockerfile來構建后端,并暴露8080端口。frontend
:這個服務使用位于./frontend
目錄的Dockerfile來構建前端。它將主機的3000端口映射到容器內的80端口depends_on:
:這行確保前端服務在啟動之前等待后端服務準備就緒。networks:
:這個部分定義了一個共享網絡,以便后端和前端可以相互通信。要運行整個應用程序(前端和后端),您可以使用以下命令:
docker-compose up --build
此命令將:
現在,你可以訪問 http://localhost:3000
來加載聊天機器人的用戶界面,并開始向AI提問。
您已成功使用 Spring Boot、React、Docker 和 OpenAI 構建了一個全棧聊天機器人應用程序。
原文鏈接:https://www.freecodecamp.org/news/ai-chatbot-with-spring-react-docker/