What you'll learn
- Create an OpenAI secret key on platform.openai.com and store it as an environment variable instead of hard-coding it in Java source
- Configure an IntelliJ run configuration that passes the OpenAI API key environment variable to the main class
- Build Java message, request, and response classes that model the user, assistant, and developer roles and message content
- Explain how the developer role sets custom chatbot instructions that take priority over user messages
- Implement an OpenAI client class that sends network requests, parses JSON responses, and manages conversation history for reuse
- Troubleshoot chatbot context loss by including previous prompts and responses in each API request
Free 50-minute video lesson with a full transcript and knowledge checks. No account needed to watch.
Creating and Using an API Key
Welcome to another skill where we'll be pulling together several different topics we've covered in this course to build a real-world application. In this skill, we'll be using network requests to interact with the OpenAI API and create a simple AI chatbot. In this first video, we see how to create an API key and access it from within our Java programs.
Knowledge Check
API keys are perfectly safe to share with others
Creating the Request and Response Classes
Now that we have an API key set up, let's create some new classes that will help us work with the requests we'll be sending the the API, as well as the responses that it will be sending back.
Knowledge Check
Which of the following is not a valid value for the "role" of a message when working with the OpenAI API?
Creating an API Client Class
Next, let's start creating the class that will represent the main functionality of our chatbot - the OpenAIClient class. As you'll see in this video, adding an interface in between this class and the rest of our app will make it much easier to swap out should we want to switch to another provider such as Claude or Gemini.
Knowledge Check
Encapsulating the conversation management logic inside our OpenAIClient class makes the class ________ flexible, and _______ difficult to use
Communicating with the OpenAI API
Finally, let's implement the method that will really make things happen. In this video, we see how to actually make a request to the OpenAI API and process the response into something our program can use.
Knowledge Check
The "Authorization" header typically begins with the word _________ when using api keys
Challenge & Solution: Bringing It All Together
Now it's time for a challenge! In this challenge, your task is to create a main method that brings together everything we've created. Watch the video for more information.
And now that you've attempted the challenge, I'll show you how to solve it.
Knowledge Check
If we forget to add new messages to the OpenAIClient's conversation list, the API will still keep track of the conversation for us.
View Transcript
Creating and Using an API Key
0:00Hi, Sean here and welcome to another skill where we're going to be building a project using what we've learned in this course. And in this skill in particular, we're going to be building our own generative AI chat bot. You might also say like, "Gend rid of AI agent," although a very simple one, " using the concepts that we've learned as well as a few additional ones." All right. So the basic idea here is we're going to create a simple Java program that will communicate with models like the chat GPT models, for example, in the same way as how you 're able to communicate with them through just the chat GPT interface, right?
0:44So if you open up chat GPT, let's just open this up right here. If you open up chat GPT and type in some sort of prompt, like create a recipe that uses bacon and maple syrup, right? Something like that. And then you hit enter, then what happens is that prompt is sent to the model behind the scenes, the model generates a response, and that response is displayed to us. So kind of the cool thing is that the chat GPT interface here, right, this user interface is actually a separate thing from the models that are completing the conversation, right, or responding to our prompts.
1:30And what this means is that we can basically create our own programs that use the models directly instead of interacting with the models through this chat GPT interface , right? That might not make a whole lot of sense yet, but this actually allows you to do some very interesting things. So for example, if you wanted to write a Java program to generate, let's say, you know, a hundred articles on different topics, right? Well, if you were going to do that manually, right, if you were going to generate a hundred articles on different topics manually, you'd have to actually copy and paste the same prompt and then change it slightly into chat GPT a hundred times.
2:11Whereas if you're, you know, if you're able to write a Java program that can do this on your behalf, all you'd have to do is give it like a list of the topics you want to generate articles for, and it would communicate with chat GPT's models for you automatically. All right. So hopefully that all makes sense, but don't worry too much about this. The main focus here is on using the concepts that we've learned in Java. And in particular, in this skill, we're going to be using the idea of network requests and also parsing JSON to make all of this happen.
2:45All right. So let's get started here. What we're going to do first is we're going to set up an account on platform. openai.com, right? This is openai is the company that maintains chat GPT. And so this, you know, platform.openai.com is basically the portal for developers to use when they want to start integrating the functionality that these models provide into our applications.
3:15All right. So you are going to need to create an account here. And once you've done that, you're going to go to dashboard and click on API keys over here on the left hand side. So an API key, you can think of this as like a password that your app is going to use in order to actually use some of the APIs that are more locked down. Right. We saw, we saw in a previous skill when we were learning the basics of making network requests that there are some APIs out there that are just totally free, right?
3:51They're not only are they totally free, but like you can use them whenever and wherever you want like that JSON placeholder URL that we were using earlier. But what you'll typically find is that with more valuable APIs like this one here, right, APIs that provide some very valuable functionality, you're going to have to get an API key. And in many cases, you're going to have to pay for them as well. Now, I do believe that with the open AI API, you have to activate billing.
4:22However, at the time of recording, once you do that, they give you something like it's like $100 in free credits, which should be more than enough to complete this project. So I'll leave that up to you. It's fairly straightforward. You just need to go into billing in your profile over here and activate it, right? You might need to put in a credit card number. But again, once you do that, they typically give you free credits to use so that you can actually test it out before spending any money. It's also not very expensive either, right?
4:53Like each request is going to cost you maybe fractions of a cent. So as long as you're careful not to put this in like an infinite loop, right, and make requests for like hours on end, it shouldn't really be a problem, right? It's again, I think it's worth it to just play around with these APIs and see what they can do. But anyway, let's get started here by creating a new secret key. And you can call this secret key, whatever you want. So I'm going to call this key something like Java SE 11 demo.
5:28All right. You can call it whatever you want. It's really just a memo to for you to remember what it's for. And I'm going to click create secret key. And as you'll see, that will generate this big sort of random string in this little text box. And we're going to want to copy that, right? Now I mentioned earlier that this is kind of like your app's password that it can use to actually access the API, right? The API will say, sorry, you're not allowed to do that if we don't include this , this API key.
6:03So you do need to keep this secret, right? You don't want to commit this to a GitHub repo. You don't want to, you know, I'm showing it to you here in this video, but I'm going to deactivate it as soon as I'm done recording so that by the time you see it, the API key won't be working anymore. All right. Cool. So anyway, let's click copy here. And that's going to copy that API key. And there's a number of things that you can do with this. But for our purposes here, what we're going to do is we're going to set this as an environment variable, which means that it's going to be defined sort of like locally on our computer, right?
6:43So it's not going to actually be in our code base, which makes it safe to still safe to, you know, commit this code to GitHub, things like that. All right. So here's what this is going to look like. What you're going to want to do first of all is you're going to want to open up a terminal and most IDEs have an integrated terminal here. In the case of IntelliJ, it's just right over here on the left hand side. I'm going to click on that. And once you see this little, you know, dollar sign thing, or you may see something slightly different there depending on your operating system, what we're going to do is we're going to say export, open AI API key equals, and then in quotation marks, I'm going to paste my API key.
7:26So you can see the full thing there. Again, I'm going to deactivate this, which is the only reason I'm showing it to you right now. These are you want to keep these very private, just as a reminder. And I'm going to hit enter. Now this is the this is what you do for Mac OS, as well as for Linux. If you're on Windows and using something like PowerShell, the command, I believe, is set X and then it's open API API key, and then you just leave a space and then you put your API key there like that.
7:58So anyway, that is how we set an environment variable. And an environment variable is basically just a value that our program can access that doesn't form part of the program or our file system itself, right? So we could put this in a file if we wanted to, but then we would have to go through the extra trouble of making sure that we don't commit that file to GitHub or share it with people that shouldn't have access to this API key. All right. So what we're going to do here is, first of all, I've created a new Maven project, which I've called gen AI chatbot.
8:34So I recommend that you do the same. Feel free to go back to the skill where we talk about adding third party libraries. If you don't remember how to do that. So you just create a new project and select Maven as the, as the build tool. And once you've done that, we have an empty project now. So we're going to create a new Java class where we're going to test out that API key that we just set up to make sure that it's working. And this will also be a great opportunity for me to show you how to access, you know, environment variables in Java programs.
9:04So we're going to call this something like this, this will be the main file that we're going to be writing our code in. So we'll just call it main. And inside here, we're going to add a main method, of course. So we'll say public static, void, main string, ARGS. And inside here, now what we're going to do is we're going to say, first of all , the way that you access an environment variable is pretty straightforward. We're just going to say string API key equals system dot get end.
9:40And then we need the name of the environment variable, which the name we gave it here was open AI API key. So that's what we're going to use there. And now just to make sure this is working, let's print this out, we're going to say system dot out dot print ln. And we're going to print out the API key like so. So let's try running this now. And if all goes well, you should see that big long random string printed out to the console, like what I have here. Now if you don't see that, then that may be because you closed your ID or like loaded a new project and you just need to run that export command that I showed you in the console a little bit earlier.
10:19So anyway, once you have that, then you should be good to go. And the next thing we're going to do is we're going to actually start building out our app. [BLANK_AUDIO]
Creating the Request and Response Classes
0:00All right, so now that we've created our project and set it up with an API key for the open AI API, the next thing that we're going to do is since we'll be using, you know, since we'll be actually making network requests to the open AI API and having to deal with that is parse the JSON responses that it's going to be giving us back. We're going to create two classes that will represent the data that we're going to be working with here, right? So we're going to create our first class, which will be called open AI request.
0:38All right. And we'll create another one here. There we go. New Java class, which will be called open AI response. So the basic idea here is that these two classes are going to represent the data that we're sending to the open AI API and the data that we're getting back from the open AI API, respectively. Okay. Now, in addition to this, there's a very important concept in working with the open AI API of something called a message.
1:11So we're going to create a class for that as well. And this message class is, and you could call it open AI message if you wanted to. I'm just going to call it message. This message class basically only has two pieces of information. And one is going to be, we're going to say private string role. And we're going to have one called private string content. Now, here's how this idea of a message works when working with the open AI API. And this is very similar for other options out there like Gemini, or if you're working with the anthropic API, which is the company that makes Claude.
1:50Basically, what we're going to be doing here is we're going to be using the role and content to specify individual messages in a conversation, what those messages contain, and who actually sent them. So for role, for example, there are actually three individual options here. The first one is user. This means that it's something that we sent to the API. Right. So that would be the equivalent of like, you know, I'll just write you.
2:23Right. The second one is going to be a message that the model has created for us. Right. And this, this role is actually called assistant. Okay. So that will be the model. Right. So, you know, if you're picturing like a text message conversation, or like an iMessage conversation, this would be the blue messages and this would be the gray messages on the other side. Right. Cool. So there's actually a third option for role, which might seem a little bit strange, but this is referred to as the developer role.
3:01You might see this called like the system role or something like that in other situations. But basically, this is where we can specify custom instructions for the model that have sort of like a higher priority than user messages. So this is where if you're trying to create a chatbot that's going to be a little bit more robust, this is where you can tell the chatbot, Hey, don't talk about politics. Don't talk about these topics. Don't agree to send the user free products. That sort of thing. Right.
3:32So we might take a look at that in a little bit more detail later. But anyway, that's the role. And then the content is just the text that each message contains. Right. So if we enter a prompt that says create a recipe that contains bacon and maple syrup again, then that's what the content would be for that message. All right. Cool. So anyway, now that we've created this message class and we can just leave that there. Oh, except we should probably also get or also add getters.
4:03So we'll just say generate getters for both of these things here. We're going to say, okay. And now that we've done that, we can go back to open AI request and open AI response. So starting off with open AI request, the only real responsibility of this, this class is to represent the data that the open AI API is going to be expecting from our program. So this includes the model. So we'll say private final string model. All right.
4:35That's going to be a string representing the model that we want to use. So GPT for Oh, GPT for Oh, mini GPT five. Those are what we have currently, although obviously in the future, there are going to be other options. So that's the model. And the second one here is just going to be a private final list of type message. That will be the messages that the request contains. Now, it might confuse you here a little bit that messages is a list instead of just an individual message .
5:08Because right when you interact with chat GPT, you're used to just typing in a single message and hitting enter. Well, the funny part about working with the open AI API is that in many cases, our program is actually the one that's going to have to keep track of and manage the messages in the conversation, which is something that's just taken care of by the platform when you use chat GPT. It takes care of storing all your messages. But all that to say that every time we make a request to the open API API, we have to include the messages from the entire conversation here as a list.
5:50All right. That's just how the open API API works because it's what's known as memory lists, right? It doesn't remember the previous requests we've made, which is a very common thing with API's just allows them to be much more performant. And kind of puts the burden of responsibility on the developer instead of on the API. All right. So now that we have the model and the messages, the next thing we're going to do is we're going to say public open AI request. All right. This is just going to take string model as an argument and list message as an argument as well. And it's just going to say this dot model equals model.
6:31And this dot messages equals messages. Okay. And now that we've done that, the next thing that we're going to do is we're going to actually go back to the message class. And since we'll need to create these messages ourselves in some cases, we're going to add a constructor to it. So here's what that's going to look like. We 're just going to say generate constructor. And it'll include both these things here, the role and the content. And there we have it. So let's go back to our open AI request. And actually that's it, right? We don't need to do anything more for this class at the moment.
7:04So the next thing, let's head over to open AI response. And this one's a little bit trickier because we are going to need to create this directly from the JSON string that we get back from the, from the open AI API. The actual structure of the JSON that we're going to get back from the open AI API is going to look like this. First thing is it's going to have a property called choices. This confuses people a lot. Basically, you know, sometimes when you're working with chat GPT, it'll give you like two options and it'll say which response do you prefer.
7:39That's what this choices thing represents. And that's actually a list. All right, the JSON array, you would call it. And inside there, it's going to contain a number of, well, usually only, usually it only contains one JSON object. And this JSON object contains a property called message. And then that message contains the role and content that we just talked about previously, right?
8:10So anyway, with that structure in mind, that's why we're going to have to define this open AI response class like we're going to. All right, there is a fair, there's a fair bit of nesting here. So the first thing we're going to need to do is we're going to say public list of type choice called choices. Now we haven't defined a choice class yet. And because this is such a specific thing to this response, what we're actually going to do is just create a static class. This is an option for us here.
8:40So we're going to say public static class choice. All right. And then what we 're going to do is we're going to say public message message as its member variable. And oops, I wanted to actually set these to private. I don't know why I was typing public there. So we're going to say private message message. And we're going to say private list choices. So we'll say import class there. And now that we've done that, that should be all we need in order to start making requests to the open API API and actually be able to do something with the data that we get back.
9:16So that's what we're going to do in the next video.
Creating an API Client Class
0:00All right, so at this point, what we've done is we've created classes that represent the request we're going to be sending to the OpenAI API, the response that we're going to be receiving from the OpenAI API, and of course, the message that represents the data that's really going to be included in both of those communications. So the next thing that we're going to do is we're going to kind of start to tie these together by creating a new class called OpenAI Client, which is really going to be the main way that are, you know, the core part of our program, this main method is going to use these things.
0:40All right. So here's what we're going to do. We're going to create a new class. So let's go into Java, new Java class, and we're going to call this one OpenAI Client. All right. And in order to make this thing a little bit more interchangeable, what we're going to do is we're actually going to create a interface here. So let's select interface, and we're going to call this interface chatbot. All right. Or actually, I don't really like that name. I was pretty confident about that name until I typed it out. Then I thought again, let's call this something like generative AI client.
1:16All right. So the reason that we're doing this, and we've seen numerous examples of this in other examples that we've, you know, other projects that we've worked on in this course. But the reason that we're doing this is so that this OpenAI client is interchangeable to the rest of our program, right? We don't want to get vendor locked with OpenAI, if let's say they raise their prices or we find another option, right? We want to be able to swap that out as quickly and easily as possible.
1:46So you know, by having this generative AI client interface, this leaves us open to create like a cloud client, a Gemini client, a llama client, really whatever, whatever other tool we want to use for this same purpose instead. Okay. So for this interface, what we're going to do is we're just going to define a single method on it. We're going to call this method string get response. And what this is going to do is this is going to take a new message as an argument.
2:20So we're going to say string user message. And this is going to be communicating across, you know, across the internet. So obviously it has the potential to throw an IO exception. We're actually going to say throws exception because there's a few other things that might happen there that we're just going to kind of like brush under the rug for now. This isn't a good practice, by the way, but since the focus here is doing the generative AI thing and communicating with this API instead of handling exceptions, I'm going to leave that one up to you. All right.
2:52So now that we've done that, what we're going to do is we're going to go back to the open AI client. And really the first thing to notice here is you may have been wondering if you were kind of thinking ahead a little bit, you may have been wondering whether this get response method that we just defined was going to take, you know, a list of messages, right, this message type that we defined up here, or a list of strings or a single string or a single message. There's really lots of ways that you could do this.
3:22And it kind of depends on how much functionality you want to encapsulate in the client classes that are going to implement this generative AI client interface. So here's what I mean by this, right? Let's just picture our interface, right? So this is our generative AI client interface. And right now we only have one specific class, which is our open AI client class. And I've already discussed here that, you know, in order to interact with these APIs, in order to interact with the open AI API, for example, our program is the one that has to manage those conversations, right?
4:02So we basically have to keep track of all of the messages that are in that conversation and then actually send that to the open AI server from inside one of our, you know, probably inside this open AI client class. Now what I meant when I said that we have to decide where to draw the line functionality wise is if we have the rest of our program right here, right, which is just our , well, I'll just call that main for now. Well, all of that management, right, managing the entire conversation and keeping track of the different, you know, messages that have been sent and received, we can either put that in here, right, inside main, and here, let me actually just write something here.
4:47So we'll say something like, well, say something like convo management, something like that. And again, we can either put that inside the main portion of our program or inside the open AI client portion of our program. And there are advantages and disadvantages to each really for our purposes right now, the big advantage of putting it in the open AI client class, which is what we 're going to do is that that will allow us to reuse that functionality, right?
5:18That'll allow us to easily create a chat bot in many different situations without having to worry about any of that conversation management. And if we want to create like a new conversation, all we have to do is create a new instance of this open AI client. Okay. Now, if we were to put it in the main portion of our program, that would give us a lot more flexibility. All right. So there are certain situations where you might want to just create an entire conversation from scratch with responses and, you know, prompts.
5:49There are situations where you might want to do that. And, you know, by putting this conversation management logic inside the main portion of our application, that would make our program a lot more flexible for those kinds of situations. So anyway, all of that to say that we are going to be putting this conversation management inside open AI client. And that's why this get response thing only has a single user message argument, right? That's all we want it to have because it's going to take care of keeping track of the response and, you know, just kind of organizing the conversations behind the scenes.
6:27So with all that said, let's go back to our open AI client class. We're going to add implements generative AI client here. We're going to add that method that it's going to need here. So we'll say, generate and we'll say implement methods and select get response. That's the only one here that we have to implement. And now what we're going to do, right, let's, let's kind of take a step back and think about how we want this thing to work. I mentioned that this is going to have to keep track of all of the messages that are going back and forth.
7:00So we're going to add a list as, you know, just a member variable here of this message class that we define. So here's what we're going to do. We're going to say list of type message. Let's import list into this class. And now we're going to say messages are here better yet. We'll call it conversation. And we're going to say equals new ArrayList and we're just going to leave it empty at first. Okay. So now that we've done that, there's a few other things we're going to want to do, you know, doing things like setting up an HTTP client to send requests is a good idea to do here.
7:36So we're going to say something like, actually, what we'll do, we'll start off by saying private, static, final, string API URL, right? This is going to be the URL of the open AI API. And I'm going to just copy this and paste this in here. Feel free to copy that. It's just API open AI comm slash V one slash chat slash completions. And now that we've done that and, oops, I put that in single quotes. Don't know why I did that. Let's try that again. We're going to swap that out with double quotes.
8:07And that's just going to make it easier to refer to the API URL. And if that API URL ever changes, as these URLs tend to do, all we would have to do is change that in this one place instead of having to, you know, make changes throughout this class. Awesome. So now that we have the API key, we're going to say private final HTTP client as well. We'll just call that HTTP client like so. And then we're going to say private final Gson.
8:40And we'll call that Gson. And we don't have Gson added to our project yet. So let's just do that real quick. You probably remember how to do this. We're just going to say, going to palm dot XML, and we need to add some dependencies to this project. So I'm just going to copy and paste that right here, like so. And if you click on this little refresh icon, or if you just wait for a minute or two, your IDE will install it. And if you go back to open AI client, you should see now that you have the option to import Gson. So there we go.
9:11All right. So let's add a constructor to our class now. What we're going to do here is we're going to say public open AI client. And this is going to take the API key as a string. All right. And then what we're going to do is we're going to say this API key. Oops. And I actually didn't add API key here. I forgot to do that. So let's just go up here. I'm going to say private final string API key. All right.
9:42And now that we've done that, we're going to say API key equals API key, this dot HTTP client, that's going to equal HTTP client dot new HTTP client, just creating a new client there like we saw how to do in previous skills. And then we're going to say this dot Gson equals new Gson. All right. So in other words, we're just setting these things up initially when we create the new client in the first place, which means that when we call get response, we're not going to have to do all of those things.
10:14That just saves us a little bit of time in there.
Communicating with the OpenAI API
0:00So now that we've done all of that, the last thing we need to do here is we need to implement this get response method. And here's what that's going to look like. So you can see that the default here just has return empty string. We're going to delete that. And we're going to create a new open AI request. Okay. And we're going to call this request body. And we're going to say equals new open AI request. And as the arguments here, we're going to specify the model we want. We'll just do GPT 40 mini.
0:33You can feel free to take a look at the open AI API reference if you want to see what other models there are and what the pricing for those models is. But I'm just going to use GPT 40 mini for now. I'm going to say list dot of. And here's what we want to do. We want to include all the messages from this conversation in this request. So we basically have to take this conversation list, add a new message with whatever string the user entered into it. And then what we're going to do is we're going to just send that over to the API.
1:07So first of all, right, before we even create that request body, we'll come back to that in a minute. We're going to say conversation dot add. And we're going to add a new message instance with the role of user, right, because this is a message that the user is actually sending to the API. Right. The other options, as you may recall, are assistant and either system or developer, depending on which API and the version you're using. So we're going to say user message.
1:38And that is adding a new message onto our conversation list. So we just need to convert this conversation now into a new list. So we just need to include this conversation with this new request and actually this list of we don't need that because we've already got a list. We've already got our conversation in list form. So we can actually just say this conversation right inside of there and that will be fine. Awesome. So now that we have the request body, here's what we're going to do.
2:10We're going to say string JSON request. And we're going to use Gson here. So we'll say Gson dot two, JSON. And we're going to pass request body there that will just take all of the member variables that are in there, right, role content. And well, it's in a list. So it'll be a JSON. JSON array is what they're called and that's going to turn it into something that we can send with the request. So here's what we're going to do next. We're going to say HTTP request and create an actual HTTP request object that sort of wraps this data up.
2:47So here's what that's going to look like. We're going to say HTTP request equals HTTP request dot new builder. You may recall this from previous skills and we're going to say first of all dot URI. This is where we want to send the request to. So we'll say URI dot create and we're going to say API URL as the URL for that. Let's also import the URI class. All right, then we're going to set something called headers.
3:18These are basically just extra information that's attached to a request that, you know, let's the server know what type of data you're going to do. So what type of data we're expecting. This is where we also include our API key to let the server know that, you know , what account this is this request is actually coming from and should be billed to. All right, so we're going to say dot header. We're going to say content type and the value for this one is going to be application slash JSON. All right, basically again telling the server that it should expect JSON data here.
3:51We're going to add another header by saying dot header again. This one is going to be an authorization header and for this one, all we need to do is say bearer. This is just something that every authorization header begins with when you're using API keys. And then we're going to add the API key onto the end like so. All right, this is going to be a post request. And inside here we're going to say HTTP dot body publishers dot of string.
4:23And we're going to pass JSON request to it. Don't worry too much about that one. That's just how we add that extra data, right, the conversation to this request . And finally we're going to say dot build and that will basically convert all of that into an instance of this HTTP request class. Awesome. So now we have our request. Let's send this thing. So we're going to be expecting an HTTP response back from it. We're going to say HTTP response of type string.
4:55All right, let's make sure we import that class here as well. There we go. And we're going to say response. And now we're going to say equals HTTP client dot send. We're going to include the request as the first argument as the second argument . We're going to say HTTP response dot body handlers dot of string. Oops, let me try that again. There we go. And now that we've done that, we're going to basically convert this into an open AI response, right, an instance of that class that we got.
5:30So here's what this is going to look like. We're going to say open AI response. And then we're going to say equals Gson dot from JSON. We're going to have the response body in there by saying response dot body. And then we're going to pass open AI response dot class as the second argument. And this just takes the data that we got back in this response here, or sorry, in this response here and converts it to an instance of this class. So once we've done that, we'll be able to access the choices and the messages inside each one.
6:05So here's what we're going to do next. We're just going to say if AI response is not null and if AI response is or AI response rather dot choices dot is empty, right? We're checking if it's not empty there using this little not symbol here. And let's actually change this to get choices, right? We need to make it so that we can access that.
6:35So we'll go into open AI response. We're going to add a getter for this one. So we'll say generate. We're going to add a getter for choices. And that should be all we need there. So, oh, and oops, I wrote open AI with a lowercase i. So let's just fix that real quick. We spelled it with a capital I. So we need to be consistent about that, of course. All right. So everything seems to be going well now. So for that if statement, what we're going to do is, you know, if that's there, what we're going to want to do is if that's there, we're just going to say return AI response.
7:10All right, dot choices or dot get choices rather dot get index zero. So we're getting the first choice there. That's just, you know, kind of the default way of working with this API because we just assume that there's one choice and ignore the others. Right. Then we're going to say dot get message. And then we're going to say dot get content. Okay. Now there are a few things we need to go in and fix there. So let's go into open AI response.
7:40We're going to add a getter for this message thing here. So we'll say generate getter for message. All right. And inside message, oh, we already have get content. So we should be all good there. So let's go back to open AI client. There's no red there anymore. And basically if the response is null or if there aren't any choices, we're going to want to just respond with some sort of default message like, you know, chat GPT or the Google Gemini interface tends to do. We're just going to say return.
8:11We'll say, sorry, I didn't get that. And then we'll say something like please try again later. All right. Not very helpful, but that'll just kind of provide a backup there. Awesome. So now that we've done that, all we have left to do is go into our main method and actually bring all of this together. And that is actually something that I'm going to leave up to you as a challenge . So head to the next video and I'll describe the challenging more detail there.
Challenge & Solution: Bringing It All Together
0:00All right, well now that we've finished up our open AI client class, it's time for you to do a challenge. And in this challenge, your task is going to be quite simply to implement the main method in this main class so that it will actually make use of this open AI client chatbot and allow the user to have a conversation with it. All right, so the basic idea here is you're just going to create an infinite loop, right? So you can just, you know, in there you're just going to want to say like, " wild true" and you're just going to keep getting input from the user.
0:33Do be careful with that wild true loop when you're sending a request to the open AI API, of course. But you're just going to keep getting input from the user and using this get Response method that we implemented in order to get the, you know, get the open AI API's response and you're going to display that to the user and maybe give the user a keyword like exit or something like that that they can enter in order to leave the app. Okay, now before we do that, there's two things I wanted to show you that are going to make this a much more pleasant experience.
1:10The first thing is you may have noticed that we forgot to add the model's response to the conversation, right? So our open AI client isn't really doing very well in its responsibilities of conversation management. So all we have to do here is just say this.conversation.add and we're going to add the new message by saying, I'm just going to copy that here and here. Let's make this a little bit neater by saying message new message equals and then I'm going to just print that out like so and we're going to say conversation add new message and last but not least, we can change this to new message dot get content.
1:55All right, cool. So that's the first thing that you needed to change. The second thing that you needed to change is something with the IDE itself. Now you may have realized this kind of depends on your operating system and stuff like that. So you may or may not run into this problem, but if you run into the problem of it not finding the API key that we set in the terminal, another thing to try, which is a little bit more robust and the way that I would recommend doing it in, you know, in the real world, is if you go into run and then go to edit configurations, I've created this application configuration.
2:30You can do that just by saying plus and then application and all you have to do is give it a name. So I called mine open AI for build and run. You just need to select the main class, right? The class with the main method in it and then for the environment variables, what you need to do is you just need to set. Let's just scroll back here. Almost there. There we go. You just need to add something here that says open AI API key equals and then paste your open AI key like so.
3:02And then when you say, okay, you just need to make sure that that's selected from this drop down when you run your app. And that's again, a little bit more robust than just setting it through the terminal. So anyway, that is your challenge is to create the main method that brings all of this together. So feel free to give this maybe five to 10 minutes to complete. And once you've done that, you can move on to the next video where I'll walk you through the solution. So best of luck and I'll see you in the next video.
Challenge & Solution: Bringing It All Together
0:00All right, well, hopefully you gave the challenge a try. Let's take a look at the solution. So the first thing that I did is I opened up main.java. And since we already had the API key, creating a new instance of this open AI client should have been pretty easy to do. So here's what I did. I just underneath where we set up the API key, and I'm gonna remove that system.out.printerlin there, 'cause we don't actually want to print that out to the console each and every time we run the program. What we're gonna do is we're gonna start off by creating a scanner.
0:33So we'll say scanner scan equals, or here I'll just call it scanner, equals new scanner system.in. And now that we have the API key, we're gonna create a new chatbot by saying generative AI client. We'll just call this chatbot equals new open AI client. And we're gonna pass the API key like so. All right, so again, if we wanted to switch this out to use something else like the Claude API or the Gemini API, all we'd have to do is create another API here that implements the same interface.
1:13Okay, so now that we have our chatbot, what we're gonna do is we're gonna start off by printing out a message to the console. You didn't have to do this, but I thought it was, you know, a pretty good thing to start off with. I said chatbot is ready. And then I said type exit to quit, okay. Cool, so just kind of initial thing giving the user some instructions on how to interact with this thing. All right, so what we're gonna do next is we're just gonna create an infinite loop that we'll only exit out of when the user types in the word exit, okay?
1:49So here's what we're gonna do. We're gonna say system.out.print. All right, and we're going to just say you, right? This is where we're gonna have the user enter in their message. And we're going to get their next prompt by saying string user input equals scanner.nextline. And now that we have the user's input, what we're gonna do is we're gonna check to see whether it equals exit or not.
2:20All right, so we'll say if, then we'll say user input.equalsignorecase exit. Well, in that case, what we're gonna do is we're just gonna say break and that will sort of pop the user out of this while loop. All right, that's how the program will end. So the next thing that we're gonna do is we're just gonna add a try catch block here because again, that here, let's just go back here, right? This getResponse method throws an exception.
2:52All right, so we'll have to catch that. And inside here, we're gonna say string response equals chatbot.getResponse. And then we're just gonna say user input. So we're passing that new prompt through to the chatbot that we created. And now we're just gonna say system.out.println. And we're gonna say bot and we're going to add that response onto there like so. And you'll see that there's a little red underline here.
3:25That's because we need to catch any exceptions that occur. So we're just gonna say catch exception e. And in this case, we're just gonna say e.printstacktrace that will just kind of print out whatever happened. And then we'll say something like system.out.println. And we'll just say error communicating with the API. All right, cool. So anyway, that's all we really need to do. The last thing is outside this while loop, we're just gonna call scanner.close.
3:56And that should be all we need to do. So let's just give this thing a try. We're going to run our file. If all goes well, we should see this come up and say that the chatbot's ready. So let's try just entering in a prompt like you'd enter into chat GPT, all right? And here I'm gonna zoom in on that a little bit so that we can see it. So let's say something like tell me three fun facts about coffee. All right, and if we hit enter, what we're gonna see is it does take a minute or two to finish because, well, it's kind of a slow, computationally intensive process behind the scenes.
4:35But anyway, we see that sure enough, we get three fun facts about coffee. And the cool thing about this is that because we're keeping track of the conversation, we can ask it to expand on a specific part of this. So we could say something like tell me more about the second point, right? And because the API is gonna have access to our previous messages, right? And the previous messages that it sent us, because we're including those in our request, it will know what we're talking about, right?
5:08If you were to remove that, here, let's just take a look at this. If you were to go into OpenAI client and remove the parts where we're actually adding this onto the conversation list, then what you would find is it would have sort of like short-term memory loss where it would say, like the second point of what? I don't know what you're talking about, right? But in this case, because we've added that, what we're gonna see is if we say, tell me more about the second point, it'll know what we're referring to. And what we should see is that it should tell us, in this case, more about the coffee plant's berries.
5:39So sure enough, yep, coffee cherries and beans. And it, that's the response that we got. So anyway, congratulations on finishing this challenge. And congratulations on building a generative AI-enabled app in Java.
Frequently asked questions
What does the Building a Generative AI-Integrated Chatbot lesson in the Java SE 11 course cover?
In about 50 minutes, the team member builds a simple Java program that talks to OpenAI models. The work covers generating an OpenAI secret key, modeling messages, requests, and responses as Java classes, and writing a client class that sends network requests, parses JSON, and manages conversation history.
Why store an OpenAI API key in an environment variable instead of hard-coding it in Java source?
The trainer stresses that secret keys should stay private, so the lesson stores the key in an environment variable rather than in source code. It shows the export command for macOS and Linux, setx for Windows PowerShell, and an IntelliJ run configuration that passes the variable to the main class, which the trainer recommends as the more robust real-world option.
What is the developer role in an OpenAI chat request and how does it differ from user messages?
Alongside the user and assistant roles, the developer role, sometimes called the system role, holds custom instructions that take priority over user messages. The lesson uses it to show how a chatbot can be told which topics to avoid or what not to agree to, such as sending users free products.
Why does a Java chatbot forget earlier messages, and how is the context loss fixed?
If previous prompts and responses are not added to the conversation list, the model shows short-term memory loss and cannot answer follow-ups like tell me more about the second point. The lesson fixes this by including the full conversation history in each API request, managed inside a reusable OpenAI client class so a new conversation starts with a new client instance.
What should a developer know before starting this generative AI chatbot lesson?
The lesson is a build project that applies concepts taught earlier in the course, particularly network requests and JSON parsing, so it suits Java developers who already have programming context. Learners also need access to platform.openai.com to generate the secret key used in the project.
How does this lesson fit the Oracle Certified Professional: Java SE 11 Developer course and exam 1Z0-819?
It is one of several applied build projects in a course of roughly 29 hours that supports preparation for the Oracle Certified Professional: Java SE 11 Developer certification, exam 1Z0-819. For an IT Director or Team Lead, it gives developers hands-on practice with network requests, JSON, and class design in a common integration scenario.
Team training path
Turn this skill into assignable team training
This free skill is a preview of the courses your team can assign, track, and report on with CBT Nuggets.
Free training library
More free lessons from CBT Nuggets
Oracle
Introduction to MySQL
Free lesson from MySQL Essentials · 54m
Oracle
Oracle Database 12c: SQL Fundamentals (1Z0-071): Relational DBs, Oracle, and SQL
Free lesson from Oracle Database SQL Certified Associate (1Z0-071) · 54m
Microsoft Windows Server
Microsoft PowerShell 4 Foundations
Free lesson from PowerShell · 7h 57m
DevOps
Docker (v18.06.3)
Free lesson from Docker · 2h 6m
Networking
Border Gateway Protocol (BGP): Basic Operations
Free lesson from Border Gateway Protocol (BGP) · 60m
Networking
Define Wireless Network Architectures
Free lesson from Wireless Design Professional Training · 55m
$59
seat / mo, billed annually
