Skip to content

Commit af018a5

Browse files
authored
Merge pull request #96 from springaialibaba/0320-yuluo/update-mailvus
feat: update milvus rag example
2 parents 2cdaa9e + 7274efa commit af018a5

File tree

11 files changed

+208
-144
lines changed

11 files changed

+208
-144
lines changed

docker-compose/milvus/docker-compose.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
version: '3.5'
2-
31
services:
2+
43
etcd:
54
container_name: milvus-etcd
65
image: quay.io/coreos/etcd:v3.5.16
@@ -60,6 +59,18 @@ services:
6059
- "etcd"
6160
- "minio"
6261

62+
dashboard:
63+
image: zilliz/attu:v2.5
64+
container_name: milvus-dashboard
65+
environment:
66+
MILVUS_URL: http://standalone:19530
67+
ports:
68+
- "8000:3000"
69+
depends_on:
70+
- standalone
71+
- etcd
72+
- minio
73+
6374
networks:
6475
default:
65-
name: milvus
76+
name: milvus

spring-ai-alibaba-integration-example/backend/src/main/java/com/alibaba/cloud/ai/application/SpringAIIntegrationApplication.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919

2020
import org.springframework.boot.SpringApplication;
2121
import org.springframework.boot.autoconfigure.SpringBootApplication;
22-
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
23-
import org.springframework.boot.autoconfigure.jdbc.JdbcClientAutoConfiguration;
24-
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
2522

