十分鐘手把手教學(xué):用DeepSeek4j開(kāi)發(fā)私有大模型知識(shí)庫(kù)
背景
deepseek4j 提供了一套強(qiáng)大的 API,涵蓋了 Reasoner、Function Calling、JSON 解析等特性。本工具旨在簡(jiǎn)化 DeepSeek API 的集成,讓開(kāi)發(fā)者能夠快速調(diào)用相關(guān)能力并集成到自己的應(yīng)用中。
然而,DeepSeek 官方并未提供向量模型,因此本工具在最初設(shè)計(jì)時(shí)未考慮向量搜索的集成。
現(xiàn)狀
- deepseek4j 已全面支持 DeepSeek 的 Reasoner、Function Calling、JSON 解析等功能。
- R1 模型的私有知識(shí)庫(kù)需求正在增長(zhǎng),許多開(kāi)發(fā)者希望在 DeepSeek 之上實(shí)現(xiàn)私有知識(shí)庫(kù)。
經(jīng)過(guò)深入的技術(shù)方案評(píng)估,我們選擇了一個(gè)優(yōu)雅的解決方案:通過(guò)兼容 OpenAI 協(xié)議標(biāo)準(zhǔn)來(lái)集成向量模型能力。這種方案具有以下優(yōu)勢(shì):
- 零額外依賴(lài):無(wú)需引入新的依賴(lài)包,保持框架輕量
- 完美兼容性:與現(xiàn)有架構(gòu)無(wú)縫銜接,確保向后兼容
- 標(biāo)準(zhǔn)化接入:采用業(yè)界通用的 OpenAI 協(xié)議,降低學(xué)習(xí)成本
詳細(xì)的技術(shù)討論和方案細(xì)節(jié)可參考 GitHub Issue:[RFC] 向量化模型支持 #15
快速上手
本文章將帶領(lǐng)大家從零開(kāi)始構(gòu)建一個(gè)基礎(chǔ) RAG 系統(tǒng)。通過(guò)白盒編碼的方式,不僅能深入理解 RAG 的核心原理,還可以根據(jù)實(shí)際需求靈活調(diào)整和優(yōu)化各個(gè)環(huán)節(jié)。相比直接使用現(xiàn)有的開(kāi)源 RAG 產(chǎn)品,這種方式能讓我們更好地掌控系統(tǒng)行為,實(shí)現(xiàn)更精準(zhǔn)的知識(shí)檢索和問(wèn)答效果。
1739407145
1. 環(huán)境準(zhǔn)備
在開(kāi)始構(gòu)建 RAG 系統(tǒng)之前,我們需要準(zhǔn)備以下環(huán)境:
1.1 Ollama 模型準(zhǔn)備
首先安裝 Ollama,然后下載以下必要的模型:
# 下載推理模型 - 用于理解和生成回答
ollama run deepseek-r1:14b
# 下載向量模型 - 用于文本向量化
ollama run bge-m3:latest
1.2 向量數(shù)據(jù)庫(kù)準(zhǔn)備
本文使用 Milvus 作為向量數(shù)據(jù)庫(kù),你可以選擇以下兩種方式之一進(jìn)行安裝:
方式一:使用 milvus 測(cè)試環(huán)境
- 訪(fǎng)問(wèn) Zilliz Cloud 中文版:https://cloud.zilliz.com.cn
- 獲取連接信息(后續(xù)配置需要用到)
方式二:Docker 安裝
# 1. 下載安裝腳本
curl -sfL https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh -o standalone_embed.sh
# 2. 啟動(dòng) Docker 容器
bash standalone_embed.sh start
注意:如果選擇 Docker 安裝方式,請(qǐng)確保你的網(wǎng)絡(luò)環(huán)境能夠正常訪(fǎng)問(wèn) Github。
- 初始化向量數(shù)據(jù):創(chuàng)建本次知識(shí)庫(kù)存儲(chǔ)、獲取鏈接信息和表信息:
1739410521
1.3 項(xiàng)目依賴(lài)
在你的 Maven 項(xiàng)目中添加以下依賴(lài):
<dependency>
<groupId>io.github.pig-mesh.ai</groupId>
<artifactId>deepseek-spring-boot-starter</artifactId>
<version>1.4.0</version>
</dependency>
<!-- 鏈接 milvus SDK-->
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.5.3</version>
</dependency>
application.yml 配置
# 推理模型鏈接信息
deepseek:
base-url: http://127.0.0.1:11434/v1
model: deepseek-r1:14b
api-key: ollama-local
# 向量模型鏈接信息
embedding:
api-key: ${deepseek.api-key}
base-url: ${deepseek.base-url}
model: bge-m3:latest
2. 初始化私有知識(shí)
在構(gòu)建 RAG 系統(tǒng)時(shí),第一步是將已有的知識(shí)內(nèi)容轉(zhuǎn)換為向量形式并存儲(chǔ)到向量數(shù)據(jù)庫(kù)中。
2.1 創(chuàng)建鏈接 鏈接客戶(hù)端
// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT) // 1.2 獲取的 Milvus 鏈接端點(diǎn)
.token(TOKEN) // 1.2 獲取的 Milvus 鏈接信息
.build();
MilvusClientV2 milvusClientV2 = new MilvusClientV2(connectConfig);
2.2 準(zhǔn)備資料并向量化上傳
以下示例為了節(jié)約篇幅,以處理純文本資料。對(duì)于 Office 文檔、圖片、PDF、音視頻等其他格式的文件處理,deepseek4j 提供了完整的解決方案,可點(diǎn)擊查看筆者開(kāi)源的office2md 項(xiàng)目。
圖片
office2md 2.0 發(fā)布,支持并發(fā)視覺(jué)理解和圖片自我矯正。
@Autowired
EmbeddingClient embeddingClient;
{
// 這里以 2025最新的我司保密條例演示,可以換成你自己的
String law = FileUtil.readString("/Users/lengleng/Downloads/law.txt", Charset.defaultCharset());
String[] lawSplits = StrUtil.split(law, 400);
List<JsonObject> data = new ArrayList<>();
for (String lawSplit : lawSplits) {
List<Float> floatList = embeddingClient.embed(lawSplit);
JsonObject jsonObject = new JsonObject();
// 將 List<Float> 轉(zhuǎn)換為 JsonArray
JsonArray 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("deepseek4j_test")
.data(data)
.build();
milvusClientV2.insert(insertReq);
}
3. 創(chuàng)建 RAG 接口
@GetMapping(value = "/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ChatCompletionResponse> chat(String prompt) {
MilvusClientV2 milvusClientV2 = new MilvusClientV2(connectConfig);
List<Float> floatList = embeddingClientOptional.get().embed(prompt);
SearchReq searchReq = SearchReq.builder()
.collectionName("deepseek4j_test")
.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()
// 根據(jù)渠道模型名稱(chēng)動(dòng)態(tài)修改這個(gè)參數(shù)
.model("deepseek-r1:14b")
.addUserMessage(String.format("你要根據(jù)用戶(hù)輸入的問(wèn)題:%s \n \n 參考如下內(nèi)容: %s \n\n 整理處理最終結(jié)果", prompt, resultList)).build();
return deepSeekClient.chatFluxCompletion(request);
}
前端測(cè)試
1739410900
總結(jié)
本文通過(guò)以下核心步驟快速構(gòu)建了基礎(chǔ) RAG 系統(tǒng):
- 環(huán)境準(zhǔn)備:部署推理模型和向量模型
- 知識(shí)庫(kù)構(gòu)建:向量化存儲(chǔ)
- 檢索增強(qiáng):通過(guò)語(yǔ)義搜索獲取關(guān)聯(lián)知識(shí)
- 推理生成:結(jié)合上下文生成最終回答
要讓 RAG 系統(tǒng)達(dá)到生產(chǎn)可用水平,每個(gè)環(huán)節(jié)都需要進(jìn)一步優(yōu)化和完善:
- 檢索策略?xún)?yōu)化:結(jié)合關(guān)鍵詞和語(yǔ)義的混合檢索,提高召回準(zhǔn)確度
- 重排序優(yōu)化:對(duì)檢索結(jié)果進(jìn)行二次排序,確保最相關(guān)內(nèi)容排在前面
- 提示詞工程:優(yōu)化 Prompt 模板,引導(dǎo)模型生成更準(zhǔn)確的回答
- 知識(shí)庫(kù)管理:定期更新和維護(hù)知識(shí)庫(kù),保證數(shù)據(jù)時(shí)效性
- 性能調(diào)優(yōu):優(yōu)化向量檢索和模型推理的性能