Create Node.js chat-bot: in Bangla / বাংলা
We'll be using the ChatGPT API along with Node.js to build a versatile chat-bot.
বর্তমান সময়ে nodejs যেমন পপুলার, ঠিক তেমনি chatGpt আমাদের দৈনন্দিন কাজের অংশ হয়ে উঠছে।কারোকারো ঘুমছুটিয়ে দিচ্ছে চাকরি হারানোর ভয়ে ,আবার কারো হার্ড জব করেছে সহজ।
প্রোগ্রামমার বা ওয়েব নিয়ে আমরা যারা কাজ করি ,প্রযুক্তির সাথে তাল মিলিয়ে এবং নিজেকে সময়ের সাথে খাপখাইয়ে নিয়ে আপডেটেড থাকা ,একজন programmer এর স্কিল গুলোর মধ্যে বড় ভূমিকা পালন করে।
প্রতি মুহূর্ত আমি শিখছি নতুনকিছু আর সেখানে সঙ্গী হিসেবে তোমাকে সাথে নিয়ে আমি, এই প্রজেক্ট এ chatGpt API এবং nodejs ব্যবহার করে ছোট একটি chatbot বানাবো।
আমাদের chatbot টি openAi API ব্যবহার করে ফলে তুমি এক নজরে জেনে যাবে কিভাবে OPENAI API ইন্ট্রিগ্রেশন করতে হয়।
এছাড়া প্রজেক্ট এর সাথে সাথে ওয়েব ডেভেলপমেন্ট ও জাভাস্ক্রিপ্ট এর ছোট কিন্তু usefull কনসেপ্ট ক্লিয়ার হয়ে যাবে। যেমনঃ .env কি কাজ ,async/await এর ব্যবহার, map ফাঙ্কশন ,while লোপ ইত্যাদি আরো অনেক কিছু।
chatbot টি wide range conversations যেমন : প্রশ্নের উত্তর দেয়া ,কোড জেনারেট করা ,ভেঙেচুরে জোকস বুঝিয়ে দেয়া এমন আরো অনেক কাজ করতে পারবে।যা Powered by the impressive GPT-3.5 Turbo model.
তুমি chatgpt পিফিসিয়াল ডকুমেন্টেশন থেকে ঘুরে আসতে পার GPT (Generative Pre-trained Transformer) সম্পর্কে বিস্তারিত জানতে।
প্রশ্ন & উত্তর:
আমরা প্রজেক্ট শুরু করার আগে কিছু প্রশ্নের জবাব খুঁজে নিব :
এই প্রজেক্ট এ chatbot কিভাবে কাজ করবে ?
আমরা কি পরবর্তীতে chatGpt পরিষেবা কাস্টমাইজ করতে পারবো ?
এই প্রজেক্ট টি জানার প্রয়োজিনীয়তা ?
যদি তুমি node js না যান ?
আমাদের প্রজেক্ট টি শুরু করতে কি লাগবে ?
chatgpt API লিমিটেশন
Prerequisites(পূর্বশর্ত):
Getting Started(তাইলে শুরু হোক ):
আমরা প্রজেক্ট শুরু করার আগে অবশ্যই chatbot প্রজেক্ট ইনভর্ম্মেন্ট সাজাব যা আমাদের nodejs এর জন্য OpenAI package এর সাথে পরিচিত হতে সাহায্য করবে।
nodejs এর জন্য নতুন প্রজেক্ট তৈরী করতে, টার্মিনাল কমান্ড এর মাধ্যমে ফোল্ডার তৈরী করব । cd লিখে সেই ফোল্ডারে যাব এবং npm init
কমান্ড লিখে nodejs প্রজেক্ট ইনিশিয়ালাইজ করব।
mkdir chatgpt-chatbot
cd chatgpt-chatbot
npm init -y
এখানে আমাদের প্রজেক্ট ফোল্ডার এর নাম chatgpt-chatbot, cd chatgpt-chatbot লিখে ফোল্ডার এ ঢুকেছি then npm init -y
লিখে nodejs ফাঁকা প্রজেক্ট তৈরী করছি যা package.json
ফাইল প্রোভাইড করে। আর -y ফ্ল্যাগ yes মিন করে যা, অটোম্যাটিক আমাদের প্রম্প্ট এর উত্তর দেয়।
আমাদের প্রজেক্ট ফান্ডামেন্টাল রেডী হয়ে গেছে এখন দরকার প্রয়োজনীয় ডিপেন্ডেন্সিস। যা আমাদের প্রজেক্ট এ effectively কাজ করতে সহায়তা করবে।
ডিপেন্ডেন্সি কি ? সহজ ভাষায় এডিশনাল প্যাকেজ বা লাইব্রেরি ,যা কোন প্রজেক্ট কে সহজ করতে কাজে আসে। ডিপেন্ডেন্সি গুলি কোড এবং ফাংশনালিটি প্রোভাইড করে যা অন্য ডেভেলপাররা তৈরী করেছে এবং আমরা তা ব্যবহার করে শুরু থেকে সবকিছু তৈরী করা থেকে সময় বাঁচাতে পারি।
chatbot node প্রজেক্ট এ আমরা ৪ টা ডিপেন্ডেন্সিস ব্যবহার করব এবং পরবর্তীতে দরকার হলে নিজেদের মত npm প্যাকেজ হিসেবে add করে নিতে পারব।
ডিপেন্ডেসিসঃ
openai: This is the official OpenAI API wrapper for Node.js.
readline and readline-sync: It's a Node.js module that helps us read data from the terminal one line at a time.
dotenv: Another Node.js module that loads environment variables from a
.env
file.colors: This is optional but can make the terminal output look nicer with colors.
আমরা নিচে দেয়া কমান্ডটি টার্মিনালে লিখে ডিপেন্ডেন্সি গুলি ইনস্টল করতে পারি :
npm install openai readline dotenv colors readline-sync
ডিপেন্ডেন্সি ইনস্টল হয়ে গেলে আমরা কোড করার জন্য সামনে আগাতে পারি।
// package.json
{
"name": "chatgpt-chatbot",
"version": "1.0.0",
"description": "we are going to utilize the ChatGPT API to create a chatbot with Node.js. It will be powered by the GPT-3.5 Turbo model. This will be a general chatbot that can talk about anything. It will be able to answer questions, generate code, tell jokes, and much more. It's essentially ChatGPT, but within your own application with a Node.js wrapper. You'll be able to chat right within your terminal. This can come in handy because you can just keep your terminal open and chat with the bot whenever you want. You can also use this as a base to create your own chatbot. Also, there are awesome new features related to the OpenAI APIs being created all of the time, such as function calls. I will use this project as a starting point to demonstrate some of that stuff in the future. Let's get started with our chatbot! ",
"main": "index.js",
"type": "module",
"scripts": {
"start": "node index.js"
},
"author": "Tanvir Mehedi",
"license": "ISC",
"dependencies": {
"colors": "^1.4.0",
"dotenv": "^16.3.1",
"openai": "^3.3.0",
"readline": "^1.3.0",
"readline-sync": "^1.4.10"
}
}
ES Modules:
প্রজেক্ট এর কোড অর্গানাইজ করার জন্ন্য আমাদের মাল্টিপল ফাইল ইমপোর্ট ,এক্সপোর্ট করতে হবে আর তাই আমরা জাভাস্ক্রিপ্ট এর ES Module সিস্টেম ব্যবহার করব,তুমি চাইলে commonjs module system ব্যবহার করতে পার।
Es মডিউল সিস্টেম ব্যবহার করতে package.json ফাইল এ "type": "module"
লাইন যুক্ত করতে হবে । টাইপ মেনশন করার ফলে nodejs আমাদের প্রজেক্ট এ es৬ ES Module সিস্টেম ব্যবহার করতে সক্ষম হবে।
শুধু একটা ব্যাপার মাথায় রাখতে হবে , যখন আমাদের নিজেদের কোন ফাইল ইম্পোর্ট করব অবশ্যই ফাইল নাম এর শেষে
.js
এক্সটেনশন ব্যবহার করব।
উদহারণ দেখি, কারণ উদহারণ দেখলেই সব কিছু সহজ হয়ে যায় :
import { chatbot } from './chatbot.js';
দেখো ./chatbot এর পরে .js এক্সটেনশন ব্যবহার করেছি। এক্সটেনশন ব্যবহার না করলে আমরা একটি error পাব।
Add Your API Key:
তুমি নিশ্চই জান, API মানে এপ্লিকেশন প্রোগ্রামিং ইন্টারফেস
।
আর সহজ ভাষায় API key হল ,digital id কার্ড যা স্পেসিফিক এপ্লিকেশন এর API অথিন্টিকেট কিনা তা চেক করে ও ব্যবহারের পারমিশন দেয়। প্রত্যেকের user এর জন্য API key ইউনিক, তাই এটি সিকিউর রাখা জরুরি যেন ,অন্য কেও তোমার api key use করতে না পারে।
সুতরাং API key সিকিউর ভাবে সংযুক্ত করার জন্য আমাদের প্রজেক্ট ফোল্ডার roo এ .env
নামের ফাইল তৈরী করে তার মধ্যে OPENAI_API_KEY(ভ্যারিয়েবল নাম) = YOUR_API_KEY(তোমার key)
ফরমেট ব্যবহার করতে পারি ।
উদহারণ :
//.env
OPENAI_API_KEY=sk-EGn00d2AnaHBFQWsL5aXXXXXXXT3BlbkFJmQ2tnEtHMQ3bmucbTHjz
Note :
.env
হল একটি কনফিগারেশন ফাইল যা, সেনসেটিভ ইনফরমেশন স্টোর করে key-value format এ। মূলত এটি ব্যবহার করা হয় API keys ,password এমন সেনসেটিভ ডাটা কোডবেস থেকে আলাদা করার জন্য।
এবং , আমরা যেহেতু আমাদের কোড GitHub এ আপলোড করব, তাই আরো একটি কনফিগারেশন ফাইল তৈরী করব .gitignore
এবং .gitignore ফাইল এ টেক্সট আকারে বলে দিব .env । এর ফলে আমাদের .env ফাইল আকসিডেন্টলি গিটহাব এ push হবে না ও API key সুরক্ষিত থাকবে।
example :
// /.gitignore
.env
Using the OpenAI Package:
আমরা অলরেডি আমাদের প্যাকেজ গুলো ইনস্টল করে ফেলেছি।
এখন আমাদের টার্গেট হচ্ছে প্রয়োজনীয় প্যাকেজ গুলো আমাদের মেইন স্ক্রিপ্ট ফাইল এ ইম্পোর্ট করা। আমার ক্ষেত্রে মেইন স্ক্রিপ্ট ফাইল এর নাম index.js
, যা প্রজেক্ট ফোল্ডার এর root এ create করব।
এরপর index.js ফাইল এর শুরুতে necessary modules এবং ক্লাস গুলো নিয়ে আসব for working with OpenAI APIএবং handling environment variables.
//index.js
import { Configuration, OpenAIApi } from 'openai';
এই লাইন টি Configuration and OpenAIApi
ক্লাস ইম্পোর্ট করে openAi প্যাকেজ থেকে। Configuration
ক্লাস ব্যবহার হয়, OpenAI API কনফিগার করার জন্য, আর OpenAIApi হল মেইন ক্লাস যা API এর সাথে ইন্টারাক্ট করতে সাহায্য করে।
dotenv:
//index.js
import dotenv from 'dotenv';
dotenv.config()
dotenv ইম্পোর্ট করে dotenv প্যাকেজ । এবং dotenv.config()
লোড করে ইনভরমেন্ট ভ্যারিয়েবল .env ফাইল থেকে, যা আমরা ব্যবহার করতে পারি process.env
অবজেক্ট এর মাধ্যমে।
এই ইমপোর্ট প্রসেস বোঝা জরুরি, কারণ এই স্টেপ make sure that আমরা আমাদের কোড এ API key পাচ্ছি Rather সরাসরি সেনসেটিভ ডাটা কোড বেসএ না লিখে।
//index.js
// rest of the code ...
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY
});
const openai = new OpenAIApi(configuration);
configuration ভ্যারিয়েবল টি openAi API এর জন্য একটা configuration অবজেক্ট তৈরী করে এবং apikey
প্রপার্টির ভ্যালুহিসেবে process.env.OPENAI_API_KEY
ভ্যারিয়েবল লোড করে .env ফাইল থেকে।
পরবর্তী লাইন টি Configuration
অবজেক্ট এর মাধ্যমে একটি নতুন ক্লাস ইন্সটান্স তৈরী করে ও ব্যবহার করে OpenAIApi
অবজেক্ট থেকে , যার নাম আমরা দিয়েছি openai, const openai = new OpenAIApi(configuration);
।
এই ইন্সটান্স ক্লাস টি ব্যবহার হয় openAI এর API সার্ভিস call করার জন্য।
Note: In JavaScript, the term "instance" is used to refer to an individual object created from a class. main ক্লাস হলো ব্লুপ্রিন্ট। এবং ইনস্ট্যান্স create করার মাধ্যমে তুমি স্ট্রাকচার ক্লাস কে পরিবর্তন না করে নিজের ক্লাস তৈরী করতে পার।
USE OF OPENAI API :
//index.js
//rest of the code ...
const chatCompletion = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'user', content: 'Tell me a joke!' },
],
});
openai.createChatCompletion
মেথড হচ্ছে openai এর ইনস্ট্যান্স, আমরা এটাকে chatGpt ব্যবহার এর সাথে সাদৃশ্য করতে পারি।
এই মেথড টা অবজেক্ট নেয় , তবে অনেক গুলো প্রপার্টি অবজেক্ট পেরামিটার হিসেবে নেয়। যেমন ধর ,model,message এমন আরো অনেক আছে। আমরা প্রজেক্ট এ model,message নিয়ে কাজ করব।
message হচ্ছে একটা array অফ object যার মদ্ধ্যে আমরা role ,content এসব বলে দিতে পারি। তোমার হয়তো মনে আছে, যখন আমরা chatGpt use করি ওইবেটা একটা role প্লে করে, বা আমরা দিয়া দেই।
আর content মানে তোবুঝোই , তুমি যা লিখে দাও বা যা জানতে চাও। এখানে একটা ব্যাপার মাথায় রাখবা message এর মধ্যে role ,content খুব গুরুত্তপূর্ন। gpt model এর উপর ভিত্তি করেই ইন্টারেক্টিভ ও ইফেক্টিভ রেজাল্ট দিয়ে থাকে।
কনসোলে দেখো :
//index.js
//rest of the code..
console.log(chatCompletion.data);
আচ্ছা যা হলো মোটামুটি বুজলাম open API কেমনে কাজ করে। আমরা কনসোল লগ করছি data অবজেক্ট কে ,এটাই আমাদের জেনারেটেড রেসপন্স এবং অন্য সব ডাটা provide করবে।
তুমি যদি চাও , ডাইরেক্ট তোমার প্রজেক্ট এর টার্মিনাল এ গিয়ে node index.js
লিখে রান করতে পারো।কোড ঠিক থাকলে আউটপুট আসবে। আর তা না হলে package.json
এর scripts
সেকশন এ scripts মেনশন করে দিতে পার।
//package.json
// rest of the code..
"scripts": {
"start": "node index.js"
}
//code ....
টার্মিনাল এ npm start
কম্যান্ড চালালে আউটপুট দেখতে পারবা।
//OUTPUT-----------------------------------------------------------
data: {
id: 'chatcmpl-7WSNhqrMVdr7vtt32o5PhYGgYrkU3',
object: 'chat.completion',
created: 1687969949,
model: 'gpt-3.5-turbo-0613',
choices: [ [Object] ],
usage: { prompt_tokens: 14, completion_tokens: 11, total_tokens: 25 }
}
Note : তোমার ক্ষেত্রে আউটপুট ভিন্ন হতে পারে। তুমি চাইলে কমেন্ট এ জানাতে পার।
Data Details:
আমরা যখন API থেকে রেস্পন্স ব্যাক পাই ,এটা একটা নিদৃষ্ট ফরমেট ফলো করে।
console.log(chatCompletion.data.choices[0].text);
Accessing Choices Array: আমরা যখন রেসপন্স পাই API সেটাকে singel choices
array অফ অবজেক্ট স্টোর করে। যা মূলত একটা array তাই choices[0]
array এর ফাস্ট এলিমেন্ট 0 দিয়ে একসেস করেছি ।
//output-----------------------
> practice-bot@1.0.0 start
> node index.js
[
{
index: 0,
message: {
role: 'assistant',
content: 'Hello! I am an AI, specifically a language model developed by OpenAI known as GPT-3. I am designed to assist with a wide range of tasks and answer questions to the best of my abilities. How can I assist you today?'
},
finish_reason: 'stop'
}
]
Message Details: choice
যেহেতু একটা array অফ অবজেক্ট তাই, তুমি message নামের প্রপার্টি খুঁজে পাবা ,যার মধ্যে role ,content এসব মেনশন করা আছে। তুমি অবজেক্ট একসেস এর dot(.) নোটেশন ব্যবহার করে choices array কে টার্গেট করে message অবজেক্ট access করতে পার।
Roles and Index: Role ইন্ডিকেট করে message জেনারেট করছে কে "assistant" নাকি "user" ।এখানে assistant হল bot । আর index হল message এর index যা আমরা API এর মাধ্যমে message array তে পাঠাই। আমরা যদি ১ টা message পাঠায় ইনডেক্স হবে 0।
Finish Reason: finish_reason
তথ্য দেয় কোনভার্সেশন শেষ কেন হয়েছে।
মনে রাখবা ,তুমি যদি message অ্যারেতে একাধিক message পাঠাও তবে, choices অ্যারেতে প্রতিটি বার্তার জন্য response পাবে এবং ইনডেক্স চেঞ্জ হবে।
//OUTPUT---------------------------
{
choices: [
{
index: 0,
message: {
role: 'assistant',
content: "Why don't scientists trust atoms? Because they make up everything!"
}
},
{
index: 1,
message: {
role: 'user',
content: "I don't know, why?"
}
}
]
}
Note: For more details about the Completions API and its parameters, you can refer to the OpenAI API documentation.
Creating the Chatbot:
ওকে ,API অনেক বোঝা হইছে ,এবার Open API প্যাকেজ ব্যবহার করে chatbot বানাই ফেলি।
কিন্তু তার আগে কোড অর্গানাইজ করার জন্য আমরা configuration এবং instantiation OpenAIApi class এর উপর ভিত্তি করে ফাইল সেপারেট করে ফেলব।
আমাদের মেইন প্রজেক্ট এর মধ্যে config
নামে একটা ফোল্ডার তৈরী করব এবং inside the config ফোল্ডার make a file name openai.js
।
এবার কাজ সহজ index.js থেকে OPENAI কনফিগারেশন কোড এবং যেখানে openai ইনস্ট্যান্স create করে সেটাকে সেপারেট করে openai.js
এর মধ্যে নিয়ে চলে আসি আর জাভাস্ক্রিপ্ট module কনসেপ্ট ব্যবহার করে export default করে দেয়। এতে করে পরবর্তীতে অন্যকোথাও কনফিগারেশন করা লাগলে সহজ হবে কোড reuse করা।
// /config/openai.js
import { Configuration, OpenAIApi } from "openai";
import dotenv from "dotenv";
dotenv.config();
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
export default openai;
Note :
.env
file কনফিগারেশনopenai.js
রাখার কারণ হচ্ছে, আমার api key কল করে নিউ ইনস্ট্যান্স তৈরী করাindex js
এ এর কোন কাজ নাই।
এখন , index.js যেটা আমাদের মেইন এন্ট্রি পয়েন্ট সেখানে openai ভ্যারিয়েবল ইম্পোর্ট করব।
এবং আরো যে যে প্যাকেজ দরকার ইমপোর্ট করব।
// index.js
import openai from "./config/openai.js";
import readlineSync from "readline-sync";
import colors from "colors";
const chatCompletion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: "user",
content: "Who are you",
},
],
});
console.log(chatCompletion.data);
Note : programming এর মেইন একটা কনসেপ্ট হলো কোড অর্গানাইজ করা, এতে করে code রিডএবিলিটি বাড়ে এবং মেইনটেন করতে সহজ হয়।
readlineSync:
আমরা এখন পর্যন্ত যা করেছি তাতে আশাকরি ,তুমি openai ইনস্ট্যান্স কি এবং তা তৈরী করতেপেরে। এই পর্যন্ত ক্লিয়ার থাকলে আমরা সামনে আগাতে পারি।
এবং এ পর্যায়ে তুমি readline-sync প্যাকেজ সম্পর্কে জানবা, আমিও জানবো তোমার সাথে। এই জার্নিতে নতুন অনেক কিছু জেনেছি তোমায় সাথে নিয়ে, থ্যাংক ইউ ।
readline-sync হল readline প্যাকেজ এর সিমপ্লিফায়েড ভার্সন।
readline-sync এর কাজ হচ্ছে user থেকে ইনপুট নেয়া সিনক্রোনাইস ভাবে মানে ,এক এক করে, যা readline প্যাকেজের অল্টারনেটিভ। readline asynchronous approch ফলো করে বলে কিছুটা জটিল। তাই আমরা জটিল এর দিকে যাবো না।
Note: প্রোগ্রামিং হোক বা কিছু নতুন শিখতে চাচ্ছ ,সহজ দিয়ে শুরু করবা ,পরে বেসিক আয়ত্তে আসলে ,জটিল জটিল কাজও সহজ হবে।
তাহলে, আমরা readline-sync
ব্যবহার করে promp এর মাধ্যমে user থেকে ইনপুট সংগ্রহ করতে পারব এবং রেসপন্স variable আকারে স্টোর করতে পারব।
//index.js
import readlineSync from 'readline-sync';
const userName = readlineSync.question('May I have your name? ');
console.log('Hi ' + userName + '!');
তুমি যখন কোড রান করার জন্য টার্মিনালে npm start কমান্ড চালাবে ,prompt এ নাম চাইবে এবং কনসোল লগ এ একটি গ্রেটিং মেসেজ ডিসপ্লে করবে।
OUTPUT------------------
> practice-bot@1.0.0 start
> node index.js
May I Know Your Name?Tanvir
Hi Tanvir!
Note: ইন্টারেক্টিভ command-line এপ্লিকেশন যেমন ,chatbot বা realtime messaging এর জন্য readline-sync খুব হ্যান্ডি কাজ করে ,ইনপুট নেয়া সহজ করে।
আমরা যত সামনে আগাবো দেখতে পাব কিভাবে readline-sync openai api ইনস্ট্যান্স এর সাথে communicate করে এবং রেস্পন্স জেনারেট করে chatbot এর জন্য।
Let's recap what we've covered so far:
এখন পর্যন্ত আমরা কি কি করেছি ,তার একটা ছোট overview নেয়া যাক :
আমরা শুরু করেছিলাম প্রজেক্ট সেটিং করা থেকে যা ছিল foundation of this project.
নতুন nodejs প্রজেক্ট তৈরী করেছি এবং dependencies ইনস্টল করেছি
openai, readline-sync, dotenv, and colors
etc.পরবর্তী ধাপে আমরা OPENAI API connection ও কনফিগার করা শিখেছি। সাথে .env কনসেপ্ট বুঝেছি যা সিকিউর ভ্যারিয়েবল দেয়।
কিভাবে user থেকে মেসেজ send করা যায় তা দেখেছি। choices ,role, index, and message.content এসবের কাজ গুলি দেখে ফেলছি ।
কিভাবে
openai
instance এর উপর ভিত্তি করে কোড অর্গানাইজ করতে হয় তা অল্পপরিষরে জেনেছি । ( রিমেম্বার ,কোড অর্গানাইজেশন বড় চ্যালেঞ্জ। তাই প্রচুর এক্সাম্পল দেখতে হবে ও চেষ্টা করতে হবে )readline-sync প্যাকেজ সম্পর্কে পরিচিত হয়েছি এবং এর ব্যবহার সম্পর্কে overview নিয়েছি।
এখন পর্যন ,যা বোঝা যাচ্ছে আমাদের core of fundamental রেডি। তাইলে পরবর্তী ধাপে যেতে আমরা প্রস্তুত।
Let's keep building! --
main()
Function:
তুমি নিচে দেয়া code গুলিতে খেয়াল কর ,
আমাদের chatbot প্রজেক্ট এর বেসিক সেট-আপ এবং এটি ডিসপ্লে করে welcoming message in green bold টেক্সট।
//index.js
import openai from "./config/openai.js";
import readlineSync from "readline-sync";
import colors from "colors";
async function main() {
console.log(colors.bold.green("Welcome to the Chatbot Program!"));
console.log(colors.bold.green("You can start chatting with the bot."));
const userName = readlineSync.question("May I Know Your Name?");
console.log(`Hi ${userName}!`);
}
main();
তুমি যদি কোড লিখে থাক তোমার প্রজেক্ট index.js এ দেখবে আমরা একটা async ফাঙ্কশন তৈরী করেছি main নামে যা আপাতত গ্রীন বোল্ড টেক্সট ডিসপ্লে করে। এই main ফাঙ্কশন responsible for হ্যান্ডেল conversation ,user inuput taking এবং ব্যাক রেসপন্স from chatbot। আমরা color প্যাকেজ ব্যবহার করেছি for format text in the টার্মিনাল।
colors.bold
is used to make the text bold.colors.green
is used to change the text color to green.
//output----------------
> practice-bot@1.0.0 start
> node index.js
Welcome to the Chatbot Program!
You can start chatting with the bot.
May I Know Your Name?Tanvir
Hi Tanvir!
xxxxxxxxxx:~/Documents/Projects/practice-Bot$
টার্মিনাল আউটপুট এর দিকে লক্ষ্য করলে দেখতে পাবে ,আউটপুট দেয়ার পরে আমাদের exit করে দিচ্ছে কনসোল থেকে আবার কমান্ড দেয়ার জন্য। সাধারণত chatbot এমন হয় না। যতক্ষণ user চাইবে চলমান কোনভার্সেশন শেষ হোক ততক্ষন টার্মিনেট করবে না।
এখানেই লুপিং কনসেপ্ট আসছে।
While Loop:
আমরা একটা while loop চালাব যা আমাদের প্রোগ্রাম কে ততক্ষন পর্যন্ত চলমান রাখবে ,যতক্ষণ না user exit টাইপ করে।
//index.js
import openai from "./config/openai.js";
import readlineSync from "readline-sync";
import colors from "colors";
async function main() {
console.log(colors.bold.green("Welcome to the Chatbot Program!"));
console.log(colors.bold.green("You can start chatting with the bot."));
while (true) {
const userInput = readlineSync.question(colors.yellow("You: "));
try {
if (userInput.toLowerCase() === "exit") {
console.log(colors.green("Bot: ") + completionText);
return;
}
console.log(colors.green("Bot: ") + completionText);
} catch(err) {
console.log(colors.red(err))
}
}
}
main();
ok,চল কোড গুলোকে ভেঙেচুরে দেখি কি হচ্ছে?
Note : while লুপ এর কনসেপ্ট খুব সহজ, তোমার মনে আছে আশাকরি।!
যদি না থাকে ,মনে রাখবা যতক্ষণ loop এর কন্ডিশন সত্য থাকবে ততক্ষন লুপ চলবে। ইনফিনিটি লুপ এ পরিণত হবে এবং explicitly ব্রেক করবে যদি, লুপ টার্মিনেট করার কন্ডিশন না পায় ।
তাই ,আমাদের এমন কন্ডিশন চালাতে হবে যেন ,তার উপর বেস করে লুপ false বা মিথ্যা হয় ও লুপ থেকে বের হয়ে যায় ।
চল কোড এ ফোকাস করি ,
const userInput = readlineSync.question(colors.yellow("You: "));
readlineSync.question
ফাঙ্কশন ব্যবহার করে user থেকে ইনপুট নিয়েছি, যা userInput ভ্যারিয়েবল এ ডাটা স্টোর করে।
try {
if (userInput.toLowerCase() === "exit") {
console.log(colors.green("Bot: ") + completionText);
return;
}
console.log(colors.green("Bot: ") + completionText);
} catch(err) {
console.log(colors.red(err))
}
loop এর মধ্যে try ও catch ব্লক নিয়েছি। try ব্লক এর মধ্যে if স্টেটমেন্ট এ কন্ডিশন apply করেছি । কন্ডিশন সহজ , লোয়ার কেস ভার্সন এ user এর ইনপুট যদি exit
হয় তবে একটা টেক্সট প্রিন্ট করবে ও return এস্টেটমেন্ট এর মাধ্যমে লুপ থেকে থেকে বের হয়ে যাবে।
আর যদি try ব্লক এ কোন error ঘটে তবে catch ব্লক error হ্যান্ডেল করবে ,colors.red
কনসোল লগ এ error টেক্সট লাল করে দিবে ।
NOTE : catch ব্লক এর err পেরামিটার javascript এর বিল্টইন ফিচার যা, জাভাস্ক্রিপ্ট আমাদের provide করে।
কোড খেয়াল করলে দেখতে পাবে আমরা এখনো completionText
ডিফাইন করিনি তাই তুমি npm start
কমান্ড চালালেও কোন bot রেসপন্স দেখতে পাবে না।
ওকে ,টার্মিনালে npm start
কমান্ড চালাই এবং exit টাইপ করে দেখি আমাদের লুপ exit করে কিনা?!
//terminal output
> practice-bot@1.0.0 start
> node index.js
Welcome to the Chatbot Program!
You can start chatting with the bot.
You: Hi
ReferenceError: completionText is not defined
at main (practice-Bot/index.js:37:1)
at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
You: exit
ReferenceError: completionText is not defined
You: ^C
completionText নাই বলে error দিয়েছে, ReferenceError: completionText is not defined।তুমি ctrl+c
প্রেস করে টার্মিনাল থেকে বের হয়ে যেতে পার।
তবে ,এতেকরে বোঝা যায় ,আমাদের কোড ঠিক ভাবে কাজ করছে কারণ ,এই error আমাদের এক্সপেকটেড ছিল।
Note : তার মানে বুজলা তো ,মাঝে মাঝে error ঝামেলার না ,কাজেরও হয়। :)
Integrate OpenAI:
আমরা এর আগে main ফাঙ্কশন create করেছি।
Most of the chatbot লজিক আমরা ফাঙ্কশন মধ্যেই লিখব। এই ফাঙ্কশনটি রেস্পন্সিবল for user থেকে ইনপুট নেয়া ,OPENAI API এর সাথে ইন্টারেক্ট করা এবং রেস্পন্সেস ডিসপ্লে করা।
//index.js
import openai from "./config/openai.js";
import readlineSync from "readline-sync";
import colors from "colors";
async function main() {
console.log(colors.bold.green("Welcome to the Chatbot Program!"));
console.log(colors.bold.green("You can start chatting with the bot."));
while (true) {
const userInput = readlineSync.question(colors.yellow("You: "));
try {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: "user",
content: userInput,
},
],
});
const completionText = completion.data.choices[0].message.content;
if (userInput.toLowerCase() === "exit") {
console.log(colors.green("Bot: ") + completionText);
return;
}
console.log(colors.green("Bot: ") + completionText);
} catch (err) {
console.log(colors.red(err));
}
}
}
main();
Note : টিউটোরিয়াল বা ব্লগ পড়ে যখন কিছু শেখার চেষ্টা করবে। প্রথমে কোড করবা পরে টিউটোরিয়াল দেখে কোড বোঝার চেষ্টা করবা। এতেকরে নোড গুলো যোগ করতে সহজ হবে ।
while(true)
তার মানে উপরের কোড অনুযায়ী লুপ এর মধ্যে chatbot চলমান থাকবে এবং অপেক্ষা করবে user ইনপুট এর জন্য।
async / await কনসেপ্ট :
তুমি জাভাস্ক্রিপ্ট ভাষায় কোড লিখছো। তার মানে, আসিনক্রোনাস জাভাস্ক্রিপ্ট কি তা যান ।
তারপরও , শর্ট overview আকারে আমরা একবার দেখে নেই async / await এর porpuse । ঝালাই দিয়ে নেয়া আরকি ! :)
জাভাস্ক্রিপ্ট এ await keyword ব্যবহার করা হয় async ফাঙ্কশন এর সাথে। এটা এক্সিকিউশন কে pause করে রাখে, যতক্ষণ না
Promise
resolved হচ্ছে । এই process পার্টিকুলারলি useful যখন আমাদের অসিনক্রোনাস অপারেশন ,যেমন ধরো সার্ভার থেকে ডাটা ফেচ করা বাI/O
(ইনপুট /আউটপুট ) অপারেশন মানে , তোমার কোথাও রেজাল্ট এর জন্য অপেক্ষা করা দরকার , পরবর্তী কোড এ যাওয়ার আগে,সেসব জায়গায় ব্যবহার হয়।
ওকে ,এবার কোড ফিরে আসি :
try {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [
{
role: "user",
content: userInput,
},
],
});
const completionText = completion.data.choices[0].message.content;
const completion = await openai.createChatCompletion
এই লাইনে কেন await ব্যবহার করলাম ?
await কীওয়ার্ডটি ব্যবহার করা হয়েছে কারণ, তুমি openai.createChatCompletion()
ফাংশন ব্যবহার করে একটি অ্যাসিঙ্ক্রোনাস API কল করছ । এই ফাংশনটি একটি Promise
Retuen করে যা OpenAI API ব্যবহার করে ,একটি চ্যাট completions তৈরি করার অ্যাসিঙ্ক্রোনাস অপারেশনকে রিপ্রেসেন্ট করে। এখানে await ব্যবহার করে,তুমি প্রোগ্রামটিকে বলছ ভাই থাম ,আগে API কল সম্পূর্ণ হোক, পরে সামনে বারবি।
তার মানে createChatCompletion
মেথড এর মাধ্যমে user যে ইনপুট দিছে সেটা OPENAI API কে পাঠাইছে, then API রেসপন্স জেনারেট করছে , যেটা আমাদের দেয়া user ইনপুট এর উপর বেস করে।
খেয়াল কর ,আমরা কিন্তু এখন রেসপন্স ব্যাক পাইছি। কিন্তু প্রশ্ন হচ্ছে রেসপন্স কই পাইছি ?!
completion.data.choices[0].message.content
এই লাইনে ,যা অবজেক্ট নোটেশন ব্যবহার করে এক্সট্র্যাক্ট করছি ,আর ডাটা completionText
ভ্যারিয়েবল এ স্টোর করছি।
pomise
আর async/await
একবারে জাইনা গেলা।এর পরের কাজ কিন্তু সোজা, if ব্লক এর বাইরে কনসোল লগ এ ডাটা দেখাবে। আর user যদি "exit" টাইপ করে তো কন্ডিশন true হবে, রিটার্ন করে লুপ শেষ করবে।
কিন্তু catch ব্লক এ কখন যাবে? ,যাবে যদি তুমি কোন ক্যাচাল লাগাও বা error খাও।
Note :
main()
ফাঙ্কশন ইনভোক না করলে ,মানে কল না করলে কিন্তু হবে না। তাই ফাঙ্কশন এর বাইরে invoke করে দিবা মনেকরে ।
এবার টার্মিনাল এ যাই , আর কমান্ড চালাও npm start
...
// output
> practice-bot@1.0.0 start
> node index.js
Welcome to the Chatbot Program!
You can start chatting with the bot.
You: Hi
Bot: Hello! How can I assist you today?
You: who are you?
Bot: I am an AI language model developed by OpenAI, known as GPT-3. I am designed to help answer questions and engage in conversations on various topics.
You: ok exit
Bot: Goodbye! If you have any more questions, feel free to ask. Have a great day!
You: exit
Bot: Goodbye! If you have any more questions in the future, feel free to ask. Have a great day!
~/Documents/Projects/practice-Bot$
Remembering Context:
আমরা chatbot বানাইছি কিন্তু প্রব্লেম হলো। ও আগের কোনভার্সেশন মনে রাখতে পারে না। যেটা chatgpt এর বিগ ফিচার। আমাদের এখন, হিস্ট্রি ইম্প্লিমেন্টেশন করতে হবে। for remember ,প্রিভিয়াস কনভার্সেশন কি ছিল ।
// index.js final
import openai from "./config/openai.js";
import readlineSync from "readline-sync";
import colors from "colors";
async function main() {
console.log(colors.bold.green("Welcome to the Chatbot Program!"));
console.log(colors.bold.green("You can start chatting with the bot."));
const chatHistory = []; //new line for store chat history
while (true) {
const userInput = readlineSync.question(colors.yellow("You: "));
try {
// new line for destructuring mapping data
const messages = chatHistory.map(([role, content]) => ({
role,
content,
}));
// new line for push data
messages.push({ role: "user", content: userInput });
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
// new line for
messages: messages,
});
const completionText = completion.data.choices[0].message.content;
if (userInput.toLowerCase() === "exit") {
console.log(colors.green("Bot: ") + completionText);
return;
}
console.log(colors.green("Bot: ") + completionText);
// new line for push privious conversation
chatHistory.push(["user", userInput]);
chatHistory.push(["assistant", completionText]);
} catch (err) {
console.log(colors.red(err));
}
}
}
main();
তাহলে চল, উপরের কোড গুলোকে ভেঙে ফেলি।
const chatHistory = [];
তুমি দেখতে পাবে chatHistory নামে একটা empty array নিয়েছি। এই array আমাদের conversation স্টোর করে রাখবে।
try {
const messages = chatHistory.map(([role, content]) => ({
role,
content,
}));
then try ব্লক এ chatHistory arrayকে map function ব্যবহার করে প্রতিটি conversation ইটারেট করে একটি নতুন formate এ রূপান্তর করছি এবং messages ভ্যারিয়েবল এ স্টোর করছি ।
কিভাবে প্রসেস গুলি আগায় ?:
chatHistory হল অ্যারে যা conversation টার্ন্স সংরক্ষণ করে। প্রতিটা tarn দুটি উপাদান নিয়ে তৈরী :
role
(either "user" or "assistant") এবংcontent
(the text of the message) ।ম্যাপ ফাংশন chatHistory অ্যারেতে প্রতিটি আইটেমের উপর iterate করে।
syntex টা ([role, content]) হল destructuring এর , যেখানে প্রতিটি role, content যথাক্রমে role, content ভেরিয়েবল আকারে পাই ।
arrow ফাংশন => curly braces
{}
এর মাধ্যমে নতুন অবজেক্ট create করে যার, properties role এবং content। destructuring এর মাধ্যমে role এবং content value হিসেবে নেয়।
messages.push({ role: "user", content: userInput });
ম্যাপ messages যেহেতু array তাই object আকারে { role: "user", content: userInput }
messages array তে অ্যাড হয় ট্রু push মেথড।
//const completion = await openai.createChatCompletion({
// model: "gpt-3.5-turbo",
messages: messages,
//});
messages
প্রোভাইড chat history API context । messages
array আমাদের conversation history রাখে, including user inputs এবং previous bot রেস্পন্সেস। এই context, model কে বুজতে সাহায্য করে বর্তমান conversation ,এবং generate করে relevant রেস্পন্সেস।
chatHistory.push(["user", userInput]);
chatHistory.push(["assistant", completionText]);
chatHistory.push(["user", userInput])
লাস্ট user কি মেসেজ দিয়েছে সেটা chatHistory তে পুশ করে আর chatHistory.push(["assistant", completionText])
এই লাইন assistant এর লাস্টকোনভার্সেশন হিস্ট্রি রাখে।
//OUTPUT
> practice-bot@1.0.0 start
> node index.js
Welcome to the Chatbot Program!
You can start chatting with the bot.
You: Hi
Bot: Hello! How can I assist you today?
You: Do you know i am from Bangladesh
Bot: That's wonderful! I'm glad to know that you're from Bangladesh. How can I help you?
You: just remember that and i am useing gpt3.5
Bot: I apologize if there was any confusion. As an AI language model, I don't have access to personal information or knowledge about specific events unless you provide me with more details. Please feel free to ask me anything or let me know how I can assist you further.
You: where i am from?
Bot: Based on your previous statement, you mentioned that you are from Bangladesh.
You: exit
Bot: I'm sorry if I couldn't assist you in the way you expected. If you have any other questions in the future, feel free to ask. Have a great day!
68:~/Documents/Projects/practice-Bot$
so ,আশাকরি তোমার সম্পূর্ণ লেখা পড়ে ভালো লাগছে । তুমি চাইলে আরো সামনে আগাই নিয়ে যেতে পার এপ্লিকেশন কে । আর টার্মিনাল এ run করে বলে মাঝে মাঝে slow কাজ করে। এসব তুমি পেইড ভার্সন এ পাবে না।
ওকে ,তো প্রাকটিস করতে থাক। পরবর্তী কোন একটা ব্লগ এ কথা হবে তোমার সাথে ততক্ষন পর্যন্ত ( GOOD BYE)
কোন কনফিশন থাকলে কমেন্ট কর ,অন্যদের শেখার জন্ন্য কনটেন্ট শেয়ার কর। এবং তোমার পার্সোনাল কোন ব্লগ রিকোয়েস্ট থাকলে আমায় জানাও।
FINALLY, SUPPORT ME IF YOU WANT