Java读取PDF后做知识库问答_SpringAI实现

核心思路:
简单来说,就是把PDF文件读取并向量化,然后放到向量存储里面,再通过大模型,来实现问答。
RAG(检索增强生成)介绍:
检索增强生成(RAG)是一种结合了信息检索和文本生成的技术,旨在提高大模型的响应准确性和相关性。通过将检索模型(用于搜索专有数据集或知识库)与生成模型(如大型语言模型LLM)相结合,RAG能够利用私有或专有的数据来辅助生成更精确的回答。这样不仅减少了由于缺乏特定背景知识导致的大模型“幻觉”现象,还使得生成的内容更加贴合用户的需求和上下文环境,特别适合于需要处理企业内部数据的应用场景。
Spring AI alibaba介绍
Spring AI Alibaba 是基于 Spring Ai 构建的,用于集成阿里云通义大模型服务的应用框架。它允许开发者通过简单的配置和少量代码,将强大的AI能力如对话、文生图等快速融入到 Java 应用程序中。其核心优势在于提供了一套标准化接口,使得应用程序能够轻松切换不同的AI提供商而无需大量修改代码;同时,该框架支持流式输出,并提供了Prompt模板等功能来简化开发流程,极大地提高了效率和灵活性。通过与Spring Boot生态系统的无缝集成,Spring AI Alibaba为开发者打造了一个既高效又便捷的AI应用开发环境。
详细例子:
1 后端代码编写
读PDF->向量化->向量存储->读取展现
1. 环境准备
确保你的开发环境满足以下条件:
- JDK版本在17或以上。
- Spring Boot版本为3.3.x或更高。
- 已经从阿里云申请到了通义千问API的
api-key。
2. 配置项目以使用Spring AI Alibaba
2.1 设置API Key
在启动应用之前,请设置环境变量AI_DASHSCOPE_API_KEY为你获得的API密钥值,并且在application.properties中正确引用它:
spring.ai.dashscope.api-key: ${AI_DASHSCOPE_API_KEY}
2.2 添加依赖
需要添加对spring-ai-alibaba-starter的依赖到你的pom.xml文件中,并且指定正确的Spring Boot父级依赖。同时不要忘记包含必要的仓库地址以便获取最新的快照版本。
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-staper-parent</artifactId><version>3.3.4</version></parent><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M2</version></dependency></dependencies><repositories><repository><id>sonatype-snapshots</id><url>https://oss.sonatype.org/content/repositories/snapshots</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories>
3. 编写RAG服务代码
创建一个名为RagService的服务类,用于处理与向量存储、文档检索相关的逻辑。该服务还将负责初始化索引构建及查询操作。
public class RagService {private final ChatClient chatClient;private final VectorStore vectorStore;private final DashScopeApi dashscopeApi = new DashScopeApi("你的apiKey");DocumentRetriever retriever;public RagService(ChatClient chatClient, EmbeddingModel embeddingModel) {this.chatClient = chatClient;vectorStore = new DashScopeCloudStore(dashscopeApi, new DashScopeStoreOptions("spring-ai知识库"));retriever = new DashScopeDocumentRetriever(dashscopeApi, DashScopeDocumentRetrieverOptions.builder().withIndexName("spring-ai知识库").build());}public String buildIndex() {String filePath = "/path/to/阿里巴巴财报.pdf";DocumentReader reader = new DashScopeDocumentCloudReader(filePath, dashscopeApi, null);List<Document> documentList = reader.get();vectorStore.add(documentList);return "SUCCESS";}public StreamResponseSpec queryWithDocumentRetrieval(String message) {StreamResponseSpec response = chatClient.prompt().user(message).advisors(new DocumentRetrievalAdvisor(retriever, DEFAULT_USER_TEXT_ADVISE)).stream();return response;}
}
4. 创建控制器暴露接口
接下来定义一个REST控制器,用来接收HTTP请求并将结果返回给客户端。
@RestController
@RequestMapping("/ai")
public class RagController {private final RagService ragService;public RagController(RagService ragService) {this.ragService = ragService;}@GetMapping("/steamChat")public Flux<String> generate(@RequestParam(value = "input", required = true) String input,HttpServletResponse httpResponse) {StreamResponseSpec chatResponse = ragService.queryWithDocumentRetrieval(input);httpResponse.setCharacterEncoding("UTF-8");return chatResponse.content();}@GetMapping("/buildIndex")public String buildIndex() {return ragService.buildIndex();}
}
5. 运行应用程序
在运行此应用程序之前,请确保已经完成了索引的构建(调用/buildIndex)。之后可以通过访问http://localhost:8080/ai/steamChat?input=你的问题来查询财务报告中的信息了。
通过上述步骤,你就可以成功地利用检索增强技术来处理阿里巴巴财务报表PDF文件,并通过一个简单的Web API提供交互式问答功能。这不仅能够帮助用户更高效地查找所需信息,同时也展示了如何结合现有技术和工具快速搭建起实用的服务。
检索增强的前端代码编写
构建项目并填写代码
首先,创建一个新的 React 应用并安装所需的依赖:
npx create-react-app ragChatFrontend
cd ragChatFrontend
npm install
public/index.html
在public/index.html中不需要做特别的修改,保持默认即可。
src/index.js
确保你的src/index.js如下所示,它负责渲染应用的根组件App:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';ReactDOM.render(<React.StrictMode><App /></React.StrictMode>,document.getElementById('root')
);
src/App.js
这个文件定义了应用的主要布局。我们在这个例子中将只包含一个聊天组件:
import React from 'react';
import RAGChatComponent from './components/RAGChatComponent';function App() {return (<div className="App"><RAGChatComponent /></div>);
}export default App;
src/components/RAGChatComponent.js
这是主要的功能实现部分,我们将在这里处理用户输入、向后端发送请求以及展示返回的数据流。
import React, { useState } from 'react';function RAGChatComponent() {const [input, setInput] = useState('');const [messages, setMessages] = useState('');const handleInputChange = (event) => {setInput(event.target.value);};const handleSendMessage = async () => {if (input.trim() === '') return;try {// 发送请求到后端的RAG Chat接口const response = await fetch(`http://localhost:8080/ai/streamChat?input=${encodeURIComponent(input)}`);const reader = response.body.getReader();const decoder = new TextDecoder('utf-8');let done = false;while (!done) {const { value, done: readerDone } = await reader.read();done = readerDone;const chunk = decoder.decode(value, { stream: true });setMessages((prevMessages) => prevMessages + chunk);}// 在每次请求完成后添加换行符以区分不同轮次的消息setMessages((prevMessages) => prevMessages + '\n\n=============================\n\n');} catch (error) {console.error('Failed to fetch', error);}};const handleClearMessages = () => {setMessages('');};return (<div><inputtype="text"value={input}onChange={handleInputChange}placeholder="Enter your message"/><button onClick={handleSendMessage}>Send</button><button onClick={handleClearMessages}>Clear</button><div><h3>Messages:</h3><pre>{messages}</pre></div></div>);
}export default RAGChatComponent;
运行项目
- 启动前端服务:
cd ragChatFrontend
npm start
解释步骤
- 我们创建了一个新的React应用,并构建了一个简单的界面来与支持检索增强(RAG)的聊天服务进行交互。
- 用户可以在文本框内输入消息并通过点击“Send”按钮将其发送给后端。
- 消息通过HTTP GET请求被发送到指定URL,即
http://localhost:8080/ai/steamChat?input=...。这里使用了fetchAPI来发起异步请求,并且通过读取响应体中的数据流来逐步显示返回的内容。
- 当接收到新数据块时,这些数据会被解码为字符串并追加到当前的消息列表中。
- 最后,在每次请求完成之后都会插入一个分隔线,以便于清晰地区分不同的对话回合。
- 提供了一个清除功能,允许用户清空消息历史记录以便开始新一轮对话。
此方案利用了浏览器内置的TextDecoder和ReadableStream API来高效地处理从服务器接收的数据流,非常适合于实时性要求较高的应用场景如在线聊天等。
相关文章:
Java读取PDF后做知识库问答_SpringAI实现
核心思路: 简单来说,就是把PDF文件读取并向量化,然后放到向量存储里面,再通过大模型,来实现问答。 RAG(检索增强生成)介绍: 检索增强生成&#x…...
打开exe程序显示没有适当的访问权限
打开exe程序显示没有适当的访问权限 打开.exe可执行程序,显示Windows 无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目。 解决方法 鼠标选中该文件或文件夹,右键单击选择属性,在弹出的属性选项卡中切换到安全选项卡…...
Python异步编程:使用`create_task`并发执行协程
Python异步编程:使用create_task并发执行协程 1. 什么是create_task?2. 为什么需要create_task?3. 如何使用create_task?3.1 基本用法3.2 任务的返回值 4. 注意事项5. 总结 在Python的异步编程中,asyncio库为我们提供了…...
从零开始搭建你的DolphinScheduler分布式任务调度平台实战指南
文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问,结合内…...
第五课:Python学习之if语句
判断(if)语句 目标 开发中的应用场景if 语句体验if 语句进阶综合应用 01. 开发中的应用场景 生活中的判断几乎是无所不在的,我们每天都在做各种各样的选择,如果这样?如果那样?…… 程序中的判断 # 定义…...
群晖前面加了雷池社区版,安装失败,然后无法识别出用户真实访问IP
有nas的相信对公网都不模式,在现在基础上传带宽能有100兆的时代,有公网代表着家里有一个小服务器,像百度网盘,优酷这种在线服务都能部署为私有化服务。但现在运营商几乎不可能提供公网ip,要么自己买个云服务器做内网穿…...
【秋招笔试】10.13拼多多(已改编)秋招-三语言题解
🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集…...
50个JAVA常见代码大全:学完这篇从Java小白到架构师(附带讲解)
基础语法 1. Hello World public class HelloWorld {public static void main(String[] args) {System.out.println("Hello, World!");} }讲解 这是一个典型的Java程序,它定义了一个名为HelloWorld的类,该类包含一个main方法——Java应用程序的入口点。System.o…...
Microsoft SQL Server 2008 R2 (RTM) - 10.50.1600.0 SP1升级到SP3操作方法(x64)
1、首先安装时候选择升级SQLEXPRADV_x64_CHS.exe。 2、接着安装SQLServer2008R2SP1-KB2528583-x64-sp1补丁后10.50.2500.0。 3、接着安装升级SQLEXPRWT_x64_CHS.exe。 4、继续安装SP3:SQLServer2008R2SP3-KB2979597-x64-CHS。 5、最后安装SP3补丁:SQ…...
Centos7安装Git及配置Github
Background Git 是一个开源的分布式版本控制系统,由 Linus Torvalds(Linux 内核的创始人)在 2005 年创建。它被设计用来快速有效地处理从小到大的项目版本管理。Git 目前是全世界最流行的版本控制系统,广泛应用于软件开发中。 1、…...
MobileNet v3(相比于MobileNet v2)
概述: 更新Block(bneck) 使用NAS搜索参数 (Neural Architecture Search) 重新设计耗时层结构 更准确,更高效 以及表中数据展示 更新Block 1.加入SE模块 2.更新了激活函数 首先通过一个1*1的卷积层来进行一个升维处理&#…...
短视频剪辑入门指南:这四大软件值得推荐!
要在众多的短视频作品中脱颖而出并不容易,这就要求制作者不仅要具备良好的创意,还需要掌握一定的剪辑技巧。这里给大家推荐几个好用的短视频剪辑工具! 福昕视频剪辑 直达链接:www.pdf365.cn/foxit-clip/ 操作教程:立…...
网络编程(22)——通过beast库快速实现websocket服务器
目录 二十二、day22 1. websocket简述 2. 基于TCP长连接实现sebsocket a. Connection b. ConnectionMgr c. WebServer d. 编译的小问题 3. 测试 4. 基于http实现的websocket 二十二、day22 因为http受限于请求-响应模式,客户端发起请求,服务器…...
从视频截取每一帧作为图像
查看视频有多少帧 import cv2def count_frames_per_second(video_path):cap cv2.VideoCapture(video_path)if not cap.isOpened():print("Error: Could not open video")return None# Get frames per secondfps cap.get(cv2.CAP_PROP_FPS)# Get total number of f…...
终端 数据表格
// // Created by HongDaYu on 17 十月 2024. //#ifndef HDYSDK_UTIL_H #define HDYSDK_UTIL_H#include <cstdint> #include <string> #include <list> #include <iomanip> #include <memory>class dataGrid { private:std::list<const char*…...
2.4.ReactOS系统运行级别降低IRQL级别KfLowerIrql 函数
2.4.ReactOS系统运行级别降低IRQL级别KfLowerIrql 函数 2.4.ReactOS系统运行级别降低IRQL级别KfLowerIrql 函数 文章目录 2.4.ReactOS系统运行级别降低IRQL级别KfLowerIrql 函数KfLowerIrql 函数 KfLowerIrql 函数 /*******************************************************…...
数字后端实现静态时序分析STA Timing Signoff之min period violation
今天给大家分享一个在高性能数字IC后端实现timing signoff阶段经常遇到的min period violation。大部分时候出现memory min period问题基本上都是需要返工重新生成memory的。这是非常致命的错误,希望大家在做静态时序分析时一定要查看min period violation。 什么是…...
phpstorm+phpstudy 配置xdebug(无需开启浏览器扩展)
今天又被xdebug折磨了,忘记了以前咋配置了现在百度发现好多都是各种浏览器扩展而且也没有真正的用到项目上的都是测试的地址怎么样的 我就简单写一下自己实战吧 不支持workerman swoole hyperf等这种服务框架 如果你会请教教我 工具版本phpstudy8.1.xphpstorm2021.x…...
AI赋能安全运营 | 赛宁网安深度参与四川省网络安全沙龙
为促进四川省、市网络安全公共服务领域的经验交流与深入探讨,打通网络安全供需上下游,加速汇聚省、市优质网络安全设备和服务资源,提升巴中市乃至四川省网络安全防护水平,共同推动四川省网络安全事业的蓬勃发展。 2024年10月15日…...
R语言中,.RData 和 .rds 的区别
.RData 和 .rds 是 R 语言中两种不同的数据保存格式,二者有一些关键的区别: 1. 存储内容的类型: .RData 文件:可以同时保存多个对象(如数据框、向量、列表等),当你加载 .RData 文件时…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
