RAG概念和使用
- [1. 什么是向量、文本向量化、向量相似度](#1. 什么是向量、文本向量化、向量相似度)
- [2. 什么是向量模型、向量数据库](#2. 什么是向量模型、向量数据库)
- [3. Spring AI整合ES作为向量数据库](#3. Spring AI整合ES作为向量数据库)
-
- 3.1.Docker安装ES
- [3.2.Spring AI整合ES作为向量数据库](#3.2.Spring AI整合ES作为向量数据库)
- 3.3.ES常用API
- [4. Spring AI利用text-embedding-v3进行文本向量化](#4. Spring AI利用text-embedding-v3进行文本向量化)
- [5. Spring AI之文本相似度查询和元数据查询](#5. Spring AI之文本相似度查询和元数据查询)
- [6. 什么是RAG检索增强生成?](#6. 什么是RAG检索增强生成?)
1. 什么是向量、文本向量化、向量相似度
向量: 向量在数据中就是就是一个空间坐标,在编程领域,一个二维向量就是一个大小为二的float类型的数组。
文本向量化: 所谓文本向量化是指,利用大模型可以把一个字、一个词或一段话映射为一个多维向量。
向量相似度: 向量相当于就是坐标点,如果两个坐标点靠得近,那么就表示这两个向量相似,所以,如果两句话对应的向量相似,那么就表示这两句话语义比较相似,当然这中间最关键的就是向量模型,因为向量是它生成的,向量模型也是经过大量机器学习训练之后产生的,向量模型效果越好,就表示它对于自然语言理解的程度越好,同时也就表示它生成出来的向量越准备,越能反映出语义的相似度
2. 什么是向量模型、向量数据库
向量模型: 具有将一个对象映射为多维向量这种功能的大模型就是向量模型
向量数据库: 而生成的多维向量需要存储,而这种数据库就叫做向量数据库
3. Spring AI整合ES作为向量数据库
3.1.Docker安装ES
bash
#拉取
docker pull elasticsearch:8.17.3
#启动
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e "ELASTIC_PASSWORD=123456" -e "xpack.security.http.ssl.enabled=false" docker.1ms.run/elasticsearch:8.17.3
然后浏览器访问:http://localhost:9200/ (主要一定得是http,不能是https,要支持https得单独有证书)
用户名/密码为:elastic/123456
3.2.Spring AI整合ES作为向量数据库
先添加starter
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-elasticsearch-store-spring-boot-starter</artifactId>
</dependency>
如果用的Spring Boot是3.3.0之前的版本,还需要新增以下依赖:
xml
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.13.3</version>
</dependency>
然后配置es的url和用户名密码:
yaml
spring:
elasticsearch:
uris: 127.0.0.1:9200
username: elastic
password: 123456
然后配置文本向量化模型:
yaml
spring:
elasticsearch:
uris: 127.0.0.1:9200
username: elastic
password: 123456
ai:
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: ${API_KEY}
chat:
options:
model: qwen-plus
embedding:
options:
model: text-embedding-v3
千问模型列表https://help.aliyun.com/zh/model-studio/getting-started/models
因为DeepSeek暂时没有提供出文本向量化模型,所以我们用阿里提供的文本向量化模型:text-embedding-v3,同时聊天模型也用千问的:qwen-plus。
配置vectorstore,text-embedding-v3负责生成向量数据,es负责存储向量数据,而vectorstore就是两者的桥梁,负责创建index,负责调用向量模型生成向量数据,负责存到es中:
yaml
spring:
elasticsearch:
uris: 127.0.0.1:9200
username: elastic
password: 123456
ai:
openai:
base-url: https://dashscope.aliyuncs.com/compatible-mode
api-key: ${API_KEY}
chat:
options:
model: qwen-plus
embedding:
options:
model: text-embedding-v3
vectorstore:
elasticsearch:
initialize-schema: true
index-name: spring-ai-demo-index
dimensions: 1024
similarity: cosine
3.3.ES常用API
bash
# 查看所有索引
curl -X GET "http://localhost:9200/_cat/indices?v"
# 删除指定索引
curl -u elastic:123456 -X DELETE "http://localhost:9200/spring-ai-demo-index"
# 查看索引数据
curl -X GET "http://localhost:9200/spring-ai-demo-index/_search?pretty"
4. Spring AI利用text-embedding-v3进行文本向量化
java
import org.springframework.ai.document.Document;
import org.springframework.ai.reader.TextReader;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class DocumentService {
@Value("classpath:三味书屋.txt")
private Resource resource;
@jakarta.annotation.Resource
private VectorStore vectorStore;
public List<Document> loadText() {
TextReader textReader = new TextReader(resource);
List<Document> documents = textReader.get();
MyTextSplitter textSplitter = new MyTextSplitter();
List<Document> list = textSplitter.apply(documents);
for (Document document : list) {
document.getMetadata().put("author", "zhoushuren");
document.getMetadata().put("article_type", "blog");
}
vectorStore.add(list);
return list;
}
public List<Document> search(String message){
SearchRequest searchRequest = SearchRequest
.builder()
.query(message)
.topK(1)
.similarityThreshold(0.1)
.filterExpression("author in ['zhoushuren', 'luxun'] && 'article_type' == 'blog'")
.build();
return vectorStore.similaritySearch(searchRequest);
}
}
java
@Autowired
private DocumentService documentService;
java
@GetMapping("/documentEmbedding")
public List<Document> documentEmbedding() {
return documentService.loadText();
}
5. Spring AI之文本相似度查询和元数据查询
java
@GetMapping("/documentSearch")
public List<Document> documentSearch(@RequestParam String message) {
return documentService.search(message);
}
java
public List<Document> search(String message){
SearchRequest searchRequest = SearchRequest
.builder()
.query(message)
.topK(1)
.similarityThreshold(0.1)
.filterExpression("author in ['luxun', 'jill'] && 'article_type' == 'blog'")
.build();
return vectorStore.similaritySearch(searchRequest);
}
6. 什么是RAG检索增强生成?
java
@GetMapping("/ragChat")
public String ragChat(@RequestParam String message) {
// 向量搜索
List<Document> documentList = documentService.search(message);
// 提示词模板
PromptTemplate promptTemplate = new PromptTemplate("{userMessage}\n\n 用以下信息回答问题:\n {contents}");
// 组装提示词
Prompt prompt = promptTemplate.create(Map.of("userMessage", message, "contents", documentList));
// 调用大模型
return chatClient.prompt(prompt).call().content();
}