springboot、deepseek4j、bge-m3和milvus

server/2025/3/1 7:45:24/

1、pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.2</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lee</groupId><artifactId>deepseektest</artifactId><version>0.0.1</version><name>deepseektest</name><description>deepseektest</description><properties><java.version>23</java.version><spring-ai.version>1.0.0-M5</spring-ai.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.github.pig-mesh.ai</groupId><artifactId>deepseek-spring-boot-starter</artifactId><version>1.4.5</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp</artifactId><version>4.12.0</version></dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifactId>okhttp-sse</artifactId><version>4.12.0</version></dependency><dependency><groupId>com.fasterxml.jackson</groupId><artifactId>jackson-bom</artifactId><version>2.12.4</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83_noneautotype</version></dependency><!-- 链接 milvus SDK--><dependency><groupId>io.milvus</groupId><artifactId>milvus-sdk-java</artifactId><version>2.5.3</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

2、配置文件

# 推理模型链接信息
deepseek.api-key=sk-bedafbqsexpyunwgfawojwcachflvafxxksdgszvdsahwtlu
deepseek.model=deepseek-r1:32b
deepseek.base-url=http://172.16.50.25:11434/v1
# 向量模型链接信息
embedding.api-key=sk-bedafbqsexpyunwgfawojwcachflvafxxksdgszvdsahwtlu
embedding.base-url=http://172.16.50.25:11434/v1
embedding.model=bge-m3:latest

3、向量数据库 milvus代码

package com.lee.deepseektest.config;import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MilvusConfig {@Beanpublic MilvusClientV2 MilvusClientV2() {ConnectConfig config = ConnectConfig.builder().uri("http://xxx.xxx.xxx.xxx:19530").build();MilvusClientV2 client = new MilvusClientV2(config);return client;}
}

4、向量数据库插入数据

