如何经常使用SpringAI React和Docker构建AI聊天机器人

嘿,Java开发人员们,有个严重好信息要通知你们:Spring如今已正式支持经过SpringAI模块来构建AI运行程序。

在本教程中,咱们将经常使用SpringBoot、React、Docker以及OpenAI来构建一个聊天机器人的运行程序。此运行程序能够让用户与由AI驱动的聊天机器人启动交互,可以向其提出疑问,并实时失掉回复。

文中提到的所有源代码已在GitHub存储库中予以提供。欢迎给它加星标,而后搬运该源代码库启动尝试体验。

为了让你对所要构建的内容有个概念,最终AI运行程序的样子如下:

你感兴味么?让咱们从头开局吧!

目录

前提条件

失掉OpenAI密钥

经常使用Spring Boot构建REST API

经常使用Reactjs构建Chat UI

如何将AI运行程序Docker化

运转AI运行程序

前提条件

在咱们深化钻研构建聊天机器人之前,你须要相熟以下几点:

失掉OpenAI密钥

首先,假设你没有Open AI账户,那么须要先注册一个,在登录之后,你会到来它的主页。

在右上角,单击“Dashboard”(控制面板)菜单。在侧边栏上,单击“APIKeys”(运行程序编程接口密钥),而后单击“Createnewsecretkey”(创立新密钥)按钮以生成你自己的密钥:

复制密钥并将其妥善保留于安保之处,由于后续你须要仰仗此密钥将你的运行程序与OpenAIAPI相衔接。

你可以查阅OpenAIAPI参考指南,以失掉更多对于如何调用API、它所接受的恳求类型以及它给出的照应内容等方面的信息。

经常使用SpringBoot构建REST API

让咱们前往SpringInitializer(用于极速创立SpringBoot名目的基础结构的一个网络工具)来生成样板文件代码:

你可以自行选用group(反向域名)、artifact(名目惟一标识符)、name(名目称号)、description(名目形容)和package(Java包名)。咱们经常使用Maven(Java名目的依赖治理和构建工具)作为构建工具,SpringBoot版本为3.3.3,打包选项为Jar(JavaArchive的缩写,是Java运行程序的规范打包格局),Java版本为17。(注:DependencyManagement:依赖治理)

点击生成按钮,将会下载一个zip文件。解压该文件,而后将其作为Maven名目导入到你青睐的IDE中(我用的是Intellij)。

在Spring中性能你的OpenAI密钥

你可以经常使用现有的application.properties文件,或许创立一个application.yaml文件。我青睐经常使用Yaml,所以创立了一个application.yaml文件,我可以在其中搁置一切的SpringBoot性能。

接上去在你的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-turbospring.ai.openai.chat.options.temperature=0.7spring.ai.openai.key="PUTYOUROPEN_API_KEYHERE"

构建ChatController

让咱们创立一个URL为/ai/chat/string的GETAPI和一个处置逻辑的方法:

@RestControllerpublicclass ChatController{@Autowiredprivate final OpenAiChatModel chatModel;@GetMapping("/ai/chat/string")public Flux<String>generateString(@RequestParam(value="message",defaultValue="Tellmeajoke")Stringmessage){return chatModel.stream(message);}}

构建、运转和测试 REST API

./mvnw clean install spring-boot:run

现实状况下,它会在8080端口上运转,除非你自定义了端口。请确保该端口闲暇,以成功运转运行程序。

你可以经常使用Postman 或Curl命令来测试你的 REST API:

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

经常使用Reactjs构建Chat UI

咱们经常使用useState来治理形态:

const [messages, setMessages] = useState([]);const [input, setInput] = useState('');const [loading, setLoading] = useState(false);

接上去,让咱们创立一个handleSend 函数,并在用户经过点击按钮或按下回车键发送信息时启动调用:

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

以下是逐渐出现的环节:

让咱们编写一个函数,当用户在输入字段中输入内容,对input形态启动降级:

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

而后,咱们创立一个函数来审核用户能否按下了 Enter 键。假设出现这种情景,它会调用 handleSend()函数来发送信息:

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

