偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何使用SpringAI、React和Docker構(gòu)建AI聊天機(jī)器人 原創(chuàng)

發(fā)布于 2024-9-30 13:06
瀏覽
0收藏

嘿,Java開發(fā)人員們,有個(gè)重大好消息要告訴你們:Spring如今已正式支持通過(guò)SpringAI模塊來(lái)構(gòu)建AI應(yīng)用程序。

在本教程中,我們將使用SpringBoot、React、Docker以及OpenAI來(lái)構(gòu)建一個(gè)聊天機(jī)器人的應(yīng)用程序。此應(yīng)用程序能夠讓用戶與由AI驅(qū)動(dòng)的聊天機(jī)器人進(jìn)行交互,可以向其提出問題,并實(shí)時(shí)獲取回復(fù)。

文中提到的全部源代碼已在GitHub存儲(chǔ)庫(kù)中予以提供。歡迎給它加星標(biāo),然后搬運(yùn)該源代碼庫(kù)進(jìn)行嘗試體驗(yàn)。

為了讓你對(duì)所要構(gòu)建的內(nèi)容有個(gè)概念,最終AI應(yīng)用程序的樣子如下:

如何使用SpringAI、React和Docker構(gòu)建AI聊天機(jī)器人-AI.x社區(qū)

你感興趣么?讓我們從頭開始吧!

目錄

前提條件

獲取OpenAI密鑰

使用Spring Boot構(gòu)建REST API

使用Reactjs構(gòu)建Chat UI

如何將AI應(yīng)用程序Docker化

運(yùn)行AI應(yīng)用程序

前提條件

在我們深入研究構(gòu)建聊天機(jī)器人之前,你需要熟悉以下幾點(diǎn):

  • 需具備Java和Spring Boot的基本知識(shí)。
  • 需要對(duì)React和CSS有基本的了解。
  • 需要把JDK、NodePackageManager和Docker安裝到本地計(jì)算機(jī)中。

獲取OpenAI密鑰

首先,如果你沒有Open AI賬戶,那么需要先注冊(cè)一個(gè),在登錄之后,你會(huì)來(lái)到它的主頁(yè)。

在右上角,單擊“Dashboard”(控制面板)菜單。在側(cè)邊欄上,單擊“API Keys”(應(yīng)用程序編程接口密鑰),然后單擊“Create new secretkey”(創(chuàng)建新密鑰)按鈕以生成你自己的密鑰:

如何使用SpringAI、React和Docker構(gòu)建AI聊天機(jī)器人-AI.x社區(qū)

復(fù)制密鑰并將其妥善保存于安全之處,因?yàn)楹罄m(xù)你需要憑借此密鑰將你的應(yīng)用程序與OpenAI API相連接。

你可以查閱OpenAI API參考指南,以獲取更多關(guān)于如何調(diào)用API、它所接受的請(qǐng)求類型以及它給出的響應(yīng)內(nèi)容等方面的信息。

使用SpringBoot構(gòu)建REST API

讓我們前往Spring Initializer(用于快速創(chuàng)建Spring Boot項(xiàng)目的基礎(chǔ)結(jié)構(gòu)的一個(gè)網(wǎng)絡(luò)工具)來(lái)生成樣板文件代碼:

如何使用SpringAI、React和Docker構(gòu)建AI聊天機(jī)器人-AI.x社區(qū)

你可以自行選擇group(反向域名)、artifact(項(xiàng)目唯一標(biāo)識(shí)符)、name(項(xiàng)目名稱)、description(項(xiàng)目描述)和package(Java包名)。我們使用Maven(Java項(xiàng)目的依賴管理和構(gòu)建工具)作為構(gòu)建工具,SpringBoot版本為3.3.3,打包選項(xiàng)為Jar(JavaArchive的縮寫,是Java應(yīng)用程序的標(biāo)準(zhǔn)打包格式),Java版本為17。(注:Dependency Management:依賴管理)

點(diǎn)擊生成按鈕,將會(huì)下載一個(gè)zip文件。解壓該文件,然后將其作為Maven項(xiàng)目導(dǎo)入到你喜歡的IDE中(我用的是Intellij)。

在Spring中配置你的OpenAI密鑰

你可以使用現(xiàn)有的application.properties文件,或者創(chuàng)建一個(gè)application.yaml文件。我喜歡使用Yaml,所以創(chuàng)建了一個(gè)application.yaml文件,我可以在其中放置所有的SpringBoot配置。

接下來(lái)在你的application.yaml文件中添加OpenAIKey、Model和Temperature:

