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);}
}