• Stars
    star
    481
  • Rank 91,384 (Top 2 %)
  • Language
    Java
  • License
    Apache License 2.0
  • Created over 1 year ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Spring Boot ChatGPT Starter

Maven GitHub repo size Open Issues Apache License 2

ChatGPT Spring Boot Starter

Spring Boot ChatGPT starter with ChatGPT chat and functions support.

Features

  • Base on Spring Boot 3.0+
  • Async with Spring Webflux
  • Support ChatGPT Chat Stream
  • Support ChatGPT functions: @GPTFunction annotation
  • Prompt Management: load prompt templates from prompt.properties with @PropertyKey, and friendly with IntelliJ IDEA
  • Prompt as Lambda: convert prompt template to lambda expression and call it with FP style
  • ChatGPT interface: Declare ChatGPT service interface with @ChatGPTExchange and @ChatCompletion annotations.
  • No third-party library: base on Spring 6 HTTP interface
  • GraalVM native image support
  • Azure OpenAI support

Get Started

Add dependency

Add chatgpt-spring-boot-starter dependency in your pom.xml.

<dependency>
    <groupId>org.mvnsearch</groupId>
    <artifactId>chatgpt-spring-boot-starter</artifactId>
    <version>0.6.0</version>
</dependency>

Adjust configuration

Add openai.api.key in application.properties:

# OpenAI API Token, or you can set environment variable OPENAI_API_KEY
openai.api.key=sk-xxxx

If you want to use Azure OpenAI, you can add openai.api.url in application.properties:

openai.api.key=1138xxxx9037
openai.api.url=https://YOUR_RESOURCE_NAME.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT_NAME/chat/completions?api-version=2023-05-15

Call ChatGPT Service

@RestController
public class ChatRobotController {
    @Autowired
    private ChatGPTService chatGPTService;

    @PostMapping("/chat")
    public Mono<String> chat(@RequestBody String content) {
        return chatGPTService.chat(ChatCompletionRequest.of(content))
                .map(ChatCompletionResponse::getReplyText);
    }

    @GetMapping("/stream-chat")
    public Flux<String> streamChat(@RequestParam String content) {
        return chatGPTService.stream(ChatCompletionRequest.of(content))
                .map(ChatCompletionResponse::getReplyText);
    }
}

ChatGPT Service Interface

ChatGPT service interface is almost like Spring 6 HTTP Interface. You can declare a ChatGPT service interface with @ChatGPTExchange annotation, and declare completion methods with @ChatCompletion annotation, then you just call service interface directly.

@GPTExchange
public interface GPTHelloService {

    @ChatCompletion("You are a language translator, please translate the below text to Chinese.\n")
    Mono<String> translateIntoChinese(String text);

    @ChatCompletion("You are a language translator, please translate the below text from {0} to {1}.\n {2}")
    Mono<String> translate(String sourceLanguage, String targetLanguage, String text);
  
    @Completion("please complete poem: {0}")
  	Mono<String> completePoem(String text);
    
}

Create ChatGPT interface service bean:

    @Bean
    public GPTHelloService gptHelloService(ChatGPTServiceProxyFactory proxyFactory) {
        return proxyFactory.createClient(GPTHelloService.class);
    }

ChatGPT functions

  • Create a Spring Bean with @Component. Annotate GPT functions with @GPTFunction annotation, and annotate function parameters with @Parameter annotation. @Nonnull means that the parameter is required.
import jakarta.annotation.Nonnull;

@Component
public class GPTFunctions {

    public record SendEmailRequest(
            @Nonnull @Parameter("Recipients of email") List<String> recipients,
            @Nonnull @Parameter("Subject of email") String subject,
            @Parameter("Content of email") String content) {
    }

    @GPTFunction(name = "send_email", value = "Send email to receiver")
    public String sendEmail(SendEmailRequest request) {
        System.out.println("Recipients: " + String.join(",", request.recipients));
        System.out.println("Subject: " + request.subject);
        System.out.println("Content:\n" + request.content);
        return "Email sent to " + String.join(",", request.recipients) + " successfully!";
    }

    public record SQLQueryRequest(
            @Parameter(required = true, value = "SQL to query") String sql) {
    }

    @GPTFunction(name = "execute_sql_query", value = "Execute SQL query and return the result set")
    public String executeSQLQuery(SQLQueryRequest request) {
        System.out.println("Execute SQL: " + request.sql);
        return "id, name, salary\n1,Jackie,8000\n2,Libing,78000\n3,Sam,7500";
    }
}
  • Call GPT function by response.getReplyCombinedText() or chatMessage.getFunctionCall().getFunctionStub().call():
public class ChatGPTServiceImplTest {
    @Test
    public void testChatWithFunctions() throws Exception {
        final String prompt = "Hi Jackie, could you write an email to Libing([email protected]) and Sam([email protected]) and invite them to join Mike's birthday party at 4 pm tomorrow? Thanks!";
        final ChatCompletionRequest request = ChatCompletionRequest.functions(prompt, List.of("send_email"));
        final ChatCompletionResponse response = chatGPTService.chat(request).block();
        // display reply combined text with function call
        System.out.println(response.getReplyCombinedText());
        // call function manually
        for (ChatMessage chatMessage : response.getReply()) {
            final FunctionCall functionCall = chatMessage.getFunctionCall();
            if (functionCall != null) {
                final Object result = functionCall.getFunctionStub().call();
                System.out.println(result);
            }
        }
    }

    @Test
    public void testExecuteSQLQuery() {
        String context = "You are SQL developer. Write SQL according to requirements, and execute it in MySQL database.";
        final String prompt = "Query all employees whose salary is greater than the average.";
        final ChatCompletionRequest request = ChatCompletionRequest.functions(prompt, List.of("execute_sql_query"));
        // add prompt context as system message
        request.addMessage(ChatMessage.systemMessage(context));
        final ChatCompletionResponse response = chatGPTService.chat(request).block();
        System.out.println(response.getReplyCombinedText());
    }
}

Note: @GPTExchange and @ChatCompletion has functions built-in, so you just need to fill functions parameters.

ChatGPT Functions use cases:

  • Structure Output: such as SQL, JSON, CSV, YAML etc., then delegate functions to process them.
  • Commands: such as send_email, post on Twitter.
  • DevOps: such as generate K8S yaml file, then call K8S functions to deploy it.
  • Search Matching: bind search with functions, such as search for a book, then call function to show it.
  • Spam detection: email spam, advertisement spam etc
  • PipeLine: you can think function as a node in pipeline. After process by function, and you can pass it to ChatGPT again.
  • Data types supported: string, number, integer, array. Nested object not supported now!

If you want to have a simple test for ChatGPT functions, you can install ChatGPT with Markdown JetBrains IDE Plugin, and take a look at chat.gpt file.

Prompt Templates

How to manage prompts in Java? Now ChatGPT starter adopts prompts.properties to save prompt templates, and uses MessageFormat to format template value.PromptPropertiesStoreImpl will load all prompts.properties files from classpath. You can extend PromptStore to load prompts from database or other sources.

You can load prompt template by PromptManager.

Tips:

  • Prompt template code completion: support by @PropertyKey(resourceBundle = PROMPTS_FQN)
  • @ChatCompletion annotation has built-in prompt template support for user,system and assistant messages.
  • Prompt value could be from classpath and URL: conversation=classpath:///conversation-prompt.txt or conversation=https://example.com/conversation-prompt.txt

Prompt Template as Lambda

For some case you want to use prompt template as lambda, such as translate first, then send it as email. You can declare prompt as function and chain them together.

public class PromptLambdaTest {
    @Test
    public void testPromptAsFunction() {
        Function<String, Mono<String>> translateIntoChineseFunction = chatGPTService.promptAsLambda("translate-into-chinese");
        Function<String, Mono<String>> sendEmailFunction = chatGPTService.promptAsLambda("send-email");
        String result = Mono.just("Hi Jackie, could you write an email to Libing([email protected]) and Sam([email protected]) and invite them to join Mike's birthday party at 4 pm tomorrow? Thanks!")
                .flatMap(translateIntoChineseFunction)
                .flatMap(sendEmailFunction)
                .block();
        System.out.println(result);
    }
}

To keep placeholders safe in prompt template, you can use record as Lambda parameter.

public class PromptTest {
    public record TranslateRequest(String from, String to, String text) {
    }

    @Test
    public void testLambdaWithRecord() {
        Function<TranslateRequest, Mono<String>> translateFunction = chatGPTService.promptAsLambda("translate");
        String result = Mono.just(new TranslateRequest("Chinese", "English", "ไฝ ๅฅฝ๏ผ"))
                .flatMap(translateFunction)
                .block();
        System.out.println(result);
    }
}

FAQ

OpenAI REST API proxy

Please refer OpenAIProxyController.

@RestController
public class OpenAIProxyController {
    @Autowired
    private OpenAIChatAPI openAIChatAPI;

    @PostMapping("/v1/chat/completions")
    public Publisher<ChatCompletionResponse> completions(@RequestBody ChatCompletionRequest request) {
        return openAIChatAPI.proxy(request);
    }
}

Of course, you can use standard URL http://localhost:8080/v1/chat/completions to call Azure OpenAI API.

How to use ChatGPT with Spring Web?

Now ChatGPT starter use Reactive style API, and you know Reactive still hard to understand. Could ChatGPT starter work with Spring Web? Yes, you can use Mono or Flux with Spring Web and Virtual Threads, please refer Spring Boot Virtual Thread Demo for details.

