springboot 整合spring ai实现 基于知识库的客服问答

news2024/12/23 13:00:47

rag 需求产生的背景介绍:

在使用大模型时,常遇到的问题之一是模型可能产生幻觉,即生成的内容缺乏准确性。此外,由于大模型不直接访问企业的专有数据,其响应可能会显得泛泛而谈,不够精准或具体,无法充分利用企业内部的特定信息进行个性化回答。这些问题限制了大模型在某些需要高精度和定制化场景中的应用效果。

整体说明

我们使用了Spring AI来做检索增强,选择Spring AI是因为它解决了过去用Java编写AI应用时缺乏标准化封装的问题。Spring AI提供了一套兼容市面上主要生成任务的接口,极大简化了开发流程。通过Spring AI,开发者可以轻松实现对多种模型的支持,仅需更改配置即可切换不同的AI服务提供者,从而极大地提高了开发效率和灵活性。此外,Spring AI与Spring生态系统的无缝集成,进一步确保了应用程序的可移植性和模块化设计。

Spring AI alibaba介绍

Spring AI Alibaba是专为Java开发者设计的一个框架,它集成了阿里云的AI能力,特别是通义大模型服务,使得开发者能够快速实现诸如文本生成、绘画等基于AI的功能。其核心优势在于标准化了不同AI提供者(如OpenAI、Azure、阿里云)的接口,这意味着开发者只需编写一次代码,通过简单的配置调整即可切换不同的AI服务。对于绘画或图像生成而言,Spring AI Alibaba简化了与阿里云万象模型交互的过程,允许用户轻松调用API生成高质量图像。此外,框架还提供了包括OutputParser、Prompt Template在内的实用功能,进一步降低了开发复杂度,让开发者可以专注于业务逻辑而非底层技术细节。总之,Spring AI Alibaba极大提升了使用Java进行AI应用开发的效率和灵活性。

检索增强的后端代码编写

根据提供的我了解的信息,为了实现通过检索增强(RAG)方式读取阿里巴巴的财务报表PDF,并对外提供服务,需要按照如下步骤进行配置和编码。这将允许你先调用/buildIndex构建索引,之后能够通过访问http://localhost:8080/ai/rag?message=...来获取基于该文档内容生成的回答。

前置条件

确保你的开发环境满足以下要求:

  • JDK版本为17或更高。
  • Spring Boot版本为3.3.x或以上。
  • 从阿里云获取通义千问API key并设置环境变量 AI_DASHSCOPE_API_KEY 或者直接在application.properties中配置 spring.ai.dashscope.api-key

添加Spring AI Alibaba依赖

在项目中添加必要的仓库以及spring-ai-alibaba-starter依赖项:

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

同时,请确保您的pom.xml文件中定义了正确的Spring Boot父项目版本。

RAG服务类实现

创建一个名为RagService的服务类,用于处理向量存储、文档检索等逻辑:

public class RagService {
    
    private final ChatClient chatClient;
    private final VectorStore vectorStore;
    private final DashScopeApi dashscopeApi = new DashScopeApi("YOUR_API_KEY_HERE");
    private DocumentRetriever retriever;

    public RagService(ChatClient chatClient, EmbeddingModel embeddingModel) {
        this.chatClient = chatClient;
        vectorStore = new DashScopeCloudStore(dashscopeApi, new DashScopeStoreOptions("financial-reports"));
        retriever = new DashScopeDocumentRetriever(dashscopeApi,
                DashScopeDocumentRetrieverOptions.builder().withIndexName("financial-reports").build());
    }

    public String buildIndex() {
        String filePath = "/path/to/your/AlibabaFinancialReport.pdf";
        DocumentReader reader = new DashScopeDocumentCloudReader(filePath, dashscopeApi, null);
        List<Document> documents = reader.get();
        vectorStore.add(documents);
        return "SUCCESS";
    }

    public StreamResponseSpec queryWithDocumentRetrieval(String message) {
        return chatClient.prompt()
                .user(message)
                .advisors(new DocumentRetrievalAdvisor(retriever, """
                        上下文信息如下。
                        ---------------------
                        {documents}
                        ---------------------
                        根据上下文回答问题。如果答案不在上下文中,请告知用户无法回答。
                        """))
                .stream();
    }
}

控制器类实现

最后,实现一个REST控制器以暴露/buildIndex/rag端点:

@RestController
@RequestMapping("/ai")
public class RagController {

    private final RagService ragService;

    @Autowired
    public RagController(RagService ragService) {
        this.ragService = ragService;
    }

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

    @GetMapping("/ragChat")
    public Flux<String> generate(@RequestParam(value = "input") String message, HttpServletResponse response) {
        response.setCharacterEncoding("UTF-8");
        return ragService.queryWithDocumentRetrieval(message).content();
    }
}

通过上述步骤,您已经成功设置了使用RAG技术处理PDF文档并提供问答服务的基础架构。记得首先运行/buildIndex来初始化数据索引,随后可以通过/rag?message=...发起查询请求获取结果。

