-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update to Spring Boot 3.3 and early chatbot example
- Loading branch information
1 parent
775652a
commit ddc6213
Showing
11 changed files
with
226 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Chatbot | ||
|
||
Chat with LLMs via Ollama. | ||
|
||
## Running the application | ||
|
||
The application relies on Ollama for providing LLMs. You can either run Ollama locally on your laptop, or rely on the Testcontainers support in Spring Boot to spin up an Ollama service automatically. | ||
|
||
### Ollama as a native application | ||
|
||
First, make sure you have [Ollama](https://ollama.ai) installed on your laptop. | ||
Then, use Ollama to run the _llama3_ large language model. | ||
|
||
```shell | ||
ollama run llama3 | ||
``` | ||
|
||
Finally, run the Spring Boot application. | ||
|
||
```shell | ||
./gradlew bootRun | ||
``` | ||
|
||
### Ollama as a dev service with Testcontainers | ||
|
||
The application relies on the native Testcontainers support in Spring Boot to spin up an Ollama service with a _llama3_ model at startup time. | ||
|
||
```shell | ||
./gradlew bootTestRun | ||
``` | ||
|
||
## Calling the application | ||
|
||
You can now call the application that will use Ollama and llama3 to answer your questions. | ||
This example uses [httpie](https://httpie.io) to send HTTP requests. | ||
|
||
```shell | ||
http --raw "Where did Saruman got the wood to build a weapon factory?" :8080/chat | ||
``` | ||
|
||
```shell | ||
http --raw "Can a wolf destroy a house?" :8080/chat | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
plugins { | ||
id 'java' | ||
id 'org.springframework.boot' | ||
id 'io.spring.dependency-management' | ||
} | ||
|
||
group = 'com.thomasvitale' | ||
version = '0.0.1-SNAPSHOT' | ||
|
||
java { | ||
toolchain { | ||
languageVersion = JavaLanguageVersion.of(21) | ||
} | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
maven { url 'https://repo.spring.io/milestone' } | ||
maven { url 'https://repo.spring.io/snapshot' } | ||
} | ||
|
||
dependencies { | ||
implementation platform("org.springframework.ai:spring-ai-bom:${springAiVersion}") | ||
|
||
implementation 'org.springframework.boot:spring-boot-starter-web' | ||
implementation 'org.springframework.ai:spring-ai-ollama-spring-boot-starter' | ||
|
||
testAndDevelopmentOnly 'org.springframework.boot:spring-boot-devtools' | ||
|
||
testImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
testImplementation 'org.springframework.boot:spring-boot-starter-webflux' | ||
testImplementation 'org.springframework.boot:spring-boot-testcontainers' | ||
testImplementation 'org.springframework.ai:spring-ai-spring-boot-testcontainers' | ||
testImplementation 'org.testcontainers:junit-jupiter' | ||
testImplementation 'org.testcontainers:ollama' | ||
} | ||
|
||
tasks.named('test') { | ||
useJUnitPlatform() | ||
} |
28 changes: 28 additions & 0 deletions
28
00-use-cases/chatbot/src/main/java/com/thomasvitale/ai/spring/Chatbot.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.thomasvitale.ai.spring; | ||
|
||
import org.springframework.ai.chat.memory.ChatMemory; | ||
import org.springframework.ai.chat.memory.InMemoryChatMemory; | ||
import org.springframework.ai.tokenizer.JTokkitTokenCountEstimator; | ||
import org.springframework.ai.tokenizer.TokenCountEstimator; | ||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.context.annotation.Bean; | ||
|
||
@SpringBootApplication | ||
public class Chatbot { | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(Chatbot.class, args); | ||
} | ||
|
||
@Bean | ||
ChatMemory chatHistory() { | ||
return new InMemoryChatMemory(); | ||
} | ||
|
||
@Bean | ||
TokenCountEstimator tokenCountEstimator() { | ||
return new JTokkitTokenCountEstimator(); | ||
} | ||
|
||
} |
21 changes: 21 additions & 0 deletions
21
00-use-cases/chatbot/src/main/java/com/thomasvitale/ai/spring/ChatbotController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.thomasvitale.ai.spring; | ||
|
||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
class ChatbotController { | ||
|
||
private final ChatbotService chatbotService; | ||
|
||
ChatbotController(ChatbotService chatbotService) { | ||
this.chatbotService = chatbotService; | ||
} | ||
|
||
@PostMapping("/chat") | ||
String chat(@RequestBody String input) { | ||
return chatbotService.chat(input); | ||
} | ||
|
||
} |
35 changes: 35 additions & 0 deletions
35
00-use-cases/chatbot/src/main/java/com/thomasvitale/ai/spring/ChatbotService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.thomasvitale.ai.spring; | ||
|
||
import org.springframework.ai.chat.ChatModel; | ||
import org.springframework.ai.chat.memory.*; | ||
import org.springframework.ai.chat.messages.UserMessage; | ||
import org.springframework.ai.chat.prompt.Prompt; | ||
import org.springframework.ai.chat.prompt.transformer.ChatServiceContext; | ||
import org.springframework.ai.chat.service.ChatService; | ||
import org.springframework.ai.chat.service.PromptTransformingChatService; | ||
import org.springframework.ai.tokenizer.TokenCountEstimator; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.List; | ||
|
||
@Service | ||
class ChatbotService { | ||
|
||
private final ChatService chatService; | ||
|
||
ChatbotService(ChatModel chatModel, ChatMemory chatMemory, TokenCountEstimator tokenCountEstimator) { | ||
this.chatService = PromptTransformingChatService.builder(chatModel) | ||
.withRetrievers(List.of(new ChatMemoryRetriever(chatMemory))) | ||
.withContentPostProcessors(List.of(new LastMaxTokenSizeContentTransformer(tokenCountEstimator, 1000))) | ||
.withAugmentors(List.of(new SystemPromptChatMemoryAugmentor())) | ||
.withChatServiceListeners(List.of(new ChatMemoryChatServiceListener(chatMemory))) | ||
.build(); | ||
} | ||
|
||
String chat(String message) { | ||
var prompt = new Prompt(new UserMessage(message)); | ||
var chatServiceResponse = this.chatService.call(new ChatServiceContext(prompt)); | ||
return chatServiceResponse.getChatResponse().getResult().getOutput().getContent(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
spring: | ||
ai: | ||
ollama: | ||
chat: | ||
options: | ||
model: llama3 | ||
threads: | ||
virtual: | ||
enabled: true |
13 changes: 13 additions & 0 deletions
13
00-use-cases/chatbot/src/test/java/com/thomasvitale/ai/spring/ChatbotTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.thomasvitale.ai.spring; | ||
|
||
import org.junit.jupiter.api.Test; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
@SpringBootTest | ||
class ChatbotTests { | ||
|
||
@Test | ||
void contextLoads() { | ||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
00-use-cases/chatbot/src/test/java/com/thomasvitale/ai/spring/TestChatbot.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.thomasvitale.ai.spring; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.devtools.restart.RestartScope; | ||
import org.springframework.boot.test.context.TestConfiguration; | ||
import org.springframework.boot.testcontainers.service.connection.ServiceConnection; | ||
import org.springframework.context.annotation.Bean; | ||
import org.testcontainers.ollama.OllamaContainer; | ||
import org.testcontainers.utility.DockerImageName; | ||
|
||
@TestConfiguration(proxyBeanMethods = false) | ||
public class TestChatbot { | ||
|
||
@Bean | ||
@RestartScope | ||
@ServiceConnection | ||
OllamaContainer ollama() { | ||
return new OllamaContainer(DockerImageName.parse("ghcr.io/thomasvitale/ollama-llama3") | ||
.asCompatibleSubstituteFor("ollama/ollama")); | ||
} | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.from(Chatbot::main).with(TestChatbot.class).run(args); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters