By now you all would have heard about OpenAI and played with its famous product ChatGPT. OpenAI also provides APIs which can be used to integrate features like text completion, code generation, image generation and chat completion in your applications.
In this post I will show you how to make use of the Text completion API in Java application. For this we will be using Spring Framework’s WebClient to invoke the APIs.
Before you start the development work you need to have OpenAI API’s secret key which you can obtain from https://platform.openai.com/account/api-keys after creating an account on OpenAI.
Text Completion API
The text completion API can be invoked by sending a POST request to the URL https://api.openai.com/v1/completions with the following parameters:
- model – the model to use for generation of text. We will use one of the models available under GPT-3.5. More details can be found here.
- prompt – this wil be the request for which you want the response. Try to make the prompt as clear as possible.Vague requests will generate vague responses.
There are other options which can be used to tweak the behavior of the model like:
- temperature – this value ranges between 0 to 2. Higher the value results in the model to return random results and lower value returns predictable result. Predictable in the sense that invoking the API multiple times with same input returns same response. This predictibility increase as the temperature values comes closer to 0.
- n – this value tells the model how many response choices to return. By default it is 1 and it should serve for most of scenarios. Increasing the value will lead to consumption of the tokens in turn leading to more charge.
We will create some Java classes to capture the response of the API
@Data
public class CompletionResponse {
String id;
String object;
Long createdOn;
String model;
List<CompletionResponseChoice> choices;
CompletionResponseUsage usage;
}
CompletionResponse
will hold the response retrieved from the API.
@Data
public class CompletionResponseChoice{
String text;
Integer index;
String finishReason;
String logProbs;
}
CompletionResponseChoice
will hold the choices returned by the API. This will contain the required information we are looking for.
@Data
public class CompletionResponseUsage{
Integer promptTokens;
Integer completionTokens;
Integer totalTokens;
}
CompletionResponseUsage
will have the token usage information.
Token is a very important concept in the API. A token approximately corresponds to 4 characters and 3/4th of the word. So 100 tokens ~= 75 words. This page shows how the tokenization works.
Lets now integrate with the API
- Create a new WebClient instance
WebClient webClient = WebClient.create();
- Create the request body which will be sent to the API
Map<String, Object> requestBody = new HashMap<>(); requestBody.put("model", "text-davinci-003"); requestBody.put("prompt", "10 tips for time management for married working professional with kids"); requestBody.put("max_tokens", 500); requestBody.put("temperature", 0.5);
In the code snippet above the model
specified is taken from the models listed here. The completion API doesnt support the newer models: gpt-3.5-turbo
and gpt-3.5-turbo-0301
. These newer models are supported in the new Chat Completion API which I will illustrate in my next post.
The below code uses WebClient
to make the API request. It handles the error scenarios as well by printing the error response to the console.
String url = "https://api.openai.com/v1/completions"; ObjectMapper objectMapper = new ObjectMapper(); Mono<CompletionResponse> completionResponseMono = webClient.post() .uri(url) .headers(httpHeaders -> { httpHeaders.setContentType(MediaType.APPLICATION_JSON); httpHeaders.setBearerAuth(secret); }) .bodyValue(objectMapper.writeValueAsString(requestBody)) .exchangeToMono(clientResponse -> { HttpStatusCode httpStatus = clientResponse.statusCode(); if (httpStatus.is2xxSuccessful()) { return clientResponse.bodyToMono(CompletionResponse.class); } else { Mono<String> stringMono = clientResponse.bodyToMono(String.class); stringMono.subscribe(s -> { System.err.println("Response from Open AI API " + s); }); System.err.println("Error occurred while invoking Open AI API"); return Mono.error(new Exception( "Error occurred while generating wordage")); } }); CompletionResponse completionResponse = completionResponseMono.block(); List<CompletionResponseChoice> choices = completionResponse.getChoices(); System.out.println(choices.get(0));
Note: The variable secret
will hold the secret which you had generated initially.
The output will be: