Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example: add rag application example #3743

Merged
merged 5 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<artifactId>spring-cloud-alibaba-examples</artifactId>
<groupId>com.alibaba.cloud</groupId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Spring Cloud Alibaba AI Text Embedding

`TongYiController` 接受一个 HTTP GET 请求 `http://localhost:8080/ai/audio`。
`controller` 将会调用 `TongYiService` 中的 `genAudio` 方法,完成服务请求得到响应。

有一个可选的 `text` 参数,其默认值为“Spring Cloud Alibaba AI 框架!”。 请求响应来自 Alibaba TongYi Text Embedding 服务。

## 构建和运行

1. 修改配置文件 `application.yml` 中的 apikey 为有效的 apikey;
2. 通过 IDE 或者 `./mvnw spring-boot:run` 运行应用程序。

## 访问接口

使用 curl 工具或者使用浏览器对接口发起请求:

```shell
$ curl http://localhost:8080/ai/textEmbedding

# Response:
为一组向量集合
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Spring Cloud Alibaba AI RAG Example

This sample describes how to implement a RAG (Retrieval Augmented Generation) application using SCA AI and Spring AI RedisVector Store.

> RAG is a generative model based on retrieval, which combines retrieval and generation to produce more accurate and diverse texts.
> SCA AI: Spring Cloud Alibaba AI, adapting TongYi LLM big model through Spring AI API.
> Spring AI: The Spring AI project aims to simplify the development of applications that include artificial intelligence features and avoid unnecessary complexity.
> Spring AI RedisVector Store: Redis extends the core functionality of Redis OSS to allow Redis to be used as a vector database. Spring AI provides the RedisVector Store adapter.
> Project Code Address: [spring-cloud-ai-rag-example](https://github.com/alibaba/spring-cloud-alibaba/tree/2023.x/spring-cloud-alibaba-examples/ai-example/spring-cloud-ai-rag-example)

## 1. Environmental preparation

Use Docker Compose to deploy a Redis service to store vector data.

```yaml
version: '3.8'

services:
redis:
image: redis/redis-stack-server
container_name: redis
hostname: redis
ports:
- 6379:6379
```

Start with `docker compose up -d`, and then you can `docker ps | grep redis` check to see if the container is running properly.

## 2. Project dependency

> This project introduces `spring-cloud-alibaba-ai-starter` and `spring-ai-redis-spring-boot-starter` realizes RAG application.

You need to introduce the following dependencies in the POM. XML:

```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-ai</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-spring-boot-starter</artifactId>
<version>${spring.ai.version}</version>
</dependency>
```

## 3. Configuration

Configure the following information in the application. Yml:

```yaml
spring:
ai:
vectorstore:
redis:
index: peer
prefix: peer
```

## 4. Write the code

The `loader` classes are as follows:

```java
@Override
public void run(ApplicationArguments args) throws Exception {

Map<String, Object> indexInfo = vectorStore.getJedis().ftInfo(properties.getIndex());
int numDocs = Integer.parseInt((String) indexInfo.getOrDefault("num_docs", "0"));
if (numDocs > 20000) {
logger.info("Embeddings already loaded. Skipping");
return;
}

Resource file = data;
if (Objects.requireNonNull(data.getFilename()).endsWith(".gz")) {
GZIPInputStream inputStream = new GZIPInputStream(data.getInputStream());
file = new InputStreamResource(inputStream, "beers.json.gz");
}

logger.info("Creating Embeddings...");
JsonReader loader = new JsonReader(file, KEYS);
vectorStore.add(loader.get());
logger.info("Embeddings created.");
}
```

The `Service` classes are as follows:

```java
public Generation retrieve(String message) {

SearchRequest request = SearchRequest.query(message).withTopK(topK);
List<Document> docs = store.similaritySearch(request);

Message systemMessage = getSystemMessage(docs);
UserMessage userMessage = new UserMessage(message);

Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
ChatResponse response = client.call(prompt);

return response.getResult();
}

private Message getSystemMessage(List<Document> similarDocuments) {

String documents = similarDocuments.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n"));
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemBeerPrompt);

