SpringAI實現AI應用-搭建知識庫

SpringAI實戰鏈接

1.SpringAl實現AI應用-快速搭建-CSDN博客

2.SpringAI實現AI應用-搭建知識庫-CSDN博客

概述

想要使用SpringAI搭建知識庫,就要使用SpringAI中的TikaDocumentReader,它屬于ETL(提取、轉換、加載)框架中的提取(Extract)階段。

作用

TikaDocumentReader是Spring AI提供的一個文檔讀取器,它基于Apache Tika技術實現,能夠讀取并解析多種格式的文檔,包括但不限于PDF、DOC/DOCX、PPT/PPTX和HTML等。這使得TikaDocumentReader成為一個非常靈活和強大的工具,適用于構建知識庫或處理各種文檔數據。

使用場景

TikaDocumentReader的使用場景非常廣泛,包括但不限于:

構建知識庫:在構建知識庫時,需要從各種格式的文檔中提取文本內容。TikaDocumentReader能夠輕松地讀取這些文檔,并將其轉換為統一的格式,以便后續的處理和存儲。
文檔處理:在處理大量文檔時,如文檔分類、摘要生成等任務中,TikaDocumentReader可以作為一個預處理步驟,將文檔內容提取出來,為后續的處理提供便利。
數據清洗:在數據清洗過程中,有時需要從非結構化的文檔中提取關鍵信息。TikaDocumentReader能夠讀取這些文檔,并將其轉換為結構化的數據格式,以便進行后續的數據清洗和分析。

準備工作一

在制作本地知識庫的時候,還需要安裝矢量數據庫并下載插件vector,下載矢量化模型

矢量數據庫(PostgreSQL)下載地址:EDB: Open-Source, Enterprise Postgres Database Management

插件vector下載地址:vector: Open-source vector similarity search for Postgres / PostgreSQL Extension Network

矢量化模型下載地址:text2vec-base-chinese · 模型庫

遇到的問題

問題一

安裝完成PostgreSQL之后,想用自帶的管理器(pgAdmin4),但是報錯,解決了半天沒成功,直接改用navicat進行連接,但是連接的時報錯(datlastsysoid does not exist),是因為Postgres?15 從pg_database表中刪除了 datlastsysoid 字段引發此錯誤。(我安裝的是PostgreSQL17)

解決方式

方法一:升級navicat

方法二:安裝Postgres 15以下

方法三:修改navicat的dll文件

詳述方法三:找到navicat安裝的位置

找到libcc.dll文件(最好進行備份)

使用在線十六進制編輯器打開文件,在線地址:HexEd.it — 基于瀏覽器的十六進制編輯器

在文件中搜索“SELECT DISTINCT datlastsysoid”,并將其替換為“SELECT DISTINCT dattablespace”

最后另存并替換原來的文件,重啟navicat就可以使用了

問題二

安裝vector插件的時候遇到的問題,網上也有很多方法,自己百度吧,(真的是一步一個坑)我參考的是:Windows 安裝 PostgreSQL 并安裝 vector 擴展_win10上安裝postgresql的 vector擴展-CSDN博客

問題三

下載矢量化模型

準備工作二

PostgreSQL和插件vector都安裝好之后,創建矢量表

CREATE EXTENSION IF NOT EXISTS vector;
CREATE EXTENSION IF NOT EXISTS hstore;
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";CREATE TABLE IF NOT EXISTS vector_store (id uuid DEFAULT uuid_generate_v4() PRIMARY KEY,content text,metadata json,embedding vector(768)
);CREATE INDEX ON vector_store USING HNSW (embedding vector_cosine_ops);

搭建工程

通過第一篇帖子,已經可以創建一個SpringAI的demo了,現在需要將矢量化模型放在resources下

