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

news2024/11/25 2:36:19

​​​​​​​​​​​​​​

核心思路:

简单来说,就是把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>
      <input
        type="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;

运行项目

  1. 启动前端服务:
cd ragChatFrontend
npm start

解释步骤

  • 我们创建了一个新的React应用,并构建了一个简单的界面来与支持检索增强(RAG)的聊天服务进行交互。
  • 用户可以在文本框内输入消息并通过点击“Send”按钮将其发送给后端。
  • 消息通过HTTP GET请求被发送到指定URL,即http://localhost:8080/ai/steamChat?input=...。这里使用了fetch API来发起异步请求,并且通过读取响应体中的数据流来逐步显示返回的内容。
  • 当接收到新数据块时,这些数据会被解码为字符串并追加到当前的消息列表中。
  • 最后,在每次请求完成之后都会插入一个分隔线,以便于清晰地区分不同的对话回合。
  • 提供了一个清除功能,允许用户清空消息历史记录以便开始新一轮对话。

此方案利用了浏览器内置的TextDecoderReadableStream API来高效地处理从服务器接收的数据流,非常适合于实时性要求较高的应用场景如在线聊天等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE5 猎户座漂浮小岛 02 模型 地形

UE5 猎户座漂浮小岛 02 模型 地形 1.模型 1.1 导入 1.2 统一模型比例 1.3 添加碰撞体 2.地形 2.1 地 2.2 山体 2.3 海洋 2.4 花草

特征提取:传统算法 vs 深度学习

特征提取&#xff1a;传统算法 vs 深度学习 特征点是图像中梯度变化较为剧烈的像素&#xff0c;比如&#xff1a;角点、边缘等。FAST&#xff08;Features from Accelerated Segment Test&#xff09;是一种高速的角点检测算法&#xff1b;而尺度不变特征变换SIFT&#xff08…

使用DataX同步hive数据到MySQL

目录 1、组件环境 2、安装datax 2.1、下载datax并解压 3、安装datax-web 3.0、下载datax-web的源码&#xff0c;进行编译 3.1、在MySQL中创建datax-web元数据 3.2、安装data-web 3.2.1执行install.sh命令解压部署 3.2.1、手动修改 datax-admin配置文件 3.2.2、手动修改…

【python实操】python小程序之文件操作的输出指定格式数据以及异常捕获

引言 python小程序之文件操作的输出指定格式数据以及异常捕获 文章目录 引言一、文件操作之输出指定格式JSON1.1 题目1.2 代码1.3 代码解释1.3.1 总结 二、异常2.1 概念2.1.1 基本语法2.1.1.1 try...except2.1.1.2 try...except...else2.1.1.3 try...except...finally2.1.1.4 t…

量化选股:原理与实战指南(二)

🌟作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~🍊个人主页:小高要坚强的博客🍓当前专栏:《Python之量化交易》🍎本文内容:量化选股:原理与实战指南(二)🌸作者“三要”格言:要坚强、要努力、要学习 目录 引言 一、价值类因子简介 …

position定位静态定位/绝对定位/相对定位

1.静态定位static&#xff1a;按照标准流进行布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>D…

基于springboot Vue3的两种图形验证码工具——vue3-puzzle-vcode纯前端防人机图形滑动验证码和kaptcha图片文字验证码

一.vue3-puzzle-vcode Vue 纯前端的拼图人机验证、右滑拼图验证 官网&#xff1a; vue3-puzzle-vcode - npm (npmjs.com)https://www.npmjs.com/package/vue3-puzzle-vcode 1.1基本使用步骤 安装 npm install vue-puzzle-vcode --save 简单例子 点击开始验证按钮弹出验证弹…

linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十一)--rpm管理和计划任务

linux从入门到精通-从基础学起&#xff0c;逐步提升&#xff0c;探索linux奥秘&#xff08;十一&#xff09;–rpm管理和计划任务 一、rpm管理&#xff08;重点&#xff09; 1、rpm管理 作用&#xff1a; rpm的作用类似于windows上的电脑管家中“软件管理”、安全卫士里面“…

【机器学习】集成学习|Boosting|随机森林|Adaboost|GBDT梯度提升树|XGBoost 极限梯度提升树 及案例实现