检索增强的前端代码编写

构建项目并填写代码

首先,创建一个新的 React 应用并安装所需的依赖:

npx create-react-app ragChatFrontend
cd ragChatFrontend
npm install
public/index.html

编辑public/index.html文件以确保基础HTML结构正确设置。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>RAG Chat App</title>

</head>

<body>
  <div id="root"></div>

</body>

</html>
src/index.js

配置React应用入口点。

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

这是核心的聊天组件,实现了与后端流式接口的交互。这里我们假设后端支持GET方法来接收查询参数input并返回flux<String>格式的数据流。

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 () => {
    try {
      // 注意这里的URL和请求方式要与你的后端服务相匹配
      const response = await fetch(`http://localhost:8080/ai/ragChat?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 data:', error);
    }
  };

  const handleClearMessages = () => {
    setMessages('');
  };

  return (
    <div>
      <input
        type="text"
        value={input}
        onChange={handleInputChange}
        placeholder="输入您的问题..."
      />
      <button onClick={handleSendMessage}>发送</button>

      <button onClick={handleClearMessages}>清空</button>

      <h3>聊天记录:</h3>

      <pre>{messages}</pre>

    </div>

  );
}

export default RAGChatComponent;

运行项目

完成以上步骤后,您可以通过以下命令启动前端应用进行测试:

cd ragChatFrontend
npm start

这将打开一个本地服务器,默认访问地址为 http://localhost:3000,您可以在这里查看到构建好的应用程序界面。

上述实现基于React框架,并通过fetch API调用后端提供的流式数据接口。每当用户点击“发送”按钮时,会触发对指定后端服务的HTTP GET请求,随后从前端逐段读取返回的流数据并显示给用户。请注意调整实际部署时可能涉及的跨域策略(CORS)以保证前后端之间通信顺畅。

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

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

相关文章

Vue包的安装使用

文章目录 vue介绍一、灵活易用1.渐进式框架2.简洁的语法 二、高效的响应式系统1.数据驱动2.响应式原理 三、强大的组件化开发1.组件化思想2.组件通信 四、丰富的生态系统1.插件和库2.社区支持 安装依赖删除新增文件夹components设置(1)home.vue(2)data.vue(3)zero.vue router配…

Visual Studio Code 中通过鼠标滚轮调整字体大小并使用 Ctrl+W 关闭文档窗口【最详细】

1. 使用鼠标滚轮调整字体大小 希望通过鼠标滚轮与 Ctrl 键组合来放大或缩小编辑器的字体大小&#xff0c;按照以下步骤进行设置&#xff1a; 打开 Visual Studio Code。 进入设置页面&#xff1a; 点击左下角的齿轮图标&#xff0c;然后选择“设置”。 或者直接使用快捷键 …

最新Prompt预设词指令教程大全ChatGPT、AI智能体(300+预设词应用)

使用指南 直接复制在AI工具助手中使用&#xff08;提问前&#xff09; 可以前往已经添加好Prompt预设的AI系统测试使用&#xff08;可自定义添加使用&#xff09; SparkAi系统现已支持自定义添加官方GPTs&#xff08;对专业领域更加专业&#xff0c;支持多模态文档&#xff0…

科研绘图系列:R语言绘制中国地理地图

文章目录 介绍加载R包导入数据图a图b图c图d系统信息介绍 文章提供了绘制图a,图b和图d的数据和代码。该图展示了不同省份的物种分布情况。 加载R包 library(geojsonsf) library(sf) library(ggplot2) library(RColorBrewer) library(ggspatial) library(</

C++AVL树详解

什么是AVL树 AVL树是最先发明的⾃平衡⼆叉查找树&#xff0c;AVL是⼀颗空树&#xff0c;或者具备下列性质的⼆叉搜索树&#xff1a;它的 左右⼦树都是AV树&#xff0c;且左右⼦树的⾼度差的绝对值不超过1。AVL树是⼀颗⾼度平衡搜索⼆叉树&#xff0c; 通过控制⾼度差去控制平衡…

python的介绍以及基本操作

python的介绍 &#xff08;1&#xff09;python是一门编程语言&#xff08;比如&#xff1a;java、c、c、.net、go等都是编程语言&#xff09; python 也是胶水语言 &#xff08;2&#xff09;python是一门面向对象&#xff0c;解释型的动态类型的编程语言&#xff0c; a、什…

select、epoll相关

select函数&#xff1a; int select(int nfds, // 监控的文件描述符集里最大文件描述符加1fd_set *readfds, // 监控有读数据到达文件描述符集合&#xff0c;引用类型的参数fd_set *writefds, // 监控写数据到达文件描述符集合&…

【零散技术】一分钟完成Odoo悬挂网站备案号

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 目录 1.激活开发者模式 2.修改视图 Odoo套上域名是常见的需求&#xff0c;当我们兴致勃勃的做好 域名申请&#xff0c;网站备案&#xff0c;域名解析&#xff0c;SSL证书申请&#xff0c;Nginx转发后&#xff0c;就可以通过域…

横向移动与痕迹清理

目录 横向移动漏洞利⽤服务利⽤IPC横向计划任务横向计划任务横向WMI横向SMB横向DCOM横向WinRM横向PSEXEC横向其他⽅式横向 软件部署利⽤GPO组策略横向 密码喷洒密码策略检查喷洒主机喷洒⽤户名喷洒密码喷洒hash喷洒服务 痕迹清除OPSEC清除webshell清除隧道⼯具清除落地样本清除…

由于找不到krpt.dll,无法继续执行代码该怎么办?总结三种简单有效修复方法

1. krpt.dll 简介 1.1 定义 krpt.dll 是一个 Windows 动态链接库文件&#xff08;Dynamic Link Library&#xff09;&#xff0c;这种类型的文件包含可由多个应用程序共享的函数和资源。它是Windows操作系统中的一个重要组件&#xff0c;对于系统的正常运行起着至关重要的作用…

模块化沙箱的功能特点

模块化沙箱是一种高灵活性和高扩展性的数据安全产品&#xff0c;通过选择不同的沙箱模块&#xff0c;满足不同的安全需求。 同时&#xff0c;深信达模块化沙箱&#xff0c;根据企事业单位各类国密标准需求&#xff0c;合理转换沙箱模式&#xff0c;满足不同场景、不同类型的数…

TK东南亚、美区、英区产品投放内容该如何选择?

TikTok是抖音在海外市场的版本&#xff0c;已经成为全球最受欢迎的短视频应用之一&#xff0c;并被视为品牌国际化的重要平台。卖家若能有效利用 TikTok&#xff0c;有望在全球范围内提升企业知名度和产品销量&#xff0c;吸引大量的粉丝和订单。那么&#xff0c;在不同国家&am…

每日论文13-18TCAS2数控调谐电感的V波段CMOS压控振荡器

《A V-Band CMOS VCO With Digitally-Controlled Inductor for Frequency Tuning》 18TCAS2 广东省毫米波与太赫兹重点实验室 有个手头上的东西感觉粗调电感可能会比粗调电容好一些&#xff0c;所以拜读一下老板18年的这篇TCAS2&#xff0c;这感觉是个偏理论一点的工作。 首…

哇塞!FLUX 杠上 Midjourney,你选谁?

大家和大家聊聊最近超火的 AI 绘图工具 ——Black Forest Labs 的 FLUX 和一直备受青睐的 Midjourney。 来源&#xff1a;blackforestlabs.ai FLUX 这套开源的文本转图像模型一经推出&#xff0c;就掀起了不小的波澜。好多设计同行都对它充满了好奇与期待&#xff0c;这无疑给…

封装、继承、抽象类

面向对象共有三个特征&#xff1a;封装&#xff0c;继承&#xff0c;多态。 封装 封装表现&#xff1a; &#xff08;1&#xff09;方法就是一个最基本封装体。 &#xff08;2&#xff09;类其实也是一个封装体。 封装的好处&#xff1a; &#xff08;1&#xff09;提高…

Jquery serialize()、serializeArray()、$.param()

param()方法 1.定义&#xff1a;param() 方法创建**数组或对象**的序列化表示。》》该序列化值可在进行 AJAX 请求时在 URL 查询字符串中使用。2.语法&#xff1a;$.param(object,trad)object&#xff1a;必需&#xff0c;规定要序列化的数组或对象。trad&#xff1a;可选。布尔…

如何提高LabVIEW编程效率

提高LabVIEW编程效率对开发者来说非常重要&#xff0c;尤其是在处理复杂项目或紧迫的开发周期时。以下是一些可以显著提升LabVIEW编程效率的技巧&#xff0c;从代码结构、工具使用到团队协作的多个角度进行详细分析&#xff1a; 1. 模块化设计 模块化设计 是提高代码可维护性和…

Linux——grep-wc-管道符

grep命令 利用关键字过滤文件行&#xff0c;找到关键字所在那一行 wc命令 统计文件行数&#xff0c;单词数量 wc命令 不带选项全选 wc -c test.txt 字节bytes数量 wc -m test.txt 字符数量 wc -l test-txt 行数 wc -w test-txt 单词数量 管道符 | 将左边命令的…

【LLM论文日更】| BGE-M3E embedding模型

论文&#xff1a;https://arxiv.org/pdf/2402.03216代码&#xff1a;GitHub - FlagOpen/FlagEmbedding: Retrieval and Retrieval-augmented LLMs机构&#xff1a;BAAI领域&#xff1a;embedding model发表&#xff1a; ​ 研究背景 研究问题&#xff1a;这篇文章要解决的问…

AI时代大厂AI项目管理学习路线

AI时代避免被裁员&#xff0c;大厂AI项目管理学习路线主要包括&#xff1a; 1、AI项目管理基础技能。 2、项目管理AI技术知识。 3、数据分析与决策。 4、AI项目管理工具。 5、AI项目管理知识扩展。 01 AI项目管理基础技能。 AI项目管理基础技能构成了项目管理的骨架&…