基于Es和智普AI实现的语义检索
1、什么是语义检索
语义检索是一种利用自然语言处理(NLP)和人工智能(AI)技术来理解搜索查询的语义,以提供更准确和相关搜索结果的搜索技术,语义检索是一项突破性的技术,旨在通过深入理解单词和短语的含义及上下文来提供更为准确的搜索结果。与传统的基于关键词的搜索不同,语义检索侧重于查询的意图和语境,而不仅仅是关键词的直接匹配。这种搜索方式可以显著提高搜索结果的准确性和相关性,尤其适用于复杂查询和模糊不清的搜索需求
上面是比较"官方"的解释,举个例子来简单说明一下吧:
比如现在有一条数据,叫诸葛亮,输入关键字孔明,传统的查询(关系型数据)和搜索引擎(Elasticsearch)是查不出来诸葛亮这条数据的,因为这二者都是通过关键字来匹配的,但是语义检索能够查出来,这就是语义检索最大的亮点
2、语义检索能做什么
除了上面提到的文字检索,还可以实现基于文档内容(本质还是文字检索)、图片、和视频内容的检索
3、语义检索的实现思路
Elasticsearch在7.X版本开始支持knn查询,也就是近似查询(也叫向量查询),关于knn的深入理解就不在这里过多的赘述了,其底层原理我也不是很懂,整体的思路如下图:

其中图片和视频的转换为向量的时候有两种方式,一种是直接将图片和视频转换为向量,这种相对较复杂,第二种是通过把图片和视频交给大模型,让其理解其中的内容,并将内容提取出来转换为文字,然后将文字再转换为向量存入es
4、操作实践
准备工作:
Elasticsearch 8.12.0
智普AI向量转换:智谱AI开放平台(embedding-3)
1、建立Es索引mapping,其中几个关键的属性字段:
dims:向量的纬度数,本质就是一个float类型的数组,我自己测试的结果是1024效果比较好,一般这个值有738,1024,2048,具体要看模型支持多少唯独
type:int8_hnsw,这个是es8.8才提供的特性
{"my_embedding": {"mappings": {"dynamic": "strict","properties": {"department": {"type": "text","fields": {"keyword": {"type": "keyword"}},"analyzer": "my_analyzer"},"embedding": {"type": "dense_vector","dims": 1024,"index": true,"similarity": "l2_norm","index_options": {"type": "int8_hnsw","m": 16,"ef_construction": 100}}}}}
}
2、通过智普AI生成向量数据写入Elasticsearch:Authorization填写自己申请的智普的授权码
@Testpublic void vectorWriteV1() throws Exception {
// List<String> text = Stream.of("刘玄德", "桃园三结义", "刘备", "毛岸英", "毛泽东思想", "新中国", "江青", "杨开慧", "毛润之", "三国", "武当山", "二万五千里长征", "太极拳").collect(Collectors.toList());List<String> text = Stream.of(
// "武当山不仅是中国道教文化的圣地,也是自然与人文景观的完美融合之地。游客在这里可以体验丰富的历史文化和壮丽的自然风光",
// "庐山集自然美景与深厚文化底蕴于一体,无论是自然景观的雄奇险秀,还是人文景观的丰富多彩,基本都使其成为不可多得的旅游胜地。对于想要探访庐山的游客来说,春夏秋三季是最佳游览时节。"
// "西安事变是**由张学良和杨虎城于1936年12月12日为劝谏蒋介石改变“攘外必先安内”的国策、停止内战一致抗日而发动的兵谏,又称双十二事变**。这次事变对我国近现代史产生了深远的影响,不仅因为其直接参与者的身份特殊,更因为它标志着国内战争向抗日战争转折的重大历史节点"
// "大势智慧科技有限公司凭借其在实景三维数字化重建及三维数据服务的深厚技术积累和丰富的实践经验,已经成为该领域的领导者。面对未来的机遇与挑战,大势智慧有望继续发挥其在技术创新和行业应用方面的优势,为不同行业提供更多高质量的三维数字化解决方案,推动相关领域的技术进步和产业升级""关羽", "张飞").collect(Collectors.toList());String url = "https://open.bigmodel.cn/api/paas/v4/embeddings";Map<String, String> header = new HashMap<>();header.put("Content-Type", "application/json");header.put("Authorization", "");for (String s : text) {List<Float> embeddings = new LinkedList<>();EmbeddingParams embeddingParams = CommonBuilder.of(EmbeddingParams.class).with(EmbeddingParams::setInput, ListBuilder.<String>ofList().add(s).build()).build();String result = HttpRequestUtil.doPost(url, header, JSON.toJSONString(embeddingParams));JSONObject jsonObject = JSON.parseObject(result);JSONArray jsonArray = jsonObject.getJSONArray("data");JSONObject embeddingObj = (JSONObject) jsonArray.get(0);JSONArray embedding = embeddingObj.getJSONArray("embedding");for (Object o : embedding) {embeddings.add(((BigDecimal) o).floatValue());}MyVector myVector = CommonBuilder.of(MyVector.class).with(MyVector::setDepartment, s).with(MyVector::setEmbedding, embeddings).build();esClientUtil.writeData(myVector, IdUtil.getSnowflakeNextId() + "", "my_embedding");}}
3、测试验证knn检索:
@Testpublic void vectorSearchV1() throws Exception {
// List<String> text = Stream.of("刘备", "关羽", "毛泽东思想", "毛泽东", "林彪", "周恩来", "张三丰", "十堰").collect(Collectors.toList());
// List<String> text = Stream.of("西安", "十堰", "江西", "张学良", "蒋介石", "杨虎城", "黄先锋").collect(Collectors.toList());List<String> text = Stream.of("桃园三结义", "十堰", "江西", "张学良", "蒋介石", "大势智慧", "黄先锋").collect(Collectors.toList());String url = "https://open.bigmodel.cn/api/paas/v4/embeddings";Map<String, String> header = new HashMap<>();header.put("Content-Type", "application/json");header.put("Authorization", "");for (String s : text) {List<Float> embeddings = new LinkedList<>();EmbeddingParams embeddingParams = CommonBuilder.of(EmbeddingParams.class).with(EmbeddingParams::setInput, ListBuilder.<String>ofList().add(s).build()).build();String result = HttpRequestUtil.doPost(url, header, JSON.toJSONString(embeddingParams));JSONObject jsonObject = JSON.parseObject(result);JSONArray jsonArray = jsonObject.getJSONArray("data");JSONObject embeddingObj = (JSONObject) jsonArray.get(0);JSONArray embedding = embeddingObj.getJSONArray("embedding");for (Object o : embedding) {embeddings.add(((BigDecimal) o).floatValue());}// 设置查询向量KnnQuery.Builder builder = new KnnQuery.Builder();builder.field("embedding").numCandidates(100).k(10)
// .similarity(0.3f).queryVector(embeddings);// 创建搜索请求SearchRequest searchRequest = new SearchRequest.Builder().index("my_embedding").knn(builder.build()).size(10).build();// 执行搜索请求SearchResponse<Product> searchResponse = es8ClientUtil.searchData(searchRequest, "my_embedding", Product.class);StringJoiner stringJoiner = new StringJoiner("\t");StringJoiner score = new StringJoiner("\t");for (Hit<Product> hit : searchResponse.hits().hits()) {stringJoiner.add(hit.source().getDepartment());score.add(hit.score() + "");}System.err.println(s + "===检索结果===:");System.err.println(stringJoiner);System.err.println(score);System.err.println();}}

其中用到的HttpRequestUtil是我自己基于apachehttpclient封装的工具类:基于ApacheHttpclient封装的请求工具类(记笔记)_java apache请求工具类-CSDN博客
PS:经过几轮测试下来,得出以下结论:
1、knn检索确实可以实现语义检索,弥补传统的关键字检索的不足,二者结合可以实现更加智能的检索
2、knn检索的"准确性"问题,比如我在测试的时候输入林彪,也能查询到诸葛亮这条数据,在我们的认知里面,这两个人是八竿子打不着的, 但是在经过模型转换之后,他们之间可能确实存在一些相似性,比如都是历史名人,这个"偏差"很依赖于模型的理解和转换能力
3、我测试过智普、阿里云、百度千帆和百川智能四个模型,总体上智普的效果比较好
相关文章:
基于Es和智普AI实现的语义检索
1、什么是语义检索 语义检索是一种利用自然语言处理(NLP)和人工智能(AI)技术来理解搜索查询的语义,以提供更准确和相关搜索结果的搜索技术,语义检索是一项突破性的技术,旨在通过深入理解单词和…...
URI和URL的区别
1: 将 URI 转换为 URL import java.net.URI; import java.net.URL;public class UriToUrlExample {public static void main(String[] args) {// 创建一个 URI 对象URI uri = new URI("http://example.com/path/to/resource");// 将 URI 转换为 URLtry {URL url = u…...
Java 入门指南:获取对象的内存地址
文章目录 hashCode()应用重写 hashCode() 方法示例 Symstem . indentityHashCode()应用 注意事项 在 Java 开发中,了解对象的内存管理是十分重要的,尽管 Java 的设计初衷是让开发者更专注于业务逻辑而非底层资源管理。但在某些情况下,了解对象…...
【Linux】项目自动化构建工具-make/Makefile 详解
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...
嵌入式开发中学习C++的用处?
这个问题一直有同学在问,其实从我的角度是一定是需要学的,最直接的就是你面试大厂的嵌入式岗位或者相关岗位,最后一定会问c,而很多人是不会的,这就是最大的用处,至于从技术角度考量倒是其次,因为…...
基于SAM大模型的遥感影像分割工具,用于创建交互式标注、识别地物的能力,可利用Flask进行封装作为Web后台服务
如有帮助,支持一下(GitHub - Lvbta/ImageSegmentationTool-SAM: An interactive annotation case developed based on SAM for remote sensing image annotation, which can generate corresponding segmentation results based on point, multi-point, …...
Selenium入门
Selenium 是一个用于自动化 web 应用程序测试的工具,它支持多种浏览器和编程语言。 下载驱动程序:根据你的浏览器类型和版本,下载相应的 WebDriver。例如,Chrome 浏览器需要 ChromeDriver。 安装 Selenium 库 pip install sele…...
USB 3.1 Micro-A 与 Micro-B 插头,Micro-AB 与 Micro-B 插座,及其引脚定义
连接器配对 下表列出 USB 插座可接受的插头: USB 3.1 Micro-B 连接器 USB 3.1 Micro-B 插头和 USB 3.1 Micro-B 插座连接器是为小型手持设备和其他可能使用小尺寸连接器的应用而定义的。其定义使得 USB 3.1 Micro-B 插座既可以接受 USB 3.1 Micro-B 插头ÿ…...
MySQL多版本并发控制MVCC实现原理
MVCC MVCC 是多版本并发控制方法,用来解决读和写之间的冲突,比如脏读、不可重复读问题,MVCC主要针对读操作做限制,保证每次读取到的数据都是本次读取之前的已经提交事务所修改的。 概述 当一个事务要对数据库中的数据进行selec…...
【并查集】[ABC372E] K-th Largest Connected Components 题解
题意 前置阅读:并查集算法介绍 洛谷链接 Atcoder 链接 给定 n ( 1 ≤ n ≤ 2 1 0 5 ) n(1 \leq n \leq 2\times 10^5) n(1≤n≤2105) 个点,初始没有边,您要进行以下操作: 1 a b,表示连接一条 ( a , b ) (a,b) …...
HarmonyOS面试题(持续更新中)
1、用过线程通信吗,线程是怎么进行通信的? emitter 和 eventHub 相同: 都是基于事件总线的 区别是: ① eventHub当前线程内通信 ② emitter是同一进程不同线程或者同一进程和同一线程也可以通信 2、页面和组件的生命周期 …...
QT中QWidget和QObject的区别与联系是什么
在Qt框架中,QWidget和QObject是两个核心类,它们各自扮演着不同的角色,但又紧密相连。以下是关于它们区别与联系的详细解释: 区别 基类和功能定位: QObject是Qt中所有类的基类,包括几乎所有的Qt对象。它提供…...
解决macOS安装redis以后不支持远程链接的问题
参考文档:https://blog.csdn.net/qq_37703224/article/details/142542179?spm1001.2014.3001.5501 安装的时候有个提示, 使用指定配置启动: /opt/homebrew/opt/redis/bin/redis-server /opt/homebrew/etc/redis.conf那么我们可以尝试修改这个配置文件: code /opt/homebrew/…...
2024年研究生数学建模“华为杯”E题——肘部法则、k-means聚类、目标检测(python)、ARIMA、逻辑回归、混淆矩阵(附:目标检测代码)
文章目录 一、情况介绍二、思路情况二、代码展示三、感受 一、情况介绍 前几天也是参加了研究生数学建模竞赛(也就是华为杯),也是和本校的两个数学学院的朋友在网上组的队伍。昨天(9.25)通宵干完论文(一条…...
绝了,自从用了它,我每天能多摸鱼2小时!
大家好,我是可乐。 俗话说的好:“摸鱼一时爽,一直摸鱼一直爽”。 作为一个程序员,是否有过调试代码熬到深夜?是否有过找不到解决方案而挠秃头顶? 但现在你即将要解放了,用了这款工具——秘塔…...
C语言指针系列1——初识指针
祛魅:其实指针这块儿并不难,有人说难只是因为基础到进阶没有处理好,大家要好好跟着一步一步学习,今天我们先来认识一下指针 指针定义:指针就是内存地址,指针变量是用来存放内存地址的变量,在同一…...
传神论文中心|第26期人工智能领域论文推荐
在人工智能领域的快速发展中,我们不断看到令人振奋的技术进步和创新。近期,开放传神(OpenCSG)传神社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自…...
NLP基础1
NLP基础1 深度学习中的NLP的特征输入 1.稠密编码(特征嵌入) 稠密编码(Dense Encoding):指将离散或者高纬的稀疏数据转化为低纬度的连续、密集向量表示 特征嵌入(Feature Embedding) 也称…...
001.docker30分钟速通版
docker简介 docker就是一个用于构建(build),运行(run),传送(share)应用程序的平台做一个不恰当的类比,就是外卖平台,如果你自己做华莱士不一定好吃࿰…...
Kafka 在 Linux 下的集群配置和安装
Kafka 在 Linux 下的集群配置和安装 Apache Kafka 是一个流行的分布式流处理平台,广泛用于实时数据管道和流处理应用。本文将详细讲解如何在 Linux 环境中配置和安装 Kafka 集群,并包括通过 Docker 安装和配置 Kafka 的步骤。每个步骤都将提供详细的解释…...
AI如何悄悄改变你的日常生活?5个你已离不开的AI应用场景
AI如何悄悄改变你的日常生活?5个你已离不开的AI应用场景 清晨被智能闹钟以最舒适的渐强音量唤醒,通勤路上听着音乐App精准推荐的歌单,晚上回家对着冰箱说出想吃的菜谱——这些场景中隐藏的AI技术,早已像水电一样成为生活基础设施。…...
I2C协议详解:从基础原理到工程实践
1. I2C协议基础与核心设计思想I2C(Inter-Integrated Circuit)总线是Philips公司(现NXP)在1980年代开发的一种同步、半双工串行通信协议。作为嵌入式系统中最常用的总线之一,I2C以其简洁的两线制(SDA数据线S…...
小白程序员必看:收藏这份RAG大模型核心技术原理详解,轻松入门智能Agent
1. 核心流程全景图RAG 的生命周期可以严格划分为两个平行的工作流:离线数据处理流(Data Pipeline) 和 在线检索生成流(Query Pipeline)。RAG 核心工作流 1.1 离线数据处理流(Data Ingestion) 这…...
告别动物实验?AI设计抗体成功率低怎么办?聊聊RFdiffusion的局限与未来优化方向
AI抗体设计的突破与挑战:从RFdiffusion看技术瓶颈与未来路径 当David Baker团队在bioRxiv上发布利用RFdiffusion实现抗体原子级精度从头设计的论文时,整个AI制药领域为之振奋。这项技术突破意味着,我们可能正站在抗体药物研发范式转变的临界点…...
终极指南:如何通过OmenSuperHub高效掌控暗影精灵硬件性能
终极指南:如何通过OmenSuperHub高效掌控暗影精灵硬件性能 【免费下载链接】OmenSuperHub 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 想要彻底摆脱官方Omen Gaming Hub的臃肿体验,获得纯净高效的暗影精灵硬件控制工具吗…...
LumiPixel Canvas Quest提示词反推(Interrogator)工具使用教程
LumiPixel Canvas Quest提示词反推(Interrogator)工具使用教程 1. 引言:为什么需要提示词反推工具 如果你经常使用AI绘画工具,一定遇到过这样的困扰:看到一张惊艳的作品,却不知道作者用了什么提示词。或者…...
xLearn性能优化秘籍:SSE指令加速与内存管理技巧
xLearn性能优化秘籍:SSE指令加速与内存管理技巧 【免费下载链接】xlearn High performance, easy-to-use, and scalable machine learning (ML) package, including linear model (LR), factorization machines (FM), and field-aware factorization machines (FFM)…...
实战:基于Local Path Provisioner与Helm的RustFS云原生存储部署详解
1. RustFS与云原生存储架构解析 第一次接触RustFS是在去年帮客户设计对象存储方案时,当时被它用Rust语言实现的内存安全特性吸引。作为一款兼容S3协议的开源分布式存储系统,RustFS在性能测试中表现出色——单节点吞吐量能达到1.2GB/s,延迟控制…...
如何使用USearch构建自动驾驶传感器数据的实时向量搜索系统
如何使用USearch构建自动驾驶传感器数据的实时向量搜索系统 【免费下载链接】usearch Fastest Open-Source Search & Clustering engine for Vectors & 🔜 Strings in C, C, Python, JavaScript, Rust, Java, Objective-C, Swift, C#, GoLang, and Wolfra…...
OneNET物联网平台接入避坑指南:Android端用MQTTS协议请求数据,为什么你的Token总失效?
OneNET物联网平台MQTTS接入实战:Android端Token失效的深度排查与解决方案 第一次在Android应用中集成OneNET的MQTTS协议时,我盯着调试日志里反复出现的"401 Unauthorized"错误整整两天。官方文档看似清晰,但实际对接时才发现&…...
