چگونه یک ربات چت هوش مصنوعی با هوش مصنوعی Spring، React و Docker بسازیم
سلام توسعه دهندگان جاوا، من خبر خوبی دارم: Spring اکنون پشتیبانی رسمی برای ساخت برنامه های هوش مصنوعی با استفاده از ماژول Spring AI دارد.
در این آموزش، ما با استفاده از Spring Boot ، React ، Docker و OpenAI یک برنامه چت بات می سازیم. این برنامه به کاربران اجازه می دهد با یک چت بات مجهز به هوش مصنوعی تعامل داشته باشند، سؤال بپرسند و پاسخ ها را در زمان واقعی دریافت کنند.
کل کد منبع ذکر شده در این مقاله در حال حاضر در مخزن GitHub موجود است. با خیال راحت به آن ستاره بدهید و آن را چنگال کنید تا در اطراف بازی کند.
برای اینکه ایده ای از آنچه در اینجا می سازیم به شما ارائه دهیم، برنامه نهایی به این صورت خواهد بود:
از Spring AI، React، Docker توسط Vikas Rajput" class="image--center mx-auto" width="729" height="883" loading="lazy">
آیا شما هیجان زده هستید؟ بیایید آن را از ابتدا بسازیم!
فهرست مطالب
کلید OpenAI خود را دریافت کنید
REST API را در Spring Boot بسازید
ChatUI را با استفاده از Reactjs بسازید
پیش نیازها
قبل از اینکه به ساخت ربات چت بپردازیم، در اینجا چند چیز وجود دارد که باید با آنها آشنا باشید:
درک اولیه جاوا و Spring Boot .
درک اولیه React و CSS .
JDK ، Node Package Manager و Docke r را روی دستگاه خود نصب کنید.
کلید OpenAI خود را دریافت کنید
ابتدا باید برای یک حساب OpenAI ثبت نام کنید اگر آن را ندارید. پس از ورود به سیستم، به صفحه اصلی هدایت خواهید شد.
در گوشه بالا سمت راست، روی منوی «داشبورد» کلیک کنید. در نوار کناری، روی «کلیدهای API» کلیک کنید، سپس روی دکمه «ایجاد کلید مخفی جدید» کلیک کنید تا کلید مخفی شما تولید شود:
را تولید کنیم" class="image--center mx-auto" width="1903" height="537" loading="lazy">
کلید مخفی را کپی کرده و در مکانی امن ذخیره کنید، زیرا بعداً برای اتصال برنامه خود به OpenAI API به آن نیاز خواهید داشت.
میتوانید راهنمای مرجع OpenAI API را مرور کنید تا درباره نحوه فراخوانی APIها، درخواستهایی که میپذیرد و پاسخهایی که میدهد بیشتر بدانید.
REST API را در Spring Boot بسازید
برای تولید کد دیگ بخار به سراغ اولیه ساز فنری می رویم:
را با استفاده از اولیه Spring بسازید" class="image--center mx-auto" width="1511" height="883" loading="lazy">
میتوانید گروه، مصنوع، نام، توضیحات و بستهای را که انتخاب میکنید بدهید. ما از Maven به عنوان ابزار ساخته شده، Spring boot نسخه 3.3.3، Jar به عنوان گزینه بسته بندی و جاوا نسخه 17 استفاده کرده ایم.
دکمه تولید را بزنید و فایل فشرده دانلود می شود. فایل ها را از حالت فشرده خارج کنید و آنها را به عنوان پروژه Maven در IDE مورد علاقه خود وارد کنید (مال Intellij است).
کلید OpenAI خود را در بهار پیکربندی کنید
می توانید از فایل 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"
ChatController را بسازید
بیایید یک GET
API با URL /ai/chat/string
و روشی برای مدیریت منطق ایجاد کنیم:
@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); } }
ابتدا، ما @RestController
اضافه می کنیم تا کلاس ChatController
را به عنوان کنترلر فنری ما علامت گذاری کنیم
سپس، ما وابستگی را برای کلاس OpenAiChatModel
تزریق می کنیم. به عنوان بخشی از وابستگی به هوش مصنوعی Spring که ما استفاده کرده ایم، از جعبه خارج می شود.
OpenAiChatModel
با یک متد stream(message)
ارائه میشود که درخواست را به عنوان String
میپذیرد و یک پاسخ String
را برمیگرداند (از لحاظ فنی یک Flux
of String
است زیرا ما از یک نسخه Reactive از همان روش استفاده کردهایم).
در داخل، OpenAiChatModel.stream(message)
OpenAI API را فراخوانی می کند و پاسخ را از آنجا دریافت می کند. فراخوانی OpenAI از مراحل پیکربندی ذکر شده در فایل application.yaml
شما استفاده می کند، پس مطمئن شوید که از یک کلید OpenAI معتبر استفاده می کنید.
ما روشی برای مدیریت تماس GET API ایجاد کردهایم که پیام را میپذیرد و Flux<String>
به عنوان پاسخ برمیگرداند.
REST API را بسازید، اجرا کنید و آزمایش کنید
از دستورات 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'
ChatUI را با استفاده از React.js بسازید
ما به خاطر این آموزش آن را بسیار ساده و آسان خواهیم کرد، پس اگر از بهترین شیوه های React پیروی نکردم، مرا ببخشید.
برای مدیریت فرم ChatUI، App.js
ایجاد کنید
ما از useState
برای مدیریت وضعیت استفاده خواهیم کرد:
const [messages, setMessages] = useState([]); const [input, setInput] = useState( '' ); const [loading, setLoading] = useState( false );
messages
: تمام پیام ها را در چت ذخیره می کند. هر پیام دارای یک text
و یک sender
(یا "کاربر" یا "ai") است.
input
: برای نگه داشتن آنچه کاربر در کادر متن تایپ می کند.
loading
: این حالت در زمانی که چت بات منتظر پاسخ از هوش مصنوعی است روی 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 ); } };
در اینجا چیزی است که گام به گام اتفاق می افتد:
بررسی ورودی خالی : اگر فیلد ورودی خالی باشد، تابع زودتر برمی گردد (هیچ چیزی ارسال نمی شود).
پیام جدید از کاربر : یک پیام جدید به آرایه messages
اضافه می شود. این پیام دارای text
است (هر آنچه کاربر تایپ کرده است) و به عنوان ارسال شده توسط "کاربر" علامت گذاری شده است.
بازنشانی ورودی : قسمت ورودی پس از ارسال پیام پاک می شود.
شروع بارگذاری : در حالی که منتظر پاسخ هوش مصنوعی هستید، loading
روی true
تنظیم می شود تا نشانگر بارگذاری را نشان دهد.
درخواست API ایجاد کنید : این کد از axios
برای درخواست API ربات چت هوش مصنوعی استفاده می شود و پیام کاربر را ارسال می کند. وقتی پاسخ برگشت، یک پیام جدید از هوش مصنوعی به چت اضافه می شود.
رسیدگی به خطا : اگر در دریافت پاسخ هوش مصنوعی مشکلی وجود داشته باشد، یک خطا در کنسول ثبت می شود.
توقف بارگذاری : در نهایت حالت بارگیری خاموش می شود.
بیایید یک تابع بنویسیم تا هر زمان که کاربر چیزی را در فیلد ورودی تایپ می کند، وضعیت 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 }`}> < 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
نمایش داده می شود.
سبک پیام : نام کلاس پیام بر اساس اینکه فرستنده چه کسی است ( user
یا ai
) تغییر میکند و مشخص میکند که چه کسی پیام را ارسال کرده است.
تصاویر آواتار : هر پیام یک آواتار کوچک با تصویری متفاوت برای کاربر و هوش مصنوعی نشان میدهد.
بیایید مقداری منطق برای نشان دادن لودر بر اساس یک پرچم ایجاد کنیم:
{loading && ( < div className = "message-container ai" > < img src = "ai-assistant.png" alt = "AI avatar" className = "avatar" /> < div className = "message ai" > ... </ div > </ div > )}
در حالی که هوش مصنوعی در حال فکر کردن است (زمانی که loading
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;
از <Chatbot/>
در App.js
برای بارگیری رابط کاربری Chatbot استفاده کنید:
function App ( ) { return ( < div className = "App" > < Chatbot /> </ div > ); }
علاوه بر این، ما از CSS نیز برای زیباتر کردن ربات چت خود استفاده می کنیم. برای آن می توانید به App.css و Chatbot.css مراجعه کنید.
Frontend را اجرا کنید
برای اجرای برنامه از دستور npm
استفاده کنید:
npm start
این باید قسمت جلویی را در URL http://localhost:3000
اجرا کند. این برنامه خوب است که اکنون آزمایش شود.
اما اجرای بکاند و فرانتاند بهصورت جداگانه کمی دردسرساز است. پس بیایید از Docker برای آسانتر کردن کل فرآیند ساخت استفاده کنیم.
نحوه Dockerize کردن برنامه
بیایید کل برنامه را باند کنیم تا به بستهبندی و ارسال آن به هر جایی بدون دردسر کمک کنیم. می توانید 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 است، که برای اجرای Spring Boot لازم است، باشد.
WORKDIR /app
: دایرکتوری کاری داخل کانتینر را روی /app
تنظیم می کند، جایی که فایل های برنامه ما در آنجا قرار می گیرند.
COPY target/chatbot-backend.jar /app/chatbot-backend.jar
: فایل JAR ساخته شده را از دستگاه محلی شما (معمولاً در پوشه target
پس از ساخت پروژه با Maven یا Gradle) در ظرف کپی می کند.
EXPOSE 8080
: این به Docker می گوید که برنامه به درخواست ها در پورت 8080 گوش می دهد.
CMD ["java", "-jar", "chatbot-backend.jar"]
: این دستوری را مشخص میکند که هنگام راهاندازی کانتینر اجرا میشود. این فایل JAR را اجرا می کند که برنامه Spring Boot را راه اندازی می کند.
Dockerize the Frontend
قسمت جلویی ربات چت ما با استفاده از React ساخته شده است، و ما میتوانیم آن را با ایجاد یک Dockerfile که وابستگیهای لازم را نصب میکند، برنامه را میسازد و با استفاده از یک وب سرور سبک مانند NGINX به آن سرویس میدهد، Dockerize کنیم.
بیایید Dockerfile
را برای بخش React بنویسیم:
# 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 برای ساخت برنامه React استفاده می کند. ما همه وابستگی ها را نصب می کنیم و برنامه را در داخل این کانتینر می سازیم.
WORKDIR /app
: پوشه کاری داخل کانتینر را روی /app
تنظیم می کند.
COPY package.json package-lock.json ./
: package.json
و package-lock.json
را برای نصب وابستگی ها کپی می کند.
RUN npm install
: وابستگی های فهرست شده در package.json را نصب می کند.
COPY . .
: تمام کد منبع frontend را در ظرف کپی می کند.
RUN npm run build
: برنامه React را می سازد. فایل های ساخته شده در یک پوشه build
قرار خواهند گرفت.
FROM nginx:alpine
: پس از ساخت برنامه، این خط یک کانتینر جدید بر اساس وب سرور nginx
راه اندازی می کند.
COPY --from=build /app/build /usr/share/nginx/html
: برنامه React ساخته شده را از اولین کانتینر در ظرف nginx کپی می کند و آن را در پوشه پیش فرضی که NGINX در آن فایل ها را ارائه می دهد قرار می دهد.
EXPOSE 80
: این پورت 80 را نشان می دهد که NGINX از آن برای ارائه ترافیک وب استفاده می کند.
CMD ["nginx", "-g", "daemon off;"]
: این کار سرور NGINX را در پیش زمینه شروع می کند تا برنامه React شما را ارائه دهد.
Docker Compose برای اجرای هر دو
اکنون که Dockerfiles جداگانه برای قسمت جلویی و بکاند داریم، 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
: این سرویس با استفاده از Dockerfile واقع در پوشه ./backend
بک اند را می سازد و پورت 8080 را در معرض نمایش قرار می دهد.
frontend
: این سرویس قسمت جلویی را با استفاده از Dockerfile واقع در فهرست ./frontend
می سازد. پورت 3000 روی هاست را به پورت 80 داخل کانتینر نگاشت می کند.
depends_on:
: این اطمینان را ایجاد می کند که قسمت جلویی قبل از شروع به کار منتظر می ماند تا backend آماده شود.
networks:
: این بخش یک شبکه اشتراکی را تعریف می کند تا هر دو قسمت باطن و فرانت اند بتوانند با یکدیگر ارتباط برقرار کنند.
برنامه را اجرا کنید
برای اجرای کل برنامه (هم فرانت اند و هم باطن)، می توانید از دستور زیر استفاده کنید:
docker-compose up --build
هم تصاویر جلویی و هم تصاویر باطنی را بسازید.
هر دو کانتینر را راه اندازی کنید (پشتیبان در پورت 8080، فرانت اند در پورت 3000).
شبکه را طوری تنظیم کنید که هر دو سرویس بتوانند با هم ارتباط برقرار کنند.
اکنون، می توانید به http://localhost:3000
مراجعه کنید و رابط کاربری Chatbot را بارگیری کنید و سوالات خود را از هوش مصنوعی بپرسید.
تبریک 🎉
شما با استفاده از Spring Boot، React، Docker و OpenAI یک برنامه چت ربات تمام پشته را با موفقیت ساختید.
کد منبع نشان داده شده در پروژه در Github موجود است، اگر آن را مفید دیدید، به آن ستاره بدهید، و با خیال راحت آن را تقسیم کنید و با آن بازی کنید.
ارسال نظر