Building a Chatbot with OpenAI/GPT3 and PubNub

pubnub share

Given any text prompt the service returns text in natural language. 

What does this mean for us? For you? Well imagine a chatbot that can walk your customers though setting up and troubleshooting your application, service or getting general help before escalating to a human with all the details on what's been tried so far. 

The platform contains a number of useful endpoints that we can specifically focus on and consume. These include: 

How does PubNub interact with OpenAI?

PubNub has a service called functions which are our javascript based serverless containers that let PubNub execute business logic (that you write) whenever an event occurs on the PubNub network. 

Common use cases for this include profanity scanning, language translation, keyword lookup and HTTPS requests to an external endpoint. 

We can use the HTTPS component of functions to reach out to OpenAI’s API, send it some data and interpret the response back to be displayed to our user. 

First off we will need to build a UI for our service, there is no shortage of bootstrap templates online, I found several really great ones at https://onaircode.com/bootstrap-chat-box-examples/ but if you have a designer to hand that can help build you some CSS and HTML that works too. 

How does a message from the chat box get to OpenAI?

When a user types a message and clicks submit the Client JS captures the message, encapsulates the message and passes it to PubNub. 

On receipt of the message, PubNub will execute the function needed to send the message to OpenAI. 

Once OpenAI responds with the response message, the function will then Publish the message into a channel that the client is subscribing to. 

What PubNub components are going to be used.

PubNub Publish

The message is published to PubNub which then will pass the message to the appropriate function. 

Functions

Functions are used to send a copy of the message to GPT3.

PubNub Subscribe 

To receive a message the client must be subscribed to the appropriate channel, once the function has communicated with OpenAI, the channel is where the message will be put ready for delivery back to the client.

You can find the example code on GitHub: https://github.com/PubNubDevelopers/dotmat.github.io

The index, CSS and JS page here are static pages that you can host anywhere. 

The function code is hosted here by PubNub on our functions infrastructure. 

You can find a copy of the functions code at https://github.com/PubNubDevelopers/dotmat.github.io/blob/master/pubnub_gpt3/PubNubFunction.js

How do you setup Functions?

You can setup a function inside your account by going to our admin dashboard

You can see from the screen shot the view functions. 

Inside that you will need to create a module for this function to sit in. 

Think of modules like containers for your functions, it's a handy way to keep track of code snippets. 

Once a module has been setup, create a new function. 

Lets breakdown what's going on here; 

OpenAI’ the name of this function

After Publish or Fire’ This function is going to be invoked AFTER a message has been submitted to PubNub. Functions can be synchronous or asynchronous. In this case, we don't need to intercept the message, just capture a copy of it to sent to GPT3. You can find more details on different types of functions described in our documentation

gpt3.*’ The channel that this function is going to listen on. As the function is going to talk to many people at the same time, we need a way to separate out what user is going to send and receive their message on. 

You can use the ‘*’ in PuNub to represent a wild card and a ‘.’ dot notation to represent channel separation. 

Eg: gpt3.mathew and gpt3.jim are two different channels, but the function can listen on both channels at the same time by using ‘gpt3.*’. How PubNub handles channel wildcards is explained in more detail in our documentation.

How do you set up OpenAI?

At current time of writing the project requires an API Key. You can sign up for a key at https://beta.openai.com/

The Function will need this key to make API requests. You can store the key in plain text within the Javascript (I have in the example just to keep things simple). But you can also store the key inside PubNub’s Vault which is used for keeping things like this secure. 

Please see our documentation for more information on the PubNub Vault.

Once you have an API key, the function script makes a curl request whenever a new user message comes in. 

Let's have a look at the options available to us when making an API request;

"model": "text-davinci-003" The OpenAI API is powered by a family of models with different capabilities and price points. The more expensive models focus on better, more complete natural language processing. 

"prompt": inboundMessage The contents of the message we are sending to be processed. 

"temperature": 0.7 The number between 0 and 1 that determines how many creative risks the engine takes when generating text. 

"max_tokens": 1000 The maximum number of tokens to generate in the completion.

"top_p": 1 An alternative to sampling with temperature, called nucleus sampling

"frequency_penalty": 0 A number between 0 and 1. The higher this value the model will make a bigger effort in not repeating itself.

"presence_penalty": 0 A number between 0 and 1. The higher this value the model will make a bigger effort in talking about new topics.

You can find more information on the OpenAI page at https://beta.openai.com/docs/api-reference/completions/create

Putting it all together

Once your function has been configured, it will look something like this:

You will know your function is ready to receive data when the green tick and ‘running’ is present in the top left corner. 

From whenever you have hosted the CSS, HTML and JS. You will need to put into the META tags of the HTML your Pub, Sub and User ID, you can find your Pub and Sub keys at the PubNub admin dashboard 

Example: 

metaname="pubNubPubKey"content="PubKey goes here" metaname="pubNubSubKey"content="SubKey goes here" metaname="userID"content="IAmMathew"

The userID is whatever you call you users, PubNub doesn't have a policy on what type of item string, email address or integer is used as as userID, you just have to provide something. 

Once configured you can call chatSPA.launcher(); which will connect to PubNub and start listening for message responses. 

Now that you are connected to PubNub, type a message and click send. The message will be sent to PubNub which will forward it to GPT3. 

Once GPT3 receives the message it will reply and the response can be provided to the user.