Java通过RAG构建专属知识问答机器人_超详细

RAG:融合检索与生成的文本精准生成技术

检索增强生成(RAG)是一种技术,它通过结合检索模型和生成模型来提高文本生成的准确性。具体来说,RAG首先利用检索模型从私有或专有的数据源中搜索相关信息,然后将这些信息提供给生成模型,如大型语言模型(LLM),以生成更加准确、基于上下文的回复。这种方法有助于减少大模型在生成过程中可能出现的“幻觉”现象,并且能够使模型的回答更贴合企业的特定数据,从而提高了回答的精确度与相关性。这样,在使用大模型时,即使面对企业特有的知识或数据,也能获得更为精准的答案。

Spring AI:提升Java AI开发效率与灵活性的解决方案

我们使用了Spring AI来做这个检索增强。

之所以选择Spring AI,是因为在过去用Java编写AI应用时面临的一个主要困境是没有非常标准的Java封装。

现在,Spring项目推出了一套可以兼容市面上主要各类生成任务的接口——Spring AI,极大地解决了这一问题。

Spring AI通过标准化不同AI提供者的接口实现,使得开发者能够一次编写代码,仅通过修改配置即可轻松切换不同的AI实现。

同时,它直接兼容Flux流输出,简化了与基于流的机器人模型的集成。通过良好的抽象设计,Spring AI显著减少了程序员在对接不同类型接口时查阅文档和迁移实现的工作量,为基于Java的AI开发带来了极大的便利性和效率提升。因此,采用Spring AI不仅提高了开发效率,还增强了项目的可维护性与灵活性。

Spring生态AI框架:Spring AI Alibaba,赋能Java开发者高效对接多AI服务商

Spring AI Alibaba 是基于 Spring 生态系统设计的用于AI工程的应用框架,特别适合 Java 和 Spring Boot 开发者。它通过提供一套统一的抽象接口,标准化了不同AI服务提供商(如阿里云、OpenAI等)的接入方式,使得开发者能够轻松切换AI服务而无需大幅改动代码。此外,Spring AI Alibaba 集成了阿里云百炼系列的多个模型,支持对话、文本生成图像等功能,并提供了诸如Prompt Template等实用工具来简化开发过程。其核心优势在于极大提高了AI应用开发的效率与灵活性,同时保持了与现有Java Spring Boot项目的良好兼容性。

增强检索:打造PDF财务报表查询后端代码

为了通过检索增强的方式读取一个阿里巴巴的财务报表PDF并提供对外服务,我们需要按照以下步骤进行:

1. 确保前置条件

  • JDK版本:确保你的JDK版本在17及以上。
  • Spring Boot版本:确认使用的Spring Boot版本为3.3.x或更高。
  • API Key申请:访问阿里云百炼页面,登录账号后开通“百炼大模型推理”服务,并创建一个新的API Key。将此Key配置到环境变量中:
export AI_DASHSCOPE_API_KEY=YOUR_VALID_API_KEY

并且,在application.properties文件里添加:

spring.ai.dashscope.api-key: ${AI_DASHSCOPE_API_KEY}

2. 添加仓库与依赖

由于spring-ai-alibaba-starter尚未发布到Maven中央仓库,因此需要在项目的pom.xml文件中添加如下仓库设置来支持获取最新快照版本及里程碑版本:

<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</version>

    </dependency>

    <!-- 其他依赖 -->
</dependencies>

3. 编写RAG服务相关代码

首先定义RagService类用于处理索引构建和查询逻辑。这包括向量存储、文档检索器以及如何使用这些组件来处理来自客户端的请求。

public class RagService {

    private final ChatClient chatClient;
    private final VectorStore vectorStore;
    private final DashScopeApi dashscopeApi = new DashScopeApi("您的API密钥");
    DocumentRetriever retriever;

