You are here
Home > ChatGPT >

Spring AI Reference

Spring AI ReferenceIn the wave of generative Artificial intelligence, everyone wants to utilize the capability of AI tools to some extent. From this prospect, the Spring community stepped forward and offered a module called ‘Spring AI’ in order to interact with AI tools and get the desired outcomes. Spring AI intended to simplify the development of applications that integrate artificial intelligence functionality without unneeded complications.

Spring AI offers abstractions that serve as the foundation for developing AI applications. These abstractions have multiple implementations, enabling easy component swapping with minimal code changes. For example, Spring AI introduces the ChatClient interface with implementations for OpenAI and Azure OpenAI. In this Spring AI reference guide, we will talk about how to add AI in our Spring based application and related concepts.

Prerequisite to use Spring AI Reference

1) You are a Spring Developer and want to learn Spring AI

2) You want to incorporate AI to an existing Application

3) Basic Knowledge of prompts that are being used in ChatGPT or any other similar tool

What is a Prompt in generative AI?

In generative AI, a “prompt” refers to the input provided to a language model to generate a response or output. The prompt acts as a starting point or a query that we use to generate a content. It can be a single sentence, a paragraph, or even a series of instructions that guide us in producing meaningful and contextually relevant content. Prompts guide an AI model to produce specific outputs. Writing effective prompts is essential for improving the resulting output.

You may also visit prompts for Java Developers in order to practice various useful prompts.

What are Prompt Templates?

“Prompt templates” refer to predefined or reusable structures for prompts in generative AI. These templates provide a standardized format or set of instructions that users can follow to interact with language models effectively. These templates often include placeholders or slots where users can insert specific information relevant to their task. Spring AI employs the OSS library, StringTemplate, for this purpose.

For example, consider the simple prompt templates:

Translate the following English text into Spanish: "{text}"

In this template, {text} is a placeholder where users can replace it with the actual text they want to translate.

Tell me a {adjective} joke about {content}.

In this template, {adjective} and {content} are the placeholders where users can replace it with the actual text to get the desired result.

In Spring AI, prompt templates can be compared to the “‘View'” in Spring MVC architecture. A model object, typically a java.util.Map, is provided to populate placeholders within the template. The “‘rendered'” string becomes the content of the prompt supplied to the AI model.

What is ChatClient in Spring AI?

The ChatClient is a functional interface simplifies the interaction with AI Models. It helps connect to different AI Models that might have different ways of working. The interface currently works with text input and output only, but we should expect more types in the future. Keep in mind that some classes and interfaces might change in later stages. The ChatClient interface has the structure as below:

@FunctionalInterface
public interface ChatClient {

    default String generate(String message) { 
       // implementation omitted
    }

    ChatResponse generate(Prompt prompt);
}

The main goals of the ChatClient interface are:

Portability: It enables easy integration with different AI Models. Developers can switch between models without changing a lot of code. This fits well with Spring’s idea of being modular and easy to switch parts.

Simplicity: The ChatClient interface uses helper classes like Prompt for input and ChatResponse for output. This makes talking to AI Models easier. It handles the complicated parts of preparing requests and understanding responses. On the whole, it provides a straightforward way to interact with AI Models.

What is ChatResponse in Spring AI?

It holds what the AI Model delivers back, and each Generation instance has one of the possible outputs from a single prompt. The ChatResponse class has the structure as below:

public class ChatResponse{
   
   private final List<Generation> generations; 
   // other methods omitted 
}

The ChatResponse class also has a map with key-value pairs. This map provides extra information about the AI Model’s response. Keep in mind that this feature is still being worked on, and there’s no detailed explanation about it in the official document.

How to use Spring AI module in your Application?

Below are the straightforward steps to incorporate Spring AI in our existing Spring based application:

1) Create a project if not already existing using your favourate IDE

2) Add a depenendency in order to use features of the Spring AI

3) Add an entry of openAI key-value in your application.xml or application.yml file

4) Create a RestController & required methods to get outcomes from AI tool

How to add OpenAI dependency in your Application?

There are two popular approaches to include a starter (dependent component) in our existing application:

1)  Using Spring Initializer

2)  Using an IDE

The third rarely used approach is to manually add dependency in your pom.xml or build.gradle file. Since Spring AI is in its pre-matured version. You can’t add it to your newly created project using Spring Initializer or an IDE. Below is the dependency that we need to add:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    <version>0.8.0-SNAPSHOT</version>
</dependency>

In this article we are using ‘0.8.0-SNAPSHOT’. You may also try using the latest available version of openAI dependency.

Your existing repository may not download the above dependeny, so you need to add an addtional repository in order to get it downloaded:

