Skip to content

Commit 853ea38

Browse files
committed
Update dependencies of AI project
1 parent dc7a771 commit 853ea38

File tree

9 files changed

+269
-155
lines changed

9 files changed

+269
-155
lines changed

.github/workflows/assist.yml

+1-3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,4 @@ jobs:
5353
--build-env BP_JVM_VERSION=17 \
5454
--env \
5555
SPRING_AI_AZURE_OPENAI_ENDPOINT=${AZURE_OPENAI_ENDPOINT} \
56-
SPRING_AI_AZURE_OPENAI_APIKEY=${AZURE_OPENAI_APIKEY} \
57-
SPRING_AI_AZURE_OPENAI_MODEL=${AZURE_OPENAI_MODEL} \
58-
SPRING_AI_AZURE_OPENAI_EMBEDDINGMODEL=${AZURE_OPENAI_EMBEDDINGMODEL} \
56+
SPRING_AI_AZURE_OPENAI_API_KEY=${AZURE_OPENAI_APIKEY}

apps/acme-assist/pom.xml

+15-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>org.springframework.boot</groupId>
88
<artifactId>spring-boot-starter-parent</artifactId>
9-
<version>3.2.1</version>
9+
<version>3.2.3</version>
1010
</parent>
1111
<groupId>com.azure.acme</groupId>
1212
<artifactId>acme-assist</artifactId>
@@ -32,17 +32,27 @@
3232
<dependency>
3333
<groupId>com.azure</groupId>
3434
<artifactId>azure-ai-openai</artifactId>
35-
<version>1.0.0-beta.3</version>
35+
<version>1.0.0-beta.7</version>
3636
</dependency>
3737
<dependency>
38-
<groupId>org.springframework.experimental.ai</groupId>
38+
<groupId>org.springframework.ai</groupId>
39+
<artifactId>spring-ai-core</artifactId>
40+
<version>0.8.1</version>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.springframework.ai</groupId>
3944
<artifactId>spring-ai-azure-openai-spring-boot-starter</artifactId>
40-
<version>0.2.0-SNAPSHOT</version>
45+
<version>0.8.1</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.springframework.ai</groupId>
49+
<artifactId>spring-ai-azure-vector-store-spring-boot-starter</artifactId>
50+
<version>0.8.1</version>
4151
</dependency>
4252
<dependency>
4353
<groupId>com.knuddels</groupId>
4454
<artifactId>jtokkit</artifactId>
45-
<version>0.6.1</version>
55+
<version>1.0.0</version>
4656
</dependency>
4757
<dependency>
4858
<groupId>org.apache.logging.log4j</groupId>

apps/acme-assist/src/main/java/com/example/acme/assist/ChatService.java

+29-28
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,41 @@
11
package com.example.acme.assist;
22

3-
import com.azure.ai.openai.models.ChatRole;
4-
import com.example.acme.assist.model.AcmeChatRequest;
5-
import com.example.acme.assist.model.Product;
6-
import io.micrometer.common.util.StringUtils;
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.stream.Collectors;
7+
78
import org.apache.logging.log4j.util.Strings;
8-
import org.springframework.ai.client.AiClient;
9-
import org.springframework.ai.client.AiResponse;
10-
import org.springframework.ai.client.Generation;
9+
import org.springframework.ai.chat.ChatClient;
10+
import org.springframework.ai.chat.ChatResponse;
11+
import org.springframework.ai.chat.messages.ChatMessage;
12+
import org.springframework.ai.chat.messages.Message;
13+
import org.springframework.ai.chat.prompt.Prompt;
14+
import org.springframework.ai.chat.prompt.SystemPromptTemplate;
1115
import org.springframework.ai.document.Document;
12-
import org.springframework.ai.prompt.Prompt;
13-
import org.springframework.ai.prompt.SystemPromptTemplate;
14-
import org.springframework.ai.prompt.messages.ChatMessage;
15-
import org.springframework.ai.prompt.messages.Message;
16-
import org.springframework.ai.vectorstore.impl.SimplePersistentVectorStore;
16+
import org.springframework.ai.vectorstore.SimpleVectorStore;
1717
import org.springframework.beans.factory.annotation.Autowired;
1818
import org.springframework.beans.factory.annotation.Value;
1919
import org.springframework.core.io.Resource;
2020
import org.springframework.stereotype.Service;
2121

