Skip to content

Commit

Permalink
Update output parsers and embedding samples
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasVitale committed Jan 20, 2024
1 parent f76ad94 commit cc65400
Show file tree
Hide file tree
Showing 54 changed files with 953 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
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.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.testcontainers.containers.GenericContainer;

@TestConfiguration(proxyBeanMethods = false)
public class TestChatModelsOllamaApplication {

@Bean
@RestartScope
@Scope("singleton") // needed because of https://github.com/spring-projects/spring-boot/issues/35786
GenericContainer<?> ollama(DynamicPropertyRegistry properties) {
var ollama = new GenericContainer<>("ghcr.io/thomasvitale/ollama-llama2")
.withExposedPorts(11434);
Expand Down
2 changes: 1 addition & 1 deletion 01-chat-models/chat-models-openai/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Chat Models: OpenAI

```shell
./gradlew bootRun
./gradlew bootTestRun
```

```shell
Expand Down
2 changes: 2 additions & 0 deletions 01-chat-models/chat-models-openai/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ dependencies {
testAndDevelopmentOnly 'org.springframework.boot:spring-boot-devtools'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ChatController {
}

@GetMapping("/ai/chat")
String chat(@RequestParam(defaultValue = "What does Gandalf say to the Balrog?") String message) {
String chat(@RequestParam(defaultValue = "What did Gandalf say to the Balrog?") String message) {
return chatClient.generate(message);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.thomasvitale.ai.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.TestConfiguration;

@TestConfiguration(proxyBeanMethods = false)
public class TestChatModelsOpenaiApplication {

public static void main(String[] args) {
SpringApplication.from(ChatModelsOpenaiApplication::main).with(TestChatModelsOpenaiApplication.class).run(args);
}

}
17 changes: 17 additions & 0 deletions 02-prompts/prompts-basics-ollama/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Prompts Basic: Ollama

```shell
./gradlew bootTestRun
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/simple
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/prompt
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/full
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ spring:
ai:
ollama:
chat:
model: mistral
model: llama2
options:
temperature: 0.7
threads:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
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.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.testcontainers.containers.GenericContainer;

@TestConfiguration(proxyBeanMethods = false)
public class TestPromptBasicsOllamaApplication {

@Bean
@RestartScope
@Scope("singleton") // needed because of https://github.com/spring-projects/spring-boot/issues/35786
GenericContainer<?> ollama(DynamicPropertyRegistry properties) {
var ollama = new GenericContainer<>("ghcr.io/thomasvitale/ollama-llama2")
.withExposedPorts(11434);
properties.add("spring.ai.ollama.base-url",
() -> "http://%s:%s".formatted(ollama.getHost(), ollama.getMappedPort(11434)));
return ollama;
}

public static void main(String[] args) {
SpringApplication.from(PromptsBasicsOllamaApplication::main).with(TestPromptBasicsOllamaApplication.class).run(args);
}
Expand Down
17 changes: 17 additions & 0 deletions 02-prompts/prompts-basics-openai/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Prompts Basic: OpenAI

```shell
./gradlew bootTestRun
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/simple
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/prompt
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/full
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.thomasvitale.ai.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.TestConfiguration;

@TestConfiguration(proxyBeanMethods = false)
public class TestPromptsBasicsOpenAiApplication {

public static void main(String[] args) {
SpringApplication.from(PromptsBasicsOpenAiApplication::main).with(TestPromptsBasicsOpenAiApplication.class).run(args);
}

}
37 changes: 37 additions & 0 deletions 02-prompts/prompts-messages-ollama/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
17 changes: 17 additions & 0 deletions 02-prompts/prompts-messages-ollama/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Prompts Messages: Ollama

```shell
./gradlew bootTestRun
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/single
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/multiple
```

```shell
http --raw "What is the capital of Italy?" :8080/ai/chat/external
```
34 changes: 34 additions & 0 deletions 02-prompts/prompts-messages-ollama/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'io.spring.dependency-management'
}

group = 'com.thomasvitale'
version = '0.0.1-SNAPSHOT'

java {
sourceCompatibility = '21'
}

repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'

implementation "org.springframework.ai:spring-ai-ollama-spring-boot-starter:${springAiVersion}"

testAndDevelopmentOnly 'org.springframework.boot:spring-boot-devtools'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
}

tasks.named('test') {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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 ChatController {

private final ChatService chatService;

ChatController(ChatService chatService) {
this.chatService = chatService;
}

@PostMapping("/ai/chat/single")
String chatWithSingleMessage(@RequestBody String input) {
return chatService.chatWithSingleMessage(input).getContent();
}

@PostMapping("/ai/chat/multiple")
String chatWithMultipleMessages(@RequestBody String input) {
return chatService.chatWithMultipleMessages(input).getContent();
}

@PostMapping("/ai/chat/external")
String chatWithExternalMessage(@RequestBody String input) {
return chatService.chatWithExternalMessage(input).getContent();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.thomasvitale.ai.spring;

import org.springframework.ai.chat.ChatClient;
import org.springframework.ai.prompt.Prompt;
import org.springframework.ai.prompt.messages.AssistantMessage;
import org.springframework.ai.prompt.messages.SystemMessage;
import org.springframework.ai.prompt.messages.UserMessage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
class ChatService {

private final ChatClient chatClient;

private final Resource systemMessageResource;

ChatService(ChatClient chatClient, @Value("classpath:/prompts/system-message.st") Resource systemMessageResource) {
this.chatClient = chatClient;
this.systemMessageResource = systemMessageResource;
}

AssistantMessage chatWithSingleMessage(String message) {
var userMessage = new UserMessage(message);
var prompt = new Prompt(userMessage);
var chatResponse = chatClient.generate(prompt);
return new AssistantMessage(chatResponse.getGeneration().getContent(), chatResponse.getGeneration().getProperties());
}

AssistantMessage chatWithMultipleMessages(String message) {
var systemMessage = new SystemMessage("""
You are a helpful and polite assistant.
Answer in one sentence using a very formal language
and starting the answer with a formal greeting.
""");
var userMessage = new UserMessage(message);
var prompt = new Prompt(List.of(systemMessage, userMessage));
var chatResponse = chatClient.generate(prompt);
return new AssistantMessage(chatResponse.getGeneration().getContent(), chatResponse.getGeneration().getProperties());
}

AssistantMessage chatWithExternalMessage(String message) {
var systemMessage = new SystemMessage(systemMessageResource);
var userMessage = new UserMessage(message);
var prompt = new Prompt(List.of(systemMessage, userMessage));
var chatResponse = chatClient.generate(prompt);
return new AssistantMessage(chatResponse.getGeneration().getContent(), chatResponse.getGeneration().getProperties());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.thomasvitale.ai.spring;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class PromptMessagesOllamaApplication {

public static void main(String[] args) {
SpringApplication.run(PromptMessagesOllamaApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
spring:
ai:
ollama:
chat:
model: llama2
options:
temperature: 0.7
threads:
virtual:
enabled: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
You are a funny and hilarious assistant.
Answer in one sentence using a very informal language
and starting the answer with a knock knowck joke.
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 PromptMessagesOllamaApplicationTests {

@Test
void contextLoads() {
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.testcontainers.containers.GenericContainer;

@TestConfiguration(proxyBeanMethods = false)
public class TestPromptMessagesOllamaApplication {

@Bean
@RestartScope
@Scope("singleton") // needed because of https://github.com/spring-projects/spring-boot/issues/35786
GenericContainer<?> ollama(DynamicPropertyRegistry properties) {
var ollama = new GenericContainer<>("ghcr.io/thomasvitale/ollama-llama2")
.withExposedPorts(11434);
properties.add("spring.ai.ollama.base-url",
() -> "http://%s:%s".formatted(ollama.getHost(), ollama.getMappedPort(11434)));
return ollama;
}

public static void main(String[] args) {
SpringApplication.from(PromptMessagesOllamaApplication::main).with(TestPromptMessagesOllamaApplication.class).run(args);
}

}
Loading

0 comments on commit cc65400

Please sign in to comment.