Langchain4j-5-向量数据库
基本概念
- 嵌入模型(向量模型):数据和用户请求通过嵌入模型转换为向量
- 向量数据库:数据向量存储在向量数据库中
- 相似度查询:用户请求也转换为向量,和向量数据库中的向量进行匹配,根据相似度高低返回结果
配置通义向量模型
获取模型
模型名称为:text-embedding-v3
配置模型
和配置聊天模型一致,只不过接口变为 EmbeddingModel
//LLMConfig.java
@Bean
public EmbeddingModel embeddingModel()
{
return OpenAiEmbeddingModel.builder()
.apiKey(System.getenv("ALIQWEN_API"))
.modelName("text-embedding-v3")
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.build();
}
使用模型
文本向量化测试,看看形成向量后的文本。
embeddingModel.embed()
:把数据或用户请求转化为向量
// Controller.java
@GetMapping(value = "/embedding/embed")
public String embed()
{
String prompt = """
咏鸡
鸡鸣破晓光,红冠映朝阳金羽披霞彩,昂首步高岗。
""";
Response<Embedding> embeddingResponse = embeddingModel.embed(prompt);
System.out.println(embeddingResponse);
return embeddingResponse.content().toString();
}
配置 Qdrant 向量数据库
安装 Qdrant
添加依赖:项目 pom.xml
文件中添加:
<!--qdrant-->
<dependency>
<groupId>dev.langchain4j</groupId>
<artifactId>langchain4j-qdrant</artifactId>
</dependency>
Docker 部署 qdrant:docker run -p 6333:6333 -p 6334:6334 qdrant/qdrant
- 6333 端口:前端端口,访问
http://localhost:6333/dashboard#/welcome
即可看到前端界面 - 6334 端口:gRpc 调用端口
配置 Qdrant
// LLMConfig.java
// Qdrant客户端:创建Collection
@Bean
public QdrantClient qdrantClient() {
QdrantGrpcClient.Builder grpcClientBuilder =
QdrantGrpcClient.newBuilder("127.0.0.1", 6334, false);
return new QdrantClient(grpcClientBuilder.build());
}
// Qdrant存储器:连接到具体的Collction
@Bean
public EmbeddingStore<TextSegment> embeddingStore() {
return QdrantEmbeddingStore.builder()
.host("127.0.0.1")
.port(6334)
.collectionName("test-qdrant")
.build();
}
使用 Qdrant
创建 Qdrant Collection(相当于在 Mysql 中创建一个数据库):qdrantClient
// Controller.java
@GetMapping(value = "/embedding/createCollection")
public void createCollection()
{
var vectorParams = Collections.VectorParams.newBuilder()
.setDistance(Collections.Distance.Cosine)
.setSize(1024)
.build();
qdrantClient.createCollectionAsync("test-qdrant", vectorParams);
}
往 Collection 中添加数据:embeddingStore.add
在 Collection 中查询数据:embeddingStore.search
// Controller.java
// 往向量数据库新增文本记录
@GetMapping(value = "/embedding/add")
public String add()
{
String prompt = """
咏鸡
鸡鸣破晓光,红冠映朝阳。金羽披霞彩,昂首步高岗。
""";
TextSegment segment1 = TextSegment.from(prompt);
segment1.metadata().put("author", "zzyy");
Embedding embedding1 = embeddingModel.embed(segment1).content();
String result = embeddingStore.add(embedding1, segment1);
System.out.println(result);
return result;
}
@GetMapping(value = "/embedding/query1")
public void query1(){
Embedding queryEmbedding = embeddingModel.embed("咏鸡说的是什么").content();
EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder()
.queryEmbedding(queryEmbedding)
.maxResults(1)
.build();
EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(embeddingSearchRequest);
System.out.println(searchResult.matches().get(0).embedded().text());
}
测试结果
// Controller.java
@Resource
InMemoryEmbeddingStore<TextSegment> embeddingStore;
@Resource
ChatAssistant chatAssistant;
// http://localhost:9013/rag/add
@GetMapping(value = "/rag/add")
public String testAdd() throws FileNotFoundException
{
//Document document = FileSystemDocumentLoader.loadDocument("/Users/iven/Documents/Research/03 Line/AI开发/Langchain4j-4-Function Call.md");
FileInputStream fileInputStream = new FileInputStream("/Users/iven/Documents/Research/03 Line/AI开发/Langchain4j-4-Function Call.md");
Document document = new ApacheTikaDocumentParser().parse(fileInputStream);
EmbeddingStoreIngestor.ingest(document, embeddingStore);
String result = chatAssistant.chat("文档内容是什么");
System.out.println(result);
return result;
}