<repositories>
   <repository>
      <id>spring-snapshots</id>
      <name>Spring Snapshots</name>
      <url>https://repo.spring.io/snapshot</url>
      <releases>
        <enabled>false</enabled>
      </releases>
   </repository>
</repositories>

It concludes the inclusion of OpenAI dependency.

How to get OpenAI secret key?

1) Visit openai.com and create an account if not done before. Even if you have ChatGPT account, the same credentials may work for you to login.

2) Click on OpenAI icon and go to API keys. You will find ‘Create new secret key’ link that will open a form to create a secret key. When you click on
‘Create a secret key’, you may ask to solve a simple puzzle in order to verify that you are a human. On solving the puzzle successfully, the secret key will be generated which can easily be copied to the clipboard. Click on ‘Done’ to close the form.

You will need this secret key to provide the value of ‘spring.ai.openai.api-key’ in your application.properties file.

How to implement Hello World Example using Spring AI?

Let’s implement our first ‘Hello World’ example using Spring AI.

Note: Spring AI is in development phase and still not in mature state. Hence, there are chances that we can see frequent API changes in future releases. Therefore, it is recommended to check API documentation for the latest changes before using it.

Step#1: Create a Spring Boot starter project 

We are using STS as an IDE to develop this example. While creating project in STS add 2 starters ‘Spring Web’ and ‘Spring Boot DevTools’. If you are new to STS, visit a separate article on how to create a sample project using STS.

Step#2: Add OpenAI dependency in pom.xml

Add dependencies as mentioned above in this article.

Step#3: Add OpenAI secret key-value in application.xml 

Add OpenAI secret key-value as shown below.

spring.ai.openai.api-key=Your OpenAI secret key

Step#4: Create RestController 

Let’s create our first example to interact with OpenAI.

import org.springframework.ai.chat.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/prompt")
public class AIPromptController {

   private final ChatClient chatClient;

   public AIPromptController(ChatClient chatClient) {
      this.chatClient= chatClient;
   }

   @GetMapping("/hello")
   public String testAiPrompt() {
      String prompt= "Hello! What is Spring Boot?";
      return chatClient.generate(prompt);
   }
}

Another Example using Spring AI

Let’s develop another example using placeholders to avoid the hardcoded values.

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.chat.ChatResponse;
import org.springframework.ai.parser.BeanOutputParser;
import org.springframework.ai.prompt.Prompt;
import org.springframework.ai.prompt.PromptTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.spring.ai.test.entity.TopLanguage;

@RestController @RequestMapping("/prompt")
public class AIPromptController {  
   
   private final ChatClient chatClient;
   
   public AIPromptController(ChatClient chatClient) { 
      this.chatClient= chatClient;  
   }
   
   @GetMapping("/learn/{topic}")
   public String getTopic(@PathVariable("topic") String topic) {
      
      //'topic' is a placeholder in the prompt
      PromptTemplate promptTemplate = new PromptTemplate("""
        I just started learning Spring. Can you provide me 
        fundamentals of {topic} to get started?
        Please provide me short and concise details in simple language.
      """);
      promptTemplate.add("topic", topic);
      return this.chatClient.generate(promptTemplate.create()).getGeneration().getContent();
   }

   @GetMapping("/getLanguage/{year}")
   public TopLanguage getTopLanguage(@PathVariable("year") int year) {

      BeanOutputParser<TopLanguage> parser = new BeanOutputParser<>(TopLanguage.class);

      //'year' is a placeholder in the prompt
      String prompt= """
        Which is the top programming Language in the year {year}?
        {format}
      """;

      PromptTemplate template = new PromptTemplate(prompt);
      template.add("year", year);
      template.add("format", parser.getFormat());
      template.setOutputParser(parser);

      System.out.println("Format String: "+parser.getFormat());

      Prompt promt= template.create();
      ChatResponse chatResponse= chatClient.generate(promt);
      String text= chatResponse.getGeneration().getContent();

      return parser.parse(text);
   } 
}

Let’s create the TopLanguage as a record:

public record TopLanguage(String language, int year, int percentage) {

}

How to test the output?

In order to test the outputs of our examples, use any tool of your choice such as Postman.

1) Hit the URL https://localhost:8080/prompt/hello to see the expected output of first method.

2) Hit the URL https://localhost:8080/prompt/learn/spring core to test the expected output of second method.

3) Hit the URL https://localhost:8080/prompt/getLanguage/2020 to test thee output of third method. In this method, we have used the format, so the output should be in the form of json like below:

{
"language": "Java",
"percentage": 75.8,
"year": 2020
}

References

https://docs.spring.io/spring-ai/reference/index.html

Leave a Reply


Top