Skip to content

Commit a6f4c06

Browse files
authored
Bael 9284 (#18669)
* BAEL-9284, Using Groq Chat with Spring AI * BAEL-9284, Using Groq Chat with Spring AI
1 parent fe518fb commit a6f4c06

File tree

8 files changed

+202
-0
lines changed

8 files changed

+202
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.baeldung.groq;
2+
3+
import org.springframework.ai.openai.OpenAiChatModel;
4+
import org.springframework.ai.openai.api.OpenAiApi;
5+
import org.springframework.beans.factory.annotation.Value;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.context.annotation.Profile;
9+
10+
@Configuration(proxyBeanMethods = false)
11+
@Profile("customgroq")
12+
public class ChatAppConfiguration {
13+
14+
@Value("${groq.api-key}")
15+
private String GROQ_API_KEY;
16+
17+
@Value("${groq.base-url}")
18+
private String GROQ_API_URL;
19+
20+
@Bean
21+
public OpenAiChatModel customGroqChatClient() {
22+
OpenAiApi groqOpenAiApi = new OpenAiApi.Builder()
23+
.apiKey(GROQ_API_KEY)
24+
.baseUrl(GROQ_API_URL)
25+
.build();
26+
return OpenAiChatModel.builder()
27+
.openAiApi(groqOpenAiApi)
28+
.build();
29+
}
30+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.baeldung.groq;
2+
3+
import org.springframework.ai.chat.prompt.ChatOptions;
4+
import org.springframework.ai.chat.prompt.Prompt;
5+
import org.springframework.ai.openai.OpenAiChatModel;
6+
import org.springframework.ai.openai.OpenAiChatOptions;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.stereotype.Service;
9+
10+
@Service
11+
public class CustomGroqChatService {
12+
@Autowired
13+
private OpenAiChatModel customGroqChatClient;
14+
15+
public String chat(String prompt, String model, Double temperature) {
16+
ChatOptions chatOptions = OpenAiChatOptions.builder()
17+
.model(model)
18+
.temperature(temperature)
19+
.build();
20+
return customGroqChatClient.call(new Prompt(prompt, chatOptions))
21+
.getResult()
22+
.getOutput()
23+
.getText();
24+
}
25+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.baeldung.groq;
2+
3+
import org.springframework.ai.autoconfigure.anthropic.AnthropicAutoConfiguration;
4+
import org.springframework.ai.autoconfigure.bedrock.converse.BedrockConverseProxyChatAutoConfiguration;
5+
import org.springframework.ai.autoconfigure.ollama.OllamaAutoConfiguration;
6+
import org.springframework.ai.autoconfigure.vectorstore.chroma.ChromaVectorStoreAutoConfiguration;
7+
import org.springframework.ai.autoconfigure.vectorstore.pgvector.PgVectorStoreAutoConfiguration;
8+
import org.springframework.boot.SpringApplication;
9+
import org.springframework.boot.autoconfigure.SpringBootApplication;
10+
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
11+
12+
@SpringBootApplication(exclude = {
13+
OllamaAutoConfiguration.class,
14+
AnthropicAutoConfiguration.class,
15+
PgVectorStoreAutoConfiguration.class,
16+
ChromaVectorStoreAutoConfiguration.class,
17+
BedrockConverseProxyChatAutoConfiguration.class,
18+
RedisAutoConfiguration.class
19+
})
20+
public class GroqChatApplication {
21+
public static void main(String[] args) {
22+
SpringApplication.run(GroqChatApplication.class, args);
23+
}
24+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.baeldung.groq;
2+
3+
import org.springframework.ai.chat.prompt.ChatOptions;
4+
import org.springframework.ai.openai.OpenAiChatModel;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.stereotype.Service;
7+
8+
@Service
9+
public class GroqChatService {
10+
@Autowired
11+
private OpenAiChatModel groqClient;
12+
13+
public String chat(String prompt) {
14+
15+
return groqClient.call(prompt);
16+
}
17+
18+
public ChatOptions getChatOptions() {
19+
return groqClient.getDefaultOptions();
20+
}
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
spring.application.name=spring-ai-custom-groq-demo
2+
groq.base-url=https://api.groq.com/openai
3+
groq.api-key=gsk_XXXX
4+
spring.autoconfigure.exclude=org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
spring.application.name=spring-ai-groq-demo
2+
spring.ai.openai.base-url=https://api.groq.com/openai
3+
spring.ai.openai.api-key=gsk_XXXX
4+
5+
spring.ai.openai.chat.base-url=https://api.groq.com/openai
6+
spring.ai.openai.chat.api-key=gsk_XXXX
7+
spring.ai.openai.chat.options.temperature=0.7
8+
spring.ai.openai.chat.options.model=llama-3.3-70b-versatile
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package com.baeldung.groq;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
import org.springframework.ai.chat.prompt.ChatOptions;
9+
import org.springframework.ai.openai.OpenAiChatOptions;
10+
import org.springframework.beans.factory.annotation.Autowired;
11+
import org.springframework.boot.test.context.SpringBootTest;
12+
import org.springframework.test.context.ActiveProfiles;
13+
14+
@SpringBootTest
15+
@ActiveProfiles("groq")
16+
public class GroqAutoconfiguredChatClientLiveTest {
17+
final Logger logger = LoggerFactory.getLogger(GroqAutoconfiguredChatClientLiveTest.class);
18+
@Autowired
19+
private GroqChatService groqChatService;
20+
21+
@Test
22+
void whenCallOpenAIClient_thenReturnResponseFromGroq() {
23+
24+
String prompt = """
25+
Context:
26+
Support Ticket #98765:
27+
Product: XYZ Wireless Mouse
28+
Issue Description: The mouse connects intermittently to my laptop.
29+
I've tried changing batteries and reinstalling drivers,
30+
but the cursor still freezes randomly for a few seconds before resuming normal movement.
31+
It affects productivity significantly.
32+
Question:
33+
Based on the support ticket, what is the primary technical issue
34+
the user is experiencing with their 'XYZ Wireless Mouse'?;
35+
""";
36+
String response = groqChatService.chat(prompt);
37+
38+
assertThat(response.toLowerCase()).isNotNull()
39+
.isNotEmpty()
40+
.containsAnyOf("laptop", "mouse", "connect");
41+
42+
ChatOptions openAiChatOptions = groqChatService.getChatOptions();
43+
String model = openAiChatOptions.getModel();
44+
Double temperature = openAiChatOptions.getTemperature();
45+
46+
assertThat(openAiChatOptions).isInstanceOf(OpenAiChatOptions.class);
47+
assertThat(model).isEqualTo("llama-3.3-70b-versatile");
48+
assertThat(temperature).isEqualTo(Double.valueOf(0.7));
49+
logger.info("Response from Groq:{}", response);
50+
}
51+
52+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.baeldung.groq;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
import org.springframework.beans.factory.annotation.Autowired;
9+
import org.springframework.boot.test.context.SpringBootTest;
10+
import org.springframework.test.context.ActiveProfiles;
11+
12+
@SpringBootTest()
13+
@ActiveProfiles("customgroq")
14+
public class GroqCustomChatClientLiveTest {
15+
private final Logger logger = LoggerFactory.getLogger(GroqCustomChatClientLiveTest.class);
16+
17+
@Autowired
18+
private CustomGroqChatService customGroqChatService;
19+
20+
@Test
21+
void whenCustomGroqClientCalled_thenReturnResponse() {
22+
String prompt = """
23+
Context:
24+
The Eiffel Tower is one of the most famous landmarks
25+
in Paris, attracting millions of visitors each year.
26+
Question:
27+
In which city is the Eiffel Tower located?
28+
""";
29+
String response = customGroqChatService.chat(prompt, "llama-3.1-8b-instant", 0.8);
30+
31+
assertThat(response)
32+
.isNotNull()
33+
.isNotEmpty()
34+
.contains("Paris");
35+
logger.info("Response from custom Groq client: {}", response);
36+
}
37+
38+
}

0 commit comments

Comments
 (0)