spring:
ai:
openai:
chat:
options:
model:"gpt-3.5-turbo"
temperature:"0.7"
key:"PUTYOUROPEN_API_KEYHERE"

application.properties中的類似配置可能如下所示:

spring.ai.openai.chat.options.model=gpt-3.5-turbo
spring.ai.openai.chat.options.temperature=0.7
spring.ai.openai.key="PUTYOUROPEN_API_KEYHERE"

構(gòu)建ChatController

讓我們創(chuàng)建一個(gè)URL為/ai/chat/string的GET API和一個(gè)處理邏輯的方法:

@RestController
publicclass ChatController{

@Autowired
private final OpenAiChatModel chatModel;

@GetMapping("/ai/chat/string")
public Flux<String>generateString(@RequestParam(value="message",defaultValue="Tellmeajoke")Stringmessage){
return chatModel.stream(message);
}
}
  • 首先,我們添加@RestController注解將ChatController類標(biāo)記為我們的Spring控制器。
  • 然后,我們注入dependency項(xiàng)(inject the dependency:一種設(shè)計(jì)模式,在 Spring 框架中廣泛使用。它允許我們?cè)诓恢苯觿?chuàng)建對(duì)象的情況下,讓 Spring 容器為我們管理和提供所需的對(duì)象)來(lái)獲取OpenAiChatModel類的實(shí)例。這個(gè)類是由我們之前添加的 Spring AI dependency庫(kù)提供的。
  • OpenAiChatModel帶有一個(gè)stream(message)方法,它接受一個(gè)String類型的提示并返回一個(gè)String響應(yīng)(技術(shù)上來(lái)說(shuō),它是一個(gè)String的Flux,因?yàn)槲覀兪褂昧嗽摲椒ǖ捻憫?yīng)式版本)。
  • 在內(nèi)部,OpenAiChatModel.stream(message)將調(diào)用OpenAI API并從那里獲取響應(yīng)。OpenAI調(diào)用將使用你在application.yaml文件中提到的配置,所以請(qǐng)確保使用有效的OpenAI密鑰。
  • 我們創(chuàng)建了一個(gè)方法來(lái)處理GET API調(diào)用,該方法接受消息并返回Flux<String>作為響應(yīng)。

構(gòu)建、運(yùn)行和測(cè)試 REST API

./mvnw clean install spring-boot:run

理想情況下,它會(huì)在8080端口上運(yùn)行,除非你自定義了端口。請(qǐng)確保該端口空閑,以成功運(yùn)行應(yīng)用程序。

你可以使用Postman 或Curl命令來(lái)測(cè)試你的 REST API:

curl --location 'http://localhost:8080/ai/chat/string?message=How%20are%20you%3F'

使用Reactjs構(gòu)建Chat UI

我們使用useState來(lái)管理狀態(tài):

const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
  • messages:它將存儲(chǔ)聊天中的所有消息。每條消息都有text(文本內(nèi)容)和sender(發(fā)送者,可能是'user'或'ai')這兩個(gè)屬性。
  • input:用于保存用戶在文本框中輸入的內(nèi)容。
  • loading:當(dāng)聊天機(jī)器人等待 AI 響應(yīng)時(shí),此狀態(tài)被設(shè)置為“true”;在收到響應(yīng)時(shí),則設(shè)置為“false”。

接下來(lái),讓我們創(chuàng)建一個(gè)handleSend 函數(shù),并在用戶通過(guò)點(diǎn)擊按鈕或按下回車鍵發(fā)送消息時(shí)進(jìn)行調(diào)用:

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);
    }
};

以下是逐步發(fā)生的過(guò)程:

  • 檢查空輸入:倘若輸入字段為空,函數(shù)將提前返回(不會(huì)發(fā)送任何內(nèi)容)。
  • 用戶新消息:一條新消息被添加到 messages 數(shù)組中。這條消息包含 text(用戶輸入的內(nèi)容)屬性,并標(biāo)記為由'user'發(fā)送。
  • 重置輸入:消息發(fā)送完畢后,輸入字段被清空。
  • 開始加載:等待 AI 響應(yīng)時(shí),loading 設(shè)置為 true 以顯示加載指示器。
  • 發(fā)起 API 請(qǐng)求:代碼使用 axios 向 AI 聊天機(jī)器人 API 發(fā)送請(qǐng)求,傳遞用戶的消息。在收到響應(yīng)后,AI 的新消息被添加到聊天中。
  • 錯(cuò)誤處理:如果獲取 AI 響應(yīng)時(shí)出現(xiàn)問題,錯(cuò)誤會(huì)被記錄至控制臺(tái)。
  • 停止加載:最終加載狀態(tài)被關(guān)閉。