2623
/**
2724
* @author yuluo

spring-ai-alibaba-rag-example/rag-milvus-example/README.md

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,67 @@
88
- Milvus (Docker Compose)
99

1010
1. 通过 Docker Compose 安装 Milvus。
11-
- docker-compose的yml文件见目录/spring-ai-alibaba-examples/docker-compose/milvus/docker-compose.yml
12-
- 详细安装文档见地址:https://milvus.io/docs/install_standalone-docker-compose.md
13-
2. 启动 Milvus。
14-
3. 创建 collection
15-
4. 打开 Milvus 向量检索。
16-
5. 修改 application.yml 中的配置。
17-
6. 运行本项目
1811

19-
其中Milvus的配置如下:
20-
注意:不同版本Milvus的配置略有不同,Milvus2.3.0版本才原生支持 Cosine 距离,请根据实际情况调整
12+
- docker-compose 的 yml 文件见目录 `/spring-ai-alibaba-examples/docker-compose/milvus/docker-compose.yml`
13+
- 详细安装文档见地址:https://milvus.io/docs/install_standalone-docker-compose.md
2114

22-
截图是Attu的WebPortal界面 (Milvus GUI),介绍地址见:https://github.com/zilliztech/attu
15+
2. 启动 Milvus;
16+
3. 打开浏览器访问 `localhost:8000`,访问 dashboard;
17+
4. 在 default 数据库创建 collection;
2318

24-
![img.png](img.png)
19+
![img.png](img.png)
20+
21+
5. 打开 Milvus 向量检索;
22+
6. 修改 application.yml 中的配置;
23+
7. 运行本项目,在项目启动时会将数据导入 Milvus;
24+
8. 在 dashboard 手动加载集合:
25+
26+
如果加载集合完成,将看到以下输出:
27+
28+
![img_1.png](img2.jpg)
29+
30+
其中 Milvus 的配置如下:
31+
32+
> 注意:不同版本 Milvus 的配置略有不同,Milvus2.3.0 版本才原生支持 Cosine 距离,请根据实际情况调整
33+
34+
## 项目演示
35+
36+
### 1. 导入
37+
38+
```shell
39+
# 注意:在执行查询前,应该手动加载集合。避免查询错误
40+
41+
# 向量查询
42+
curl http://localhost:8080/ai/select
43+
```
44+
45+
如果一切正常,将看到以下输出:
46+
47+
```json
48+
[
49+
{
50+
"id": "fae19802-f6c0-42a6-8408-6c68dba55722",
51+
"text": "17. SpringAIAlibaba支持自然语言处理、计算机视觉、语音处理和数据分析与预测功能。",
52+
"media": null,
53+
"metadata": {
54+
"distance": 0.25151956
55+
},
56+
"score": 0.7484804391860962
57+
},
58+
{
59+
....
60+
}
61+
]
62+
```
63+
64+
### 查询提问
65+
66+
浏览器访问:
67+
68+
http://localhost:8080/ai/chat?prompt="如何使用 spring ai alibaba 开发 ai 应用"
69+
70+
将看到如下输出:
71+
72+
```text
73+
要使用 Spring AI Alibaba 开发 AI 应用,您可以按照以下步骤进行: 1. ......
74+
```
48.9 KB
Loading
95.2 KB
Loading

spring-ai-alibaba-rag-example/rag-milvus-example/pom.xml

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,27 +19,25 @@
1919
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2020
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2121
<modelVersion>4.0.0</modelVersion>
22+
2223
<parent>
2324
<groupId>com.alibaba.cloud.ai</groupId>
2425
<artifactId>spring-ai-alibaba-rag-example</artifactId>
2526
<version>${revision}</version>
2627
<relativePath>../pom.xml</relativePath>
2728
</parent>
29+
2830
<artifactId>rag-milvus-example</artifactId>
2931
<version>${revision}</version>
3032
<name>rag-milvus-example</name>
31-
<description>Demo project for Spring AI Alibaba</description>
33+
<description>Milvus RAG Example project for Spring AI Alibaba</description>
3234

3335
<properties>
3436
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3537
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
3638
<maven.compiler.source>17</maven.compiler.source>
3739
<maven.compiler.target>17</maven.compiler.target>
3840
<maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version>
39-
40-
<!-- Spring AI -->
41-
<spring-ai-alibaba.version>1.0.0-M3.1</spring-ai-alibaba.version>
42-
<spring-ai.version>1.0.0-M3</spring-ai.version>
4341
</properties>
4442

4543
<dependencies>
@@ -58,21 +56,8 @@
5856
<groupId>org.springframework.ai</groupId>
5957
<artifactId>spring-ai-milvus-store-spring-boot-starter</artifactId>
6058
</dependency>
61-
6259
</dependencies>
6360

64-
<dependencyManagement>
65-
<dependencies>
66-
<dependency>
67-
<groupId>org.springframework.ai</groupId>
68-
<artifactId>spring-ai-bom</artifactId>
69-
<version>${spring-ai.version}</version>
70-
<type>pom</type>
71-
<scope>import</scope>
72-
</dependency>
73-
</dependencies>
74-
</dependencyManagement>
75-
7661
<build>
7762
<plugins>
7863
<plugin>

spring-ai-alibaba-rag-example/rag-milvus-example/src/main/java/com/alibaba/cloud/ai/example/rag/config/PromptConfiguration.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package com.alibaba.cloud.ai.example.rag.config;
1818

19-
2019
import org.springframework.ai.chat.client.ChatClient;
2120
import org.springframework.context.annotation.Bean;
2221
import org.springframework.context.annotation.Configuration;
@@ -26,7 +25,7 @@ public class PromptConfiguration {
2625

2726
@Bean
2827
ChatClient chatClient(ChatClient.Builder builder) {
29-
return builder.defaultSystem("你将作为一名Spring-AI-Alibaba的专家,对于用户的使用需求作出解答")
28+
return builder.defaultSystem("你将作为一名 Spring-AI-Alibaba 的专家,对于用户的使用需求作出解答")
3029
.build();
3130
}
3231
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.alibaba.cloud.ai.example.rag.config;
18+
19+
20+
import java.util.List;
21+
22+
import org.slf4j.Logger;
23+
import org.slf4j.LoggerFactory;
24+
25+
import org.springframework.ai.document.Document;
26+
import org.springframework.ai.vectorstore.milvus.MilvusVectorStore;
27+
import org.springframework.boot.ApplicationArguments;
28+
import org.springframework.boot.ApplicationRunner;
29+
import org.springframework.context.annotation.Configuration;
30+
31+
@Configuration
32+
public class VectorDataInit implements ApplicationRunner {
33+
34+
private final Logger logger = LoggerFactory.getLogger(VectorDataInit.class);
35+
36+
private final MilvusVectorStore vectorStore;
37+
38+
public VectorDataInit(MilvusVectorStore vectorStore) {
39+
this.vectorStore = vectorStore;
40+
}
41+
42+
@Override
43+
public void run(ApplicationArguments args) {
44+
45+
List<Document> documents = List.of(
46+
new Document("1. 使用SpringAIAlibaba创建一个Spring Boot项目,并添加spring-ai-alibaba-starter依赖。"),
47+
new Document("2. 在SpringAIAlibaba项目的pom.xml中添加Spring Milestone和Snapshot存储库。"),
48+
new Document("3. 通过SpringAIAlibaba申请阿里云通义API Key,在application.yml中进行配置。"),
49+
new Document("4. 使用SpringAIAlibaba的ChatClient和Prompt功能实现对话模型。"),
50+
new Document("5. 通过SpringAIAlibaba的Spring Boot与Spring Cloud Alibaba AI对接,实现基本聊天功能。"),
51+
new Document("6. SpringAIAlibaba支持文本生成、翻译、摘要等生成式AI功能。"),
52+
new Document("7. SpringAIAlibaba支持文本数据的语义搜索和AI绘画功能。"),
53+
new Document("8. 使用SpringAIAlibaba的TongYiChatModel和TongYiImagesModel实现聊天和图片服务。"),
54+
new Document("9. 在SpringAIAlibaba的REST控制器中提供对外的API接口。"),
55+
new Document("10. 通过SpringAIAlibaba的简单API调用实现AI模型的集成。"),
56+
new Document("11. 使用SpringAIAlibaba的Prompt模板管理控制AI模型的输出。"),
57+
new Document("12. 结合SpringAIAlibaba的检索和生成技术(RAG)提高生成内容的质量。"),
58+
new Document("13. 使用SpringAIAlibaba实现文本生成图像和图像识别功能。"),
59+
new Document("14. 准备SpringAIAlibaba需要的Java 17及以上的开发环境。"),
60+
new Document("15. 使用IDEA进行SpringAIAlibaba的Java开发和HBuilder X进行前端开发。"),
61+
new Document("16. 在SpringAIAlibaba的Spring Boot项目中集成多种AI模型和向量数据库。"),
62+
new Document("17. SpringAIAlibaba支持自然语言处理、计算机视觉、语音处理和数据分析与预测功能。"),
63+
new Document("18. 通过SpringAIAlibaba的配置中心和注册中心实现动态扩展。")
64+
);
65+
66+
vectorStore.add(documents);
67+
logger.info("Vector data initialized");
68+
}
69+
70+
}

spring-ai-alibaba-rag-example/rag-milvus-example/src/main/java/com/alibaba/cloud/ai/example/rag/controller/RagController.java

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,83 @@
1616

1717
package com.alibaba.cloud.ai.example.rag.controller;
1818

19-
import lombok.extern.slf4j.Slf4j;
19+
import java.util.ArrayList;
20+
import java.util.List;
21+
22+
import jakarta.servlet.http.HttpServletResponse;
23+
import reactor.core.publisher.Flux;
24+
2025
import org.springframework.ai.chat.client.ChatClient;
2126
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
2227
import org.springframework.ai.chat.messages.Message;
2328
import org.springframework.ai.chat.messages.UserMessage;
29+
import org.springframework.ai.document.Document;
2430
import org.springframework.ai.vectorstore.SearchRequest;
2531
import org.springframework.ai.vectorstore.VectorStore;
26-
import org.springframework.beans.factory.annotation.Autowired;
27-
import org.springframework.web.bind.annotation.PostMapping;
32+
import org.springframework.web.bind.annotation.GetMapping;
2833
import org.springframework.web.bind.annotation.RequestMapping;
2934
import org.springframework.web.bind.annotation.RequestParam;
3035
import org.springframework.web.bind.annotation.RestController;
3136

32-
import java.util.ArrayList;
33-
import java.util.List;
34-
35-
3637
@RestController
37-
@Slf4j
3838
@RequestMapping("/ai")
3939
public class RagController {
4040

41-
@Autowired
42-
private ChatClient chatClient;
41+
private final VectorStore vectorStore;
42+
43+
private final ChatClient chatClient;
4344

44-
@Autowired
45-
private VectorStore vectorStore;
45+
public RagController(VectorStore vectorStore, ChatClient chatClient) {
46+
this.vectorStore = vectorStore;
47+
this.chatClient = chatClient;
48+
}
4649

4750
// 历史消息列表
48-
static List<Message> historyMessage = new ArrayList<>();
51+
private static List<Message> historyMessage = new ArrayList<>();
52+
4953
// 历史消息列表的最大长度
50-
static int maxLen = 10;
54+
private final static int maxLen = 10;
55+
56+
@GetMapping(value = "/chat")
57+
public Flux<String> generation(
58+
@RequestParam("prompt") String userInput,
59+
HttpServletResponse response
60+
) {
61+
62+
response.setCharacterEncoding("UTF-8");
5163

52-
@PostMapping(value = "/chat", produces = "text/plain; charset=UTF-8")
53-
public String generation(String userInput) {
5464
// 发起聊天请求并处理响应
55-
String output = chatClient.prompt()
65+
Flux<String> resp = chatClient.prompt()
5666
.messages(historyMessage)
5767
.user(userInput)
58-
.advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
59-
.call()
68+
.advisors(new QuestionAnswerAdvisor(
69+
vectorStore,
70+
SearchRequest.builder().build())
71+
).stream()
6072
.content();
61-
// 用户输入的文本是UserMessage
73+
74+
// 用户输入的文本是 UserMessage
6275
historyMessage.add(new UserMessage(userInput));
63-
// 发给AI前对历史消息对列的长度进行检查
76+
77+
// 发给 AI 前对历史消息对列的长度进行检查
6478
if (historyMessage.size() > maxLen) {
6579
historyMessage = historyMessage.subList(historyMessage.size() - maxLen - 1, historyMessage.size());
6680
}
67-
return output;
81+
82+
return resp;
6883
}
6984

85+
/**
86+
* 向量数据查询测试
87+
*/
88+
@GetMapping("/select")
89+
public List<Document> search() {
90+
91+
return vectorStore.similaritySearch(
92+
SearchRequest.builder()
93+
.query("SpringAIAlibaba")
94+
.topK("SpringAIAlibaba".length()
95+
).build());
96+
}
7097

71-
}
98+
}

0 commit comments

Comments
 (0)