return systemPromptTemplate.createMessage(Map.of("documents", documents));
}
```

## 5. Run and verify

You can start the SprigBoot main class and then use a browser to access:

```shell
# request params is prompt,the default value:What ber pairs well with smoked meats?"
http://localhost:8080/rag/chat
```

To experience the RAG application.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Spring Cloud Alibaba AI RAG Example

本示例介绍如何使用 SCA AI 和 Spring AI RedisVectorStore 实现 RAG(Retrieval Augmented Generation)应用。

> RAG 是一个基于检索的生成模型,它将检索和生成结合在一起,以生成更加准确和多样化的文本。
> SCA AI: Spring Cloud Alibaba AI, 通过 Spring AI API 适配 TongYi LLM 大模型。
> Spring AI: Spring AI项目旨在简化包含人工智能功能的应用程序的开发,避免不必要的复杂性。
> Spring AI RedisVectorStore: Redis 扩展了 Redis OSS 的核心功能,允许将 Redis 用作矢量数据库,Spring AI 提供了 RedisVectorStore 适配器。
> 项目代码地址:[spring-cloud-ai-rag-example](https://github.com/alibaba/spring-cloud-alibaba/tree/2023.x/spring-cloud-alibaba-examples/ai-example/spring-cloud-ai-rag-example)

## 1. 环境准备

使用 Docker Compose 部署一个 Redis 服务,用于存储向量数据。

```yaml
version: '3.8'

services:
redis:
image: redis/redis-stack-server
container_name: redis
hostname: redis
ports:
- 6379:6379
```

使用 `docker compose up -d` 启动,然后您可以通过 `docker ps | grep redis` 查看容器是否正常运行。

## 2. 项目依赖

> 本项目通过引入 `spring-cloud-alibaba-ai-starter` 和 `spring-ai-redis-spring-boot-starter` 实现 RAG 应用。

您需要在 pom.xml 中引入如下依赖:

```xml
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-ai</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-redis-spring-boot-starter</artifactId>
<version>${spring.ai.version}</version>
</dependency>
```

## 3. 配置

在 application.yml 中配置如下信息:

```yaml
spring:
ai:
vectorstore:
redis:
index: peer
prefix: peer
```

## 4. 编写代码

`loader` 类如下所示:

```java
@Override
public void run(ApplicationArguments args) throws Exception {

Map<String, Object> indexInfo = vectorStore.getJedis().ftInfo(properties.getIndex());
int numDocs = Integer.parseInt((String) indexInfo.getOrDefault("num_docs", "0"));
if (numDocs > 20000) {
logger.info("Embeddings already loaded. Skipping");
return;
}

Resource file = data;
if (Objects.requireNonNull(data.getFilename()).endsWith(".gz")) {
GZIPInputStream inputStream = new GZIPInputStream(data.getInputStream());
file = new InputStreamResource(inputStream, "beers.json.gz");
}

logger.info("Creating Embeddings...");
JsonReader loader = new JsonReader(file, KEYS);
vectorStore.add(loader.get());
logger.info("Embeddings created.");
}
```

`Service` 类如下所示:

```java
public Generation retrieve(String message) {

SearchRequest request = SearchRequest.query(message).withTopK(topK);
List<Document> docs = store.similaritySearch(request);

Message systemMessage = getSystemMessage(docs);
UserMessage userMessage = new UserMessage(message);

Prompt prompt = new Prompt(List.of(systemMessage, userMessage));
ChatResponse response = client.call(prompt);

return response.getResult();
}

private Message getSystemMessage(List<Document> similarDocuments) {

String documents = similarDocuments.stream()
.map(Document::getContent)
.collect(Collectors.joining("\n"));
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemBeerPrompt);

return systemPromptTemplate.createMessage(Map.of("documents", documents));
}
```

## 5. 运行并验证

您可以通过启动 SprigBoot 主类,之后使用浏览器访问:

```shell
# 参数为 prompt,默认值为:What ber pairs well with smoked meats?"
http://localhost:8080/rag/chat
```

来体验 RAG 应用。
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
version: '3.8'

services:
redis:
image: redis/redis-stack-server
container_name: redis
hostname: redis
ports:
- 6379:6379
Loading
Loading