讓我們編寫一個(gè)函數(shù),當(dāng)用戶在輸入字段中輸入內(nèi)容,對(duì)input狀態(tài)進(jìn)行更新:

const handleInputChange = (e) => {
    setInput(e.target.value);
};

然后,我們創(chuàng)建一個(gè)函數(shù)來(lái)檢查用戶是否按下了 Enter 鍵。如果出現(xiàn)這種情形,它會(huì)調(diào)用 handleSend()函數(shù)來(lái)發(fā)送消息:

const handleKeyPress = (e) => {
    if (e.key === 'Enter') {
        handleSend();
    }
};

現(xiàn)在讓我們創(chuàng)建 UI 元素來(lái)呈現(xiàn)聊天消息:

{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>
))}

這個(gè)代碼塊呈現(xiàn)聊天中的所有消息:

  • 遍歷消息:使用 .map() 函數(shù)將每條消息顯示為一個(gè)div。
  • 消息樣式:消息的類名根據(jù)發(fā)送者(user或ai)而變化,清楚地表明誰(shuí)發(fā)送了消息。
  • 頭像圖片:每條消息顯示一個(gè)小頭像,用戶和 AI 使用不同的圖片。

讓我們創(chuàng)建一些基于某個(gè)標(biāo)志來(lái)顯示加載器的邏輯:

{loading && (
    <div className="message-container ai">
        <img src="ai-assistant.png" alt="AI avatar" className="avatar" />
        <div className="message ai">...</div>
    </div>
)}

當(dāng) AI 處于思考狀態(tài)(即 loading 為 true 時(shí)),我們顯示一條加載消息(...),以便讓用戶知道響應(yīng)即將到來(lái)。

最后,創(chuàng)建一個(gè)用于點(diǎn)擊發(fā)送消息的按鈕:

<button onClick={handleSend}>
    <FaPaperPlane />
</button>

當(dāng)此按鈕被點(diǎn)擊時(shí),將會(huì)觸發(fā) handleSend() 函數(shù)。這里所采用的圖標(biāo)為一個(gè)紙飛機(jī),這是“發(fā)送”按鈕的常見圖標(biāo)。

完整的 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/>來(lái)加載聊天機(jī)器人 UI:

function App() {
  return (
    <div className="App">
            <Chatbot />
        </div>
  );
}

除此之外,我們還使用 CSS 來(lái)使我們的聊天機(jī)器人更加美觀。你可以參考 App.css 和 Chatbot.css 文件來(lái)了解具體樣式。

運(yùn)行前端

使用npm命令運(yùn)行應(yīng)用程序:

npm start

程序會(huì)在URL http://localhost:3000上運(yùn)行前端。此時(shí)應(yīng)用程序已能夠進(jìn)行測(cè)試。

然而,分別運(yùn)行后端和前端稍顯繁瑣。因此,讓我們借助Docker來(lái)使整個(gè)構(gòu)建流程更加簡(jiǎn)單。

如何將AI應(yīng)用程序Docker化

讓我們將整個(gè)應(yīng)用程序Docker化,以便輕松打包和部署到任何地方。你可以從Docker的官方網(wǎng)站安裝并配置Docker。

Docker化后端

聊天機(jī)器人的后端是用Spring Boot構(gòu)建的,因此我們將創(chuàng)建一個(gè)Dockerfile,它將Spring Boot應(yīng)用程序構(gòu)建為可執(zhí)行JAR文件并在容器中運(yùn)行。

讓我們?yōu)槠渚帉慏ockerfile:

# 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:這條語(yǔ)句指定了Docker基于包含JDK 17的輕量級(jí)Alpine Linux鏡像,JDK 17是運(yùn)行Spring Boot所必備的。
  • WORKDIR /app:這條語(yǔ)句設(shè)置了Docker內(nèi)部的工作目錄為/app,這是我們應(yīng)用程序文件將要存放的位置。
  • COPY target/chatbot-backend.jar /app/chatbot-backend.jar:這條語(yǔ)句將本地機(jī)器上(通常在使用Maven或Gradle構(gòu)建項(xiàng)目后,位于target文件夾中)構(gòu)建的JAR文件復(fù)制到容器中。
  • EXPOSE 8080:這條語(yǔ)句告訴Docker,應(yīng)用程序?qū)⒃诙丝?080上監(jiān)聽請(qǐng)求。
  • CMD ["java", "-jar", "chatbot-backend.jar"]:這條語(yǔ)句指定了容器啟動(dòng)時(shí)將要執(zhí)行的命令。它運(yùn)行JAR文件以啟動(dòng)Spring Boot應(yīng)用程序。

