LangChain4j实战-嵌入(向量)存储Embedding(Vector)Stores

news/2025/12/1 22:39:13/文章来源:https://www.cnblogs.com/shenStudy/p/19294945

LangChain4j实战-嵌入(向量)存储Embedding(Vector)Stores

向量相关的概念

向量的基本定义

  • 数学定义:
向量是一个有序的数字列表,通常表示为[v1,v2,...,vn],其中每个数字称为分量,对应一个维度。向量既可以看作空间中的点,也可以看作带方向和大小的箭头。
  • 在AI中的意义
在人工智能中,向量常被用来表示复杂的数据,比如图像、文本、声音等。通过将现实世界的对象"向量化",AI模型能够处理和理解这些数据。向量承载了数据的特征和语义信息,是机器学习、深度学习等算法的"通用语言"。

向量在AI中的核心作用

  • 数据表示与特征提取
非结构化数据向量化,文本、图像、音频等原始数据通常是非结构化的,AI模型无法直接处理。通过embedding(嵌入)技术,这些数据被转换为高维稠密向量,每个维度代表一种抽象特征。
eg: 
文本:单词或句子通过Word2Vec、BERT等模型转化为向量,向量间距离表示语义相似性。
图像:通过卷积神经网络(CNN)提取特征,生成表示图像内容的向量。
  • 相似性度量与搜索
向量之间的距离(如欧式距离、余弦相似度)可以用来衡量数据间的相似性。例如,推荐系统中,通过比较用户和商品的向量实现个性化推荐。

向量化的定义

向量化是将非数值数据(如文本、图像、音频等)映射为高维数值向量(即一组有序数字)的过程。这些向量能够捕捉数据的语义、特征或上下文信息,使计算机能够通过数学运算(如相似度计算、聚类、分类等)处理和理解非结构化内容。

向量化与嵌入(Embedding)的关系

"嵌入"(Embedding)是向量化的一种主流技术,通常由深度学习模型生成。嵌入模型经过专门训练,能够高效地将数据映射为低维稠密向量,捕捉复杂的语义关系。"向量嵌入"(Vector Embedding)是一种将单词、句子和其他数据转换成数字的方法,可以捕捉它们的含义和关系。它们将不同的数据类型表示多维空间中的点,其中相似的数据点聚集在一起。这些数值表示帮助机器更有效地理解和处理这些数据。

LangChain4j中嵌入(向量)存储相关的类

Embedding(嵌入)

Embedding类封装了一个表示数值向量,表示嵌入内容的"语义"(通常是文本,比如TextSegment)。

Embedding Model(嵌入模型)

EmbeddingModel接口表示一种特殊类型的模型,它将文本转换为Embedding类。常用的方法:
EmbeddingModel.embed(String)
嵌入给定的文本EmbeddingModel.embed(TextSegment) 
嵌入给定的TextSegmentEmbeddingModel.embedAll(List<TextSegment>)
嵌入给定的所有TextSegmentEmbeddingModel.dimension()
返回该模型产生的Embedding的维度

1

Embedding Store(嵌入存储)

EmbeddingStore接口表示存储Embedding,也称为向量数据库。它允许存储和高效搜索相似的Embedding

当前Embedding支持的嵌入存储可以在官网中找到:

https://docs.langchain4j.dev/integrations/embedding-stores/

EmbeddingStore可以单独存储Embeddding或者与相应的TextSegment一起存储:

  • 只能按ID存储Embedding。原始嵌入数据可以存储在其他地方,并使用ID进行关联。
  • 既可以存储Embedding,也可以存储已嵌入的原始数据(通常为TextSegment)。

Embedding Store的常用方法

2

