Build your custom chatbot using chatgpt
Tags: chatgpt, chatbot, python, react
Published: 2023-03-26 17:52:59

ChatGPT is the most powerful language model ever built. It is an amazing tool that can be used in various ways to enhance your productivity and learning. ChatGPT can supports for quick answers to trivial questions or in-depth explanations of complex concepts. ChatGPT has become a trending AI tool in just a matter of weeks. It hit 100 million monthly active users in last January, according to data from Similarweb.

According to Drift’s 2021 State of Conversational Marketing report, 74% of companies want to implement conversational Artificial Intelligence (AI) tools to streamline workflow. It is clear that it has wide range of applications from customer service to virtual assistants. ChatGPT is a well-suited example as it can generate human-like responses to user inputs.

In this article, we will learn more about ChatGPT and build a custom chatbot using python and react frameworks.

## Getting Started
### Table of contents
- What is ChatGPT
- How to use ChatGPT
- GPT3 integration in Python
- Gradio based frontend creation
- Build a custom chatbot
- Applications of ChatGPT

### What is ChatGPT
ChatGPT was created by OpenAI, a research company co-founded by Elon Musk and Sam Altman. The company launched ChatGPT on Nov. 30, 2022. It is one of the most sophisticated language processing AI models with 175 billion parameters.

ChatGPT can generate anything with a language structure, which includes answering questions, writing essays and poetry, translating languages, summarizing long texts, and even writing code snippets!

ChatGPT uses state of the art AI techniques to understand and generate human-like responses to a wide range of questions and prompts. It uses a combination of natural language processing techniques and machine learning algorithms to understand the meaning behind words and sentences and to generate responses that are appropriate to the context of the conversation. It has been trained on a massive corpus of text data, including articles, books, and websites, enabling it to provide precise and insightful answers.

### [How to use ChatGPT](https://youtu.be/JipdMYDnwzY)

You can access ChatGPT by visiting chat.openai.com, creating an OpenAI account and agreeing to chatGPT terms.