Docker化前端

聊天機(jī)器人的前端用React構(gòu)建而成,通過(guò)創(chuàng)建一個(gè)Dockerfile來(lái)對(duì)其進(jìn)行Docker化處理,該Dockerfile會(huì)安裝必要的依賴項(xiàng)( dependencies)、構(gòu)建應(yīng)用程序,并借助像NGINX這類輕量級(jí)的Web服務(wù)器來(lái)提供服務(wù)。

讓我們?yōu)镽eact前端編寫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: 使用輕量級(jí)的Node.js鏡像來(lái)構(gòu)建React應(yīng)用。我們?cè)谶@個(gè)容器內(nèi)部安裝所有依賴項(xiàng)并構(gòu)建應(yīng)用。
  • WORKDIR /app: 設(shè)置容器內(nèi)部的工作目錄為/app。
  • COPY package.json package-lock.json ./: 復(fù)制package.js和package-lock.json文件以便安裝依賴項(xiàng)。
  • RUN npm install: 安裝package.json中列出的所有依賴項(xiàng)。
  • COPY . .: 將當(dāng)前目錄下的所有前端源代碼文件復(fù)制到容器中。
  • RUN npm run build: 將構(gòu)建完React后的文件置入一個(gè)名為build的文件夾中。
  • FROM nginx:alpine: 在構(gòu)建完應(yīng)用后,基于nginx Web服務(wù)器鏡像啟動(dòng)了一個(gè)新的容器。
  • COPY --from=build /app/build /usr/share/nginx/html: 將第一個(gè)容器(即構(gòu)建React應(yīng)用的容器)中的build文件夾復(fù)制到nginx容器中,這是nginx默認(rèn)用于提供文件的目錄。
  • EXPOSE 80: 開放端口80,nginx將使用此端口來(lái)提供Web流量。
  • CMD ["nginx", "-g", "daemon off;"]: 以前臺(tái)模式啟動(dòng)nginx服務(wù)器,以提供你的React應(yīng)用。

使用Docker Compose同時(shí)運(yùn)行前后端

現(xiàn)在我們已經(jīng)為前端和后端分別創(chuàng)建了Dockerfile,我們將使用 docker-compose來(lái)協(xié)調(diào)同時(shí)運(yùn)行這兩個(gè)容器。

讓我們?cè)陧?xiàng)目的根目錄下編寫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:這定義了我們想要運(yùn)行的服務(wù)。
  1. backend: 此服務(wù)使用位于./backend 目錄中的 Dockerfile 構(gòu)建后端,并暴露 8080 端口。
  2. frontend: 此服務(wù)使用位于./frontend 目錄中的 Dockerfile 構(gòu)建前端。它將主機(jī)上的 3000 端口映射到容器內(nèi)的 80 端口。
  • depends_on: 這確保前端在啟動(dòng)之前等待后端準(zhǔn)備就緒。
  • networks: 此部分定義了一個(gè)共享網(wǎng)絡(luò),以便后端和前端能夠相互通信。

運(yùn)行AI應(yīng)用程序

要運(yùn)行整個(gè)應(yīng)用程序(前端和后端),你可以使用以下命令:

docker-compose up --build

這個(gè)命令將會(huì)實(shí)現(xiàn):

  • 構(gòu)建前端和后端的鏡像。
  • 啟動(dòng)兩個(gè)容器(后端在 8080 端口,前端在 3000 端口)。
  • 設(shè)置網(wǎng)絡(luò),使兩個(gè)服務(wù)可以相互通信。

現(xiàn)在,你可以訪問 http://localhost:3000 加載聊天機(jī)器人 UI,并開始向 AI 提問。

你已經(jīng)成功使用 Spring Boot、React、Docker 和 OpenAI 構(gòu)建了一個(gè)全棧聊天機(jī)器人應(yīng)用。

項(xiàng)目中展示的源代碼可在 Github 上獲取,如果你覺得它有幫助,請(qǐng)加星標(biāo),并隨意搬運(yùn)該源代碼庫(kù)進(jìn)行嘗試體驗(yàn)。

譯者介紹

劉濤,51CTO社區(qū)編輯,某大型央企系統(tǒng)上線檢測(cè)管控負(fù)責(zé)人。

原文標(biāo)題:??How to Build an AI Chatbot with Spring AI, React, and Docker??,作者:Vikas Rajput

?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任
已于2024-9-30 13:11:56修改
收藏
回復(fù)
舉報(bào)
回復(fù)
相關(guān)推薦