EmbeddingStore.add(Embedding)
将给定的Embedding添加到存储并返回一个随机IDEmbeddingStore.add(String id,Embedding)
将指定ID的Embedding添加到存储中EmbeddingStore.add(Embedding, TextSegment)
将给定的Embedding与关联的TextSegment添加到存储并返回一个随机IDEmbeddingStore.addAll(List<Embedding>)
向存储中添加一个给定Embedding的列表,并返回一个随机ID列表EmbeddingStore.addAll(List<Embedding>, List<TextSegment>)
将给定的Embedding与关联的TextSegment的列表添加到存储中,并返回一个随机id列表EmbeddingStore.addAll(List<String> ids, List<Embedding>, List<TextSegment>)
将给定的Embedding与关联id和TextSegment的列表添加到存储中EmbeddingStore.search(EmbeddingSearchRequest)
查找最相似的EmbeddingEmbeddingStore.remove(String id)
按ID从存储中删除单个EmbeddingEmbeddingStore.removeAll(Collection<String> ids)
从存储中删除id存在于给定集合中的所有EmbeddingEmbeddingStore.removeAll(Filter)
从存储中删除所有与指定的Filter匹配的EmbeddingEmbeddingStore.removeAll()
从存储中删除所有的Embedding

EmbeddingSearchRequest类

EmbeddingSearchRequest表示在EmbeddingStore中搜索的请求。它具有以下属性:

  • Embedding queryEmbedding:作为引用的Embedding。
  • int maxResults:返回结果的最大数目。可选的参数,默认值为3
  • double minScore:最小得分,取值范围0-1(含1)。只有分数>=minScore的Embedding才会被返回。这是一个可选参数。默认值为0
  • Filter filter:搜索时应用与Metadata的过滤器。只有TextSegment的Metadata匹配Filter的才会返回。

Filter类

Filter允许在执行矢量搜索时按Metadata项进行过滤。目前支持的Filter类型/操作如下:

  • IsEqualTo
  • IsNotEqualTo
  • IsGreaterThan
  • IsGreaterThanOrEqualTo
  • IsLessThan
  • IsLessThanOrEqualTo
  • IsIn
  • IsNotIn
  • ContainsString
  • And
  • Not
  • Or

EmbeddingSearchResult类

EmbeddingSearchResult表示在EmbeddingStore中的搜索结果。它包含EmbeddingMatch的列表。

EmbeddingMatch类

EmbeddingMatch表示匹配的Embedding及其关联评分、ID和原始嵌入数据

向量数据库-Qdrant

Qdrant是什么

Qdrant是一个向量相似度搜索引擎,它提供了一个生产就绪的服务,并配备了便捷的API,用于存储、搜索和管理带有附加有效载荷的点(即向量)。你可以将有效负载视为额外的信息片段,这些信息可以帮助你精确搜索,同时也能获取到可以提供给用户的有用信息。

什么是向量数据库

3

向量数据库是一种旨在高效存储和查询高纬度向量的数据。在传统的OLTP和OLAP数据库中,数据以行和列的形式组织(并称为表),查询则根据这些列中的值进行。然后,在图像识别、自然语言处理和推荐系统等特定应用中,数据通常被表示为高维空间的向量,而这些向量,加上一个id和一个playload,我们称之为"点"。这些"点"正式我们存储在Qdrant这类向量数据库的"集合"中的元素。在此语境下,向量是对象或数据点的一种数字表示,其向量中的元素会隐式或显式地对应于该对象的特定特征或属性。例如,在图像识别系统中,一个向量可以代表一张图片,其中向量的每个元素代表一个像素值或该像素的描述符/特征。在音乐推荐系统中,每个向量可以代表一首歌,而向量的元素则捕捉了歌曲的特征,如节奏、流派、歌词等等。

Qdrant架构的高级概念

4

上面的图片显示了Qdrant的一些主要组件的高层次概念,以下是你应该熟悉的一些术语。

  • Collections(集合):
集合是一个命名的点(带有有效载荷的向量)集合,你可以在其中进行搜索。在同一个集合中,每个点的向量必须具有相同的维度,并通过单一的度量标准进行比较。命名向量可以用于在单个点中包含多个向量,其中每个向量都可以有自己的维度和度量要求。
  • Distance Metrics(距离度量):
这些度量标准用于衡量向量之间的相似度,并且必须在创建集合时进行选择。度量标准的选择取决于向量的获取方式,尤其取决于将用于编码新查询的神经网络。
  • Points(点):点是Qdrant操作的核心实体,它由一个向量(vector)和一个可选的id和payload组成。
    • id:向量的唯一标识符。
    • Vector(向量):数据的高维表示,例如图像、声音、文档、视频等。
    • Payload(有效载荷):有效载荷是一个JSON对象,你可以将其附加数据添加到向量中。
  • Storage(c存储):
