DEV Community

lou
lou

Posted on

2

Build Your Own ChatGPT AI Spring Application

By the end of this tutorial we will be able to communicate with ChatGPT API using our own spring application.

Before we start we need to understand the ChatGPT request, expected Input and Output.
For that we will refer to the examples provided by the OpenAI documentation

Take a look at the Input.

{
  "model": "text-davinci-003",
  "prompt": "Say this is a test",
  "max_tokens": 7,
  "temperature": 0,
  "top_p": 1,
  "n": 1,
  "stream": false,
  "logprobs": null,
  "stop": "\n"
}
Enter fullscreen mode Exit fullscreen mode

You can see that the post body defines some parameters some of which are optional except for the model parameter.

For this project we will do with just 4 parameters:

model expects a String, we will keep the same model as the example which is text-davinci-003 but you can check their overview for more models.
prompt expects a String or an Array, it will contain the question we want to ask ChatGPT.
temperature expects a Number.
max_tokens expects an Integer.
You can play around with temperature and max_tokens values but will use 4096 and 1 respectively.

Now that we're finished with the Input let's take a look at the Output

{
  "id": "cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7",
  "object": "text_completion",
  "created": 1589478378,
  "model": "text-davinci-003",
  "choices": [
    {
      "text": "\n\nThis is indeed a test",
      "index": 0,
      "logprobs": null,
      "finish_reason": "length"
    }
  ],
  "usage": {
    "prompt_tokens": 5,
    "completion_tokens": 7,
    "total_tokens": 12
  }
}

Enter fullscreen mode Exit fullscreen mode

The most interesting property here is "text" which is a String, it will contain the answer to the question sent earlier to the API.

Now we can start to imagine how our java classes will look like.

The Input java class

package com.example.openaiapi.entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter @AllArgsConstructor
public class Call {
private String model;
private String prompt;
private Integer max_tokens;
private Double temperature;
}



Since Choices in a list of Objects we will create a Choice class

package com.example.openaiapi.entities;
import lombok.Getter;
@Getter
public class Choice {
private String text;
private Integer index;
private Integer logprobs;
private String finish_reason;
}
view raw Choice.java hosted with ❤ by GitHub



And a Usage record since we don't need a getter

package com.example.openaiapi.entities;
record Usage(Integer prompt_tokens, Integer completion_tokens,Integer total_tokens){
}
view raw Usage.java hosted with ❤ by GitHub



The Output java class

package com.example.openaiapi.entities;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.time.LocalDate;
import java.util.List;
@Getter @AllArgsConstructor
public class Answer {
String id;
String object;
LocalDate created;
String model;
List<Choice> choices;
Usage usage;
}

You can hardcode the parameters inside the constructor or use the application.properties with the following variables

openai.apikey=<YOUR KEY>
openai.model = text-davinci-003
openai.maxTokens = 4096
openai.temperature = 1.0
url = https://api.openai.com/v1/completions

Generate your OpenAI API Key here

OpenAI Platform

Explore developer resources, tutorials, API docs, and dynamic examples to get the most out of OpenAI's platform.

favicon platform.openai.com

Click on Create new secret key

API Key

In your Service Java class add the methods that will communicate with the API

To understand the next steps take a look at an Example of a request

curl https://api.openai.com/v1/completions \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -d '{
  "model": "text-davinci-003",
  "prompt": "Say this is a test",
  "max_tokens": 7,
  "temperature": 0
}'

Enter fullscreen mode Exit fullscreen mode

This request expects a URL that points to the API
A header that defines the content type as JSON object
An authorization header as a Bearer Token
And the body

So we will build an http client request that will take the parameters defined above and send it to the URI. The answer will then be returned as a Json String.

@Value("${openai.apikey}")
private String openaiApiKey;
@Value("${url}")
private String URL;
private final HttpClient client = HttpClient.newHttpClient();
@Override
public String sendChatgptRequest(String body) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(URL))
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + openaiApiKey)
.POST(HttpRequest.BodyPublishers.ofString(body)).build();
return client.send(request, HttpResponse.BodyHandlers.ofString()).body();
}

Create another method that takes as parameters the prompt which is a String that contains the question.

Inside this method we will create an Input object using the class constructor and pass it the predefined parameters along with the prompt.
Next we will pass the object to the sendChatgptRequest() method as a JSON string and map the response into an Output Object using the ObjectMapper class.
If you want to save the data to a database add the JPA repository Interfaces and save the call and answer objects at this point.

@Autowired
private ObjectMapper jsonMapper;
@Value("${openai.model}")
private String model;
@Value("${openai.maxTokens}")
private Integer max_tokens;
@Value("${openai.temperature}")
private Double temperature;
@Override
public Answer sendPrompt(String prompt) throws Exception {
Call call = new Call(model,prompt,max_tokens,temperature);
String responseBody = sendChatgptRequest(jsonMapper.writeValueAsString(call));
Answer answer = jsonMapper.readValue(responseBody, Answer.class);
return answer;
}
view raw sendPrompt.java hosted with ❤ by GitHub

Inside your Rest Controller class add your Post request

@AllArgsConstructor
@RestController
public class OpenaiRestController {
ChatgptService chatgptService;
@PostMapping("/sendPrompt")
public Answer sendPrompt(@RequestBody String prompt) throws Exception {
return chatgptService.sendPrompt(prompt);
}
}

Link to the Source code

GitHub logo leriaetnasta / OpenAI-Question-Answering-API

This web app asks questions and saves answers retrieved from chatgpt. With link to tutorial

GitHub Clones

OpenAI Question Answering API

This API utilizes the OpenAI API to answer user queries.

The OpenAI expected Input

{
  "model": "text-davinci-003",
  "prompt": "Say this is a test",
  "max_tokens": 7,
  "temperature": 0,
  "top_p": 1,
  "n": 1,
  "stream": false,
  "logprobs": null,
  "stop": "\n"
}

You can see that the post body defines some parameters some of which are optional except for the model parameter.

For this project I only used 4 parameters:

model expects a String, we will keep the same model as the example which is text-davinci-003 but you can check their overview for more models.

prompt expects a String or an Array, it will contain the question we want to ask ChatGPT.

temperature expects a Number.

max_tokens expects an Integer.

You can play around with temperature and max_tokens values but will use 4096 and 1 respectively.

The expected Output

{
  "id": "cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7"
  "object": "text_completion",
  "created": 1589478378,
  "model": "text-davinci-003",
  "choices": [

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more