22-
import java.util.ArrayList;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.stream.Collectors;
22+
import com.azure.ai.openai.models.ChatRole;
23+
import com.example.acme.assist.model.AcmeChatRequest;
24+
import com.example.acme.assist.model.Product;
25+
26+
import io.micrometer.common.util.StringUtils;
2627

2728
@Service
2829
public class ChatService {
2930

3031
@Autowired
31-
private SimplePersistentVectorStore store;
32+
private SimpleVectorStore store;
3233

3334
@Autowired
3435
private ProductRepository productRepository;
3536

3637
@Autowired
37-
private AiClient aiClient;
38+
private ChatClient chatClient;
3839

3940
@Value("classpath:/prompts/chatWithoutProductId.st")
4041
private Resource chatWithoutProductIdResource;
@@ -66,7 +67,7 @@ private List<String> chatWithProductId(Product product, List<AcmeChatRequest.Mes
6667
String question = chatRequestMessages.get(chatRequestMessages.size() - 1).getContent();
6768

6869
// step 1. Query for documents that are related to the question from the vector store
69-
List<Document> candidateDocuments = this.store.similaritySearch(question, 5, 0.4);
70+
List<Document> candidateDocuments = this.store.similaritySearch(question);
7071

7172
// step 2. Create a SystemMessage that contains the product information in addition to related documents.
7273
List<Message> messages = new ArrayList<>();
@@ -89,13 +90,13 @@ protected List<String> chatWithoutProductId(List<AcmeChatRequest.Message> acmeCh
8990
String question = acmeChatRequestMessages.get(acmeChatRequestMessages.size() - 1).getContent();
9091

9192
// step 1. Query for documents that are related to the question from the vector store
92-
List<Document> relatedDocuments = store.similaritySearch(question, 5, 0.4);
93+
List<Document> relatedDocuments = store.similaritySearch(question);
9394

9495
// step 2. Create the system message with the related documents;
9596
List<Message> messages = new ArrayList<>();
9697
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.chatWithoutProductIdResource);
9798
String relatedDocsAsString = relatedDocuments.stream()
98-
.map(entry -> String.format("Product Name: %s\nText: %s\n", entry.getMetadata().get("name"), entry.getText()))
99+
.map(entry -> String.format("Product Name: %s\nText: %s\n", entry.getMetadata().get("name"), entry.getContent()))
99100
.collect(Collectors.joining("\n"));
100101
Message systemMessage = systemPromptTemplate.createMessage(Map.of("context", relatedDocsAsString));
101102
messages.add(systemMessage);
@@ -113,7 +114,7 @@ private List<String> addUserMessagesAndSendToAI(List<AcmeChatRequest.Message> ac
113114

114115
// Call to OpenAI chat API
115116
Prompt prompt = new Prompt(messages);
116-
AiResponse aiResponse = this.aiClient.generate(prompt);
117+
ChatResponse aiResponse = this.chatClient.call(prompt);
117118

118119
// Process the result and return to client
119120
List<String> response = processResult(aiResponse);
@@ -123,21 +124,21 @@ private List<String> addUserMessagesAndSendToAI(List<AcmeChatRequest.Message> ac
123124

124125
public Message getProductDetailMessage(Product product, List<Document> documents) {
125126
String additionalContext = documents.stream()
126-
.map(entry -> String.format("Product Name: %s\nText: %s\n", entry.getMetadata().get("name"), entry.getText()))
127+
.map(entry -> String.format("Product Name: %s\nText: %s\n", entry.getMetadata().get("name"), entry.getContent()))
127128
.collect(Collectors.joining("\n"));
128-
Map map = Map.of(
129+
Map<String,Object> map = Map.of(
129130
"name", product.getName(),
130131
"tags", String.join(",", product.getTags()),
131132
"shortDescription", product.getShortDescription(),
132133
"fullDescription", product.getDescription(),
133134
"additionalContext", additionalContext);
134135
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(this.chatWithProductIdResource);
135-
return systemPromptTemplate.create(map).getMessages().get(0);
136+
return systemPromptTemplate.create(map).getInstructions().get(0);
136137
}
137138

138-
private List<String> processResult(AiResponse aiResponse) {
139-
List<String> response = aiResponse.getGenerations().stream()
140-
.map(Generation::getText)
139+
private List<String> processResult(ChatResponse aiResponse) {
140+
List<String> response = aiResponse.getResults().stream()
141+
.map(result -> result.getOutput().getContent())
141142
.filter(text -> !StringUtils.isEmpty(text))
142143
.map(this::filterMessage)
143144
.collect(Collectors.toList());

apps/acme-assist/src/main/java/com/example/acme/assist/config/FitAssistConfiguration.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.example.acme.assist.config;
22

33
import org.springframework.ai.embedding.EmbeddingClient;
4-
import org.springframework.ai.vectorstore.impl.SimplePersistentVectorStore;
4+
import org.springframework.ai.vectorstore.SimpleVectorStore;
55
import org.springframework.beans.factory.annotation.Value;
66
import org.springframework.context.annotation.Bean;
77
import org.springframework.context.annotation.Configuration;
@@ -12,9 +12,10 @@ public class FitAssistConfiguration {
1212

1313
@Value("classpath:/vector_store.json")
1414
private Resource vectorDbResource;
15+
1516
@Bean
16-
public SimplePersistentVectorStore simpleVectorStore(EmbeddingClient embeddingClient) {
17-
SimplePersistentVectorStore simpleVectorStore = new SimplePersistentVectorStore(embeddingClient);
17+
public SimpleVectorStore simpleVectorStore(EmbeddingClient embeddingClient) {
18+
SimpleVectorStore simpleVectorStore = new SimpleVectorStore(embeddingClient);
1819
simpleVectorStore.load(vectorDbResource);
1920
return simpleVectorStore;
2021
}

apps/acme-assist/src/main/java/com/example/acme/assist/tools/BuildVectorStoreApplication.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
package com.example.acme.assist.tools;
22

33
import org.springframework.ai.document.Document;
4-
import org.springframework.ai.loader.impl.JsonLoader;
5-
import org.springframework.ai.loader.impl.JsonMetadataGenerator;
6-
import org.springframework.ai.vectorstore.impl.SimplePersistentVectorStore;
4+
import org.springframework.ai.reader.JsonMetadataGenerator;
5+
import org.springframework.ai.reader.JsonReader;
6+
import org.springframework.ai.vectorstore.SimpleVectorStore;
77
import org.springframework.beans.factory.annotation.Autowired;
88
import org.springframework.boot.CommandLineRunner;
99
import org.springframework.boot.DefaultApplicationArguments;
@@ -25,7 +25,7 @@
2525
public class BuildVectorStoreApplication implements CommandLineRunner {
2626

2727
@Autowired
28-
private SimplePersistentVectorStore simpleVectorStore;
28+
private SimpleVectorStore simpleVectorStore;
2929

3030
public static void main(String[] args) {
3131
new SpringApplicationBuilder(BuildVectorStoreApplication.class)
@@ -50,10 +50,10 @@ public void run(String... originalArgs) throws Exception {
5050

5151
for (var file : jsonFiles) {
5252
File sourceFile = new File(file);
53-
JsonLoader jsonLoader = new JsonLoader(new FileSystemResource(sourceFile),
53+
JsonReader jsonLoader = new JsonReader(new FileSystemResource(sourceFile),
5454
new ProductMetadataGenerator(),
5555
"price", "name", "shortDescription", "description", "tags");
56-
List<Document> documents = jsonLoader.load();
56+
List<Document> documents = jsonLoader.get();
5757
this.simpleVectorStore.add(documents);
5858
}
5959
this.simpleVectorStore.save(new File(to.get(0)));

apps/acme-assist/src/main/resources/application.yaml

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ spring:
22
ai:
33
azure:
44
openai:
5-
model: gpt-35-turbo-16k
5+
chat:
6+
options:
7+
deployment-name: gpt-35-turbo-16k
8+
embedding:
9+
options:
10+
deployment-name: text-embedding-ada-002
611
management:
712
endpoints:
813
web:
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,66 @@
1-
You are an AI assistant of this website named 'Acme Fitness Store', which sells bikes and accessories online.
2-
You help people find information.
3-
Please answer the questions based the following product details with the text that follows the placeholder """PRODUCT-DETAILS""" and then
4-
try to improve your answer with additional text that follows the placeholder """ADDITIONAL-CONTEXT"""
1+
[Overall Rules to follow]
2+
* You are an AI assistant of the website named 'Acme Fitness Store', which sells bikes and accessories online.
3+
* Content in [PRODUCT-INFO] is introduction of commodity user is watching.
4+
* User's question only relates to this website, bikes and accessories.
5+
* Answer user's question according to content in [PRODUCT-INFO] or reference [Examples]
6+
* Improve answer using [ADDITIONAL-CONTEXT]
7+
* Answer 'Sorry, I cannot answer your question. Please contact us.' if question is not related to given content.
58

6-
"""PRODUCT-DETAILS"""
9+
[PRODUCT-INFO]
10+
[Begin]
711
Name: {name}
812
Tags: {tags}
913
Short description:
1014
{shortDescription}
1115
Full description:
1216
{fullDescription}
17+
[End]
1318

14-
15-
16-
"""ADDITIONAL-CONTEXT"""
19+
[ADDITIONAL-CONTEXT]
20+
[Begin]
1721
{additionalContext}
22+
[End]
23+
24+
[EXAMPLES]
25+
[Begin]
26+
[Question]
27+
How long will it take to get the bike delivered to me?
28+
[Answer]
29+
We offer two shipping options: 1. Free standard: With our standard shipping option, you can expect your products to arrive within 3-7 business days. 2. Premium: If you prefer priority handling and express delivery, our premium shipping option ensures delivery within 1-3 business days. Feeling reassured by the estimated delivery time, Alex completes the remaining form fields, including his credit card information. With the order finalized, Alex is excitedly looking forward to receiving his new e-bike and accessories. He's grateful for the helpful guidance provided by FitAssist throughout the entire shopping experience.
30+
[Question]
31+
How will you ship my bike?
32+
[Answer]
33+
Great question! We offer two shipping options: Free Shipping: Get your Model A e-bike and Rear Rack delivered to your doorstep at no additional cost with our standard shipping option. Estimated delivery time is 3-7 business days. Premium Shipping: If you prefer priority handling and express delivery, you can choose our premium shipping option. Your e-bike and accessories will arrive within 1-3 business days. Please let me know which option you'd like, or if you have any other questions. I'm here to assist you throughout the process.
34+
[Question]
35+
How do I place an order for a bike on your website?
36+
[Answer]
37+
To place an order, browse through our selection of bikes and click on the one you wish to purchase. On the product page, you'll find an "Add to Cart" button. Click on it, and the bike will be added to your shopping cart. Proceed to the checkout page to complete your order.
38+
[Question]
39+
What payment methods do you accept for bike purchases?
40+
[Answer]
41+
We accept various payment methods, including credit/debit cards (Visa, Mastercard, etc.), PayPal, and other secure online payment options. You can select your preferred payment method during the checkout process.
42+
[Question]
43+
Do you offer free shipping for bike orders?
44+
[Answer]
45+
Absolutely! We offer free standard shipping for all bike orders. With our free shipping option, it will be delivered to your doorstep at no additional cost. Estimated delivery time is 3-7 business days. If you prefer faster delivery, we also have a premium shipping option available for a small additional fee, which ensures express delivery within 1-3 business days. Please let me know if you have any more questions or if there's anything else I can assist you with!
46+
[Question]
47+
Can I return or exchange the bike if I'm not satisfied?
48+
[Answer]
49+
Yes, we have a hassle-free return and exchange policy. If you are not satisfied with your bike, you can return it within 30 days of delivery for a full refund or exchange. The bike must be in its original condition, and you may be responsible for return shipping costs.
50+
[Question]
51+
Are the bikes on your website pre-assembled or do I need to assemble them myself?
52+
[Answer]
53+
The bikes are usually shipped partially assembled for safer transportation. You will receive detailed instructions and the necessary tools to complete the assembly easily at home. If you need assistance, you can contact our customer support team.
54+
[Question]
55+
Do you offer any warranties on your bikes?
56+
[Answer]
57+
Yes, all our bikes come with a manufacturer's warranty that covers defects in materials and workmanship. The duration and coverage of the warranty may vary depending on the bike model. Please check the product page or contact us for specific warranty information.
58+
[Question]
59+
Can I get expert advice on choosing the right bike for me?
60+
[Answer]
61+
Absolutely! We have a team of knowledgeable bike experts ready to assist you. You can reach out to our customer support through email, phone, or live chat, and they will be happy to help you find the perfect bike based on your needs and preferences.
62+
[Question]
63+
Do you offer any discounts or promotions on bike purchases?
64+
[Answer]
65+
Yes, we frequently run promotions and special offers on our website. Keep an eye on our homepage and subscribe to our newsletter to stay updated on the latest deals and discounts.
66+
[End]

0 commit comments

Comments
 (0)