Building the Code

The code uses the Spring Java Formatter Maven plugin, which keeps the code consistent. In order to build the code, run:

./mvnw spring-javaformat:apply

This will ensure that all contributions have the exact same code formatting, allowing us to focus on bigger issues, like functionality,

References

More Repositories

1

jenv

Java enVironment Manager
Shell
603
star
2

spring-boot-dubbo

Spring Boot with Dubbo support
Java
278
star
3

dubbo3

Dubbo3: distributed RPC framework from Alibaba Dubbo2
Java
255
star
4

ddd-base

DDD(Domain Driven Design) base package for java
Java
255
star
5

awesome-rsocket

Awesome RSocket
190
star
6

mybatis-r2dbc

MyBatis R2DBC Adapter
Java
131
star
7

weixin-robot-java

ๅพฎไฟกๅ…ฌๅ…ฑๅนณๅฐๆœบๅ™จไบบJava SDK
Java
119
star
8

plantuml-gist

PlantUML with Github Gist and Gitlab Support
Java
96
star
9

dx

A tool and task runner for writing better scripts with Deno
TypeScript
93
star
10

zookeeper-intellij

IntelliJ IDEA ZooKeeper Plugin
Java
62
star
11

spring-boot-starter-redisson

Spring Boot starter for Redisson
Java
58
star
12

h2-functions-4-mysql

H2 functions for MySQL
Java
57
star
13

spring-boot-starter-okhttp3

Spring Boot Starter for OkHttp3
Java
55
star
14

spring-boot-starter-httpclient

Spring Boot Starter for HttpClient
Java
54
star
15

vitest-jetbrains-plugin

Vitest JetBrains plugin
Kotlin
52
star
16

spring-boot-rsocket-demo

Spring Boot RSocket Demo with RPC style
Java
42
star
17

spring-boot-thymeleaf3-bootstrap4-angular4

Spring Boot Kotlin Application Template for Thymeleaf3, BootStrap4 and Angularjs 4
TypeScript
42
star
18

toolchains-maven-plugin

Toolchains Maven Plugin with JDK auto download
Java
36
star
19

xtermjs-spring-boot-starter

Web terminal to manage your Spring Boot app
Java
30
star
20

spring-cloud-function-demo

Spring cloud function with RSocket
Java
24
star
21

spring-boot-starter-wechatmp

Spring Boot with Wechat Support
Java
23
star
22

ngrok-spring-boot-starter

Easy to expose a local Spring Boot Application to the internet by ngrok
Java
23
star
23

smarty4j

Smarty Template Engine for Java
Java
22
star
24

spring-boot-starter-oss

Spring Boot Start with Aliyun OSS
Java
19
star
25

reactive-demo

Reactive Demo with Reactor, RxJava and reactive-stream
Java
19
star
26

jetbrains-just-plugin

JetBrains Just Command Runner Plugin
Kotlin
19
star
27

cli-completion

CLI completion for bash, zsh, fish and powershell
Rust
18
star
28

spring-boot-microservices

Spring Boot MicroServices
Java
18
star
29

spring-boot-starter-shell

Spring Shell with Spring Boot Driven
Java
17
star
30

chrome_js_api_stub

Chrome JavaScript API Stub to assistant extension development in IDE
JavaScript
16
star
31

rsocket-load-balancing

RSocket load balancing based on Spring Cloud Service Registry
Java
15
star
32

kotlin-wasm-demo

Kotlin WebAssembly Demo
Kotlin
15
star
33

spring-boot-kotlin-microservices

Spring Boot MicroServices with Kotlin
Kotlin
14
star
34

task-keeper

A cli to manage tasks from different task runners or package managers
Rust
13
star
35

open2internet-spring-boot-starter

Expose local Spring Boot Application to internet for demonstration, testing and debuging
Java
13
star
36

ali-oss-shell

Aliyun OSS Shell
Java
12
star
37

easy-random-junit5-extension

JUnit 5 extension for easy-random
Java
12
star
38

rocker-template-demo

Rocker template demo with Spring Boot
Java
12
star
39

mail-catcher

MailCatcher runs a super simple SMTP server which catches any message sent to it to display in a web interface
Java
12
star
40

kotlin-platform-bom

Kotlin Platform BOM
Just
11
star
41

axum-demo

Axum demo
Rust
11
star
42

rsocket-deno

๐Ÿฆ•RSocket Deno module
TypeScript
11
star
43

r2dbc-demo

R2DBC demo
Java
11
star
44

oh-my-zsh-spring-boot-plugin

oh-my-zsh Spring Boot plugin
10
star
45

team

Team Instruction
10
star
46

java-error-messages-wizard

Java Error Message Wizard
Java
10
star
47

ddd-demo

DDD demo with Java 8 and Spring Boot
Java
9
star
48

jenv-ps