#### Create an OpenAI account
Go to [chat.openai.com](https://chat.openai.com) and register for an account with an email address. You need to create an account on the OpenAI website to log in and access ChatGPT.
![login](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hd7n1wtjvdr7bsy92pdh.png)

#### Accept ChatGPT terms
Once you logged into your OpenAI account on the website, go through the terms and conditions for ChatGPT and click on Next. Click on Done to finish it.
![terms and conditions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6tbvqhq2mxchpuor6c1y.png)

#### Start writing prompts
ChatGPT is ready to use now. You can type in any prompts in the textbox at the bottom of the page and press enter to submit it. The AI chatbot will then provide helpful answers to your prompts.
![chatgpt](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1vke48xm6btght1tvfv.png)
You can put any of the example prompts mentioned in the site or your own one to get the answer. The result for Explain quantum computing in simple terms looks like below,

![prompting example 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vsobdeedqj318d1fku5l.png)
![prompting example 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f2v1genqn1dumdn5mhg5.png)

### GPT3 integration in Python
The OpenAI Python library provides convenient access to the OpenAI API from applications written in the Python language.

Follow the below steps to integrate GPT3 in python.

- An API token is required to access OpenAI’s services.
- Open [platform.openai.com](https://platform.openai.com).
- Click on your name or icon option which is located on the top right corner of the page and select “API Keys” or click on the link — [Account API Keys — OpenAI API](https://platform.openai.com/account/api-keys)
- Click on **create new secret** key button to create a new openai key.
![api key](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kzc2u34xe1cg90n3t19.png)

- Create and switch to a virtual environment before installing dependencies for openai and other libraries.
```
python -m venv venv
source venv/bin/activate  # for linux
venv\Scripts\activate     # for windows
```
- Install the OpenAI Python library using pip.
```
pip install openai
```
![openai installation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/447oxe8ksh4tiqu1e7z7.png)
- Create a new python file `chatgpt_demo.py` and add the following code to it.
```
import openai
openai.api_key = "" # your token goes here

def get_model_reply(query, context=[]):
    # combines the new question with a previous context
    context += [query]
    
    # given the most recent context (4096 characters)
    # continue the text up to 2048 tokens ~ 8192 charaters
    completion = openai.Completion.create(
        engine='text-davinci-002',
        prompt='\n\n'.join(context)[:4096],
        max_tokens = 2048,
        temperature = 0.4, # Lower values make responses more deterministic
    )
    
    # append response to context
    response = completion.choices[0].text.strip('\n')
    context += [response]
    
    # list of (user, bot) responses. We will use this format later
    responses = [(u,b) for u,b in zip(context[::2], context[1::2])]
    
    return responses, context

query = 'Which is the largest country by area in the world?'
responses, context = get_model_reply(query, context=[])

print('<USER> ' + responses[-1][0])
print('<BOT> ' + responses[-1][1])
```
- Run the script using the following command,
```
python chatgpt_demo.py
```
![run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/holfbs4b1wd1ehnyob4z.png)
`openai.Completion.create()` gives you the GPT3 response based on your query. In the above example, we asked it to explain what quantum computing in single terms. It was able to come up with a sharp answer to the query.

### Gradio based frontend creation
Gradio is an open-source Python library used to build AI related web applications. It allows developers to create user-friendly and customizable interfaces.

Follow the below steps to create gradio based frontend for displaying the content.

- Install the gradio python library using pip.
```
pip install gradio
```
- Add the following code to the chatgpt_demo.py file.
```
import gradio as gr

# defines a basic dialog interface using Gradio
with gr.Blocks() as dialog_app:
    chatbot = gr.Chatbot()
    state = gr.State([])
    
    with gr.Row():
        txt = gr.Textbox(
            show_label=False, 
            placeholder="Enter text and press enter"
        ).style(container=False)

    txt.submit(get_model_reply, [txt, state], [chatbot, state])

# launches the app in a new local port
dialog_app.launch()
```
- Run the app using the following command,
```
python chatgpt_demo.py
```
![run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bmztalkw93mmogfuf3lb.png)

Gradio will open a new port and launch an interactive app when `dialog_app.launch()` is executed. Running the examples provided in the previous section should return the same expected results. Messages entered by the user will appear on the right-hand side, while messages generated by OpenAI will be displayed on the left-hand side.
![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93rivi736vpqf2c6evla.png)

### Build a custom chatbot
In this section, we will create a custom chatbot using GPT3 with python as the backend and react as the frontend.

#### 1.1 Create a data file
The first step is to create a data file which contains the information about a specific topic. In this example, we use a quantum physics related content. Scrap the data from the link — [scienceexchange quantum-physics](https://scienceexchange.caltech.edu/topics/quantum-science-explained/quantum-physics) and add it inside a text file named `data.txt` under the data folder.

Ensure that you have added the below text as a prefix in the `data.txt` file.

```
I am VBot, your personal assistant. I can answer questions based on general knowledge.

Answer questions based on the passage given below.
The final data file looks as below,
```

#### 1.2 Create the environment
Create and switch to a virtual environment before installing dependencies for openai and other libraries.
```
python -m venv venv
source venv/bin/activate  # for linux
venv\Scripts\activate     # for windows
```
#### 1.3 Install dependencies
Install the `openai`, `fastapi`, `uvicorn`, `itsdangerous` and `python-dotenv` libraries using pip.
```
pip install openai fastapi uvicorn itsdangerous python-dotenv
```
#### 1.4 Create environment (.env) file
Create a file named `.env` and add environment variables for openai api key and secret key to it.
```
export OPENAI_API_KEY="openai-key"
export SECRET_KEY="32-length-random-text" 
```
#### 1.5 Openai GPT3 backend integration
Create a new file `main.py` and add the following code to integrate the Openai GPT3 model for your query responses.

```
import openai
import os
from dotenv import load_dotenv
import os 

load_dotenv(".env")
openai.api_key = os.getenv("OPENAI_API_KEY")

def read_file(file):
    content = ""
    f = open(file, 'r')
    Lines = f.readlines()
    for line in Lines:
        content = content + " " + line.strip()
    return content

session_prompt = read_file("datas/data.txt")
restart_sequence = "\n\nUser:"
start_sequence = "\nVBot:"

def answer(ques, chat_log = None):
    max_try = 1
    try_count = 0
    while True:
        try:
            prompt_text = f'{chat_log}{restart_sequence} {ques}{start_sequence}'
            print(prompt_text)
            response = openai.Completion.create(
                model = "text-davinci-002",
                prompt = prompt_text,
                temperature = 0.8,
                max_tokens = 500,
                top_p = 1,
                frequency_penalty = 0.0,
                presence_penalty = 0.6,
                stop = ["User:", "VBot:"]
            ) 
            # print(response)
            ans = response['choices'][0]['text']
            return str(ans)
        except:
            try_count = try_count + 1
            if(try_count >= max_try): 
                return 'GTP3 error'
            print('Error')

def checkViolation(ans):
    response = openai.Moderation.create(input=ans)
    output = response["results"][0]["flagged"]
    return output

def gpt3_logs(question, answer, chat_log=None):
    if chat_log is None:
        chat_log = session_prompt
    return f'{chat_log}{restart_sequence} {question}{start_sequence}{answer}'

def message_check(message, chat_log):
    flag_user = checkViolation(message)
    if(not flag_user):
        ans = answer(message,chat_log)
        flag_bot = checkViolation(ans)
        if(flag_bot):
            ans = "My response violates OpenAI's Content Policy."
    else:
        ans = "Your message violates OpenAI's Content Policy."
    return ans

def main(msg,chat):
    ans = message_check(msg,chat)
    print("VBot: ", str(ans))
    return ans

if __name__ == "__main__":
    ans = main("What is your name",chat=None)
```

**Understand the code:**

- Load the environment variables and set the `openai.api_key`.
- Create a method `read_file(file)` to read the contents from the text file.
- Initialize `session_prompt` variable with the data file content using the `read_file()` method. Also, initialize `start_sequence` and `restart_sequence` values as “\nVBot:” and “\n\nUser:”
- Create a method `answer(ques, chat_log)`. It takes questions and chat log as arguments and provides response from the openai with the help of `openai.Completion.create()` method.
- `message_check()` and `checkViolation()` methods are responsible for verifying the openai requests and responses using the `openai.Moderation.create()` method.
- `gpt3_logs` method specifies the openai requests and responses in a predefined format.

#### 1.6 Create and integrate a fastapi server
Create an api server to make the gpt3 integration available via http requests. For which, fastapi is selected to create apis.

Create a file named `app.py` and add the following code to it.

```
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware
import uvicorn
import os
from dotenv import load_dotenv
from main import gpt3_logs, main

app = FastAPI()

load_dotenv(".env")
secret_key_from_env = os.getenv("SECRET_KEY")

app.add_middleware(
    SessionMiddleware,
    secret_key = secret_key_from_env
)

app.add_middleware(
    CORSMiddleware,
    allow_origins = ["*"],
    allow_credentials = True,
    allow_methods = ["*"],
    allow_headers = ["*"],
)

@app.get("/")
def home():
    return "Hit from VBot"

@app.get("/api/response")
async def get_response(message: str, request: Request):
    chat_log = request.session.get('chat_log')
    if(chat_log == None):
        request.session['chat_log'] = gpt3_logs('', '', chat_log)
        chat_log = request.session.get('chat_log')
    response =  main(message,chat_log)
    if(len(response)!=0):
        request.session['chat_log'] = gpt3_logs(message, response, chat_log)
        return response
    else: 
        return "Oops! Something went wrong"

if __name__ == "__main__":
    uvicorn.run("app:app",port = 8000,reload=True)
```

Understand the code:

- Import `fastapi` library methods and middlewares. Create a basic `fastapi` object app as `app = FastAPI()`.
- Load the environment file and add the secret key inside the fastapi middleware. Configure the middleware with CORS.
- Create a get route “/” which will send a response as “Hit from VBot”.
- Create a get route “/api/response” which will receive a request from the user and send it to the `main()` method and send the response back to the user if the response is non-empty.
- Run the `uvicorn` server using `uvicorn.run(“app:app”,port = 8000,reload=True)`.

#### 1.7 Run backend server
- Run the backend python server using the following command.
```
python app.py
```
![run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c6g4wxftcn3cmseub0j2.png)
- You can hit the url [http://127.0.0.1:8000](http://127.0.0.1:8000) once the server is up and running.
- You can hit [http://127.0.0.1:8000/api/response?message=”what is quantum physics”](http://127.0.0.1:8000/api/response?message=”what is quantum physics”) to see the GPT3 response.
![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b674fonboyuskkuzqhmz.png)

### 2.1 Create the frontend app
Create a react application using create-react-app cli.
```
npx create-react-app chatbot-frontend
```
#### 2.2 Install Tailwind CSS
- Install tailwindcss and generate tailwind.config.js file using npm.
```
npm install -D tailwindcss
npx tailwindcss init
```
- Add the following code to the `tailwind.config.js` file.
```
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```
- Add the @tailwind directives to the top of the `./src/index.css` file.
```
@tailwind base;
@tailwind components;
@tailwind utilities;
```
#### 2.3 Install dependencies
Install react-speech-recognition,axios and react-loader-spinner packages to the app using the following command.
```
npm i react-speech-recognition axios react-loader-spinner
```
#### 2.4 Create bot frontend
Add the following code to the `App.js` file.
```
import './App.css';
import { useEffect, useState, useRef } from 'react'
import React from 'react'
import arrow from './assets/arrow.png'
import bg from './assets/bg.png'
import mic from './assets/mic.png'
import mic_on from './assets/mic_on.png'
import axios from 'axios';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'
import { Dna } from 'react-loader-spinner'

function App() {
  const [userInput, setUserInput] = useState('')
  const [recording, setRecording] = useState(false)
  const [loading, setLoading] = useState(false)
  const [messages, setMessages] = useState([
    {
      msg: "Hello, How can I help you ?",
      fromUser: false,
    }
  ])
  const bottomRef = useRef(null);

  const themes = {
    primaryColor: "#475569",
    secondryColor: "#475569",
    primaryFontColor: "white",
    secondryFontColor: "#2C3333",
    logoColor: "#E7F6F2",
    backgroudImage: bg
  }

  const commands = [
    {
      command: 'clear',
      callback: ({ resetTranscript }) => resetTranscript()
    },
    {
      command: 'reset',
      callback: ({ resetTranscript }) => resetTranscript()
    }
  ]

  const {
    transcript,
    resetTranscript,
    browserSupportsSpeechRecognition
  } = useSpeechRecognition({ commands });

  useEffect(() => {
    if (userInput !== '') {
      setLoading(true)
      axios.get(`http://localhost:8000/api/response?message=${userInput}`)
        .then((response) => {

          speechSynthesis.cancel();
          let utterance = new SpeechSynthesisUtterance(response.data);
          speechSynthesis.speak(utterance);

          setUserInput('')
          resetTranscript()
          setMessages([...messages, { msg: response.data, fromUser: false }])
          setLoading(false)
        }, (error) => {
          console.log(error);
        });
    }
  // eslint-disable-next-line
  }, [messages])

  useEffect(() => {
    setUserInput(transcript)
  }, [transcript]);

  const sendMessage = () => {
    if (userInput !== '') {
      setMessages([...messages, { msg: userInput, fromUser: true }]);
    }
  };

  if (!browserSupportsSpeechRecognition) {
    alert("Browser doesn't support speech recognition.")
  }

  const handleRecording = () => {
    if (recording) {
      SpeechRecognition.stopListening()
    }
    else {
      resetTranscript()
      setUserInput('')
      SpeechRecognition.startListening({ continuous: true })
    }
    setRecording(!recording)
  }

  return (
    <div className="min-h-screen bg-gray-100" style={{ background: `url(${themes.backgroudImage})`, backgroundSize: 'cover' }}>

      <div style={{ backgroundColor: themes.primaryColor }} className={`w-full h-18  fixed flex justify-between`}>
        <div style={{ color: themes.logoColor }} className='text-green-100 text-3xl font-bold p-5 font-sans'>VBot</div>
      </div>

      <div className='py-32'>
        <div className="max-w-2xl mx-auto space-y-12 grid grid-cols-1 overflow-y-auto scroll-smooth scrollbar-hide overflow-x-hidden" style={{ maxHeight: '30rem' }}>
          {loading && 
            <div className='flex justify-center items-center'>
              <Dna visible={true} height="100" width="100" ariaLabel="dna-loading" wrapperStyle={{}} wrapperClass="dna-wrapper" />
            </div>
          }
          <ul>
            {messages && messages.map((message, idx) => {
              return (
                <div key={idx} className={`mt-3 ${message.fromUser ? "place-self-end text-right" : "place-self-start text-left"}`}>
                  <div className="mt-3  p-3 rounded-2xl" 
                    style={{ backgroundColor: message.fromUser ? themes.primaryColor : 'white', 
                             color: message.fromUser ? themes.primaryFontColor : themes.secondryFontColor, 
                             borderTopLeftRadius: !message.fromUser && 0, borderTopRightRadius: message.fromUser && 0 }} >
                    <p className="break-words text-md">
                      {message.fromUser ? message.msg : message.msg}
                    </p>
                  </div>
                </div>
              )
            })}
          </ul>
          <div ref={bottomRef} />
        </div>
      </div>

      <div className={`w-full fixed bottom-0`}>
        <div className='justify-end items-center bg-white rounded-xl flex mx-96 my-3'>
          <input className='p-3 bg-white w-full rounded-l-md border-0 outline-none'
            placeholder="Ask your question..."
            type="text"
            id="message"
            name="message"
            value={userInput}
            onChange={(e) => setUserInput(e.target.value)}
          />
          <button className='bg-white px-4' disabled={!browserSupportsSpeechRecognition} onClick={handleRecording}>
            {recording ? <img className='w-10' src={mic_on} alt="mic"></img> : <img className='w-10' src={mic} alt="mic"></img>}
          </button>
          <button style={{ backgroundColor: themes.secondryColor }} className={`p-4 rounded-r-xl`} onClick={sendMessage}>
            <img className='w-8' src={arrow} alt="arrow" />
          </button>
        </div>
      </div>
    </div>
  )
}

export default App;
```
**Understand the code:**

- Import assets (bg, arrow, mic, mic_on icons), axios, speech recognition and dna (react loader spinner) packages.
- Initialize states such as userInput, recording, loading and messages. userInput is used to keep the user inputs, recording collects user input from the mic and messages stores the request / response from the bot.
- The useEffect hook (line no 50–69) calls the backend api (http://localhost:8000/api/response?message=userInput) with user input and stores the responses from the bot in the messages state.
- The sendMessage() sets the user input inside the messages state if the user input is not empty. This action calls the useEffect() method where the message state added in the dependency array.
- The handleRecording() method handles the user voice input and stores it in the userInput state.
- Lines from 97 to 150 sets the UI with a user input text box, audio input icon, send button and message bubbles.
- The UI accept the user input in the text box as text from console or through the speech recognition module. The userInput state updates on each key press. When the user clicks on the send button, it calls the sendMessage() method and it will set the messages state with userInput value if userInput is not empty. The messages values changes will call the useEffect() and send a request to the backend (http://localhost:8000). The response from the backend will be updated to the messages state with fromUser attribute as false. This value will be displayed on the message bubble as the bot response.

#### 2.5 Run the app
- Follow step 1.7 to run the backend server.
- Run the frontend react app using the following command.
```
npm start
```
You will get the output as below,
![output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcuwpn3y44qvlvwxqqwv.png)

There you have it! Your own chatbot powered by GPT3 :)

### Applications of ChatGPT
ChatGPT is an amazing tool that can be used to enhance your productivity and learning. Let’s explore some of the ways you can use this tool to make your life easier and more productive.

#### Generate ideas and brainstorm
ChatGPT can be beneficial for brainstorming ideas such as a birthday party celebration idea, recipe ideas or entire meal plans.
#### Understand complicated topics
ChatGPT can give you precise, clear overviews on complex topics in layman’s terms. If you want to understand machine learning, or find out how quantum computing is being used, ChatGPT is the perfect choice to assist you to understand the topics.
#### Get assistance with coding and debugging
ChatGPT can provide code examples, or help you troubleshoot by providing solutions to common coding issues or errors. It can also help you to look up syntax and parameters.
#### Train ChatGPT on your own data
You can feed your own data into the model,and fine-tune the parameters of the model with algorithms. ChatGPT will be trained on your specific data. Finally, you can export the model and develop APIs that allow your system to interact with other tools and platforms.
#### As a writing assistant
Whether it’s a poem, a news article, an email, or an essay, ChatGPT will provide customized content that you can use in different scenarios.
#### Get personalized recommendations
ChatGPT can act as your shopping assistant, health assistant that provides you with customized recommendations to suit your tasks.
#### Summarize the latest research
ChatGPT can summarize research works including entire reports, web pages, or studies. It will provide summarize content of your prompt.
#### Translate text
It is a powerful tool to translate a text into different languages. It supports 95 different languages.
#### Find data sets
ChatGPT is useful for looking for datasets, it can search through various online databases, repositories, and resources to find relevant data sets for you. You can use the feature for research, business intelligence, or for training a machine learning model.
#### Sentiment Analysis
ChatGPT can analyze the words, phrases, and punctuation used in the text and determine the tone of it such as positive, negative, or neutral.

Thanks for reading this article.

Thanks [Gowri M Bhatt](https://www.linkedin.com/in/gowri-m-bhatt-85b31814b/) for reviewing the content.

Thanks [Fabius S Thottappilly](https://www.linkedin.com/in/fabius-s-thottappilly/) and [Grigary C Antony](https://www.linkedin.com/in/grigary-c-antony/) for the support in creating a custom chatbot using ChatGPT.

If you enjoyed this article, please click on the heart button ♥ and share to help others find it!

The article is also available on [Medium](https://codemaker2016.medium.com/build-your-custom-chatbot-using-chatgpt-1393e4d5a300).

If you are interested to develop chatbot using Rasa then checkout the following article,

[Create your chatbot using Rasa and deploy it on AWS | medium.com](https://medium.com/coinmonks/create-your-chatbot-using-rasa-and-deploy-it-on-aws-e59b4f296605)

The full source code for this tutorial can be found here,

[GitHub - codemaker2015/VBot-custom-gpt3-chatbot: Custom GPT3 powered chatbot using python and react | github.com](https://github.com/codemaker2015/VBot-custom-gpt3-chatbot)

**Useful links:**

- [How to use the new Bing with ChatGPT - and what you can do with it | www.tomsguide.com](https://www.tomsguide.com/how-to/how-to-use-the-new-bing-with-chatgpt-and-what-you-can-do-with-it)
- [Top 8 ChatGPT Use Cases: How is the AI Tool Revolutionizing - Industries? | emeritus.org](https://emeritus.org/blog/ai-and-ml-chatgpt-use-cases/)
- [OpenAI API | platform.openai.com](https://platform.openai.com/account/api-keys)
- [react-speech-recognition | www.npmjs.com](https://www.npmjs.com/package/react-speech-recognition)
- [What Is Quantum Physics? | scienceexchange.caltech.edu](https://scienceexchange.caltech.edu/topics/quantum-science-explained/quantum-physics)