    public RagService(ChatClient chatClient, EmbeddingModel embeddingModel) {
        this.chatClient = chatClient;
        vectorStore = new DashScopeCloudStore(dashscopeApi,
                new DashScopeStoreOptions("阿里巴巴财报知识库"));
        retriever = new DashScopeDocumentRetriever(dashscopeApi,
                DashScopeDocumentRetrieverOptions.builder().withIndexName("阿里巴巴财报知识库").build());
    }

    // 构建索引
    public String buildIndex() {
        String filePath = "/path/to/your/financial_report.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. 创建Controller以暴露REST API

最后,我们需要创建一个控制器类来接收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", defaultValue = "2024年6月止,云智能集团的营收是多少?") String input, HttpServletResponse httpResponse) {
        StreamResponseSpec chatResponse = ragService.queryWithDocumentRetrieval(input);
        httpResponse.setCharacterEncoding("UTF-8");
        return chatResponse.content();
    }

    @GetMapping("/buildIndex")
    public String buildIndex() {
        return ragService.buildIndex();
    }
}

通过上述步骤,我们实现了基于Spring Cloud Alibaba框架下的检索增强功能,能够从指定的PDF文件中提取信息并通过HTTP接口返回给用户。需要注意的是,在实际部署前,请确保已经完成了所有必要的环境配置,特别是关于API密钥的安全管理和正确配置。

构建React流式聊天应用:从零开始的实现攻略


基于提供的知识,我们可以分析出构建一个支持流式输出的前端项目需要遵循一定的步骤。这里的项目将使用React框架来创建,并与后端服务进行交互以处理用户输入并显示响应。后端接口返回的是flux<String>数据类型,这意味着客户端能够以渐进的方式接收和展示信息,而非等待全部数据加载完毕后再一次性展示。

分析

从给出的知识来看,我们已经有了关于如何设置基础React环境、以及如何处理流式数据请求的具体示例。这些例子非常适合用来作为本问题解决方案的基础。接下来将详细介绍如何根据要求实现这样一个前端应用。

实现步骤

首先,确保你已经安装了Node.js和npm(或yarn),然后按照以下步骤操作:

  1. 初始化一个新的React应用
npx create-react-app rag-chat-frontend
cd rag-chat-frontend
npm install
  1. 修改public/index.html文件(如果需要自定义HTML头部等信息):不过在这个案例中,我们可以直接使用默认生成的内容。
  1. 更新src/index.js以引入应用程序入口点:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
  1. 编写主组件src/App.js:
import React from 'react';
import ChatComponent from './components/ChatComponent';

function App() {
  return (
    <div className="App">
      <ChatComponent />
    </div>

  );
}