Qdrant提供两种存储选项:一种是内存存储,它将所有向量保存在RAM中,仅在持久化时才访问磁盘,因为速度最快;另一种是内存映射存储,它会创建一个与磁盘文件相关联的虚拟地址空间。
  • Clients(客户端):
可以用来连接到Qdrant的编程语言

快速本地使用Qdrant

使用docker下载并运行Qdrant

从Dockerhub下载最新的Qdrant镜像

docker pull qdrant/qdrant

直接运行服务

docker run -p 6333:6333 -p 6334:6334 \-v "$(pwd)/qdrant_storage:/qdrant/storage:z" \qdrant/qdrant

运行之后,默认配置下,所有数据将存储在./qdrant_storage目录下。

  • REST API: localhost:6333
  • Web UI: localhost:6333/dashboard
  • GRPC API: localhost:6334

使用Embedding模型向量化存储到向量数据库并进行相似性搜索的示例

bom物料清单

    <properties><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>21</java.version><!--Spring Boot--><spring-boot.version>3.5.3</spring-boot.version><!--LangChain4J--><langchain4j.version>1.7.1</langchain4j.version><!--LangChain4J community--><langchain4j-community.version>1.7.1-beta14</langchain4j-community.version></properties><!--    <dependencyManagement> 是一个声明和集中管理依赖版本和配置的机制(物料清单)。它本身并不引入实际的依赖,而是为依赖提供一个“模板”或“蓝图”--><dependencyManagement><dependencies><!--Spring Boot--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><!--LangChain4J--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-bom</artifactId><version>${langchain4j.version}</version><type>pom</type><scope>import</scope></dependency><!--langchain4j-community--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-community-bom</artifactId><version>${langchain4j-community.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>

pom依赖

    <dependencies><!--快速构建一个基于 Spring MVC 的 Web 应用程序而预置的一组依赖项的集合--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--一个通过注解在编译时自动生成 Java 样板代码的库--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--LangChain4J openAI集成依赖(低级API依赖)--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId></dependency><!--LangChain4J 高级AI服务API依赖--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j</artifactId></dependency><!--LangChain4J 响应式编程依赖(AI服务使用Flux)--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-reactor</artifactId></dependency><!--hutool Java工具库--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.40</version></dependency><!--langchain4j 依赖qdrant向量数据库的依赖--><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-qdrant</artifactId></dependency></dependencies>

大模型配置类

@Configuration
public class LLMConfig {/*** 嵌入(向量化)模型** @return 嵌入模型*/@Beanpublic EmbeddingModel embeddingModel() {return OpenAiEmbeddingModel.builder().apiKey(System.getenv("aliyunQwen-apiKey")).modelName("text-embedding-v4").baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1").build();}/*** qdrant客户端** @return qdrant客户端*/@Beanpublic QdrantClient qdrantClient() {QdrantGrpcClient.Builder clientBuilder = QdrantGrpcClient.newBuilder("127.0.0.1", 6334, false);return new QdrantClient(clientBuilder.build());}/*** 向量数据库** @return 向量数据库*/@Beanpublic EmbeddingStore<TextSegment> embeddingStore() {return QdrantEmbeddingStore.builder().host("127.0.0.1").port(6334).collectionName("test-qdrant").build();}
}

大模型控制层接口

@Slf4j
@RestController
@RequestMapping("/embedding")
public class ChatEmbeddingController {//在Java 15中,文本块现在是官方的,可以使用。public static final String POETRY = """定风波·莫听穿林打叶声(宋)苏轼三月七日,沙湖道中遇雨。雨具先去,同行皆狼狈,余独不觉。已而遂晴,故作此词。莫听穿林打叶声,何妨吟啸且徐行。竹杖芒鞋轻胜马,谁怕?一蓑烟雨任平生。料峭春风吹酒醒,微冷,山头斜照却相迎。回首向来萧瑟处,归去,也无风雨也无晴。""";@Autowiredprivate EmbeddingModel embeddingModel;@Autowiredprivate QdrantClient qdrantClient;@Autowiredprivate EmbeddingStore<TextSegment> embeddingStore;/*** 通过文本向量化模型进行文本向量化** @return 向量化文本*/@GetMapping("/textEmbedding")public String textEmbedding() {Response<Embedding> embeddingResponse = embeddingModel.embed(POETRY);log.info("embeddingResponse: {}", embeddingResponse);return embeddingResponse.content().toString();}/*** 新建向量数据库实例和创建索引*/@GetMapping("/createCollection")public void createCollection() {var vectorParmas = Collections.VectorParams.newBuilder().setDistance(Collections.Distance.Cosine).setSize(1024).build();qdrantClient.createCollectionAsync("test-qdrant", vectorParmas);}/*** 嵌入存储** @return 存储结果*/@GetMapping("/add")public String add() {TextSegment textSegment = TextSegment.from(POETRY);textSegment.metadata().put("author", "苏轼");Embedding embedding = embeddingModel.embed(textSegment).content();String result = embeddingStore.add(embedding, textSegment);log.info("embedding add result: {}", result);return result;}/*** 查找最相似的Embedding** @return 最相似的Embedding*/@GetMapping("queryOne")public String queryOne() {Embedding queryEmbedding = embeddingModel.embed("莫听穿林打叶声").content();EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder().queryEmbedding(queryEmbedding).maxResults(1).build();EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(embeddingSearchRequest);List<EmbeddingMatch<TextSegment>> matchList = searchResult.matches();if (CollUtil.isEmpty(matchList)) {return "未找到相似的Embedding";}String resultText = searchResult.matches().getFirst().embedded().text();log.info("searchResult: {}", resultText);return resultText;}/*** 查找最相似的Embedding(带过滤器Filter)** @return 最相似的Embedding*/@GetMapping("queryTwo")public String queryTwo() {Embedding queryEmbedding = embeddingModel.embed("莫听穿林打叶声").content();EmbeddingSearchRequest embeddingSearchRequest = EmbeddingSearchRequest.builder().queryEmbedding(queryEmbedding).filter(new IsEqualTo("author", "王维")).maxResults(1).build();EmbeddingSearchResult<TextSegment> searchResult = embeddingStore.search(embeddingSearchRequest);List<EmbeddingMatch<TextSegment>> matchList = searchResult.matches();if (CollUtil.isEmpty(matchList)) {return "未找到相似的Embedding";}String resultText = searchResult.matches().getFirst().embedded().text();log.info("searchResult: {}", resultText);return resultText;}
}

参考资料

https://www.elastic.co/what-is/vector-embedding

https://docs.langchain4j.dev/tutorials/embedding-stores

https://docs.langchain4j.dev/tutorials/rag/#embedding-store

https://qdrant.tech/documentation/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/983496.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

12.1每日总结

今天的主要课程有案例分析、软件设计、大数据、物联网,案例分析课上提前做了期末考试的题型,软件设计和大数据的实验也在继续完善,加油

Java/PHP源码解析:一站式上门维修服务系统的全栈完成

Java/PHP源码解析:一站式上门维修服务系统的全栈完成pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&qu…

实用指南:在智能制造语境下理解ISA-95、IIoT和UNS

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

251201本年进入最后一个月

今天找到一点学习的感觉,就是要专注投入,由此可见,专注力是很珍贵的。

20251201

接下来一个月得自己实操springweb,不能一直用ai辅助了

12月1号

今天进行了统一建模和数据结构的学习。 然后进行了java的练习。

AI浏览器Dia的华丽转身:从安全漏洞到垂直标签的回归

本文作者分享了其对The Browser Company旗下浏览器Arc与Dia的使用体验。文章详述了Dia早期版本过度依赖AI功能带来的安全风险(如提示注入攻击),以及后续更新如何回归Arc的成功核心:垂直标签栏、键盘快捷操作等提升…

2025-12-01

CF Problem - 1455D - Codeforces 贪心,从小到大遍历 因为a[i]>x才能交换 所以把大的换小,使其满足单调不递减 #include <bits/stdc++.h> using namespace std; #define LL long long const LL mod = 99824…

PyTorch入门:一步步训练你的首个深度学习模型

本文是一份详尽的PyTorch入门实践教程,指导读者如何使用PyTorch框架构建并训练一个多层感知机(MLP)模型。内容涵盖环境配置、数据加载与预处理、模型定义、训练与验证循环编写等核心步骤,并通过CIFAR10图像分类任务…

2025最新锂电池品牌/电动车锂电池厂家推荐!电动车储能电池生产厂家权威榜单,恒续能源等TOP5企业实力解析

引言 后疫情时代新能源产业迎来爆发式增长,锂电池作为核心动力源,行业竞争呈现技术迭代加速、产品差异化加剧的新格局。据中国化学与物理电源行业协会数据,2024年全球动力电池装机量达652GWh,同比增长37%,储能电池…

2025最新锂电池品牌推荐!电动车与储能电池优质厂家权威榜单发布,技术实力铸就行业标杆

随着新能源产业的蓬勃发展,锂电池作为核心能源载体,其性能与品质直接决定下游应用的竞争力。本榜单基于技术创新、生产规模、客户口碑三大维度,结合行业权威数据与市场反馈,为您解析2025年五大锂电池品牌综合实力,…

深入解析:【SpringBoot】32 核心功能 - 单元测试 - JUnit5 单元测试中的嵌套测试与参数化测试详解

深入解析:【SpringBoot】32 核心功能 - 单元测试 - JUnit5 单元测试中的嵌套测试与参数化测试详解2025-12-01 22:16 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !…

MYSQL - explain

MYSQL - explain 准备数据 drop table orders; drop table products; drop table users;CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, passwor…

【UEFI基础】Protocol介绍

简要说明 Protocol是UEFI中的一个重要概念(事实上《UEFI SPEC》中有超过70%的内容都是在讲Protocol),下面简单说明下:首先,非常重要的一点,Protocol不是什么特殊的东西,它就是一个结构体,比如说下面是一个用于…

清障车口碑排行:2025年最受推荐品牌TOP5,清障车/二手清障车蓝牌/重载清障车/清障车带吊/清障车企业找哪家

行业权威榜单揭晓,五大品牌引领清障车市场新格局 随着我国道路交通网络的不断完善和汽车保有量的持续增长,清障车作为道路救援领域的重要装备,其市场需求呈现出稳步上升态势。本文基于市场调研数据、用户反馈及产品…

2025年目前评价高的智能货架厂家口碑推荐,钢制货架/重载货架/仓库货架/模具架/精益管料架/背网货架/智能货架厂家榜单推荐

智能仓储升级浪潮下的优质供应商盘点 随着智能制造与物流自动化需求的持续增长,智能货架作为仓储系统的核心装备,其市场关注度显著提升。本文基于企业规模、技术实力、客户案例及市场反馈等多维度数据,对当前国内智…

Flink - PyFlink

Flink - PyFlinkI have installed Apache Flink and run start-cluster.sh. How to use it with PyFlink? ChatGPT said:Perfect! Since you already have Apache Flink installed and the cluster is running, you c…

2025年GEO公司推荐榜单,GEO服务/GEO优化AI搜索/GEO优化AI工具排名/GEO老牌厂家排行

行业洞察与榜单背景 随着人工智能技术的快速发展,GEO优化服务正成为企业品牌传播的重要战略方向。据行业数据显示,2024年已有超过65%的企业将AI内容优化纳入营销预算,预计2025年这一比例将提升至80%。本文基于市场调…

STM32F103直流有刷电机速度闭环控制

在《基于直流有刷电机的速度闭环控制以及matlab仿真》我们介绍了速度闭环控制的实现,其采用的是PID控制算法,本节我们就基于STM32F103来实现直流电机的增量式PID速度闭环控制。 一、软件实现 我们需要将PID控制器应用…

英语_阅读_City Park Facilities Survey_待读

City Park Facilities Survey 城市公园设施调查 The City Park is a popular place for residents to enjoy outdoor activities. 城市公园是居民们享受户外活动的热门场所。 The park management conducted a survey …