package com.lee.deepseektest.controller;import ch.qos.logback.core.util.FileUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import io.github.pigmesh.ai.deepseek.core.EmbeddingClient;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;@RestController
public class MilvusController {@AutowiredMilvusClientV2 milvusClientV2;@AutowiredEmbeddingClient embeddingClient;@GetMapping("/milvus")public String insert() {// 这里以 2025最新的我司保密条例演示,可以换成你自己的
//        String law = FileUtil.readString("/Users/lengleng/Downloads/law.txt", Charset.defaultCharset());
//        String[] lawSplits = StrUtil.split(law, 400);String[] lawSplits = new String[]{"高速公路", "航运"};List<JsonObject> data = new ArrayList<>();for (String lawSplit : lawSplits) {List<Float> floatList = embeddingClient.embed(lawSplit);JsonObject jsonObject = new JsonObject();// 将 List<Float> 转换为 JsonArrayJsonArray jsonArray = new JsonArray();for (Float value : floatList) {jsonArray.add(value);}jsonObject.add("vector", jsonArray);jsonObject.addProperty("text", lawSplit);data.add(jsonObject);}InsertReq insertReq = InsertReq.builder().collectionName("deepseek4jtest").data(data).build();InsertResp insertResp =  milvusClientV2.insert(insertReq);System.out.println(insertResp.getInsertCnt());return "ok";}}

5、deepseek模型使用

package com.lee.deepseektest.controller;import io.github.pigmesh.ai.deepseek.core.DeepSeekClient;
import io.github.pigmesh.ai.deepseek.core.Json;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionChoice;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionRequest;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;@RestController
public class DeepSeekController {@Autowiredprivate DeepSeekClient deepSeekClient;public final static HashMap<String, String> cache = new HashMap<>();Function<List<ChatCompletionChoice>, String> choicesProcess = list -> list.stream().map(e -> e.delta().content()).collect(Collectors.joining());Function<String, String> elt = s -> s.replaceAll("<think>[\\s\\S]*?</think>", "").replaceAll("\n", "");/***  流式返回示例* @param prompt* @return*/@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatCompletionResponse> chat(String prompt) {return deepSeekClient.chatFluxCompletion(prompt);}@GetMapping(value = "/sync/chat")public ChatCompletionResponse syncChat(String prompt) {ChatCompletionRequest request = ChatCompletionRequest.builder()// 根据渠道模型名称动态修改这个参数
//                .model(deepSeekProperties.getModel()).addUserMessage(prompt).build();return deepSeekClient.chatCompletion(request).execute();}@GetMapping(value = "/chat/advanced", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatCompletionResponse> chatAdvanced(String prompt, String cacheCode) {ChatCompletionRequest request = ChatCompletionRequest.builder()
//                .model(deepSeekProperties.getModel()).addUserMessage(prompt).addAssistantMessage(elt.apply(cache.getOrDefault(cacheCode, ""))).addSystemMessage("你是一个专业的助手").maxCompletionTokens(5000).build();// 只保留上一次回答内容cache.remove(cacheCode);return deepSeekClient.chatFluxCompletion(request).doOnNext(i -> {String content = choicesProcess.apply(i.choices());// 其他ELT流程cache.merge(cacheCode, content, String::concat);}).doOnError(e -> System.out.println(e.getMessage()));}}

6、deepseek4j官方文档

deepseek4j简介 - 零基础入门Java AI

7、测试推理过程

deepseek 调试

8、向量数据库中的collections在使用时必须要先加载

判断和加载向量数据库milvus中的collection

package com.lee.deepseektest.service;import io.milvus.param.R;
import io.milvus.param.collection.LoadCollectionParam;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.collection.request.GetLoadStateReq;
import io.milvus.v2.service.collection.request.HasCollectionReq;
import io.milvus.v2.service.collection.request.LoadCollectionReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MilvusService {@AutowiredMilvusClientV2 milvusClientV2;public boolean loadCollection(String collectionName) {//先判断是否有 collectionHasCollectionReq hasCollectionReq = HasCollectionReq.builder().collectionName(collectionName).build();boolean hasCollection = milvusClientV2.hasCollection(hasCollectionReq);//在判断是否已加载 collectionGetLoadStateReq getLoadStateReq = GetLoadStateReq.builder().collectionName(collectionName).build();boolean hasLoad = milvusClientV2.getLoadState(getLoadStateReq);// 加载集合到内存LoadCollectionReq loadCollectionReq = LoadCollectionReq.builder().collectionName(collectionName).build();milvusClientV2.loadCollection(loadCollectionReq);hasCollection = milvusClientV2.hasCollection(hasCollectionReq);return hasCollection;}
}

9、RAG接口

package com.lee.deepseektest.controller;import io.github.pigmesh.ai.deepseek.core.DeepSeekClient;
import io.github.pigmesh.ai.deepseek.core.EmbeddingClient;
import io.github.pigmesh.ai.deepseek.core.Json;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionChoice;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionRequest;
import io.github.pigmesh.ai.deepseek.core.chat.ChatCompletionResponse;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;@RestController
public class DeepSeekController {@Autowiredprivate DeepSeekClient deepSeekClient;@AutowiredMilvusClientV2 milvusClientV2;@AutowiredEmbeddingClient embeddingClient;public final static HashMap<String, String> cache = new HashMap<>();Function<List<ChatCompletionChoice>, String> choicesProcess = list -> list.stream().map(e -> e.delta().content()).collect(Collectors.joining());Function<String, String> elt = s -> s.replaceAll("<think>[\\s\\S]*?</think>", "").replaceAll("\n", "");/***  流式返回示例* @param prompt* @return*/@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatCompletionResponse> chat(String prompt) {return deepSeekClient.chatFluxCompletion(prompt);}@GetMapping(value = "/sync/chat")public ChatCompletionResponse syncChat(String prompt) {ChatCompletionRequest request = ChatCompletionRequest.builder()// 根据渠道模型名称动态修改这个参数
//                .model(deepSeekProperties.getModel()).addUserMessage(prompt).build();return deepSeekClient.chatCompletion(request).execute();}/*** 多轮会话* @param prompt* @param cacheCode* @return*/@GetMapping(value = "/chat/advanced", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatCompletionResponse> chatAdvanced(String prompt, String cacheCode) {ChatCompletionRequest request = ChatCompletionRequest.builder()
//                .model(deepSeekProperties.getModel()).addUserMessage(prompt).addAssistantMessage(elt.apply(cache.getOrDefault(cacheCode, ""))).addSystemMessage("你是一个专业的助手").maxCompletionTokens(5000).build();// 只保留上一次回答内容cache.remove(cacheCode);return deepSeekClient.chatFluxCompletion(request).doOnNext(i -> {String content = choicesProcess.apply(i.choices());// 其他ELT流程cache.merge(cacheCode, content, String::concat);}).doOnError(e -> System.out.println(e.getMessage()));}/*** RAG知识库接口* @param prompt* @return*/@GetMapping(value = "/rag/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ChatCompletionResponse> ragchat(String prompt) {List<Float> floatList = embeddingClient.embed(prompt);SearchReq searchReq = SearchReq.builder().collectionName("test1").data(Collections.singletonList(new FloatVec(floatList))).outputFields(Collections.singletonList("text")).topK(3).build();SearchResp searchResp = milvusClientV2.search(searchReq);List<String> resultList = new ArrayList<>();List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();for (List<SearchResp.SearchResult> results : searchResults) {System.out.println("TopK results:");for (SearchResp.SearchResult result : results) {resultList.add(result.getEntity().get("text").toString());}}ChatCompletionRequest request = ChatCompletionRequest.builder()// 根据渠道模型名称动态修改这个参数.model("deepseek-r1:32b").addUserMessage(String.format("你要根据用户输入的问题:%s \n \n 参考如下内容: %s  \n\n 整理处理最终结果", prompt, resultList)).build();return deepSeekClient.chatFluxCompletion(request);}
}


http://www.ppmy.cn/server/171497.html

相关文章

嵌入式硬件篇---数字电子技术中的时序逻辑

文章目录 前言简介1. 关键延迟时间的定义与作用(1) 传输延迟&#xff08;Propagation Delay&#xff09;定义作用示例 (2) 时钟到输出延迟&#xff08;Clock-to-Q Delay, Tcq&#xff09;定义作用示例 (3) 建立时间&#xff08;Setup Time, Tsetup&#xff09;定义作用示例 (4)…

Full GC 排查

在 Java 中&#xff0c;Full GC&#xff08;完全垃圾回收&#xff09;会对整个堆&#xff08;包括年轻代和老年代&#xff0c;甚至可能包括永久代/元空间&#xff09;进行垃圾回收&#xff0c;通常会导致较长的停顿&#xff08;STW&#xff0c;Stop-The-World&#xff09;。如果…

MyBatis基础模块-缓存模块

缓存模块 MyBatis作为一个强大的持久层框架,缓存是其必不可少的功能之一,Mybatis中的缓存分为一级缓存和二级缓存。但本质上是一样的,都是使用Cache接口实现的。缓存位于 org.apache.ibatis.cache包下。 通过结构我们能够发现Cache其实使用到了装饰器模式来实现缓存的处理。…

wordpress子分类调用父分类名称和链接的3种方法

专为导航而生&#xff0c;在wordpress模板制作过程中常常会在做breadcrumbs导航时会用到&#xff0c;子分类调用父分类的名称和链接&#xff0c;下面这段简洁的代码&#xff0c;可以完美解决这个问题。 <?php echo get_category_parents( $cat, true, &raquo; ); ?…

【电路笔记】-MOD计数器

MOD计数器 文章目录 MOD计数器1、概述2、D型触发器3、二分频计数器4、MOD-4 计数器5、模“m”计数器5.1 模5计数器5.2 模 10 计数器6、总结MOD 计数器是级联计数器电路,在复位之前计数到设定的模数值。 1、概述 计数器的工作是通过每个时钟脉冲将计数器的内容前进一个计数来进…

中值滤波结合快速排序算法优化传感器数据预处理

一、算法核心逻辑 目标&#xff1a;在嵌入式系统中&#xff0c;通过快速排序的 “部分排序” 特性&#xff0c;优化中值滤波的计算效率。适用场景&#xff1a;实时传感器数据处理&#xff08;如红外、超声波、加速度计等&#xff09;&#xff0c;窗口大小 N5&#xff08;可根据…

使用逻辑分析仪测量RS485的通讯方法

1. 硬件连接 连接参考地&#xff1a;逻辑分析仪的参考地需要连接到被测设备RS-485收发器的参考地。信号线连接&#xff1a;有以下几种接线方式&#xff1a; 单线连接&#xff1a;将逻辑分析仪的一个信号通道连接到RS-485总线的A端。双线连接&#xff1a;用逻辑分析仪两个信号通…

【六祎 - Note】SQL备忘录;DDL,DML,DQL,DCL

SQL备忘录 from to : 点击访问源地址