修改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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>SpringAI_Demo</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/> <!-- lookup parent from repository --></parent><properties><java.version>17</java.version><spring-ai.version>1.0.0-M6</spring-ai.version><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><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><dependencies><!--    常規jar--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--    springAI--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-openai-spring-boot-starter</artifactId></dependency><!--    向量存儲引擎--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-transformers-spring-boot-starter</artifactId></dependency><!--   向量庫--><dependency><groupId>org.postgresql</groupId><artifactId>postgresql</artifactId></dependency><!--    文檔解析器--><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-tika-document-reader</artifactId></dependency><!--    lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies><build><resources><resource><directory>src/main/java</directory><!--所在的目錄--><includes><!--包括目錄下的.properties,.xml 文件都會被掃描到--><include>**/*.properties</include><include>**/*.xml</include></includes><filtering>false</filtering></resource><resource><directory>src/main/resources</directory><includes><include>**/*.*</include></includes></resource></resources><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.2.5</version></plugin></plugins></build><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories>
</project>

與第一篇相比,多了如下依賴

每個依賴的作用也已經在文件中加了注釋

修改application.yml

server:port: 3210spring:#向量庫datasource:url: jdbc:postgresql://localhost:5432/postgresusername: postgrespassword: #數據庫密碼driver-class-name: org.postgresql.Driverai:#調用ai大模型(可使用本地化部署模型,也可以使用線上的)openai:base-url: https://api.siliconflow.cnapi-key: #你自己申請的keychat:options:model: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B#調用矢量化模型embedding:transformer:onnx:modelUri: classpath:/text2vec-base-chinese/onnx/model.onnxtokenizer:uri: classpath:/text2vec-base-chinese/onnx/tokenizer.json#矢量化配置vectorstore:pgvector:index-type: HNSWdistance-type: COSINE_DISTANCEdimensions: 768

EmbeddingController(矢量化接口)

import org.springframework.ai.document.Document;
import org.springframework.ai.reader.tika.TikaDocumentReader;
import org.springframework.ai.transformer.splitter.TokenTextSplitter;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.util.List;import static java.util.stream.Collectors.toList;/*** @Author majinzhong* @Date 2025/4/30 14:00* @Version 1.0*/
@RestController
public class EmbeddingController {@AutowiredVectorStore vectorStore;@PostMapping("/ai/vectorStore")public List<String> vectorStore(@RequestParam(name = "file") MultipartFile file) throws Exception {// 從IO流中讀取文件TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(new InputStreamResource(file.getInputStream()));// 將文本內容劃分成更小的塊List<Document> splitDocuments = new TokenTextSplitter().apply(tikaDocumentReader.read());// 存入向量數據庫,這個過程會自動調用embeddingModel,將文本變成向量再存入。vectorStore.add(splitDocuments);return splitDocuments.stream().map(Document::getText).collect(toList());}@GetMapping("/ai/vectorSearch")public List<String> vectorSearch(@RequestParam(name = "text") String text) {List<Document> documents = vectorStore.similaritySearch(SearchRequest.builder().query(text).topK(1).build());return documents.stream().map(Document::getText).collect(toList());}
}

修改SimpleAiController(AI接口)

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.document.Document;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;import java.util.List;
import java.util.Map;/*** @Author majinzhong* @Date 2025/4/28 10:37* @Version 1.0* SpringAI對話樣例*/
@CrossOrigin
@RestController
public class SimpleAiController {@AutowiredVectorStore vectorStore;// 負責處理OpenAI的bean,所需參數來自properties文件private final ChatClient chatClient;//對話記憶private final InMemoryChatMemory inMemoryChatMemory;public SimpleAiController(ChatClient chatClient,InMemoryChatMemory inMemoryChatMemory) {this.chatClient = chatClient;this.inMemoryChatMemory = inMemoryChatMemory;}/*** 根據消息直接輸出回答* @param map* @return*/@PostMapping("/ai/call")public String call(@RequestBody Map<String,String> map) {String message = map.get("message");return chatClient.prompt().user(message).call().content().trim();}/*** 根據消息采用流式輸出* @param message* @return*/@PostMapping(value = "/ai/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ServerSentEvent<String>> streamChat(@RequestParam(value = "message", defaultValue = "Hello!") String message) {return chatClient.prompt(message).stream().content().map(content -> ServerSentEvent.builder(content).event("message").build())//問題回答結速標識,以便前端消息展示處理.concatWithValues(ServerSentEvent.builder("").build()).onErrorResume(e -> Flux.just(ServerSentEvent.builder("Error: " + e.getMessage()).event("error").build()));}/*** 對話記憶(多輪對話)* @param message* @return* @throws InterruptedException*/@GetMapping(value = "/ai/streamresp", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<ServerSentEvent<String>> streamResp(@RequestParam(value = "message", defaultValue = "Hello!") String message){Flux<ServerSentEvent<String>> serverSentEventFlux = chatClient.prompt(message).advisors(new MessageChatMemoryAdvisor(inMemoryChatMemory, "123", 10), new SimpleLoggerAdvisor()).stream().content().map(content -> ServerSentEvent.builder(content).event("message").build())//問題回答結速標識,以便前端消息展示處理.concatWithValues(ServerSentEvent.builder("").build()).onErrorResume(e -> Flux.just(ServerSentEvent.builder("Error: " + e.getMessage()).event("error").build()));return serverSentEventFlux;}/*** 整合知識庫和自己提問的問題一塊向AI提問* @param message* @return*/@GetMapping("/ai/vectorStoreChat")public Flux<String> ollamaApi(@RequestParam(value = "message") String message) {//從知識庫檢索相關信息,再將檢索得到的信息同用戶的輸入一起構建一個prompt,最后調用ollama apiList<Document> documents = vectorStore.similaritySearch(SearchRequest.builder().query(message).topK(1).build());String targetMessage = String.format("已知信息:%s\n 用戶提問:%s\n", documents.get(0).getText(), message);return chatClient.prompt(targetMessage).stream().content();}
}

與第一篇相比,多了如下代碼

測試

首先測試上傳文件到矢量庫

上傳成功之后,查看數據庫已經有數據了

然后測試查詢矢量庫

最后測試矢量庫和AI統一的接口

再來看一下如果只通過AI進行查詢會返回什么(沒有矢量庫)

如此看來,本地化知識庫成功,接下來就剩往里面一直添數據了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903875.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903875.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903875.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

內網服務器映射到公網上怎么做?網絡將內網服務轉換到公網上

如何將內網映射到公網&#xff1f;本地局域網的網絡下部署的內網服務地址轉換到公網上連接訪問是大家比較關注的問題&#xff0c;特別是在無公網IP使用的情況下&#xff0c;很多人不知道怎么做。 在沒有公網 IP 的情況下&#xff0c;要將內網映射到公網&#xff0c;以便外網能…

intellij idea最新版git開啟Local Changes

習慣了在idea的git插件里&#xff0c;查看項目已修改的文件&#xff0c;但是新版idea默認不展示了&#xff0c;用起來很難受。 參考網上教程開啟方法如下&#xff1a; 1. 確保安裝Git Modal Commit Interface插件并開啟該插件 2. 在Advanced Settings開啟Use Modal Commit In…

??智能制造中的預測性維護:基于深度學習的設備故障預測??

智能制造中的預測性維護:基于深度學習的設備故障預測 引言 在智能制造領域,設備突發故障可能導致巨大的經濟損失。傳統維護方式(如定期檢修或事后維修)往往效率低下且成本高昂。預測性維護(Predictive Maintenance, PdM)通過實時監測設備狀態并預測潛在故障,能夠顯著減…

DeepSeek+即夢:AI視頻創作從0到1全突破

目錄 一、開啟 AI 視頻創作大門&#xff1a;前期準備1.1 注冊與登錄1.2 熟悉工具界面1.3 硬件與網絡要求 二、用 DeepSeek 構思視頻腳本2.1 明確創作主題與目標2.2 編寫優質提示詞2.3 生成并優化腳本 三、即夢 AI 實現畫面生成3.1 文生圖基礎操作3.2 調整參數提升畫質3.3 保持人…

初始化列表詳解

1.類中包含以下成員&#xff0c;必須放在初始化列表位置進行初始化&#xff1a; 1. 引用成員變量 2.const成員變量 3. 自定義類型成員(且該類沒有默認構造函數時 ) 2. 成員變量在類中聲明次序就是其在初始化列表中的初始化順序&#xff0c;與其在初始化列表中的先后次序無關…

基于建造者模式的信號量與理解建造者模式

信號量是什么&#xff1f; AI解釋&#xff1a;信號量&#xff08;Semaphore&#xff09;是操作系統中用于 進程同步與互斥 的經典工具&#xff0c;由荷蘭計算機科學家 Edsger Dijkstra 在 1965 年提出。它本質上是一個 非負整數變量&#xff0c;通過原子操作&#xff08;P 操作…

開閉原則(OCP)

非常棒的問題&#xff01;&#x1f50d; 開閉原則&#xff08;OCP, Open/Closed Principle&#xff09;是軟件設計的核心原則之一&#xff0c;下面我將從定義、意義、優劣分析、Python示例和結構圖五個方面完整解析給你。 &#x1f9e0; 什么是開閉原則&#xff1f; 開閉原則&a…

python數據分析(七):Pandas 數據變形與重塑

Pandas 數據變形與重塑全面指南 1. 引言 在數據分析過程中&#xff0c;我們經常需要將數據從一種結構轉換為另一種結構&#xff0c;以適應不同的分析需求。Pandas 提供了豐富的數據變形與重塑功能&#xff0c;包括旋轉(pivot)、堆疊(stack)、融合(melt)等多種操作。本文將詳細…

Android學習總結之jetpack組件間的聯系

在傳統安卓開發中&#xff0c;UI 組件&#xff08;Activity/Fragment&#xff09;常面臨三個核心問題&#xff1a; 生命周期混亂&#xff1a;手動管理 UI 與數據的綁定 / 解綁&#xff0c;易導致內存泄漏&#xff08;如 Activity 銷毀后回調仍在觸發&#xff09;。數據斷層&am…

C++初階:類和對象(二)

大家好&#xff0c;我是小卡皮巴拉 文章目錄 目錄 一.運算符重載 1.1 基本概念 定義 參數規則 特性 選擇原則 重載要點 二.類的默認成員函數 2.1 構造函數 構造函數的特點 2.2 析構函數 析構函數的特點 2.3 拷貝構造函數 拷貝構造的特點 2.4 拷貝賦值運算符重…

【c++】【STL】priority_queue詳解

目錄 priority_queue的作用priority_queue的接口構造函數emptysizetoppushpopswap priority_queue的實現仿函數&#xff08;函數對象&#xff09;是什么&#xff1f;向上調整算法&#xff08;adjustup&#xff09;向下調整算法&#xff08;adjustdown&#xff09;迭代器構造pus…

測試——用例篇

目錄 1. 測試用例 1.1 概念 2. 設計測試用例的萬能公式 2.1 常規思考逆向思維發散性思維 2.2 萬能公式 3. 設計測試用例例的方法 3.1 基于需求的設計方法 ?編輯 3.2 具體的設計方法 3.2.1 等價類 3.2.2 邊界值 3.2.3 正交法 3.2.4 判定表法 3.2.5 場景法 3.2.6…

銷售總監求職簡歷模板

模板信息 簡歷范文名稱&#xff1a;銷售總監求職簡歷模板&#xff0c;所屬行業&#xff1a;其他 | 職位&#xff0c;模板編號&#xff1a;KREUNY 專業的個人簡歷模板&#xff0c;邏輯清晰&#xff0c;排版簡潔美觀&#xff0c;讓你的個人簡歷顯得更專業&#xff0c;找到好工作…

AE腳本 關鍵幀緩入緩出曲線調節工具 Flow v1.5.0 Win/Mac

Flow是一個非常好用的After Effects腳本,它可以讓你更加輕松自如地調整關鍵幀的速度曲線,無需觸碰老舊復雜的圖形編輯器。 AE腳本介紹 Flow為After Effects帶來了一個簡潔的界面,使自定義動畫曲線變得十分容易,無需深入研究速度和影響力這些讓人困惑的概念 - 只需繪制一個曲線…

ACGRIME:用于全局優化和特征選擇的自適應混沌高斯RIME優化器,附完整版免費代碼

自然現象中&#xff0c;軟冰的形成過程由 Set al. [42] 提出&#xff0c;軟冰是空氣中的過冷水滴在接觸固體物體并凍結時形成的。這種現象發生在特定的氣候條件下&#xff0c;當水蒸氣尚未凝結時&#xff0c;導致冰覆蓋的表面呈現出獨特的樹枝狀和葉子狀景觀。它在軟冰的生長和…

大模型開發學習筆記

文章目錄 大模型基礎大模型的使用大模型訓練的階段大模型的特點及分類大模型的工作流程分詞化(tokenization)與詞表映射 大模型的應用 進階agent的組成和概念planning規劃子任務分解ReAct框架 memory記憶Tools工具\工具集的使用langchain認知框架ReAct框架plan-and-Execute計劃…

4.27-5.4學習周報

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 摘要Abstract一、方法介紹2.Rainbow Memory(RM)2.1多樣性感知內存更新2.2通過數據增強增強樣本多樣性(DA) 二、使用步驟1.實驗概況2.RM核心代碼 總結 摘要 本博客概…

AI Rack架構高速互連的挑戰:損耗設計與信號完整性的設計框架

在AI驅動的時代&#xff0c;系統設計已經從單一PCB的視角&#xff0c;逐步轉向以整個rack為單位來考量。 對于信號完整性而言&#xff0c;焦點以不再局限于單一PCB上的損耗&#xff0c;而是擴展到芯片與芯片之間的端到端互連損耗&#xff08;end-to-end interconnect loss&…

杭電oj(1180、1181)題解

目錄 1180 題目 思路 問題概述 代碼思路分析 1. 數據結構與全局變量 2. BFS 函數 bfs 3. 主函數 main 總結 代碼 1181 題目 思路 1. 全局變量的定義 2. 深度優先搜索函數 dfs 3. 主函數 main 總結 代碼 1180 題目 思路 注&#xff1a;當走的方向和樓梯方向一…

軟件測試概念

這里寫目錄標題 需求開發模型軟件生命周期瀑布模型螺旋模型增量模型、迭代模型敏捷模型Scrum 測試模型V模型W模型&#xff08;雙V模型&#xff09; 需求 用戶需求&#xff1a;沒有經過合理的評估&#xff0c;通常就是一句話 軟件需求&#xff1a;是開發人員和測試人員執行工作…