export default App;
  1. 创建聊天组件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 () => {
    try {
      const response = await fetch(`http://localhost:8080/ai/steamChat?input=${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);
    }
  };

  return (
    <div>
      <input
        type="text"
        value={input}
        onChange={handleInputChange}
        placeholder="Enter your message"
      />
      <button onClick={handleSendMessage}>Send</button>

      <div>
        <h3>Messages:</h3>

        <pre>{messages}</pre>

      </div>

    </div>

  );
}

export default ChatComponent;
  1. 启动你的React应用:
npm start

这将打开浏览器并自动导航到 http://localhost:3000/ ,你可以在这里测试你的聊天界面。

小结

通过上述步骤,我们建立了一个基本的聊天应用程序界面,它可以通过发送GET请求至指定URL (http://localhost:8080/ai/steamChat) 来与后端通信。该请求会携带用户的输入文本参数。当后端开始流式地返回数据时,前端应用程序会逐步解析这些数据片段,并即时更新显示给用户。这种方式非常适合于实时性较强的场景,如在线聊天或实时问答系统。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32—SPI通讯协议

前言 由于I2C开漏外加上拉电阻的电路结构&#xff0c;使得通信线高电平的驱动能力比较弱&#xff0c;这就会号致&#xff0c;通信线由候电平变到高电平的时候&#xff0c;这个上升沿耗时比较长&#xff0c;这会限制I2C的最大通信速度&#xff0c; 所以&#xff0c;I2C的标准模…

uniapp学习(003-2 vue3学习 Part.2)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第15p-第p20的内容 文章目录 事件监听以及组件内置事件处理自定义模板快速创建uniapp条件渲染 v-if和v-elsev-e…

搭建一个vue3+vite框架

可以使用以下两种搭建方式 通过create-vue搭建vue3 项目&#xff08;建议使用&#xff09; create-vue create-vue 是 Vue.js 官方推荐的用于快速启动 Vite 驱动的 Vue 项目的脚手架工具。它简化了创建新 Vue 项目的过程&#xff0c;提供了预配置的项目结构&#xff0c;并集…

Mac 远程 Windows 等桌面操作系统工具 Microsoft Remote Desktop for Mac 下载安装详细使用教程

最近需要在 Mac 上远程连接控制我的 windows 电脑系统&#xff0c;经过一番尝试对于 win 来说还是微软自家推出的 Microsoft Remote Desktop for Mac 最最好用&#xff0c;没有之一 简介 Microsoft Remote Desktop是一款由微软公司开发的远程桌面连接工具&#xff0c;可以让用…

如何解决与kernel32.dll相关的常见错误:详细指南解析kernel32.dll文件缺失、损坏或错误加载问题

当你的电脑中出现错误kernel32.dll丢失的问题&#xff0c;会导致电脑不能出现正常运行&#xff0c;希望能够有效的帮助你有效的将丢失的kernel32.dll文件进行修复同时也给大家介绍一些关于kernel32.dll文件的相关介绍&#xff0c;希望能够有效的帮助你快速修复错误。 kernel32.…

学习笔记——交换——STP(生成树)基本概念

三、基本概念 1、桥ID/网桥ID (Bridege ID&#xff0c;BID) 每一台运行STP的交换机都拥有一个唯一的桥ID(BID)&#xff0c;BID(Bridge ID/桥ID)。在STP里我们使用不同的桥ID标识不同的交换机。 (2)BID(桥ID)组成 BID(桥ID)组成(8个字节)&#xff1a;由16位(2字节)的桥优先级…

QT布局详解 QT5大布局详解

QT布局详解 QT5大布局详解 1. Qt 布局基础 在 Qt 中&#xff0c;布局管理器用于自动调整窗口中控件的位置和大小。它们根据控件的尺寸策略、父窗口的大小以及控件的彼此关系&#xff0c;动态地调整控件。 常用的布局类包括&#xff1a; QHBoxLayout&#xff1a;水平布局管理…

MybatisWebApp

如何构建一个有关Mybatis的Web&#xff1f; 在这里给出我自己的一些配置。我的TomCat版本&#xff1a;10.1.28 &#xff0c;IDEA版本&#xff1a;2024.1.4 Pom.XML文件 <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/200…

小米电机与STM32——CAN通信

背景介绍&#xff1a;为了利用小米电机&#xff0c;搭建机械臂的关节&#xff0c;需要学习小米电机的使用方法。计划采用STM32驱动小米电机&#xff0c;实现指定运动&#xff0c;为此需要了解他们之间的通信方式&#xff0c;指令写入方法等。花了很多时间学习&#xff0c;但网络…

Solidity优质例子(二)物流的增删改查智能合约(附truffle测试)

本合约非常适合新手学习&#xff0c;其包含了基本的增删改查功能以及各个方式的不同之处的总结&#xff0c;本套合约我也编写了truffle测试&#xff0c;学习truffle测试的小伙伴也有福了~ 该合约的主要作用是通过区块链技术实现物流追踪系统的透明化、自动化与防篡改特性&#…

AES对称加密算法

AES&#xff08;Advanced Encryption Standard&#xff09;是取代DES而成为新标准的一种对称加密算法。在全世界提交的众多对称加密算法的候选中&#xff0c;其中有一个名为Rijndael的对称加密算法&#xff0c;将其命名为AES。 整体流程 分组长度 在AES中&#xff0c;分组长度…

Linux:信号保存与处理

使用kill -l命令查看信号&#xff1a; 信号量和信号确实一点关系没有 信号是操作系统发出的进程与进程之间的通知于中断&#xff0c;是进程之间时间异步通知的一种方式 先了解同步通信&#xff1a;同步通信是一种比特同步通信技术&#xff0c;要求发收双方具有同频同相的同步…

若依框架篇-若依框架搭建具体过程、后端源代码分析、功能详解(权限控制、数据字典、定时任务、代码生成、表单构建、接口测试)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 若依框架概述 1.1 若依构建 1.2 后端项目搭建 1.3 前端项目搭建 2.0 利用若依框架生成前后端代码案例 3.0 功能详解 3.1 功能详解 - 权限控制 3.1.1 使用权限控制…

Djang学习- URL反转

代码中url书写规范&#xff1a; 、 url反向解析 urls: path(test/url, views.test_url),path(test_result/<int:age>, views.test_result, name"rl") views: def test_url(request):return render(request, test_url.html)def test_result(request,age):re…

Lintcode 3686 · N 叉树的直径【中等 DFS/BFS java答案】

题目 题目链接&#xff1a;https://www.lintcode.com/problem/3686/ 思路 1.利用map创建图 2.找到直径的其中一个端点last,通过bfs可以实现 3.从last出发&#xff0c;再次bfs,有多少层&#xff0c;直径就是多少Java代码 /*** Definition for Undirected graph.* class Undir…

100. UE5 GAS RPG 显示范围魔法的攻击范围

在这一篇里&#xff0c;我们将制作一个范围魔法&#xff0c;释放魔法时&#xff0c;我们将在鼠标拾取位置绘制一个魔法光圈&#xff0c;用于显示技能释放时攻击的范围&#xff0c;然后再次点击可以释放技能。 创建贴花类 魔法范围标识的光圈&#xff0c;我们采用贴花实现&…

2014年国赛高教杯数学建模B题创意平板折叠桌解题全过程文档及程序

2014年国赛高教杯数学建模 B题 创意平板折叠桌 某公司生产一种可折叠的桌子&#xff0c;桌面呈圆形&#xff0c;桌腿随着铰链的活动可以平摊成一张平板&#xff08;如图1-2所示&#xff09;。桌腿由若干根木条组成&#xff0c;分成两组&#xff0c;每组各用一根钢筋将木条连接…

44 C 语言输入输出流、scanf 与 printf 函数详解、清除输入缓冲区

目录 1 文件基本介绍 1.1 文件的主要功能 1.2 输入输出流 2 C 语言中的输入与输出 2.1 输入 2.2 输出 2.3 标准文件与文件指针 3 scanf() 函数详解 3.1 功能描述 3.2 函数原型 3.3 常用格式说明符 3.4 返回值 3.5 注意事项 3.5.1 处理空白字符 3.5.2 防止缓冲区…

Linux命令进阶

grep 从文件中搜索字符串 grep "字符串" 文件 参数&#xff1a; -n 显示行号 -R 递归及子目录例如 grep "hello" log.c grep "main" * -nRfind 在指定路径下搜索文件 find 路径 -name 文件名find /home/linux -name hello.c //在/home/linux…

精选优质不收费数据恢复软件全解析

数据已经成为了我们生活和工作中无比珍贵的资产。然而我们在使用中总会因为各种意外导致数据丢失。今天&#xff0c;我们就来深入了解一些优秀的不收费的数据恢复软件&#xff0c;看看他们如果帮我们力挽狂澜。 1.福晰数据恢复 链接直达&#xff1a;https://www.pdf365.cn/fo…