【spring ai】java 实现RAG检索增强,超快速入门
rag 需求产生的背景介绍:
在使用大模型时,一个常见的问题是模型会产生幻觉(即生成的内容与事实不符),同时由于缺乏企业内部数据的支持,导致其回答往往不够精准和具体,偏向于泛泛而谈。这些问题限制了大模型直接应用于特定业务场景的效果。通过引入RAG (Retrieval-Augmented Generation)机制,可以结合外部知识库或私有数据源来提高生成内容的准确性和相关性,有效缓解上述问题。
基于spring ai来做rag的优势介绍
我们使用了Spring AI来做检索增强,因为过去用Java写AI应用时面临的主要困境是没有标准的封装。现在Spring推出了Spring AI,它提供了一套可以兼容市面上主要生成任务的接口,极大地方便了开发工作。Spring AI不仅支持阿里云的通义大模型等服务,还能够通过简单的配置切换不同的AI提供商,使得开发者可以更加专注于业务逻辑而无需过多关注底层实现细节。这种标准化和模块化的设计,让Spring AI成为了构建AI应用程序的理想选择。
Spring AI alibaba介绍
Spring AI Alibaba 是一个针对 Spring AI 的实现,基于阿里云百炼系列云产品提供大模型接入。它主要支持包括对话、文生图、文生语音等在内的多种生成式AI功能,并且能够兼容市面上大部分基于流的机器人模型。通过使用 Spring AI Alibaba,开发者可以轻松地将这些强大的AI能力集成到自己的Java应用程序中。其核心优势在于提供了统一且标准化的接口来访问不同的AI服务提供商(如OpenAI、Azure和阿里云),从而减少了因切换不同服务商而带来的开发工作量。此外,Spring AI Alibaba 还支持通过简单的配置即可调整使用的具体模型,比如用于绘画或图像生成的通义万象模型,极大简化了AI应用开发流程。
检索增强的后端代码编写
为了通过检索增强的方式读取一个阿里巴巴的财务报表PDF,并对外提供服务,基于提供的知识内容,首先需要理解RAG(检索增强生成)的基本概念和技术实现。这里采用的是阿里云百炼平台与Spring AI Alibaba集成的技术栈来完成这个需求。下面将详细介绍具体的配置和代码实现步骤。
一、环境准备
- 确保JDK版本:必须使用JDK 17或更高版本。
- Spring Boot版本:项目应基于Spring Boot 3.3.x 版本。
- 获取API Key:访问阿里云百炼页面,按照指引开通“百炼大模型推理”服务后创建并保存好API key。
- 设置环境变量:在你的开发环境中设置
AI_DASHSCOPE_API_KEY
为刚才获得的API key值。 - 项目依赖配置:
- 添加额外的Maven仓库以支持spring ai alibaba starter 的引入。
- 在pom.xml中加入spring ai alibaba starter以及指定Spring Boot的父级项目。
<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><dependencies><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter</artifactId><version>1.0.0-M2.1</version></dependency><!-- Spring Boot Parent --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.4</version></parent>...other dependencies...
</dependencies>
二、服务端代码实现
根据上述配置完成后,接下来是具体的服务端逻辑编写,主要包括构建索引和查询两个部分。
1. 构建索引
此步骤用于从给定的PDF文件中提取文档数据并将其转换为向量存储到VectorStore中。只需要首次运行时调用一次。
public String buildIndex() {String filePath = "/path/to/your/alibaba_financial_report.pdf";DocumentReader reader = new DashScopeDocumentCloudReader(filePath, dashscopeApi, null);List<Document> documentList = reader.get();vectorStore.add(documentList);return "SUCCESS";
}
2. 提供查询接口
客户端可通过GET请求向/ai/steamChat
发送消息参数input
,服务器将返回基于上下文信息生成的回答。
@GetMapping("/steamChat")
public Flux<String> generate(@RequestParam("input") String message, HttpServletResponse httpResponse) {StreamResponseSpec chatResponse = ragService.queryWithDocumentRetrieval(message);httpResponse.setCharacterEncoding("UTF-8");return chatResponse.content();
}
三、启动应用并测试
完成以上步骤后,启动Spring Boot应用。第一次运行时,请先访问http://localhost:8080/ai/buildIndex
来初始化索引。之后就可以通过访问http://localhost:8080/ai/steamChat?input=您的问题
来进行问答了。
这样,我们就完成了基于RAG技术对阿里巴巴财务报告PDF文件的处理,并且能够通过简单的HTTP接口进行交互式问答。
检索增强的前端代码编写
基于我了解的信息中的内容,我们将使用React构建一个前端项目,该项目能够通过流式方式从前端向后端发送请求,并接收后端返回的flux<String>
数据。根据题目要求,后端接口URL为http://localhost:8080/ai/steamChat?input=…
,该接口会返回基于检索增强生成的内容。
构建并配置React项目
首先,确保你的开发环境已经安装了Node.js和npm(或yarn)。然后按照以下步骤创建一个新的React应用:
npx create-react-app frontend
cd frontend
npm install
此命令将帮助你快速搭建起基础的React项目结构,并自动安装所有必需的依赖项。
接下来,在public/index.html
中保持默认设置即可,因为这个文件主要用于定义基本HTML文档结构。
修改关键组件
在src/App.js
中引入我们即将编写的聊天组件ChatComponent
:
import React from 'react';
import ChatComponent from './components/ChatComponent';function App() {return (<div className="App"><ChatComponent /></div>);
}export default App;
然后,我们需要重点实现src/components/ChatComponent.js
,这是整个交互的核心所在。在这个组件里,我们将实现输入框、发送消息按钮以及展示从服务器接收到的消息的功能。
import React, { useState } from 'react';function ChatComponent() {const [input, setInput] = useState('');const [messages, setMessages] = useState('');const handleInputChange = (event) => {setInput(event.target.value);};const handleSendMessage = async () => {if (!input.trim()) return; // 确保不发送空消息try {const response = await fetch(`http://localhost:8080/ai/steamChat?input=${encodeURIComponent(input)}`);if (!response.ok) throw new Error('Network response was not ok');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);} finally {setInput(''); // 清除输入框}};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 ChatComponent;
这里的关键点在于如何处理流式响应。我们使用了fetch
API来发起请求,并利用TextDecoder
解码每个读取的数据块。每次获取到新数据时,我们都更新状态变量messages
,以便于实时显示最新消息。
运行项目
最后,启动你的React应用程序:
npm start
这将打开本地开发服务器,默认监听端口3000。你可以通过浏览器访问http://localhost:3000
查看效果。
小结
上述过程展示了如何利用现代Web技术栈结合Spring AI Alibaba提供的流式接口功能,快速构建一个简单的支持流输出的聊天应用程序。用户界面非常直观,允许用户输入文本并通过点击“Send”按钮发送给后端进行处理,而前端则负责动态地展示接收到的信息。这样的设计非常适合需要即时反馈的应用场景,比如在线客服系统或智能助手等。
相关文章:

【spring ai】java 实现RAG检索增强,超快速入门
rag 需求产生的背景介绍: 在使用大模型时,一个常见的问题是模型会产生幻觉(即生成的内容与事实不符),同时由于缺乏企业内部数据的支持,导致其回答往往不够精准和具体,偏向于泛泛而谈。这些问题…...

【Java SE 题库】递归的魅力之--> 汉诺塔问题
🔥博客主页🔥:【 坊钰_CSDN博客 】 欢迎各位点赞👍评论✍收藏⭐ 目录 1. 题目 2. 分析 2.1 图解 2.2 代码解析 3. 完整代码 3.1 运行截图 4. 小结 1. 题目 汉诺塔问题是一个经典的递归问题,源自一个古老的印度传…...

《为什么要在三层交换机 VLAN 上配置 IP 地址?》
如果在三层交换机上划分了 VLAN10 和 VLAN20 但没有给 IP 地址的情况下,只有相同 VLAN 的端口之间才能相互通信。 这是因为在没有为 VLAN 配置 IP 地址(即没有创建 SVI,交换虚拟接口)时,三层交换机仅作为一个二层设备…...

Git的基本使用入门
参考:Git速查 git的基本概念 git常用命令大部分是基于三大分区来执行的。先来了解一些专有名词吧。 工作区,也叫 Working Directory暂存区,也叫 stage,index版本库,也叫本地仓库,commit History 将代码推…...

Elasticsearch 入门
ES 概述 ES 是一个开源的高扩展的分布式全文搜索引擎。 倒排索引 环境准备 Elasticsearch 官方地址:https://www.elastic.co/cn/ 下载地址: 注意:9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 h…...

WebSocket 集成 Spring Boot 的实战指南
🍁 作者:知识浅谈,CSDN签约讲师&博客专家,华为云云享专家,阿里云专家博主,InfoQ签约作者 📌 擅长领域:全栈工程师、爬虫、ACM算法,大数据,深度学习 &…...

无人机集群路径规划:四种优化算法(BKA、CO、PSO、PIO)求解无人机集群路径规划,提供MATLAB代码
一、单个无人机路径规划模型介绍 无人机三维路径规划是指在三维空间中为无人机规划一条合理的飞行路径,使其能够安全、高效地完成任务。路径规划是无人机自主飞行的关键技术之一,它可以通过算法和模型来确定无人机的航迹,以避开障碍物、优化…...

第二届 龙信杯 电子数据取证竞赛部分Writeup
大佬文章: 龙信杯复现(23、24) | BthclsBlog 手机部分 资料:2024年第二届龙信杯 WP_2024龙信杯wp-CSDN博客 1.分析手机检材,请问此手机共通过adb连接过几个设备?[标准格式:3] 2 /data/a…...

偷啥的都有!
好久不做地铁了,昨个儿加班儿太晚,就没骑车回家。早上到了地铁站,想起我前一阵儿下雨时候,把自行车放在了地铁站,结果尾灯被人偷了! 真是偷啥的都有! 2024年10月15日 7:41...

【中文注释】planning_scene_tutorial.cpp
planning_scene_tutorial.cpp #include <rclcpp/rclcpp.hpp>// MoveIt 相关头文件 #include <moveit/robot_model_loader/robot_model_loader.h> #include <moveit/planning_scene/planning_scene.h> #include <moveit/kinematic_constraints/utils.h>…...

【Vue3】 h()函数的用法
目录 介绍 参数 使用案例 1.创建虚拟 DOM 元素 2. 组件的动态渲染 3. 创建功能组件 4.渲染动态属性 5. 使用插槽 6. 创建动态标签 介绍 h() 函数用于辅助创建虚拟 DOM 节点,它是 hypescript 的简称——能生成 HTML (超文本标记语言) 的 JavaScript&#x…...

Flask如何实现前后端分离项目
在现代Web开发中,前后端分离是一种常见的架构模式,其中前端和后端分别独立开发和部署,通过API进行通信。Flask作为后端框架,可以很容易地与前端框架(如React、Vue.js或Angular)配合使用来实现前后端分离。以…...

二维码生成器 1.02.41| 一站式QR码生成器和美化工具
二维码生成器是一个有用的QR码生成器应用程序。可以轻松地为网站链接、文本、WiFi、名片、短信、社交媒体账户等生成QR码。该应用支持更改QR码的颜色、码眼图案和框架,并可以添加徽标和文本,使QR码更加美观。使用此QR码生成器,可以使用设计精…...

腾讯云视立方·直播 SDK 合规使用指南
为帮助使用直播 SDK 的开发运营者(以下简称“您”)在符合个人信息保护相关法律法规、政策及标准的规定下合规接入、使用第三方SDK,深圳市腾讯计算机系统有限公司(以下简称"我们")特制定《直播 SDK 接入使用说…...

在 Spring 中使用 @EhCache 注解作为缓存
文章目录 项目概况项目设置一个简单的 RESTful Web 服务Spring 整合 EhCache第 1 步:更新依赖项以使用 EhCache Spring 注解第 2 步:设置自定义缓存管理器第 3 步:配置 EhCache第 4 步:测试缓存 刷新缓存总结推荐阅读文章 EhCache…...

npm install进度卡在 idealTree:node_global: sill idealTree buildDeps
ping一下源:ping http://registry.npm.taobao.org/ ping不通,原因:原淘宝npm永久停止服务,已更新新域名~~震惊!!! 重新安装:npm config set registry https://registry.npmmirror.c…...

力扣1031. 两个非重叠子数组的最大和
力扣1031. 两个非重叠子数组的最大和 题目解析及思路 题目要求找到两段长分别为firstLen 和 secondLen的子数组,使两段元素和最大 图解见灵神 枚举第二段区间的右端点,在左边剩余部分中找出元素和最大的第一段区间,并用前缀和优化求子数组…...

【Unity实战篇】 接入百度翻译,实现文本自动翻译功能
前言【Unity实战篇】 接入百度自动翻译,实现文本自动翻译功能一、获取百度翻译开发平台的APPID和密钥二、Unity中接入自动翻译功能三、Unity中实现自动翻译文本Text功能总结前言 日常在做项目的过程中,游戏本地化几乎已经成为必不可少的一步。本篇文章将演示怎样在Unity中接入…...

ubuntu samba
参考: 基于Ubuntu22.04的Samba服务器搭建教程(新手保姆级教程)_ubuntu samba-CSDN博客 当时按照这个不行: 主要做了这些修改 1、ufw 打开端口 这些都打开了 Samba服务使用的端口和协议如下1234: Port 137 (UDP) - NetBIOS 名…...

Linux系统和数据库常用的命令2
Linux系统和数据库常用的命令2 1、两台Linux机器ssh免密登录 client端登录server端需要免密,只需把公钥发送到server就可,会在server端生成一个authorized_keys文件 # 108机器上[rootclient ~]# ssh-keygen -t rsa // 非对称算法 Generating public/…...

Golang | Leetcode Golang题解之第468题验证IP地址
题目: 题解: func validIPAddress(queryIP string) string {if sp : strings.Split(queryIP, "."); len(sp) 4 {for _, s : range sp {if len(s) > 1 && s[0] 0 {return "Neither"}if v, err : strconv.Atoi(s); err …...

mermaid 图表相关
1.mermaid图表的代码 1.1 flowchart 流程图代码 flowchart TDA[Christmas] -->|Get money| B(Go shopping)B --> C{Let me think}C -->|One| D[Laptop]C -->|Two| E[iPhone]C -->|Three| F[fa:fa-car Car]1.2 sequece 时序图代码 sequenceDiagramAlice->&…...

Unity接入人工智能
在Unity接入人工智能中,本篇实现了接入百度智能云ai进行npc智能对话,通过http方式,并非插件,适合于所有支持Http链接的Unity版本。对于Chartgpt可以参考本篇内容的实现过程。 1-4节讲解测试,第5节讲解Unity中的实现&a…...

C语言笔记 14
函数原型 函数的先后关系 我们把自己定义的函数isPrime()写在main函数上面 是因为C的编译器自上而下顺序分析你的代码,在看到isPrime的时候,它需要知道isPrime()的样子——也就是isPrime()要几个参数,每个参数的类型如何,返回什么…...

Cpp::STL—list类的模拟实现(上)(13)
文章目录 前言一、结点类的实现二、迭代器类的实现迭代器类的存在意义迭代器类的模板参数构造函数运算符的重载--运算符的重载、!运算符的重载*运算符的重载->运算符的重载 总结 前言 注意本篇难度偏高,其主要体现在迭代器类的实现! 什么…...

ListView的Items绑定和comboBox和CheckBox组合使用实现复选框的功能
为 ListView 控件的内容指定视图模式的方法,参考官方文档。 ComboBox 样式和模板 案例说明:通过checkBox和ComboBox的组合方式实现下拉窗口的多选方式,同时说明了ListView中Items项目的两种绑定方式. 示例: 设计样式 Xaml代码…...

PetaLinux工程的常用命令——petalinux-build
petalinux-build:编译项目或指定组件。 注:有些命令我没用过,瞎翻译有可能会翻译错了。 用法: petalinux-build [options] 可选参数: -h, --help 显示函数用法。 -p, --project <PROJECT> PetaLinuxSDK项目的路径。默认…...

【Qt】窗口预览(1)—— 菜单栏
窗口预览(1) 1. QMainWindow2. QMenuBar——菜单栏2.1 创建菜单栏/将菜单栏添加到widget中2.2 addMenu——在菜单栏中添加菜单2.3 在菜单中添加选项2.4 添加快捷键2.5 支持嵌套添加菜单2.6 添加信号2.7 添加分割线 1. QMainWindow Qt窗口是通过QMainWin…...

揭秘酱香型白酒中的6大劣质酒的特点,守好你的健康与钱包
你知道吗?居然有 90%的人都喝过这 6 种劣质酱香型白酒,今天酱酒亮哥就带大家一起揭开它们的真面目,看看你中招了没有! 先说那种有很浓的生粮味的酱酒,就像刚磨出来还没烧开的豆浆味,喝起来那叫一个难受。想…...

C#拓展方法
定义 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改原始类型。 扩展方法是一种静态方法,但可以像扩展类型上的实例方法一样进行调用。 对于用 C#、F# 和 Visual Basic 编写的客户端代码,调用扩…...