如今让咱们创立 UI 元历来出现聊天信息:

{messages.map((message, index) => (<div key={index} className={`message-container ${message.sender}`}><imgsrc={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>)}

当 AI 处于思索形态(即 loading 为 true 时),咱们显示一条加载信息(...),以便让用户知道照应行将到来。

最后,创立一个用于点击发送信息的按钮:

当此按钮被点击时,将会触发 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}`}><imgsrc={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"><inputtype="text"value={input}onChange={handleInputChange}onKeyPress={handleKeyPress}placeholder="Type your message..."/><button onClick={handleSend}><FaPaperPlane /></button></div></div>);};export default Chatbot;

在 App.js 中经常使用 <Chatbot/>来加载聊天机器人 UI:

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

除此之外,咱们还经常使用 CSS 来使咱们的聊天机器人愈加好看。你可以参考 App.css 和 Chatbot.css 文件来了解详细样式。

运转前端

经常使用npm命令运转运行程序:

程序会在URL上运转前端。此时运行程序已能够启动测试。

但是,区分运转后端和前端稍显繁琐。因此,让咱们借助Docker来使整个构建流程愈加便捷。

如何将AI运行程序Docker化

让咱们将整个运行程序Docker化,以便轻松打包和部署就任何中央。你可以从Docker的官网网站装置并性能Docker。

Docker化后端

聊天机器人的后端是用Spring Boot构建的,因此咱们将创立一个Dockerfile,它将Spring Boot运行程序构建为可执行JAR文件并在容器中运转。

让咱们为其编写Dockerfile:

# Start with an official image that has Java installedFROM openjdk:17-jdk-alpine# Set the working directory inside the containerWORKDIR /app# Copy the Maven/Gradle build file and source code into the containerCOPY target/chatbot-backend.jar /app/chatbot-backend.jar# Expose the application’s portEXPOSE 8080# Command to run the Spring Boot appCMD ["java", "-jar", "chatbot-backend.jar"]

Docker化前端

聊天机器人的前端用React构建而成,经过创立一个Dockerfile来对其启动Docker化处置,该Dockerfile会装置必要的依赖项(dependencies)、构建运行程序,并借助像NGINX这类轻量级的Web主机来提供服务。

让咱们为React前端编写Dockerfile:

# Use a Node image to build the React appFROM node:16-alpine AS build# Set the working directory inside the containerWORKDIR /app# Copy the package.json and install the dependenciesCOPY package.json package-lock.json ./RUN npm install# Copy the rest of the application code and build itCOPY . .RUN npm run build# Use a lightweight NGINX server to serve the built appFROM nginx:alpineCOPY --from=build /app/build /usr/share/nginx/html# Expose port 80 for the web trafficEXPOSE 80# Start NGINXCMD ["nginx", "-g", "daemon off;"]

经常使用Docker Compose同时运转前后端

如今咱们曾经为前端和后端区分创立了Dockerfile,咱们将经常使用 docker-compose来协调同时运转这两个容器。

让咱们在名目的根目录下编写docker-compose.yml 文件:

version: '3'services:backend:build: ./backendports:- "8080:8080"networks:- chatbot-networkfrontend:build: ./frontendports:- "3000:80"depends_on:- backendnetworks:- chatbot-networknetworks:chatbot-network:driver: bridge

运转AI运行程序

要运转整个运行程序(前端和后端),你可以经常使用以下命令:

docker-compose up --build

这个命令将会成功:

如今,你可以访问加载聊天机器人 UI,并开局向 AI 提问。

你曾经成功经常使用 Spring Boot、React、Docker 和 OpenAI 构建了一个全栈聊天机器人运行。

名目中展现的源代码可在 Github 上失掉,假设你觉得它有协助,请加星标,并轻易搬运该源代码库启动尝试体验。

译者引见

刘涛,社区编辑,某大型央企系统上线检测管控担任人。

原文题目: How to Build an AI Chatbot with Spring AI, React, and Docker ,作者:Vikas Rajput

您可能还会对下面的文章感兴趣: