SpringAI 基于 milvus 的向量检索

向量数据库可以使用 milvus,redis,Elasticsearch 等,本文以 milvus 为例:

1. 启动milvus

为了尽可能快速上手springai的vectordb功能,我们推荐使用云上的milvus,注册就能创建免费的milvus实例,测试完全够了。从控制台复制域名和token
在这里插入图片描述

docker安装一个attu可视化工具去连接公网的milvus

docker run -p 8000:3000  -e MILVUS_URL=0.0.0.0:19530 zilliz/attu:latest

在这里插入图片描述

2. pom添加依赖

因为考虑到后期可能随时更换向量模型,所以不推荐以yml方式让springboot自动配置VectorStore,这里以手动方式配置

    <dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-milvus-store</artifactId></dependency>
3. 注册Bean
@Configuration
public class SpringAIConfig {@Beanpublic MilvusServiceClient milvusClient() {return new MilvusServiceClient(ConnectParam.newBuilder().withToken("9b06645c438b57b982585fc9b4bd678e6d74d3ae62771exxxxxxxxxxxxxxxxxxxxxxxx").withUri("https://in03-d7f9d7fd8895405.serverless.ali-cn-hangzhou.cloud.zilliz.com.cn").withDatabaseName("db_d7f9d7fxxxxxxx").build());}//如果同时定义多个向量库这里需要起个名字@Bean("milvusVectorStore")public VectorStore vectorStore(MilvusServiceClient milvusClient, EmbeddingModel embeddingModel) {return MilvusVectorStore.builder(milvusClient, embeddingModel).collectionName("test_vector_store").databaseName("db_d7f9d7fxxxxxxx").indexType(IndexType.IVF_FLAT).metricType(MetricType.COSINE).batchingStrategy(new TokenCountBatchingStrategy()).initializeSchema(true).build();}
}
4. 创建向量数据的创建和检索方法

保存时在Metadata字段保存知识库的id,用于过滤向量数据,实现知识库的知识隔离


@Component
@RequiredArgsConstructor
public class VectorService {@Qualifier("milvusVectorStore")@Autowiredprivate VectorStore milvusVectorStore;public void embedFileToMilvus(MultipartFile file,String knowledgeId) {try {// 读取上传文件内容String content = new String(file.getBytes(), StandardCharsets.UTF_8);// 切分为小块List<Document> docs = splitTextToDocuments(content,knowledgeId); // 每500字符为一块// 写入向量库milvusVectorStore.add(docs);} catch (Exception e) {throw new RuntimeException("文件向量化失败: " + e.getMessage(), e);}}// 按固定长度分割文本为 Document 列表private List<Document> splitTextToDocuments(String text,String knowledgeId) {List<Document> docs = new ArrayList<>();int length = text.length();for (int i = 0; i < length; i += 500) {int end = Math.min(length, i + 500);String chunk = text.substring(i, end);Document document = new Document(chunk);//指定向量数据的知识库Iddocument.getMetadata().put("knowledgeId",knowledgeId);docs.add(document);}return docs;}public void store(List<Document> documents) {if (documents == null || documents.isEmpty()) {return;}milvusVectorStore.add(documents);}public List<Document> search(String query,String knowledgeId,Double threshold) {FilterExpressionBuilder b = new FilterExpressionBuilder();return milvusVectorStore.similaritySearch(SearchRequest.builder().query(query).topK(5)   //返回条数.similarityThreshold(threshold)   //相似度,阈值范围0~1,值越大匹配越严格‌.filterExpression(b.eq("knowledgeId", knowledgeId).build()).build());}public void delete(Set<String> ids) {milvusVectorStore.delete(new ArrayList<>(ids));}}
5. 测试接口

@Tag(name = "向量检索", description = "向量检索")
@RestController
@RequestMapping("/vector")
public class VectorController {@Autowiredprivate VectorService vectorService;@Operation(summary = "文本文件向量化", description = "文本文件向量化")@PostMapping("/uploadFile")public RestVO<Map<String, Object>> uploadFile(@RequestPart MultipartFile file, @RequestParam String knowledgeId) {vectorService.embedFileToMilvus(file, knowledgeId);return RestVO.success(Map.of("success", true, "message", "文件已向量化"));}@Operation(summary = "向量检索", description = "向量检索")@GetMapping("/query")public RestVO<List<Document>> uploadFile(@RequestParam String query, @RequestParam Double threshold, @RequestParam(required = false) String knowledgeId) {List<Document> documentList = vectorService.search(query, knowledgeId,threshold);return RestVO.success(documentList);}
}

数据库插入内容预览
在这里插入图片描述
检索效果
在这里插入图片描述

6. 将检索结果作为上下文
  // 系统提示词private final static String SYSTEM_PROMPT = """你需要使用文档内容对用户提出的问题进行回复,同时你需要表现得天生就知道这些内容,不能在回复中体现出你是根据给出的文档内容进行回复的,这点非常重要。当用户提出的问题无法根据文档内容进行回复或者你也不清楚时,回复不知道即可。文档内容如下:{documents}""";...String systemPrompt;// 判断是否需要检索知识库if (body.getKnowledgeId() != null) {List<Document> documentList = vectorStore.similaritySearch(body.getMessage());System.out.println("检索结果" + documentList.size());if (documentList != null && !documentList.isEmpty()) {String context = documentList.stream().map(Document::getText).collect(Collectors.joining(""));// 用文档内容填充SYSTEM_PROMPT模板String filledSystemPrompt = SYSTEM_PROMPT.replace("{documents}", context);// 判断用户是否指定自定义系统提示词if (body.getSystemPrompt() != null && !body.getSystemPrompt().trim().isEmpty()) {systemPrompt = body.getSystemPrompt() + "\n" + filledSystemPrompt;} else {systemPrompt = filledSystemPrompt;}} else {// 没有检索到内容,判断用户是否指定自定义系统提示词systemPrompt = (body.getSystemPrompt() != null && !body.getSystemPrompt().trim().isEmpty())? body.getSystemPrompt(): "中文回答";}}...//将系统提示词添加到提示词消息中messages.add(new SystemMessage(systemPrompt));Prompt prompt = new Prompt(messages);

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

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

相关文章

如何使用数字化动态水印对教育视频进行加密?

文章目录前言一、什么是数字化动态水印二、使用数字化动态水印对教育视频加密的好处&#xff1f;三、数字化动态水印的实现原理四、如何实现数字化动态水印对教育视频加密总结前言 教育资源数字化蓬勃发展的今天&#xff0c;优质视频课程已成为机构的核心知识资产。然而&#…

解决bash终端的路径名称乱码问题

解决bash终端的路径名称乱码 默认打开了zsh&#xff0c;当我输入bash后&#xff0c;就出现了乱码 (context_rag) [23fanyaohead1]~/mycode-thesis% bash (context_rag) [%n%m]%~%#乱码原因排查 我遇到了终端乱码问题&#xff0c;需要检查当前的终端环境和编码设置&#xff0c;下…

【深度学习】【入门】Sequential的使用和简单神经网络搭建

1.Sequential的概念它是一种按顺序封装神经网络层的容器&#xff0c;能让层按照添加顺序依次执行计算&#xff0c;简化网络搭建流程2.Sequential的作用1.代码简洁化对比不用 Sequential 时手动搭建层的繁琐代码&#xff08;如每层需手动定义并连接&#xff09;&#xff0c;展示…

前端开发中的资源缓存详解

资源缓存用于缓存静态资源,良好的缓存策略可以减少资源重复加载进而提高网页的整体加载速度。 通常浏览器缓存策略分为两种:强缓存和协商缓存,当然还包括 service worker。 浏览器在资源加载时,根据请求头中的 expires 和 cache-control 值来判断是否命中强缓存,命中则直…

零基础入门指南:华为数通认证体系详解

一、华为数通认证的定位与行业价值华为数通认证&#xff08;Datacom&#xff09;是ICT领域核心方向&#xff0c;覆盖路由器、交换机等网络基础设备技术&#xff0c;被誉为“网络行业的骨骼”。2020年升级为Datacom认证体系&#xff0c;新增SDN、VXLAN、网络自动化等前沿技术&am…

超低功耗CC2340R SimpleLink™ 系列 2.4GHz 无线 MCU支持BLE5.3/Zigbee/Thread/专有协议

CC2340R SimpleLink™ 系列 2.4GHz 无线 MCU支持BLE5.3/Zigbee/Thread/专有协议优势简介性能介绍应用场景优势简介 CC2340R SimpleLink™ 系列器件为 2.4GHz 无线微控制器 (MCU)&#xff0c;面向低功耗 Bluetooth5.3、Zigbee、Thread 和专有 2.4GHz 应用。这些器件针对低功耗无…

若依前后端分离Vue3版本接入阿里云OSS

一、引入依赖首先在commom 模块的pom 下面引入 阿里云OSS 的 依赖<!-- 阿里云oss --><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>3.17.4</version></depende…

2025年微软mos备考攻略-穷鬼版

说实话&#xff0c;微软MOS认证是微软官芳推出的办公软件方面的认证&#xff0c;考试难度真的不大&#xff0c;完全没必要报班&#xff0c;自学完全OK&#xff01;一、25 年报考MOS认证详情报名时间&#xff1a;随时可以在官网或ji构报名&#xff08;ji构报名会送备考资料&…

数据库版本自动管理

FlywayDB 是一款 开源数据库版本管理工具&#xff0c;开发中将表结构的变更或数据初始化脚本维护好&#xff0c;更新到测试环境或线上发版启动服务的时候&#xff0c;会检测版本号自动执行数据库变更&#xff0c;可以减少每次发版到其他环境的人工执行操作。 工作流程初始化阶段…

解决Linux绑定失败地址已使用(端口被占用)的问题

文章目录解决 bind failed: Address already in use 问题一、问题原因1. **端口已经被其他程序占用**2. **端口处于 TIME_WAIT 状态**3. **未正确关闭套接字**二、如何排查和解决问题1. **确认端口是否被占用**2. **查找并杀掉占用端口的进程**3. **等待端口释放&#xff08;TI…

Ragas的Prompt Object

Prompt在Ragas中被用在各种指标、合成数据生成任务中。同时也为提供了替换各种自动以提示词的方式。Ragas提供了如下几种Prompt Objects。 instruction:prompt的基础组成,通过自然语言清晰的描述LLM需要完成的任务。在prompt object中用instruction变量定义。few-shot exampl…

PHP语法高级篇(一):日期时间处理和包含文件

从本篇文章开始&#xff0c;将学习PHP的高级特性内容。本篇文章将记录在PHP中如何进行日期时间处理和包含文件的学习过程。 一、日期和时间 在PHP中&#xff0c;date() 函数用于格式化日期或时间。 说明 date(string $format, ?int $timestamp null): string 使用指定整数…

请求服务端获取broker的机房归属信息异常

该错误表明服务在尝试获取 broker 的 ​机房归属信息​ 时遇到异常。以下是详细分析和解决方案建议&#xff1a;​问题定位与常见原因​​网络问题​客户端无法连接存储机房信息的元数据服务​&#xff08;如配置中心、注册中心&#xff09;。防火墙或安全组阻断了相关端口&…

Android 中的多线程编程全面解析

Android 中的多线程编程全面解析 一、Android 线程模型基础 主线程&#xff08;UI 线程&#xff09;特性 唯一性&#xff1a;每个应用只有一个主线程职责&#xff1a;处理 UI 操作和用户交互限制&#xff1a;禁止在主线程执行耗时操作&#xff08;超过5秒会导致 ANR&#xff09…

golang -gorm 增删改查操作,事务操作

增删改查 1. 插入数据// api func SaveUser(ctx *gin.Context) {result : &common.Result{}user : &dao.User{}err : ctx.ShouldBindJSON(&user)if err ! nil {ctx.JSON(http.StatusOK, result.Fail(400, "请使用json数据格式传值"))return}// 调用验证函…

大数据时代UI前端的智能化服务升级:基于用户情境的主动服务设计

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;从 “被动响应” 到 “主动预判” 的 UI 服务革命当用户在暴雨天打开外卖…

CUDA性能优化实战:7个步骤让并行归约算法提升10倍效率

本文深入探讨了一个经典的并行计算算法——并行归约&#xff08;Parallel Reduction&#xff09;的性能优化过程&#xff0c;通过七个渐进式的优化步骤&#xff0c;展示了如何将算法性能提升至极致。这项研究基于Mark Harris在NVIDIA网络研讨会中提出的优化方法&#xff0c;在重…

详解梯度消失和梯度爆炸(反向传播)?

什么是梯度消失&#xff1f;梯度消失&#xff08;Gradient Vanishing&#xff09; 是指在训练神经网络时&#xff0c;反向传播过程中计算得到的梯度&#xff08;用于更新参数的重要信息&#xff09;随着网络层数的增加而急剧减小&#xff0c;甚至趋近于零的现象。这会导致深层网…

端到端自动驾驶:挑战与前沿

端到端自动驾驶&#xff1a;挑战与前沿 End-to-End Autonomous Driving: Challenges and Frontiers 自动驾驶研究社区已见证了越来越多采用端到端算法框架的方法的快速增长&#xff0c;这些方法利用原始传感器输入生成车辆的运动规划&#xff0c;而不是专注于诸如检测和运动预测…

rust cargo 编译双架构的库

这个错误表明你的 Rust 工具链没有安装 aarch64-apple-darwin 目标平台。以下是完整的解决方案&#xff1a; 解决方案 ​​安装目标平台​​ (必须步骤) rustup target add aarch64-apple-darwin​​验证安装​​ (可选但推荐) rustup target list --installed # 应该能看到 aa…