jenv Power Shell Edition
PowerShell
9
star
49

nats-spring-boot-starter

Spring Boot starter for NATS
Java
9
star
50

struts2-spring-boot-integration

Spring Boot with Struts 2.5.x Integration
Java
8
star
51

kafka-demo

Kafka Demo with Spring Boot, Docker and Terraform
Java
8
star
52

rest-editor-client-contrib

REST Editor Client Contrib plugin for IntelliJ IDEA
Java
8
star
53

jenv-idea-plugin

jenv IntelliJ IDEA plugin
Java
8
star
54

mybatis-demo

MyBatis Demo with spring-boot-starter-mybatis integration
Java
8
star
55

platform-bom-contrib

Spring Platform IO BOM Contrib
Java
8
star
56

java9-in-action

Java 9 in Action
Java
7
star
57

aliyun-openapi-rust-sdk

Aliyun OpenAPI SDK for Rust
Rust
7
star
58

tgm

Template generator management
Rust
7
star
59

npm-export-spring-boot-starter

Spring Boot Starter to generate npm package to call REST API
Java
7
star
60

xterm-demo

Xterm.js with RSocket
JavaScript
7
star
61

apache-pulsar-demo

Apache Pulsar demo
Java
7
star
62

http2-java-demo

Spring Boot with HTTP/2
Java
7
star
63

spring-boot-apache-dubbo

Spring Boot 2.0 with Apache Dubbo
Java
7
star
64

markdown-chatgpt

Talk to ChatGPT from Markdown
Kotlin
7
star
65

trpc-spring-boot-starter

Spring Boot Starter for tRPC
Java
7
star
66

reactive-grpc-demo

gRPC with reactive Reactor
Java
6
star
67

unitTest_templates

unitTest IntelliJ IDEA plugin templates
6
star
68

proto-rsocket-plugin

Protobuf to RSocket service interface
Java
6
star
69

grpc-kotlin-demo

gRPC with Kotlin Demo
Kotlin
6
star
70

java11_in_action

Java 11 in Action
Java
6
star
71

markdown-wasm

Markdown wasm based on md4c for Deno ๐Ÿฆ•
TypeScript
6
star
72

kotlin-deno-example

๐Ÿฆ•Deno app development with Kotlin
Kotlin
6
star
73

zshmarks

zsh marks for oh-my-zsh
6
star
74

trunk-demo

WebAssembly development with Trunk & Vite.js
Rust
6
star
75

reactive-grpc-spring-boot-starter

Spring Boot Starter for Reactive gRPC
Java
6
star
76

hessian-spring-boot-starter

Spring Boot Start for Hessian
Java
6
star
77

alibaba-broker-example-parent

Alibaba RSocket Broker Example
Java
6
star
78

akka-demo

Akka Demo with Kotlin, Spring Integration
Java
5
star
79

intellij-templates

IntelliJ IDEA live templates
5
star
80

zookeeper-shell

New ZooKeeper shell just like bash
Java
5
star
81

embind_demo

Emscripten embind demo
C++
5
star
82

graal-native-image-demo

Graal native image demo with RSocket and Netty
Java
5
star
83

dkim-spring-boot-starter

DKIM for spring-boot-starter-mail
Java
5
star
84

akka-spring-boot-starter

akka-spring-boot-starter
Java
5
star
85

rsocket-dart

RSocket Dart SDK
Dart
4
star
86

deno-rust-wasm-demo

Deno with Rust Wasm
TypeScript
4
star
87

rest-graphql-rsocket-demo

One controller to combine HTTP REST, GraphQL and RSocket
Java
4
star
88

aria2-shell

Aria2 Shell
Java
4
star
89

spring-boot-starter-job-controller

Spring Boot with Job Controller
Java
4
star
90

aeron-demo

Aeron Spring Reactive Demo
Java
4
star
91

rsocket-transport-quic

RSocket QUIC transport
Java
4
star
92

spring-cloud-aliyun

Integration for Aliyun Cloud Services APIs with Spring Cloud
Shell
4
star
93

jvmtop

Clone from https://code.google.com/p/jvmtop
Java
4
star
94

kotlin-wasm-browser-demo

Kotlin WebAssembly demo for Browser
Kotlin
4
star
95

deno-httpx

httpx: cli to run requests from http file
TypeScript
4
star
96

kotlin-coroutine-demo

Kotlin Coroutines demo
Kotlin
4
star
97

spring-boot-polyglot-demo

Spring Boot Polyglot with Kotlin, Java + Lombok + Groovy
Kotlin
4
star
98

esnippet_idea_plugin

eSnippet IntelliJ IDEA plugin
Java
4
star
99

microservices-annotator

Java Annotations for Microservices annotator to mark your code
Java
3
star
100

logback-fluentd-appender

Logback Fluentd Appender
Java
3
star