文章目录 集成学习集成学习思想概述集成学习分类Bagging 思想Boosting思想Bagging 和 Boosting 的对比 随机森林算法随机森林实现步骤随机森林算法apiAPI 代码实现 Adaboost 算法实现步骤整体过程实现 算法推导Adaboost 案例 葡萄酒数据 GBDT (梯度提升树)提升树 BDT (Boosting…

WPF 中的 StackPanel 详解

Windows Presentation Foundation&#xff08;WPF&#xff09;是微软开发的一种用于创建桌面客户端应用程序的用户界面框架。WPF 提供了一套丰富的控件和布局能力&#xff0c;使得开发者可以轻松构建出功能强大、视觉优美的用户界面。在 WPF 的布局系统中&#xff0c;StackPane…

Git上传命令汇总

进入企业&#xff0c;每日需要上传执行用例记录到gitlab平台上&#xff0c;本文记录了常用git上传命令&#xff0c; 并用github演示。 1、本地建立分支&#xff0c;克隆远程仓库 在gitlab中&#xff0c;每个人需要创建自己的分支&#xff0c;一般以自己的名字命名&#xff0c;…

新品牌Sesame Street《芝麻街》商标版权双维权,尚未TRO

案件基本情况起诉时间&#xff1a;2024-10-8案件号&#xff1a;24-cv-09713品牌&#xff1a;Sesame Street原告&#xff1a;Sesame Workshop原告律所&#xff1a;TME起诉地&#xff1a;伊利诺伊州北部法院品牌介绍Sesame Street《芝麻街》是美国公共广播协会&#xff08;PBS&…

5个IO控制20个LED灯的方案详解

工程师们经常为了节省一两个IO口想各种方案想到抠脑壳&#xff0c;今天给大家整点活儿&#xff0c;介绍一种超级节省IO口的LED灯控制方案。 5个IO口控制20个LED灯&#xff0c;而且可以对每个LED灯实现单独控制。电路结构如下&#xff1a; 注意一下这种电路网络&#xff0c;其…

ctf.bugku-baby lfi

题目来源&#xff1a;baby lfi - Bugku CTF平台 访问页面&#xff0c; 翻译解析&#xff1a;百度翻译-您的超级翻译伙伴&#xff08;文本、文档翻译&#xff09; (baidu.com) LFI Warmups - 本地文件包含&#xff08;Local File Inclusion&#xff0c;简称LFI&#xff09; H…

【最新华为OD机试E卷-支持在线评测】喊7的次数重排(100分)多语言题解-(Python/C/JavaScript/Java/Cpp)

🍭 大家好这里是春秋招笔试突围 ,一枚热爱算法的程序员 💻 ACM金牌🏅️团队 | 大厂实习经历 | 多年算法竞赛经历 ✨ 本系列打算持续跟新华为OD-E/D卷的多语言AC题解 🧩 大部分包含 Python / C / Javascript / Java / Cpp 多语言代码 👏 感谢大家的订阅➕ 和 喜欢�…

Linux基础-进程的超详细讲解(1)_进程的概念与属性

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 Linux基础-进程的超详细讲解(1) 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1. 进…

day-65 鸡蛋掉落-两枚鸡蛋

思路 动态规划&#xff1a;dp[i]表示i楼f确切的值的最小操作次数&#xff0c;对于上一次选择的楼层共有i-1种可能&#xff08;上一次从1楼,2楼…扔下&#xff09;&#xff0c;所以需要在i-1中可能中去最小值 解题过程 对于每一种可能&#xff0c;如dp[10]上一次从5楼扔下&…

ES-入门聚合查询

url 请求地址 http://192.168.1.108:9200/shopping/_search {"aggs": { //聚合操作"price_group":{ //名称,随意起名"terms":{ //分组"field": "price" //分组字段}}} } 查询出来的结果是 查询结果中价格的平均值 {&q…

KubeSphere部署mysql

演示示例使用的是3.4.1&#xff0c;各版本有名字差异 功能是一样的 由于mysql需要做数据持久化所以需要挂载数据 1.创建mysql基础配置 项目中-配置-配置字典 mysql-conf添加键值对 [client] default-character-setutf8mb4 [mysql] default-character-setutf8mb4 [mysqld] …

数据库设计与开发—初识SQLite与DbGate

一、SQLite与DbGate简介 &#xff08;一&#xff09;SQLite[1][3] SQLite 是一个部署最广泛、用 C 语言编写的数据库引擎&#xff0c;属于嵌入式数据库&#xff0c;其作为库被软件开发人员嵌入到应用程序中。 SQLite 的设计允许在不安装数据库管理系统或不需要数据库管理员的情…